ifeq ($(PKG_VERSION),4.3.3)
PKG_MD5SUM:=cc3c5565fdb9ab87a05ddb106ba0bd1f
endif
- ifeq ($(PKG_VERSION),4.3.4)
- PKG_MD5SUM:=60df63222dbffd53ca11492a2545044f
- endif
ifeq ($(PKG_VERSION),4.3.5)
PKG_MD5SUM:=e588cfde3bf323f82918589b94f14a15
endif
ifeq ($(PKG_VERSION),4,4,1)
PKG_MD5SUM:=927eaac3d44b22f31f9c83df82f26436
endif
- ifeq ($(PKG_VERSION),4.4.2)
- PKG_MD5SUM:=70f5ac588a79e3c9901d5b34f58d896d
- endif
- ifeq ($(PKG_VERSION),4.4.3)
- PKG_MD5SUM:=fe1ca818fc6d2caeffc9051fe67ff103
- endif
- ifeq ($(PKG_VERSION),4.4.4)
- PKG_MD5SUM:=7ff5ce9e5f0b088ab48720bbd7203530
- endif
ifeq ($(PKG_VERSION),4.4.5)
PKG_MD5SUM:=44b3192c4c584b9be5243d9e8e7e0ed1
endif
- ifeq ($(PKG_VERSION),4.5.0)
- PKG_MD5SUM:=ff27b7c4a5d5060c8a8543a44abca31f
- endif
ifeq ($(PKG_VERSION),4.5.1)
PKG_MD5SUM:=48231a8e33ed6e058a341c53b819de1a
endif
$(call qstrip,$(CONFIG_EXTRA_GCC_CONFIG_OPTIONS)) \
$(if $(CONFIG_mips64)$(CONFIG_mips64el),--with-arch=mips64 --with-abi=64) \
$(if $(CONFIG_GCC_VERSION_LLVM),--enable-llvm=$(BUILD_DIR_BASE)/host/llvm) \
- $(if $(CONFIG_GCC_VERSION_4_3_3_CS)$(CONFIG_GCC_VERSION_4_4_1_CS)$(CONFIG_GCC_VERSION_4_4_3_CS),--enable-poison-system-directories)
+ $(if $(CONFIG_GCC_VERSION_4_3_3_CS)$(CONFIG_GCC_VERSION_4_4_1_CS),--enable-poison-system-directories)
ifneq ($(CONFIG_GCC_VERSION_4_4)$(CONFIG_GCC_VERSION_4_5),)
ifneq ($(CONFIG_mips)$(CONFIG_mipsel),)
+++ /dev/null
---- gcc/gcc/config/--- gcc/contrib/regression/objs-gcc.sh
-+++ gcc/contrib/regression/objs-gcc.sh
-@@ -105,6 +105,10 @@
- then
- make all-gdb all-dejagnu all-ld || exit 1
- make install-gdb install-dejagnu install-ld || exit 1
-+elif [ $H_REAL_TARGET = $H_REAL_HOST -a $H_REAL_TARGET = i686-pc-linux-uclibc ]
-+ then
-+ make all-gdb all-dejagnu all-ld || exit 1
-+ make install-gdb install-dejagnu install-ld || exit 1
- elif [ $H_REAL_TARGET = $H_REAL_HOST ] ; then
- make bootstrap || exit 1
- make install || exit 1
---- gcc/libjava/classpath/ltconfig
-+++ gcc/libjava/classpath/ltconfig
-@@ -603,7 +603,7 @@
-
- # Transform linux* to *-*-linux-gnu*, to support old configure scripts.
- case $host_os in
--linux-gnu*) ;;
-+linux-gnu*|linux-uclibc*) ;;
- linux*) host=`echo $host | sed 's/^\(.*-.*-linux\)\(.*\)$/\1-gnu\2/'`
- esac
-
-@@ -1251,7 +1251,7 @@
- ;;
-
- # This must be Linux ELF.
--linux-gnu*)
-+linux*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
+++ /dev/null
-diff -rdup gcc-4.2.1.oorig/gcc/config.gcc gcc-4.2.1/gcc/config.gcc
---- gcc-4.2.1.oorig/gcc/config.gcc 2007-10-01 11:52:52.000000000 +0200
-+++ gcc-4.2.1/gcc/config.gcc 2007-10-01 13:22:12.000000000 +0200
-@@ -494,6 +494,9 @@ case ${target} in
- alpha*)
- tm_file="${cpu_type}/${cpu_type}.h alpha/elf.h alpha/linux.h alpha/linux-elf.h gnu.h ${tm_file}"
- ;;
-+ i[34567]86-*hurd*-*)
-+ tm_file="${cpu_type}/${cpu_type}.h i386/unix.h i386/att.h dbxelf.h elfos.h svr4.h i386/gnu.h gnu.h ${tm_file}"
-+ ;;
- i[34567]86-*-*)
- tm_file="${cpu_type}/${cpu_type}.h i386/unix.h i386/att.h dbxelf.h elfos.h svr4.h linux.h i386/linux.h gnu.h ${tm_file}"
- ;;
+++ /dev/null
-2008-03-02 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
-
- Backport from upstream Libtool:
-
- 2007-10-12 Eric Blake <ebb9@byu.net>
-
- Deal with Autoconf 2.62's semantic change in m4_append.
- * ltsugar.m4 (lt_append): Replace broken versions of
- m4_append.
- (lt_if_append_uniq): Don't require separator to be overquoted, and
- avoid broken m4_append.
- (lt_dict_add): Fix typo.
- * libtool.m4 (_LT_DECL): Don't overquote separator.
-
-diff --git a/libtool.m4 b/libtool.m4
-index e86cd02..26a039a 100644
---- a/libtool.m4
-+++ b/libtool.m4
-@@ -319,7 +319,7 @@ m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])],
- # VALUE may be 0, 1 or 2 for a computed quote escaped value based on
- # VARNAME. Any other value will be used directly.
- m4_define([_LT_DECL],
--[lt_if_append_uniq([lt_decl_varnames], [$2], [[, ]],
-+[lt_if_append_uniq([lt_decl_varnames], [$2], [, ],
- [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name],
- [m4_ifval([$1], [$1], [$2])])
- lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3])
-diff --git a/ltsugar.m4 b/ltsugar.m4
-index fc51dc7..dd4f871 100644
---- a/ltsugar.m4
-+++ b/ltsugar.m4
-@@ -1,13 +1,13 @@
- # ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*-
- #
--# Copyright (C) 2004, 2005 Free Software Foundation, Inc.
-+# Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc.
- # Written by Gary V. Vaughan.
- #
- # This file is free software; the Free Software Foundation gives
- # unlimited permission to copy and/or distribute it, with or without
- # modifications, as long as this notice is preserved.
-
--# serial 3 ltsugar.m4
-+# serial 4 ltsugar.m4
-
- # This is to help aclocal find these macros, as it can't see m4_define.
- AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])])
-@@ -46,6 +46,20 @@ m4_define([lt_cdr],
- m4_define([lt_unquote], $1)
-
-
-+# lt_append(MACRO-NAME, STRING, [SEPARATOR])
-+# ------------------------------------------
-+# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'.
-+# Note that neither SEPARATOR nor STRING are expanded. No SEPARATOR is
-+# output if MACRO-NAME was previously undefined (different than defined
-+# and empty).
-+# This macro is needed until we can rely on Autoconf 2.62, since earlier
-+# versions of m4 mistakenly expanded SEPARATOR.
-+m4_define([lt_append],
-+[m4_define([$1],
-+ m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])])
-+
-+
-+
- # lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...])
- # ----------------------------------------------------------
- # Produce a SEP delimited list of all paired combinations of elements of
-@@ -67,10 +81,10 @@ m4_define([lt_combine],
- # by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ.
- m4_define([lt_if_append_uniq],
- [m4_ifdef([$1],
-- [m4_bmatch($3[]m4_defn([$1])$3, $3[]m4_re_escape([$2])$3,
-- [$5],
-- [m4_append([$1], [$2], [$3])$4])],
-- [m4_append([$1], [$2], [$3])$4])])
-+ [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1],
-+ [lt_append([$1], [$2], [$3])$4],
-+ [$5])],
-+ [lt_append([$1], [$2], [$3])$4])])
-
-
- # lt_dict_add(DICT, KEY, VALUE)
-
+++ /dev/null
---- a/gcc/cp/Make-lang.in
-+++ b/gcc/cp/Make-lang.in
-@@ -73,7 +73,7 @@ g++-cross$(exeext): g++$(exeext)
- CXX_C_OBJS = attribs.o c-common.o c-format.o c-pragma.o c-semantics.o c-lex.o \
- c-dump.o $(CXX_TARGET_OBJS) c-pretty-print.o c-opts.o c-pch.o \
- c-incpath.o cppdefault.o c-ppoutput.o c-cppbuiltin.o prefix.o \
-- c-gimplify.o c-omp.o tree-inline.o
-+ c-gimplify.o c-omp.o
-
- # Language-specific object files for C++ and Objective C++.
- CXX_AND_OBJCXX_OBJS = cp/call.o cp/decl.o cp/expr.o cp/pt.o cp/typeck2.o \
+++ /dev/null
---- gcc-4.0.0/boehm-gc/include/gc.h-orig 2005-04-28 22:28:57.000000000 -0500
-+++ gcc-4.0.0/boehm-gc/include/gc.h 2005-04-28 22:30:38.000000000 -0500
-@@ -500,7 +500,7 @@
- #ifdef __linux__
- # include <features.h>
- # if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1 || __GLIBC__ > 2) \
-- && !defined(__ia64__)
-+ && !defined(__ia64__) && !defined(__UCLIBC__)
- # ifndef GC_HAVE_BUILTIN_BACKTRACE
- # define GC_HAVE_BUILTIN_BACKTRACE
- # endif
+++ /dev/null
-Index: gcc-4.3.0/libstdc++-v3/include/c_global/cstdio
-===================================================================
---- gcc-4.3.0/libstdc++-v3/include/c_global/cstdio (revision 129202)
-+++ gcc-4.3.0/libstdc++-v3/include/c_global/cstdio (working copy)
-@@ -144,7 +144,7 @@
-
- _GLIBCXX_END_NAMESPACE
-
--#if _GLIBCXX_USE_C99
-+#if _GLIBCXX_USE_C99 || defined __UCLIBC__
-
- #undef snprintf
- #undef vfscanf
+++ /dev/null
-Index: gcc-4.2/libmudflap/mf-hooks2.c
-===================================================================
---- gcc-4.2/libmudflap/mf-hooks2.c (revision 119834)
-+++ gcc-4.2/libmudflap/mf-hooks2.c (working copy)
-@@ -427,7 +427,7 @@
- {
- TRACE ("%s\n", __PRETTY_FUNCTION__);
- MF_VALIDATE_EXTENT(s, n, __MF_CHECK_WRITE, "bzero region");
-- bzero (s, n);
-+ memset (s, 0, n);
- }
-
-
-@@ -437,7 +437,7 @@
- TRACE ("%s\n", __PRETTY_FUNCTION__);
- MF_VALIDATE_EXTENT(src, n, __MF_CHECK_READ, "bcopy src");
- MF_VALIDATE_EXTENT(dest, n, __MF_CHECK_WRITE, "bcopy dest");
-- bcopy (src, dest, n);
-+ memmove (dest, src, n);
- }
-
-
-@@ -447,7 +447,7 @@
- TRACE ("%s\n", __PRETTY_FUNCTION__);
- MF_VALIDATE_EXTENT(s1, n, __MF_CHECK_READ, "bcmp 1st arg");
- MF_VALIDATE_EXTENT(s2, n, __MF_CHECK_READ, "bcmp 2nd arg");
-- return bcmp (s1, s2, n);
-+ return n == 0 ? 0 : memcmp (s1, s2, n);
- }
-
-
-@@ -456,7 +456,7 @@
- size_t n = strlen (s);
- TRACE ("%s\n", __PRETTY_FUNCTION__);
- MF_VALIDATE_EXTENT(s, CLAMPADD(n, 1), __MF_CHECK_READ, "index region");
-- return index (s, c);
-+ return strchr (s, c);
- }
-
-
-@@ -465,7 +465,7 @@
- size_t n = strlen (s);
- TRACE ("%s\n", __PRETTY_FUNCTION__);
- MF_VALIDATE_EXTENT(s, CLAMPADD(n, 1), __MF_CHECK_READ, "rindex region");
-- return rindex (s, c);
-+ return strrchr (s, c);
- }
-
- /* XXX: stpcpy, memccpy */
+++ /dev/null
-Fixes GCC PR36350
-
---- a/gcc/regrename.c
-+++ b/gcc/regrename.c
-@@ -783,6 +783,10 @@ build_def_use (basic_block bb)
- recog_data.operand_type[i] = OP_INOUT;
- }
-
-+ /* Unshare dup_loc RTL */
-+ for (i = 0; i < recog_data.n_dups; i++)
-+ *recog_data.dup_loc[i] = copy_rtx(*recog_data.dup_loc[i]);
-+
- /* Step 1: Close chains for which we have overlapping reads. */
- for (i = 0; i < n_ops; i++)
- scan_rtx (insn, recog_data.operand_loc[i],
-@@ -813,7 +817,7 @@ build_def_use (basic_block bb)
- OP_IN, 0);
-
- for (i = 0; i < recog_data.n_dups; i++)
-- *recog_data.dup_loc[i] = copy_rtx (old_dups[i]);
-+ *recog_data.dup_loc[i] = old_dups[i];
- for (i = 0; i < n_ops; i++)
- *recog_data.operand_loc[i] = old_operands[i];
- if (recog_data.n_dups)
+++ /dev/null
---- a/gcc/config/arm/arm.c
-+++ b/gcc/config/arm/arm.c
-@@ -3769,6 +3769,7 @@ arm_legitimate_address_p (enum machine_m
- rtx xop1 = XEXP (x, 1);
-
- return ((arm_address_register_rtx_p (xop0, strict_p)
-+ && GET_CODE(xop1) == CONST_INT
- && arm_legitimate_index_p (mode, xop1, outer, strict_p))
- || (arm_address_register_rtx_p (xop1, strict_p)
- && arm_legitimate_index_p (mode, xop0, outer, strict_p)));
---- a/gcc/config/arm/arm.md
-+++ b/gcc/config/arm/arm.md
-@@ -4199,7 +4199,7 @@
-
- (define_expand "extendqihi2"
- [(set (match_dup 2)
-- (ashift:SI (match_operand:QI 1 "general_operand" "")
-+ (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")
- (const_int 24)))
- (set (match_operand:HI 0 "s_register_operand" "")
- (ashiftrt:SI (match_dup 2)
-@@ -4224,7 +4224,7 @@
-
- (define_insn "*arm_extendqihi_insn"
- [(set (match_operand:HI 0 "s_register_operand" "=r")
-- (sign_extend:HI (match_operand:QI 1 "memory_operand" "Uq")))]
-+ (sign_extend:HI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
- "TARGET_ARM && arm_arch4"
- "ldr%(sb%)\\t%0, %1"
- [(set_attr "type" "load_byte")
-@@ -4235,7 +4235,7 @@
-
- (define_expand "extendqisi2"
- [(set (match_dup 2)
-- (ashift:SI (match_operand:QI 1 "general_operand" "")
-+ (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")
- (const_int 24)))
- (set (match_operand:SI 0 "s_register_operand" "")
- (ashiftrt:SI (match_dup 2)
-@@ -4267,7 +4267,7 @@
-
- (define_insn "*arm_extendqisi"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
-- (sign_extend:SI (match_operand:QI 1 "memory_operand" "Uq")))]
-+ (sign_extend:SI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
- "TARGET_ARM && arm_arch4 && !arm_arch6"
- "ldr%(sb%)\\t%0, %1"
- [(set_attr "type" "load_byte")
-@@ -4278,7 +4278,8 @@
-
- (define_insn "*arm_extendqisi_v6"
- [(set (match_operand:SI 0 "s_register_operand" "=r,r")
-- (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uq")))]
-+ (sign_extend:SI
-+ (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
- "TARGET_ARM && arm_arch6"
- "@
- sxtb%?\\t%0, %1
---- a/gcc/config/arm/predicates.md
-+++ b/gcc/config/arm/predicates.md
-@@ -234,6 +234,10 @@
- (match_test "arm_legitimate_address_p (mode, XEXP (op, 0), SIGN_EXTEND,
- 0)")))
-
-+(define_special_predicate "arm_reg_or_extendqisi_mem_op"
-+ (ior (match_operand 0 "arm_extendqisi_mem_op")
-+ (match_operand 0 "s_register_operand")))
-+
- (define_predicate "power_of_two_operand"
- (match_code "const_int")
- {
+++ /dev/null
---- a/gcc/config/cris/cris.md 2009-10-12 10:28:01.000000000 +0200
-+++ b/gcc/config/cris/cris.md 2009-10-12 10:29:09.000000000 +0200
-@@ -4920,7 +4920,9 @@
- "REGNO (operands[2]) == REGNO (operands[0])
- && INTVAL (operands[3]) <= 65535 && INTVAL (operands[3]) >= 0
- && !CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'I')
-- && !side_effects_p (operands[1])"
-+ && !side_effects_p (operands[1])
-+ && (!REG_P (operands[1])
-+ || REGNO (operands[1]) <= CRIS_LAST_GENERAL_REGISTER)"
- ;; FIXME: CC0 valid except for M (i.e. CC_NOT_NEGATIVE).
- [(set (match_dup 0) (match_dup 4))
- (set (match_dup 5) (match_dup 6))]
-
-
+++ /dev/null
-Index: gcc-4.3.0/gcc/config/arm/t-linux
-===================================================================
---- gcc-4.3.0/gcc/config/arm/t-linux (revision 129896)
-+++ gcc-4.3.0/gcc/config/arm/t-linux (working copy)
-@@ -3,7 +3,10 @@
- TARGET_LIBGCC2_CFLAGS = -fomit-frame-pointer -fPIC
-
- LIB1ASMSRC = arm/lib1funcs.asm
--LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_lnx
-+LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_lnx \
-+ _negdf2 _addsubdf3 _muldivdf3 _cmpdf2 _unorddf2 _fixdfsi _fixunsdfsi \
-+ _truncdfsf2 _negsf2 _addsubsf3 _muldivsf3 _cmpsf2 _unordsf2 \
-+ _fixsfsi _fixunssfsi _floatdidf _floatundidf _floatdisf _floatundisf
-
- # MULTILIB_OPTIONS = mhard-float/msoft-float
- # MULTILIB_DIRNAMES = hard-float soft-float
-Index: gcc-4.3.0/gcc/config/arm/linux-elf.h
-===================================================================
---- gcc-4.3.0/gcc/config/arm/linux-elf.h (revision 129896)
-+++ gcc-4.3.0/gcc/config/arm/linux-elf.h (working copy)
-@@ -48,7 +62,7 @@
- %{shared:-lc} \
- %{!shared:%{profile:-lc_p}%{!profile:-lc}}"
-
--#define LIBGCC_SPEC "%{msoft-float:-lfloat} %{mfloat-abi=soft*:-lfloat} -lgcc"
-+#define LIBGCC_SPEC "-lgcc"
-
- #define GLIBC_DYNAMIC_LINKER "/lib/ld-linux.so.2"
-
+++ /dev/null
---- a/libgcc/Makefile.in
-+++ b/libgcc/Makefile.in
-@@ -680,11 +680,12 @@ $(libgcov-objects): %$(objext): $(gcc_sr
-
- # Static libraries.
- libgcc.a: $(libgcc-objects)
-+libgcc_pic.a: $(libgcc-s-objects)
- libgcov.a: $(libgcov-objects)
- libunwind.a: $(libunwind-objects)
- libgcc_eh.a: $(libgcc-eh-objects)
-
--libgcc.a libgcov.a libunwind.a libgcc_eh.a:
-+libgcc.a libgcov.a libunwind.a libgcc_eh.a libgcc_pic.a:
- -rm -f $@
-
- objects="$(objects)"; \
-@@ -706,7 +707,7 @@ libgcc_s$(SHLIB_EXT): libunwind$(SHLIB_E
- endif
-
- ifeq ($(enable_shared),yes)
--all: libgcc_eh.a libgcc_s$(SHLIB_EXT)
-+all: libgcc_eh.a libgcc_pic.a libgcc_s$(SHLIB_EXT)
- ifneq ($(LIBUNWIND),)
- all: libunwind$(SHLIB_EXT)
- endif
-@@ -879,6 +880,10 @@ install-shared:
- chmod 644 $(DESTDIR)$(inst_libdir)/libgcc_eh.a
- $(RANLIB) $(DESTDIR)$(inst_libdir)/libgcc_eh.a
-
-+ $(INSTALL_DATA) libgcc_pic.a $(mapfile) $(DESTDIR)$(inst_libdir)/
-+ chmod 644 $(DESTDIR)$(inst_libdir)/libgcc_pic.a
-+ $(RANLIB) $(DESTDIR)$(inst_libdir)/libgcc_pic.a
-+
- $(subst @multilib_dir@,$(MULTIDIR),$(subst \
- @shlib_base_name@,libgcc_s,$(subst \
- @shlib_slibdir_qual@,$(MULTIOSSUBDIR),$(SHLIB_INSTALL))))
+++ /dev/null
-
- This patch brings over a few features from MirBSD:
- * -fhonour-copts
- If this option is not given, it's warned (depending
- on environment variables). This is to catch errors
- of misbuilt packages which override CFLAGS themselves.
- * -Werror-maybe-reset
- Has the effect of -Wno-error if GCC_NO_WERROR is
- set and not '0', a no-operation otherwise. This is
- to be able to use -Werror in "make" but prevent
- GNU autoconf generated configure scripts from
- freaking out.
- * Make -fno-strict-aliasing and -fno-delete-null-pointer-checks
- the default for -O2/-Os, because they trigger gcc bugs
- and can delete code with security implications.
-
- This patch was authored by Thorsten Glaser <tg at mirbsd.de>
- with copyright assignment to the FSF in effect.
-
-Index: gcc-4.3.0/gcc/c-opts.c
-===================================================================
---- gcc-4.3.0.orig/gcc/c-opts.c 2007-07-31 02:27:12.007256629 +0200
-+++ gcc-4.3.0/gcc/c-opts.c 2007-07-31 02:27:39.324813371 +0200
-@@ -108,6 +108,9 @@
- /* Number of deferred options scanned for -include. */
- static size_t include_cursor;
-
-+/* Check if a port honours COPTS. */
-+static int honour_copts = 0;
-+
- static void set_Wimplicit (int);
- static void handle_OPT_d (const char *);
- static void set_std_cxx98 (int);
-@@ -462,6 +465,14 @@
- enable_warning_as_error ("implicit-function-declaration", value, CL_C | CL_ObjC);
- break;
-
-+ case OPT_Werror_maybe_reset:
-+ {
-+ char *ev = getenv ("GCC_NO_WERROR");
-+ if ((ev != NULL) && (*ev != '0'))
-+ cpp_opts->warnings_are_errors = 0;
-+ }
-+ break;
-+
- case OPT_Wformat:
- set_Wformat (value);
- break;
-@@ -708,6 +719,12 @@
- flag_exceptions = value;
- break;
-
-+ case OPT_fhonour_copts:
-+ if (c_language == clk_c) {
-+ honour_copts++;
-+ }
-+ break;
-+
- case OPT_fimplement_inlines:
- flag_implement_inlines = value;
- break;
-@@ -1248,6 +1265,47 @@
- /* Has to wait until now so that cpplib has its hash table. */
- init_pragma ();
-
-+ if (c_language == clk_c) {
-+ char *ev = getenv ("GCC_HONOUR_COPTS");
-+ int evv;
-+ if (ev == NULL)
-+ evv = -1;
-+ else if ((*ev == '0') || (*ev == '\0'))
-+ evv = 0;
-+ else if (*ev == '1')
-+ evv = 1;
-+ else if (*ev == '2')
-+ evv = 2;
-+ else if (*ev == 's')
-+ evv = -1;
-+ else {
-+ warning (0, "unknown GCC_HONOUR_COPTS value, assuming 1");
-+ evv = 1; /* maybe depend this on something like MIRBSD_NATIVE? */
-+ }
-+ if (evv == 1) {
-+ if (honour_copts == 0) {
-+ error ("someone does not honour COPTS at all in lenient mode");
-+ return false;
-+ } else if (honour_copts != 1) {
-+ warning (0, "someone does not honour COPTS correctly, passed %d times",
-+ honour_copts);
-+ }
-+ } else if (evv == 2) {
-+ if (honour_copts == 0) {
-+ error ("someone does not honour COPTS at all in strict mode");
-+ return false;
-+ } else if (honour_copts != 1) {
-+ error ("someone does not honour COPTS correctly, passed %d times",
-+ honour_copts);
-+ return false;
-+ }
-+ } else if (evv == 0) {
-+ if (honour_copts != 1)
-+ inform ("someone does not honour COPTS correctly, passed %d times",
-+ honour_copts);
-+ }
-+ }
-+
- return true;
- }
-
-Index: gcc-4.3.0/gcc/c.opt
-===================================================================
---- gcc-4.3.0.orig/gcc/c.opt 2007-07-31 02:27:12.015257093 +0200
-+++ gcc-4.3.0/gcc/c.opt 2007-07-31 02:27:39.328813597 +0200
-@@ -207,6 +207,10 @@
- C ObjC RejectNegative Warning
- This switch is deprecated; use -Werror=implicit-function-declaration instead
-
-+Werror-maybe-reset
-+C ObjC C++ ObjC++
-+; Documented in common.opt
-+
- Wfloat-equal
- C ObjC C++ ObjC++ Var(warn_float_equal) Warning
- Warn if testing floating point numbers for equality
-@@ -590,6 +594,9 @@
- fhonor-std
- C++ ObjC++
-
-+fhonour-copts
-+C ObjC C++ ObjC++ RejectNegative
-+
- fhosted
- C ObjC
- Assume normal C execution environment
-Index: gcc-4.3.0/gcc/common.opt
-===================================================================
---- gcc-4.3.0.orig/gcc/common.opt 2007-07-31 02:27:12.023257546 +0200
-+++ gcc-4.3.0/gcc/common.opt 2007-07-31 02:27:39.360815422 +0200
-@@ -102,6 +102,10 @@
- Common Joined
- Treat specified warning as error
-
-+Werror-maybe-reset
-+Common
-+If environment variable GCC_NO_WERROR is set, act as -Wno-error
-+
- Wextra
- Common Warning
- Print extra (possibly unwanted) warnings
-@@ -528,6 +532,9 @@
- Common Report Var(flag_guess_branch_prob) Optimization
- Enable guessing of branch probabilities
-
-+fhonour-copts
-+Common RejectNegative
-+
- ; Nonzero means ignore `#ident' directives. 0 means handle them.
- ; Generate position-independent code for executables if possible
- ; On SVR4 targets, it also controls whether or not to emit a
-Index: gcc-4.3.0/gcc/opts.c
-===================================================================
---- gcc-4.3.0.orig/gcc/opts.c 2007-07-31 02:27:12.031257991 +0200
-+++ gcc-4.3.0/gcc/opts.c 2007-07-31 02:28:36.320061346 +0200
-@@ -830,9 +830,6 @@
- flag_schedule_insns_after_reload = 1;
- #endif
- flag_regmove = 1;
-- flag_strict_aliasing = 1;
-- flag_strict_overflow = 1;
-- flag_delete_null_pointer_checks = 1;
- flag_reorder_blocks = 1;
- flag_reorder_functions = 1;
- flag_tree_store_ccp = 1;
-@@ -850,6 +847,10 @@
-
- if (optimize >= 3)
- {
-+ flag_strict_aliasing = 1;
-+ flag_strict_overflow = 1;
-+ flag_delete_null_pointer_checks = 1;
-+
- flag_predictive_commoning = 1;
- flag_inline_functions = 1;
- flag_unswitch_loops = 1;
-@@ -1441,6 +1442,17 @@
- enable_warning_as_error (arg, value, lang_mask);
- break;
-
-+ case OPT_Werror_maybe_reset:
-+ {
-+ char *ev = getenv ("GCC_NO_WERROR");
-+ if ((ev != NULL) && (*ev != '0'))
-+ warnings_are_errors = 0;
-+ }
-+ break;
-+
-+ case OPT_fhonour_copts:
-+ break;
-+
- case OPT_Wextra:
- set_Wextra (value);
- break;
-Index: gcc-4.3.0/gcc/doc/cppopts.texi
-===================================================================
---- gcc-4.3.0.orig/gcc/doc/cppopts.texi 2007-07-31 02:27:12.039258455 +0200
-+++ gcc-4.3.0/gcc/doc/cppopts.texi 2007-07-31 02:27:39.408818157 +0200
-@@ -168,6 +168,11 @@
- Make all warnings into hard errors. Source code which triggers warnings
- will be rejected.
-
-+ at item -Werror-maybe-reset
-+ at opindex Werror-maybe-reset
-+Act like @samp{-Wno-error} if the @env{GCC_NO_WERROR} environment
-+variable is set to anything other than 0 or empty.
-+
- @item -Wsystem-headers
- @opindex Wsystem-headers
- Issue warnings for code in system headers. These are normally unhelpful
-Index: gcc-4.3.0/gcc/doc/invoke.texi
-===================================================================
---- gcc-4.3.0.orig/gcc/doc/invoke.texi 2007-07-31 02:27:12.047258920 +0200
-+++ gcc-4.3.0/gcc/doc/invoke.texi 2007-07-31 02:29:13.218164047 +0200
-@@ -233,7 +233,7 @@
- -Wconversion -Wcoverage-mismatch -Wno-deprecated-declarations @gol
- -Wdisabled-optimization -Wno-div-by-zero @gol
- -Wempty-body -Wno-endif-labels @gol
---Werror -Werror=* @gol
-+-Werror -Werror=* -Werror-maybe-reset @gol
- -Wfatal-errors -Wfloat-equal -Wformat -Wformat=2 @gol
- -Wno-format-extra-args -Wformat-nonliteral @gol
- -Wformat-security -Wformat-y2k -Wignored-qualifiers @gol
-@@ -4030,6 +4030,22 @@
- @option{-Wall} and by @option{-pedantic}, which can be disabled with
- @option{-Wno-pointer-sign}.
-
-+ at item -Werror-maybe-reset
-+ at opindex Werror-maybe-reset
-+Act like @samp{-Wno-error} if the @env{GCC_NO_WERROR} environment
-+variable is set to anything other than 0 or empty.
-+
-+ at item -fhonour-copts
-+ at opindex fhonour-copts
-+If @env{GCC_HONOUR_COPTS} is set to 1, abort if this option is not
-+given at least once, and warn if it is given more than once.
-+If @env{GCC_HONOUR_COPTS} is set to 2, abort if this option is not
-+given exactly once.
-+If @env{GCC_HONOUR_COPTS} is set to 0 or unset, warn if this option
-+is not given exactly once.
-+The warning is quelled if @env{GCC_HONOUR_COPTS} is set to @samp{s}.
-+This flag and environment variable only affect the C language.
-+
- @item -Wstack-protector
- @opindex Wstack-protector
- @opindex Wno-stack-protector
-@@ -5490,7 +5806,7 @@
- second branch or a point immediately following it, depending on whether
- the condition is known to be true or false.
-
--Enabled at levels @option{-O2}, @option{-O3}, @option{-Os}.
-+Enabled at levels @option{-O3}.
-
- @item -fsplit-wide-types
- @opindex fsplit-wide-types
-@@ -5635,7 +5514,7 @@
- @option{-fno-delete-null-pointer-checks} to disable this optimization
- for programs which depend on that behavior.
-
--Enabled at levels @option{-O2}, @option{-O3}, @option{-Os}.
-+Enabled at levels @option{-O3}.
-
- @item -fexpensive-optimizations
- @opindex fexpensive-optimizations
-Index: gcc-4.3.0/gcc/java/jvspec.c
-===================================================================
---- gcc-4.3.0.orig/gcc/java/jvspec.c 2007-07-31 02:27:12.055259364 +0200
-+++ gcc-4.3.0/gcc/java/jvspec.c 2007-07-31 02:27:39.484822490 +0200
-@@ -670,6 +670,7 @@
- class name. Append dummy `.c' that can be stripped by set_input so %b
- is correct. */
- set_input (concat (main_class_name, "main.c", NULL));
-+ putenv ("GCC_HONOUR_COPTS=s"); /* XXX hack! */
- err = do_spec (jvgenmain_spec);
- if (err == 0)
- {
+++ /dev/null
-gcc/ChangeLog
-2007-11-27 Bernhard Fischer <>
-
- * config/arm/arm-protos.h (arm_vector_mode_supported_p,
- arm_hard_regno_mode_ok, const_ok_for_arm): Do not hide non-rtx related
- function prototypes in RTX_CODE.
- * genopinit.c: Include tm_p.h.
-
-Index: gcc-4.3.0/gcc/config/arm/arm-protos.h
-===================================================================
---- gcc-4.3.0/gcc/config/arm/arm-protos.h (revision 130463)
-+++ gcc-4.3.0/gcc/config/arm/arm-protos.h (working copy)
-@@ -40,15 +40,14 @@
- unsigned int);
- extern unsigned int arm_dbx_register_number (unsigned int);
- extern void arm_output_fn_unwind (FILE *, bool);
--
-
- #ifdef TREE_CODE
- extern int arm_return_in_memory (const_tree);
- #endif
--#ifdef RTX_CODE
- extern bool arm_vector_mode_supported_p (enum machine_mode);
- extern int arm_hard_regno_mode_ok (unsigned int, enum machine_mode);
- extern int const_ok_for_arm (HOST_WIDE_INT);
-+#ifdef RTX_CODE
- extern int arm_split_constant (RTX_CODE, enum machine_mode, rtx,
- HOST_WIDE_INT, rtx, rtx, int);
- extern RTX_CODE arm_canonicalize_comparison (RTX_CODE, enum machine_mode,
-Index: gcc-4.3.0/gcc/genopinit.c
-===================================================================
---- gcc-4.3.0/gcc/genopinit.c (revision 130463)
-+++ gcc-4.3.0/gcc/genopinit.c (working copy)
-@@ -486,6 +486,7 @@
- printf ("#include \"expr.h\"\n");
- printf ("#include \"optabs.h\"\n");
- printf ("#include \"reload.h\"\n\n");
-+ printf ("#include \"tm_p.h\"\n\n");
-
- printf ("void\ninit_all_optabs (void)\n{\n");
-
+++ /dev/null
-see gcc PR34205
-Index: gcc-4.3.0/gcc/tree.h
-===================================================================
---- gcc-4.3.0/gcc/tree.h (revision 130511)
-+++ gcc-4.3.0/gcc/tree.h (working copy)
-@@ -38,6 +38,7 @@
-
- LAST_AND_UNUSED_TREE_CODE /* A convenient way to get a value for
- NUM_TREE_CODES. */
-+ ,__LAST_AND_UNUSED_TREE_CODE=32767 /* Force 16bit width. */
- };
-
- #undef DEFTREECODE
-Index: gcc-4.3.0/gcc/rtl.h
-===================================================================
---- gcc-4.3.0/gcc/rtl.h (revision 130511)
-+++ gcc-4.3.0/gcc/rtl.h (working copy)
-@@ -48,9 +48,11 @@
- #include "rtl.def" /* rtl expressions are documented here */
- #undef DEF_RTL_EXPR
-
-- LAST_AND_UNUSED_RTX_CODE}; /* A convenient way to get a value for
-+ LAST_AND_UNUSED_RTX_CODE /* A convenient way to get a value for
- NUM_RTX_CODE.
- Assumes default enum value assignment. */
-+ ,__LAST_AND_UNUSED_RTX_CODE=32767 /* Force 16bit width. */
-+};
-
- #define NUM_RTX_CODE ((int) LAST_AND_UNUSED_RTX_CODE)
- /* The cast here, saves many elsewhere. */
-Index: gcc-4.3.0/gcc/c-common.h
-===================================================================
---- gcc-4.3.0/gcc/c-common.h (revision 130511)
-+++ gcc-4.3.0/gcc/c-common.h (working copy)
-@@ -125,6 +125,7 @@
- RID_LAST_AT = RID_AT_IMPLEMENTATION,
- RID_FIRST_PQ = RID_IN,
- RID_LAST_PQ = RID_ONEWAY
-+ ,__LAST_AND_UNUSED_RID=32767 /* Force 16bit width. */
- };
-
- #define OBJC_IS_AT_KEYWORD(rid) \
+++ /dev/null
-\\\\
-\\ gcc PR33200
-Index: gcc-4.3.0/gcc/config.gcc
-===================================================================
---- gcc-4.3.0/gcc/config.gcc (revision 131628)
-+++ gcc-4.3.0/gcc/config.gcc (working copy)
-@@ -2302,7 +2305,7 @@ sh-*-symbianelf* | sh[12346l]*-*-symbian
- if test x${enable_incomplete_targets} = xyes ; then
- tm_defines="$tm_defines SUPPORT_SH1=1 SUPPORT_SH2E=1 SUPPORT_SH4=1 SUPPORT_SH4_SINGLE=1 SUPPORT_SH2A=1 SUPPORT_SH2A_SINGLE=1 SUPPORT_SH5_32MEDIA=1 SUPPORT_SH5_32MEDIA_NOFPU=1 SUPPORT_SH5_64MEDIA=1 SUPPORT_SH5_64MEDIA_NOFPU=1"
- fi
-- use_fixproto=yes
-+ # XXX: why? use_fixproto=yes
- ;;
- sh-*-rtemscoff*)
- tmake_file="sh/t-sh t-rtems sh/t-rtems"
+++ /dev/null
---- gcc-4.3.1/gcc/config.gcc.old 2008-06-17 23:49:00.000000000 +0200
-+++ gcc-4.3.1/gcc/config.gcc 2008-06-17 23:03:07.000000000 +0200
-@@ -1630,6 +1630,7 @@
- if test x$sjlj != x1; then
- tmake_file="$tmake_file m68k/t-slibgcc-elf-ver"
- fi
-+ tmake_file="m68k/t-floatlib m68k/t-m68kbare m68k/t-m68kelf"
- ;;
- m68k-*-rtems*)
- default_m68k_cpu=68020
+++ /dev/null
---- gcc/gcc/config/--- gcc/contrib/regression/objs-gcc.sh
-+++ gcc/contrib/regression/objs-gcc.sh
-@@ -105,6 +105,10 @@
- then
- make all-gdb all-dejagnu all-ld || exit 1
- make install-gdb install-dejagnu install-ld || exit 1
-+elif [ $H_REAL_TARGET = $H_REAL_HOST -a $H_REAL_TARGET = i686-pc-linux-uclibc ]
-+ then
-+ make all-gdb all-dejagnu all-ld || exit 1
-+ make install-gdb install-dejagnu install-ld || exit 1
- elif [ $H_REAL_TARGET = $H_REAL_HOST ] ; then
- make bootstrap || exit 1
- make install || exit 1
---- gcc/libjava/classpath/ltconfig
-+++ gcc/libjava/classpath/ltconfig
-@@ -603,7 +603,7 @@
-
- # Transform linux* to *-*-linux-gnu*, to support old configure scripts.
- case $host_os in
--linux-gnu*) ;;
-+linux-gnu*|linux-uclibc*) ;;
- linux*) host=`echo $host | sed 's/^\(.*-.*-linux\)\(.*\)$/\1-gnu\2/'`
- esac
-
-@@ -1251,7 +1251,7 @@
- ;;
-
- # This must be Linux ELF.
--linux-gnu*)
-+linux*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
+++ /dev/null
-diff -rdup gcc-4.2.1.oorig/gcc/config.gcc gcc-4.2.1/gcc/config.gcc
---- gcc-4.2.1.oorig/gcc/config.gcc 2007-10-01 11:52:52.000000000 +0200
-+++ gcc-4.2.1/gcc/config.gcc 2007-10-01 13:22:12.000000000 +0200
-@@ -494,6 +494,9 @@ case ${target} in
- alpha*)
- tm_file="${cpu_type}/${cpu_type}.h alpha/elf.h alpha/linux.h alpha/linux-elf.h gnu.h ${tm_file}"
- ;;
-+ i[34567]86-*hurd*-*)
-+ tm_file="${cpu_type}/${cpu_type}.h i386/unix.h i386/att.h dbxelf.h elfos.h svr4.h i386/gnu.h gnu.h ${tm_file}"
-+ ;;
- i[34567]86-*-*)
- tm_file="${cpu_type}/${cpu_type}.h i386/unix.h i386/att.h dbxelf.h elfos.h svr4.h linux.h i386/linux.h gnu.h ${tm_file}"
- ;;
+++ /dev/null
-2008-03-02 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
-
- Backport from upstream Libtool:
-
- 2007-10-12 Eric Blake <ebb9@byu.net>
-
- Deal with Autoconf 2.62's semantic change in m4_append.
- * ltsugar.m4 (lt_append): Replace broken versions of
- m4_append.
- (lt_if_append_uniq): Don't require separator to be overquoted, and
- avoid broken m4_append.
- (lt_dict_add): Fix typo.
- * libtool.m4 (_LT_DECL): Don't overquote separator.
-
-diff --git a/libtool.m4 b/libtool.m4
-index e86cd02..26a039a 100644
---- a/libtool.m4
-+++ b/libtool.m4
-@@ -319,7 +319,7 @@ m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])],
- # VALUE may be 0, 1 or 2 for a computed quote escaped value based on
- # VARNAME. Any other value will be used directly.
- m4_define([_LT_DECL],
--[lt_if_append_uniq([lt_decl_varnames], [$2], [[, ]],
-+[lt_if_append_uniq([lt_decl_varnames], [$2], [, ],
- [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name],
- [m4_ifval([$1], [$1], [$2])])
- lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3])
-diff --git a/ltsugar.m4 b/ltsugar.m4
-index fc51dc7..dd4f871 100644
---- a/ltsugar.m4
-+++ b/ltsugar.m4
-@@ -1,13 +1,13 @@
- # ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*-
- #
--# Copyright (C) 2004, 2005 Free Software Foundation, Inc.
-+# Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc.
- # Written by Gary V. Vaughan.
- #
- # This file is free software; the Free Software Foundation gives
- # unlimited permission to copy and/or distribute it, with or without
- # modifications, as long as this notice is preserved.
-
--# serial 3 ltsugar.m4
-+# serial 4 ltsugar.m4
-
- # This is to help aclocal find these macros, as it can't see m4_define.
- AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])])
-@@ -46,6 +46,20 @@ m4_define([lt_cdr],
- m4_define([lt_unquote], $1)
-
-
-+# lt_append(MACRO-NAME, STRING, [SEPARATOR])
-+# ------------------------------------------
-+# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'.
-+# Note that neither SEPARATOR nor STRING are expanded. No SEPARATOR is
-+# output if MACRO-NAME was previously undefined (different than defined
-+# and empty).
-+# This macro is needed until we can rely on Autoconf 2.62, since earlier
-+# versions of m4 mistakenly expanded SEPARATOR.
-+m4_define([lt_append],
-+[m4_define([$1],
-+ m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])])
-+
-+
-+
- # lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...])
- # ----------------------------------------------------------
- # Produce a SEP delimited list of all paired combinations of elements of
-@@ -67,10 +81,10 @@ m4_define([lt_combine],
- # by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ.
- m4_define([lt_if_append_uniq],
- [m4_ifdef([$1],
-- [m4_bmatch($3[]m4_defn([$1])$3, $3[]m4_re_escape([$2])$3,
-- [$5],
-- [m4_append([$1], [$2], [$3])$4])],
-- [m4_append([$1], [$2], [$3])$4])])
-+ [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1],
-+ [lt_append([$1], [$2], [$3])$4],
-+ [$5])],
-+ [lt_append([$1], [$2], [$3])$4])])
-
-
- # lt_dict_add(DICT, KEY, VALUE)
-
+++ /dev/null
---- a/gcc/cp/Make-lang.in
-+++ b/gcc/cp/Make-lang.in
-@@ -73,7 +73,7 @@ g++-cross$(exeext): g++$(exeext)
- CXX_C_OBJS = attribs.o c-common.o c-format.o c-pragma.o c-semantics.o c-lex.o \
- c-dump.o $(CXX_TARGET_OBJS) c-pretty-print.o c-opts.o c-pch.o \
- c-incpath.o cppdefault.o c-ppoutput.o c-cppbuiltin.o prefix.o \
-- c-gimplify.o c-omp.o tree-inline.o
-+ c-gimplify.o c-omp.o
-
- # Language-specific object files for C++ and Objective C++.
- CXX_AND_OBJCXX_OBJS = cp/call.o cp/decl.o cp/expr.o cp/pt.o cp/typeck2.o \
+++ /dev/null
---- gcc-4.0.0/boehm-gc/include/gc.h-orig 2005-04-28 22:28:57.000000000 -0500
-+++ gcc-4.0.0/boehm-gc/include/gc.h 2005-04-28 22:30:38.000000000 -0500
-@@ -500,7 +500,7 @@
- #ifdef __linux__
- # include <features.h>
- # if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1 || __GLIBC__ > 2) \
-- && !defined(__ia64__)
-+ && !defined(__ia64__) && !defined(__UCLIBC__)
- # ifndef GC_HAVE_BUILTIN_BACKTRACE
- # define GC_HAVE_BUILTIN_BACKTRACE
- # endif
+++ /dev/null
-Index: gcc-4.3.0/libstdc++-v3/include/c_global/cstdio
-===================================================================
---- gcc-4.3.0/libstdc++-v3/include/c_global/cstdio (revision 129202)
-+++ gcc-4.3.0/libstdc++-v3/include/c_global/cstdio (working copy)
-@@ -144,7 +144,7 @@
-
- _GLIBCXX_END_NAMESPACE
-
--#if _GLIBCXX_USE_C99
-+#if _GLIBCXX_USE_C99 || defined __UCLIBC__
-
- #undef snprintf
- #undef vfscanf
+++ /dev/null
-Index: gcc-4.2/libmudflap/mf-hooks2.c
-===================================================================
---- gcc-4.2/libmudflap/mf-hooks2.c (revision 119834)
-+++ gcc-4.2/libmudflap/mf-hooks2.c (working copy)
-@@ -427,7 +427,7 @@
- {
- TRACE ("%s\n", __PRETTY_FUNCTION__);
- MF_VALIDATE_EXTENT(s, n, __MF_CHECK_WRITE, "bzero region");
-- bzero (s, n);
-+ memset (s, 0, n);
- }
-
-
-@@ -437,7 +437,7 @@
- TRACE ("%s\n", __PRETTY_FUNCTION__);
- MF_VALIDATE_EXTENT(src, n, __MF_CHECK_READ, "bcopy src");
- MF_VALIDATE_EXTENT(dest, n, __MF_CHECK_WRITE, "bcopy dest");
-- bcopy (src, dest, n);
-+ memmove (dest, src, n);
- }
-
-
-@@ -447,7 +447,7 @@
- TRACE ("%s\n", __PRETTY_FUNCTION__);
- MF_VALIDATE_EXTENT(s1, n, __MF_CHECK_READ, "bcmp 1st arg");
- MF_VALIDATE_EXTENT(s2, n, __MF_CHECK_READ, "bcmp 2nd arg");
-- return bcmp (s1, s2, n);
-+ return n == 0 ? 0 : memcmp (s1, s2, n);
- }
-
-
-@@ -456,7 +456,7 @@
- size_t n = strlen (s);
- TRACE ("%s\n", __PRETTY_FUNCTION__);
- MF_VALIDATE_EXTENT(s, CLAMPADD(n, 1), __MF_CHECK_READ, "index region");
-- return index (s, c);
-+ return strchr (s, c);
- }
-
-
-@@ -465,7 +465,7 @@
- size_t n = strlen (s);
- TRACE ("%s\n", __PRETTY_FUNCTION__);
- MF_VALIDATE_EXTENT(s, CLAMPADD(n, 1), __MF_CHECK_READ, "rindex region");
-- return rindex (s, c);
-+ return strrchr (s, c);
- }
-
- /* XXX: stpcpy, memccpy */
+++ /dev/null
---- a/gcc/config/arm/arm.c
-+++ b/gcc/config/arm/arm.c
-@@ -3769,6 +3769,7 @@ arm_legitimate_address_p (enum machine_m
- rtx xop1 = XEXP (x, 1);
-
- return ((arm_address_register_rtx_p (xop0, strict_p)
-+ && GET_CODE(xop1) == CONST_INT
- && arm_legitimate_index_p (mode, xop1, outer, strict_p))
- || (arm_address_register_rtx_p (xop1, strict_p)
- && arm_legitimate_index_p (mode, xop0, outer, strict_p)));
---- a/gcc/config/arm/arm.md
-+++ b/gcc/config/arm/arm.md
-@@ -4199,7 +4199,7 @@
-
- (define_expand "extendqihi2"
- [(set (match_dup 2)
-- (ashift:SI (match_operand:QI 1 "general_operand" "")
-+ (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")
- (const_int 24)))
- (set (match_operand:HI 0 "s_register_operand" "")
- (ashiftrt:SI (match_dup 2)
-@@ -4224,7 +4224,7 @@
-
- (define_insn "*arm_extendqihi_insn"
- [(set (match_operand:HI 0 "s_register_operand" "=r")
-- (sign_extend:HI (match_operand:QI 1 "memory_operand" "Uq")))]
-+ (sign_extend:HI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
- "TARGET_ARM && arm_arch4"
- "ldr%(sb%)\\t%0, %1"
- [(set_attr "type" "load_byte")
-@@ -4235,7 +4235,7 @@
-
- (define_expand "extendqisi2"
- [(set (match_dup 2)
-- (ashift:SI (match_operand:QI 1 "general_operand" "")
-+ (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")
- (const_int 24)))
- (set (match_operand:SI 0 "s_register_operand" "")
- (ashiftrt:SI (match_dup 2)
-@@ -4267,7 +4267,7 @@
-
- (define_insn "*arm_extendqisi"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
-- (sign_extend:SI (match_operand:QI 1 "memory_operand" "Uq")))]
-+ (sign_extend:SI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
- "TARGET_ARM && arm_arch4 && !arm_arch6"
- "ldr%(sb%)\\t%0, %1"
- [(set_attr "type" "load_byte")
-@@ -4278,7 +4278,8 @@
-
- (define_insn "*arm_extendqisi_v6"
- [(set (match_operand:SI 0 "s_register_operand" "=r,r")
-- (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uq")))]
-+ (sign_extend:SI
-+ (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
- "TARGET_ARM && arm_arch6"
- "@
- sxtb%?\\t%0, %1
---- a/gcc/config/arm/predicates.md
-+++ b/gcc/config/arm/predicates.md
-@@ -234,6 +234,10 @@
- (match_test "arm_legitimate_address_p (mode, XEXP (op, 0), SIGN_EXTEND,
- 0)")))
-
-+(define_special_predicate "arm_reg_or_extendqisi_mem_op"
-+ (ior (match_operand 0 "arm_extendqisi_mem_op")
-+ (match_operand 0 "s_register_operand")))
-+
- (define_predicate "power_of_two_operand"
- (match_code "const_int")
- {
+++ /dev/null
-Index: gcc-4.3.0/gcc/config/arm/t-linux
-===================================================================
---- gcc-4.3.0/gcc/config/arm/t-linux (revision 129896)
-+++ gcc-4.3.0/gcc/config/arm/t-linux (working copy)
-@@ -3,7 +3,10 @@
- TARGET_LIBGCC2_CFLAGS = -fomit-frame-pointer -fPIC
-
- LIB1ASMSRC = arm/lib1funcs.asm
--LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_lnx
-+LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_lnx \
-+ _negdf2 _addsubdf3 _muldivdf3 _cmpdf2 _unorddf2 _fixdfsi _fixunsdfsi \
-+ _truncdfsf2 _negsf2 _addsubsf3 _muldivsf3 _cmpsf2 _unordsf2 \
-+ _fixsfsi _fixunssfsi _floatdidf _floatundidf _floatdisf _floatundisf
-
- # MULTILIB_OPTIONS = mhard-float/msoft-float
- # MULTILIB_DIRNAMES = hard-float soft-float
-Index: gcc-4.3.0/gcc/config/arm/linux-elf.h
-===================================================================
---- gcc-4.3.0/gcc/config/arm/linux-elf.h (revision 129896)
-+++ gcc-4.3.0/gcc/config/arm/linux-elf.h (working copy)
-@@ -48,7 +62,7 @@
- %{shared:-lc} \
- %{!shared:%{profile:-lc_p}%{!profile:-lc}}"
-
--#define LIBGCC_SPEC "%{msoft-float:-lfloat} %{mfloat-abi=soft*:-lfloat} -lgcc"
-+#define LIBGCC_SPEC "-lgcc"
-
- #define GLIBC_DYNAMIC_LINKER "/lib/ld-linux.so.2"
-
+++ /dev/null
---- a/libgcc/Makefile.in
-+++ b/libgcc/Makefile.in
-@@ -680,11 +680,12 @@ $(libgcov-objects): %$(objext): $(gcc_sr
-
- # Static libraries.
- libgcc.a: $(libgcc-objects)
-+libgcc_pic.a: $(libgcc-s-objects)
- libgcov.a: $(libgcov-objects)
- libunwind.a: $(libunwind-objects)
- libgcc_eh.a: $(libgcc-eh-objects)
-
--libgcc.a libgcov.a libunwind.a libgcc_eh.a:
-+libgcc.a libgcov.a libunwind.a libgcc_eh.a libgcc_pic.a:
- -rm -f $@
-
- objects="$(objects)"; \
-@@ -706,7 +707,7 @@ libgcc_s$(SHLIB_EXT): libunwind$(SHLIB_E
- endif
-
- ifeq ($(enable_shared),yes)
--all: libgcc_eh.a libgcc_s$(SHLIB_EXT)
-+all: libgcc_eh.a libgcc_pic.a libgcc_s$(SHLIB_EXT)
- ifneq ($(LIBUNWIND),)
- all: libunwind$(SHLIB_EXT)
- endif
-@@ -879,6 +880,10 @@ install-shared:
- chmod 644 $(DESTDIR)$(inst_libdir)/libgcc_eh.a
- $(RANLIB) $(DESTDIR)$(inst_libdir)/libgcc_eh.a
-
-+ $(INSTALL_DATA) libgcc_pic.a $(mapfile) $(DESTDIR)$(inst_libdir)/
-+ chmod 644 $(DESTDIR)$(inst_libdir)/libgcc_pic.a
-+ $(RANLIB) $(DESTDIR)$(inst_libdir)/libgcc_pic.a
-+
- $(subst @multilib_dir@,$(MULTIDIR),$(subst \
- @shlib_base_name@,libgcc_s,$(subst \
- @shlib_slibdir_qual@,$(MULTIOSSUBDIR),$(SHLIB_INSTALL))))
+++ /dev/null
-
- This patch brings over a few features from MirBSD:
- * -fhonour-copts
- If this option is not given, it's warned (depending
- on environment variables). This is to catch errors
- of misbuilt packages which override CFLAGS themselves.
- * -Werror-maybe-reset
- Has the effect of -Wno-error if GCC_NO_WERROR is
- set and not '0', a no-operation otherwise. This is
- to be able to use -Werror in "make" but prevent
- GNU autoconf generated configure scripts from
- freaking out.
- * Make -fno-strict-aliasing and -fno-delete-null-pointer-checks
- the default for -O2/-Os, because they trigger gcc bugs
- and can delete code with security implications.
-
- This patch was authored by Thorsten Glaser <tg at mirbsd.de>
- with copyright assignment to the FSF in effect.
-
-Index: gcc-4.3.0/gcc/c-opts.c
-===================================================================
---- gcc-4.3.0.orig/gcc/c-opts.c 2007-07-31 02:27:12.007256629 +0200
-+++ gcc-4.3.0/gcc/c-opts.c 2007-07-31 02:27:39.324813371 +0200
-@@ -108,6 +108,9 @@
- /* Number of deferred options scanned for -include. */
- static size_t include_cursor;
-
-+/* Check if a port honours COPTS. */
-+static int honour_copts = 0;
-+
- static void set_Wimplicit (int);
- static void handle_OPT_d (const char *);
- static void set_std_cxx98 (int);
-@@ -462,6 +465,14 @@
- enable_warning_as_error ("implicit-function-declaration", value, CL_C | CL_ObjC);
- break;
-
-+ case OPT_Werror_maybe_reset:
-+ {
-+ char *ev = getenv ("GCC_NO_WERROR");
-+ if ((ev != NULL) && (*ev != '0'))
-+ cpp_opts->warnings_are_errors = 0;
-+ }
-+ break;
-+
- case OPT_Wformat:
- set_Wformat (value);
- break;
-@@ -708,6 +719,12 @@
- flag_exceptions = value;
- break;
-
-+ case OPT_fhonour_copts:
-+ if (c_language == clk_c) {
-+ honour_copts++;
-+ }
-+ break;
-+
- case OPT_fimplement_inlines:
- flag_implement_inlines = value;
- break;
-@@ -1248,6 +1265,47 @@
- /* Has to wait until now so that cpplib has its hash table. */
- init_pragma ();
-
-+ if (c_language == clk_c) {
-+ char *ev = getenv ("GCC_HONOUR_COPTS");
-+ int evv;
-+ if (ev == NULL)
-+ evv = -1;
-+ else if ((*ev == '0') || (*ev == '\0'))
-+ evv = 0;
-+ else if (*ev == '1')
-+ evv = 1;
-+ else if (*ev == '2')
-+ evv = 2;
-+ else if (*ev == 's')
-+ evv = -1;
-+ else {
-+ warning (0, "unknown GCC_HONOUR_COPTS value, assuming 1");
-+ evv = 1; /* maybe depend this on something like MIRBSD_NATIVE? */
-+ }
-+ if (evv == 1) {
-+ if (honour_copts == 0) {
-+ error ("someone does not honour COPTS at all in lenient mode");
-+ return false;
-+ } else if (honour_copts != 1) {
-+ warning (0, "someone does not honour COPTS correctly, passed %d times",
-+ honour_copts);
-+ }
-+ } else if (evv == 2) {
-+ if (honour_copts == 0) {
-+ error ("someone does not honour COPTS at all in strict mode");
-+ return false;
-+ } else if (honour_copts != 1) {
-+ error ("someone does not honour COPTS correctly, passed %d times",
-+ honour_copts);
-+ return false;
-+ }
-+ } else if (evv == 0) {
-+ if (honour_copts != 1)
-+ inform ("someone does not honour COPTS correctly, passed %d times",
-+ honour_copts);
-+ }
-+ }
-+
- return true;
- }
-
-Index: gcc-4.3.0/gcc/c.opt
-===================================================================
---- gcc-4.3.0.orig/gcc/c.opt 2007-07-31 02:27:12.015257093 +0200
-+++ gcc-4.3.0/gcc/c.opt 2007-07-31 02:27:39.328813597 +0200
-@@ -207,6 +207,10 @@
- C ObjC RejectNegative Warning
- This switch is deprecated; use -Werror=implicit-function-declaration instead
-
-+Werror-maybe-reset
-+C ObjC C++ ObjC++
-+; Documented in common.opt
-+
- Wfloat-equal
- C ObjC C++ ObjC++ Var(warn_float_equal) Warning
- Warn if testing floating point numbers for equality
-@@ -590,6 +594,9 @@
- fhonor-std
- C++ ObjC++
-
-+fhonour-copts
-+C ObjC C++ ObjC++ RejectNegative
-+
- fhosted
- C ObjC
- Assume normal C execution environment
-Index: gcc-4.3.0/gcc/common.opt
-===================================================================
---- gcc-4.3.0.orig/gcc/common.opt 2007-07-31 02:27:12.023257546 +0200
-+++ gcc-4.3.0/gcc/common.opt 2007-07-31 02:27:39.360815422 +0200
-@@ -102,6 +102,10 @@
- Common Joined
- Treat specified warning as error
-
-+Werror-maybe-reset
-+Common
-+If environment variable GCC_NO_WERROR is set, act as -Wno-error
-+
- Wextra
- Common Warning
- Print extra (possibly unwanted) warnings
-@@ -528,6 +532,9 @@
- Common Report Var(flag_guess_branch_prob) Optimization
- Enable guessing of branch probabilities
-
-+fhonour-copts
-+Common RejectNegative
-+
- ; Nonzero means ignore `#ident' directives. 0 means handle them.
- ; Generate position-independent code for executables if possible
- ; On SVR4 targets, it also controls whether or not to emit a
-Index: gcc-4.3.0/gcc/opts.c
-===================================================================
---- gcc-4.3.0.orig/gcc/opts.c 2007-07-31 02:27:12.031257991 +0200
-+++ gcc-4.3.0/gcc/opts.c 2007-07-31 02:28:36.320061346 +0200
-@@ -830,9 +830,6 @@
- flag_schedule_insns_after_reload = 1;
- #endif
- flag_regmove = 1;
-- flag_strict_aliasing = 1;
-- flag_strict_overflow = 1;
-- flag_delete_null_pointer_checks = 1;
- flag_reorder_blocks = 1;
- flag_reorder_functions = 1;
- flag_tree_store_ccp = 1;
-@@ -850,6 +847,10 @@
-
- if (optimize >= 3)
- {
-+ flag_strict_aliasing = 1;
-+ flag_strict_overflow = 1;
-+ flag_delete_null_pointer_checks = 1;
-+
- flag_predictive_commoning = 1;
- flag_inline_functions = 1;
- flag_unswitch_loops = 1;
-@@ -1441,6 +1442,17 @@
- enable_warning_as_error (arg, value, lang_mask);
- break;
-
-+ case OPT_Werror_maybe_reset:
-+ {
-+ char *ev = getenv ("GCC_NO_WERROR");
-+ if ((ev != NULL) && (*ev != '0'))
-+ warnings_are_errors = 0;
-+ }
-+ break;
-+
-+ case OPT_fhonour_copts:
-+ break;
-+
- case OPT_Wextra:
- set_Wextra (value);
- break;
-Index: gcc-4.3.0/gcc/doc/cppopts.texi
-===================================================================
---- gcc-4.3.0.orig/gcc/doc/cppopts.texi 2007-07-31 02:27:12.039258455 +0200
-+++ gcc-4.3.0/gcc/doc/cppopts.texi 2007-07-31 02:27:39.408818157 +0200
-@@ -168,6 +168,11 @@
- Make all warnings into hard errors. Source code which triggers warnings
- will be rejected.
-
-+ at item -Werror-maybe-reset
-+ at opindex Werror-maybe-reset
-+Act like @samp{-Wno-error} if the @env{GCC_NO_WERROR} environment
-+variable is set to anything other than 0 or empty.
-+
- @item -Wsystem-headers
- @opindex Wsystem-headers
- Issue warnings for code in system headers. These are normally unhelpful
-Index: gcc-4.3.0/gcc/doc/invoke.texi
-===================================================================
---- gcc-4.3.0.orig/gcc/doc/invoke.texi 2007-07-31 02:27:12.047258920 +0200
-+++ gcc-4.3.0/gcc/doc/invoke.texi 2007-07-31 02:29:13.218164047 +0200
-@@ -233,7 +233,7 @@
- -Wconversion -Wcoverage-mismatch -Wno-deprecated-declarations @gol
- -Wdisabled-optimization -Wno-div-by-zero @gol
- -Wempty-body -Wno-endif-labels @gol
---Werror -Werror=* @gol
-+-Werror -Werror=* -Werror-maybe-reset @gol
- -Wfatal-errors -Wfloat-equal -Wformat -Wformat=2 @gol
- -Wno-format-extra-args -Wformat-nonliteral @gol
- -Wformat-security -Wformat-y2k -Wignored-qualifiers @gol
-@@ -4030,6 +4030,22 @@
- @option{-Wall} and by @option{-pedantic}, which can be disabled with
- @option{-Wno-pointer-sign}.
-
-+ at item -Werror-maybe-reset
-+ at opindex Werror-maybe-reset
-+Act like @samp{-Wno-error} if the @env{GCC_NO_WERROR} environment
-+variable is set to anything other than 0 or empty.
-+
-+ at item -fhonour-copts
-+ at opindex fhonour-copts
-+If @env{GCC_HONOUR_COPTS} is set to 1, abort if this option is not
-+given at least once, and warn if it is given more than once.
-+If @env{GCC_HONOUR_COPTS} is set to 2, abort if this option is not
-+given exactly once.
-+If @env{GCC_HONOUR_COPTS} is set to 0 or unset, warn if this option
-+is not given exactly once.
-+The warning is quelled if @env{GCC_HONOUR_COPTS} is set to @samp{s}.
-+This flag and environment variable only affect the C language.
-+
- @item -Wstack-protector
- @opindex Wstack-protector
- @opindex Wno-stack-protector
-@@ -5490,7 +5806,7 @@
- second branch or a point immediately following it, depending on whether
- the condition is known to be true or false.
-
--Enabled at levels @option{-O2}, @option{-O3}, @option{-Os}.
-+Enabled at levels @option{-O3}.
-
- @item -fsplit-wide-types
- @opindex fsplit-wide-types
-@@ -5635,7 +5514,7 @@
- @option{-fno-delete-null-pointer-checks} to disable this optimization
- for programs which depend on that behavior.
-
--Enabled at levels @option{-O2}, @option{-O3}, @option{-Os}.
-+Enabled at levels @option{-O3}.
-
- @item -fexpensive-optimizations
- @opindex fexpensive-optimizations
-Index: gcc-4.3.0/gcc/java/jvspec.c
-===================================================================
---- gcc-4.3.0.orig/gcc/java/jvspec.c 2007-07-31 02:27:12.055259364 +0200
-+++ gcc-4.3.0/gcc/java/jvspec.c 2007-07-31 02:27:39.484822490 +0200
-@@ -670,6 +670,7 @@
- class name. Append dummy `.c' that can be stripped by set_input so %b
- is correct. */
- set_input (concat (main_class_name, "main.c", NULL));
-+ putenv ("GCC_HONOUR_COPTS=s"); /* XXX hack! */
- err = do_spec (jvgenmain_spec);
- if (err == 0)
- {
+++ /dev/null
-gcc/ChangeLog
-2007-11-27 Bernhard Fischer <>
-
- * config/arm/arm-protos.h (arm_vector_mode_supported_p,
- arm_hard_regno_mode_ok, const_ok_for_arm): Do not hide non-rtx related
- function prototypes in RTX_CODE.
- * genopinit.c: Include tm_p.h.
-
-Index: gcc-4.3.0/gcc/config/arm/arm-protos.h
-===================================================================
---- gcc-4.3.0/gcc/config/arm/arm-protos.h (revision 130463)
-+++ gcc-4.3.0/gcc/config/arm/arm-protos.h (working copy)
-@@ -40,15 +40,14 @@
- unsigned int);
- extern unsigned int arm_dbx_register_number (unsigned int);
- extern void arm_output_fn_unwind (FILE *, bool);
--
-
- #ifdef TREE_CODE
- extern int arm_return_in_memory (const_tree);
- #endif
--#ifdef RTX_CODE
- extern bool arm_vector_mode_supported_p (enum machine_mode);
- extern int arm_hard_regno_mode_ok (unsigned int, enum machine_mode);
- extern int const_ok_for_arm (HOST_WIDE_INT);
-+#ifdef RTX_CODE
- extern int arm_split_constant (RTX_CODE, enum machine_mode, rtx,
- HOST_WIDE_INT, rtx, rtx, int);
- extern RTX_CODE arm_canonicalize_comparison (RTX_CODE, enum machine_mode,
-Index: gcc-4.3.0/gcc/genopinit.c
-===================================================================
---- gcc-4.3.0/gcc/genopinit.c (revision 130463)
-+++ gcc-4.3.0/gcc/genopinit.c (working copy)
-@@ -486,6 +486,7 @@
- printf ("#include \"expr.h\"\n");
- printf ("#include \"optabs.h\"\n");
- printf ("#include \"reload.h\"\n\n");
-+ printf ("#include \"tm_p.h\"\n\n");
-
- printf ("void\ninit_all_optabs (void)\n{\n");
-
+++ /dev/null
-see gcc PR34205
-Index: gcc-4.3.0/gcc/tree.h
-===================================================================
---- gcc-4.3.0/gcc/tree.h (revision 130511)
-+++ gcc-4.3.0/gcc/tree.h (working copy)
-@@ -38,6 +38,7 @@
-
- LAST_AND_UNUSED_TREE_CODE /* A convenient way to get a value for
- NUM_TREE_CODES. */
-+ ,__LAST_AND_UNUSED_TREE_CODE=32767 /* Force 16bit width. */
- };
-
- #undef DEFTREECODE
-Index: gcc-4.3.0/gcc/rtl.h
-===================================================================
---- gcc-4.3.0/gcc/rtl.h (revision 130511)
-+++ gcc-4.3.0/gcc/rtl.h (working copy)
-@@ -48,9 +48,11 @@
- #include "rtl.def" /* rtl expressions are documented here */
- #undef DEF_RTL_EXPR
-
-- LAST_AND_UNUSED_RTX_CODE}; /* A convenient way to get a value for
-+ LAST_AND_UNUSED_RTX_CODE /* A convenient way to get a value for
- NUM_RTX_CODE.
- Assumes default enum value assignment. */
-+ ,__LAST_AND_UNUSED_RTX_CODE=32767 /* Force 16bit width. */
-+};
-
- #define NUM_RTX_CODE ((int) LAST_AND_UNUSED_RTX_CODE)
- /* The cast here, saves many elsewhere. */
-Index: gcc-4.3.0/gcc/c-common.h
-===================================================================
---- gcc-4.3.0/gcc/c-common.h (revision 130511)
-+++ gcc-4.3.0/gcc/c-common.h (working copy)
-@@ -125,6 +125,7 @@
- RID_LAST_AT = RID_AT_IMPLEMENTATION,
- RID_FIRST_PQ = RID_IN,
- RID_LAST_PQ = RID_ONEWAY
-+ ,__LAST_AND_UNUSED_RID=32767 /* Force 16bit width. */
- };
-
- #define OBJC_IS_AT_KEYWORD(rid) \
+++ /dev/null
-\\\\
-\\ gcc PR33200
-Index: gcc-4.3.0/gcc/config.gcc
-===================================================================
---- gcc-4.3.0/gcc/config.gcc (revision 131628)
-+++ gcc-4.3.0/gcc/config.gcc (working copy)
-@@ -2302,7 +2305,7 @@ sh-*-symbianelf* | sh[12346l]*-*-symbian
- if test x${enable_incomplete_targets} = xyes ; then
- tm_defines="$tm_defines SUPPORT_SH1=1 SUPPORT_SH2E=1 SUPPORT_SH4=1 SUPPORT_SH4_SINGLE=1 SUPPORT_SH2A=1 SUPPORT_SH2A_SINGLE=1 SUPPORT_SH5_32MEDIA=1 SUPPORT_SH5_32MEDIA_NOFPU=1 SUPPORT_SH5_64MEDIA=1 SUPPORT_SH5_64MEDIA_NOFPU=1"
- fi
-- use_fixproto=yes
-+ # XXX: why? use_fixproto=yes
- ;;
- sh-*-rtemscoff*)
- tmake_file="sh/t-sh t-rtems sh/t-rtems"
+++ /dev/null
---- gcc-4.3.1/gcc/config.gcc.old 2008-06-17 23:49:00.000000000 +0200
-+++ gcc-4.3.1/gcc/config.gcc 2008-06-17 23:03:07.000000000 +0200
-@@ -1630,6 +1630,7 @@
- if test x$sjlj != x1; then
- tmake_file="$tmake_file m68k/t-slibgcc-elf-ver"
- fi
-+ tmake_file="m68k/t-floatlib m68k/t-m68kbare m68k/t-m68kelf"
- ;;
- m68k-*-rtems*)
- default_m68k_cpu=68020
+++ /dev/null
---- a/contrib/regression/objs-gcc.sh
-+++ b/contrib/regression/objs-gcc.sh
-@@ -106,6 +106,10 @@
- then
- make all-gdb all-dejagnu all-ld || exit 1
- make install-gdb install-dejagnu install-ld || exit 1
-+elif [ $H_REAL_TARGET = $H_REAL_HOST -a $H_REAL_TARGET = i686-pc-linux-uclibc ]
-+ then
-+ make all-gdb all-dejagnu all-ld || exit 1
-+ make install-gdb install-dejagnu install-ld || exit 1
- elif [ $H_REAL_TARGET = $H_REAL_HOST ] ; then
- make bootstrap || exit 1
- make install || exit 1
---- a/libjava/classpath/ltconfig
-+++ b/libjava/classpath/ltconfig
-@@ -603,7 +603,7 @@
-
- # Transform linux* to *-*-linux-gnu*, to support old configure scripts.
- case $host_os in
--linux-gnu*) ;;
-+linux-gnu*|linux-uclibc*) ;;
- linux*) host=`echo $host | sed 's/^\(.*-.*-linux\)\(.*\)$/\1-gnu\2/'`
- esac
-
-@@ -1251,7 +1251,7 @@
- ;;
-
- # This must be Linux ELF.
--linux-gnu*)
-+linux*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
+++ /dev/null
---- a/gcc/cp/Make-lang.in
-+++ b/gcc/cp/Make-lang.in
-@@ -72,8 +72,7 @@ g++-cross$(exeext): g++$(exeext)
- # Shared with C front end:
- CXX_C_OBJS = attribs.o c-common.o c-format.o c-pragma.o c-semantics.o c-lex.o \
- c-dump.o $(CXX_TARGET_OBJS) c-pretty-print.o c-opts.o c-pch.o \
-- incpath.o cppdefault.o c-ppoutput.o c-cppbuiltin.o prefix.o \
-- c-gimplify.o c-omp.o tree-inline.o
-+ incpath.o c-ppoutput.o c-cppbuiltin.o prefix.o c-gimplify.o c-omp.o
-
- # Language-specific object files for C++ and Objective C++.
- CXX_AND_OBJCXX_OBJS = cp/call.o cp/decl.o cp/expr.o cp/pt.o cp/typeck2.o \
+++ /dev/null
---- a/boehm-gc/include/gc.h
-+++ b/boehm-gc/include/gc.h
-@@ -503,7 +503,7 @@
- #if defined(__linux__) || defined(__GLIBC__)
- # include <features.h>
- # if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1 || __GLIBC__ > 2) \
-- && !defined(__ia64__)
-+ && !defined(__ia64__) && !defined(__UCLIBC__)
- # ifndef GC_HAVE_BUILTIN_BACKTRACE
- # define GC_HAVE_BUILTIN_BACKTRACE
- # endif
+++ /dev/null
---- a/libstdc++-v3/include/c_global/cstdio
-+++ b/libstdc++-v3/include/c_global/cstdio
-@@ -139,7 +139,7 @@
-
- _GLIBCXX_END_NAMESPACE
-
--#if _GLIBCXX_USE_C99
-+#if _GLIBCXX_USE_C99 || defined __UCLIBC__
-
- #undef snprintf
- #undef vfscanf
+++ /dev/null
---- a/libmudflap/mf-hooks2.c
-+++ b/libmudflap/mf-hooks2.c
-@@ -421,7 +421,7 @@
- {
- TRACE ("%s\n", __PRETTY_FUNCTION__);
- MF_VALIDATE_EXTENT(s, n, __MF_CHECK_WRITE, "bzero region");
-- bzero (s, n);
-+ memset (s, 0, n);
- }
-
-
-@@ -431,7 +431,7 @@
- TRACE ("%s\n", __PRETTY_FUNCTION__);
- MF_VALIDATE_EXTENT(src, n, __MF_CHECK_READ, "bcopy src");
- MF_VALIDATE_EXTENT(dest, n, __MF_CHECK_WRITE, "bcopy dest");
-- bcopy (src, dest, n);
-+ memmove (dest, src, n);
- }
-
-
-@@ -441,7 +441,7 @@
- TRACE ("%s\n", __PRETTY_FUNCTION__);
- MF_VALIDATE_EXTENT(s1, n, __MF_CHECK_READ, "bcmp 1st arg");
- MF_VALIDATE_EXTENT(s2, n, __MF_CHECK_READ, "bcmp 2nd arg");
-- return bcmp (s1, s2, n);
-+ return n == 0 ? 0 : memcmp (s1, s2, n);
- }
-
-
-@@ -450,7 +450,7 @@
- size_t n = strlen (s);
- TRACE ("%s\n", __PRETTY_FUNCTION__);
- MF_VALIDATE_EXTENT(s, CLAMPADD(n, 1), __MF_CHECK_READ, "index region");
-- return index (s, c);
-+ return strchr (s, c);
- }
-
-
-@@ -459,7 +459,7 @@
- size_t n = strlen (s);
- TRACE ("%s\n", __PRETTY_FUNCTION__);
- MF_VALIDATE_EXTENT(s, CLAMPADD(n, 1), __MF_CHECK_READ, "rindex region");
-- return rindex (s, c);
-+ return strrchr (s, c);
- }
-
- /* XXX: stpcpy, memccpy */
+++ /dev/null
---- a/config.sub
-+++ b/config.sub
-@@ -283,6 +283,7 @@ case $basic_machine in
- | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
- | spu | strongarm \
- | tahoe | thumb | tic4x | tic80 | tron \
-+ | ubicom32 \
- | v850 | v850e \
- | ubicom32 \
- | we32k \
-@@ -367,6 +368,7 @@ case $basic_machine in
- | tahoe-* | thumb-* \
- | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
- | tron-* \
-+ | ubicom32-* \
- | v850-* | v850e-* | vax-* \
- | ubicom32-* \
- | we32k-* \
---- a/configure
-+++ b/configure
-@@ -2688,6 +2688,9 @@ case "${target}" in
- ip2k-*-*)
- noconfigdirs="$noconfigdirs target-libiberty target-libstdc++-v3 ${libgcj}"
- ;;
-+ ubicom32-*-*)
-+ noconfigdirs="$noconfigdirs target-libffi"
-+ ;;
- *-*-linux* | *-*-gnu* | *-*-k*bsd*-gnu | *-*-kopensolaris*-gnu)
- noconfigdirs="$noconfigdirs target-newlib target-libgloss"
- ;;
---- /dev/null
-+++ b/gcc/config/ubicom32/constraints.md
-@@ -0,0 +1,149 @@
-+; Constraint definitions for Ubicom32
-+
-+; Copyright (C) 2009 Free Software Foundation, Inc.
-+; Contributed by Ubicom, Inc.
-+
-+; This file is part of GCC.
-+
-+; GCC is free software; you can redistribute it and/or modify it
-+; under the terms of the GNU General Public License as published
-+; by the Free Software Foundation; either version 3, or (at your
-+; option) any later version.
-+
-+; GCC is distributed in the hope that it will be useful, but WITHOUT
-+; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-+; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
-+; License for more details.
-+
-+; You should have received a copy of the GNU General Public License
-+; along with GCC; see the file COPYING3. If not see
-+; <http://www.gnu.org/licenses/>.
-+
-+(define_register_constraint "a" "ALL_ADDRESS_REGS"
-+ "An An register.")
-+
-+(define_register_constraint "d" "DATA_REGS"
-+ "A Dn register.")
-+
-+(define_register_constraint "h" "ACC_REGS"
-+ "An accumulator register.")
-+
-+(define_register_constraint "l" "ACC_LO_REGS"
-+ "An accn_lo register.")
-+
-+(define_register_constraint "Z" "FDPIC_REG"
-+ "The FD-PIC GOT pointer: A0.")
-+
-+(define_constraint "I"
-+ "An 8-bit signed constant value."
-+ (and (match_code "const_int")
-+ (match_test "(ival >= -128) && (ival <= 127)")))
-+
-+(define_constraint "Q"
-+ "An 8-bit signed constant value represented as unsigned."
-+ (and (match_code "const_int")
-+ (match_test "(ival >= 0x00) && (ival <= 0xff)")))
-+
-+(define_constraint "R"
-+ "An 8-bit signed constant value represented as unsigned."
-+ (and (match_code "const_int")
-+ (match_test "((ival >= 0x0000) && (ival <= 0x007f)) || ((ival >= 0xff80) && (ival <= 0xffff))")))
-+
-+(define_constraint "J"
-+ "A 7-bit unsigned constant value."
-+ (and (match_code "const_int")
-+ (match_test "(ival >= 0) && (ival <= 127)")))
-+
-+(define_constraint "K"
-+ "A 7-bit unsigned constant value shifted << 1."
-+ (and (match_code "const_int")
-+ (match_test "(ival >= 0) && (ival <= 254) && ((ival & 1) == 0)")))
-+
-+(define_constraint "L"
-+ "A 7-bit unsigned constant value shifted << 2."
-+ (and (match_code "const_int")
-+ (match_test "(ival >= 0) && (ival <= 508) && ((ival & 3) == 0)")))
-+
-+(define_constraint "M"
-+ "A 5-bit unsigned constant value."
-+ (and (match_code "const_int")
-+ (match_test "(ival >= 0) && (ival <= 31)")))
-+
-+(define_constraint "N"
-+ "A signed 16 bit constant value."
-+ (and (match_code "const_int")
-+ (match_test "(ival >= -32768) && (ival <= 32767)")))
-+
-+(define_constraint "O"
-+ "An exact bitmask of contiguous 1 bits starting at bit 0."
-+ (and (match_code "const_int")
-+ (match_test "exact_log2 (ival + 1) != -1")))
-+
-+(define_constraint "P"
-+ "A 7-bit negative constant value shifted << 2."
-+ (and (match_code "const_int")
-+ (match_test "(ival >= -504) && (ival <= 0) && ((ival & 3) == 0)")))
-+
-+(define_constraint "S"
-+ "A symbolic reference."
-+ (match_code "symbol_ref"))
-+
-+(define_constraint "Y"
-+ "An FD-PIC symbolic reference."
-+ (and (match_test "TARGET_FDPIC")
-+ (match_test "GET_CODE (op) == UNSPEC")
-+ (ior (match_test "XINT (op, 1) == UNSPEC_FDPIC_GOT")
-+ (match_test "XINT (op, 1) == UNSPEC_FDPIC_GOT_FUNCDESC"))))
-+
-+(define_memory_constraint "T1"
-+ "A memory operand that can be used for .1 instruction."
-+ (and (match_test "memory_operand (op, GET_MODE(op))")
-+ (match_test "GET_MODE (op) == QImode")))
-+
-+(define_memory_constraint "T2"
-+ "A memory operand that can be used for .2 instruction."
-+ (and (match_test "memory_operand (op, GET_MODE(op))")
-+ (match_test "GET_MODE (op) == HImode")))
-+
-+(define_memory_constraint "T4"
-+ "A memory operand that can be used for .4 instruction."
-+ (and (match_test "memory_operand (op, GET_MODE(op))")
-+ (ior (match_test "GET_MODE (op) == SImode")
-+ (match_test "GET_MODE (op) == DImode")
-+ (match_test "GET_MODE (op) == SFmode"))))
-+
-+(define_memory_constraint "U1"
-+ "An offsettable memory operand that can be used for .1 instruction."
-+ (and (match_test "memory_operand (op, GET_MODE(op))")
-+ (match_test "GET_MODE (op) == QImode")
-+ (match_test "GET_CODE (XEXP (op, 0)) != POST_INC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_INC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != POST_DEC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_DEC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != POST_MODIFY")
-+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_MODIFY")))
-+
-+(define_memory_constraint "U2"
-+ "An offsettable memory operand that can be used for .2 instruction."
-+ (and (match_test "memory_operand (op, GET_MODE(op))")
-+ (match_test "GET_MODE (op) == HImode")
-+ (match_test "GET_CODE (XEXP (op, 0)) != POST_INC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_INC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != POST_DEC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_DEC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != POST_MODIFY")
-+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_MODIFY")))
-+
-+(define_memory_constraint "U4"
-+ "An offsettable memory operand that can be used for .4 instruction."
-+ (and (match_test "memory_operand (op, GET_MODE(op))")
-+ (ior (match_test "GET_MODE (op) == SImode")
-+ (match_test "GET_MODE (op) == DImode")
-+ (match_test "GET_MODE (op) == SFmode"))
-+ (match_test "GET_CODE (XEXP (op, 0)) != POST_INC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_INC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != POST_DEC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_DEC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != POST_MODIFY")
-+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_MODIFY")))
-+
---- /dev/null
-+++ b/gcc/config/ubicom32/crti.S
-@@ -0,0 +1,54 @@
-+/* Specialized code needed to support construction and destruction of
-+ file-scope objects in C++ and Java code, and to support exception handling.
-+ Copyright (C) 1999 Free Software Foundation, Inc.
-+ Contributed by Charles-Antoine Gauthier (charles.gauthier@iit.nrc.ca).
-+
-+This file is part of GCC.
-+
-+GCC is free software; you can redistribute it and/or modify
-+it under the terms of the GNU General Public License as published by
-+the Free Software Foundation; either version 2, or (at your option)
-+any later version.
-+
-+GCC is distributed in the hope that it will be useful,
-+but WITHOUT ANY WARRANTY; without even the implied warranty of
-+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+GNU General Public License for more details.
-+
-+You should have received a copy of the GNU General Public License
-+along with GCC; see the file COPYING. If not, write to
-+the Free Software Foundation, 59 Temple Place - Suite 330,
-+Boston, MA 02111-1307, USA. */
-+
-+/* As a special exception, if you link this library with files
-+ compiled with GCC to produce an executable, this does not cause
-+ the resulting executable to be covered by the GNU General Public License.
-+ This exception does not however invalidate any other reasons why
-+ the executable file might be covered by the GNU General Public License. */
-+
-+/*
-+ * This file just supplies function prologues for the .init and .fini
-+ * sections. It is linked in before crtbegin.o.
-+ */
-+ .file "crti.o"
-+ .ident "GNU C crti.o"
-+
-+ .section .init
-+ .align 2
-+ .globl _init
-+ .type _init, @function
-+_init:
-+ move.4 -4(sp)++, a5
-+#ifdef __UBICOM32_FDPIC__
-+ move.4 -4(sp)++, a0
-+#endif
-+
-+ .section .fini
-+ .align 2
-+ .globl _fini
-+ .type _fini, @function
-+_fini:
-+ move.4 -4(sp)++, a5
-+#ifdef __UBICOM32_FDPIC__
-+ move.4 -4(sp)++, a0
-+#endif
---- /dev/null
-+++ b/gcc/config/ubicom32/crtn.S
-@@ -0,0 +1,47 @@
-+/* Specialized code needed to support construction and destruction of
-+ file-scope objects in C++ and Java code, and to support exception handling.
-+ Copyright (C) 1999 Free Software Foundation, Inc.
-+ Contributed by Charles-Antoine Gauthier (charles.gauthier@iit.nrc.ca).
-+
-+This file is part of GCC.
-+
-+GCC is free software; you can redistribute it and/or modify
-+it under the terms of the GNU General Public License as published by
-+the Free Software Foundation; either version 2, or (at your option)
-+any later version.
-+
-+GCC is distributed in the hope that it will be useful,
-+but WITHOUT ANY WARRANTY; without even the implied warranty of
-+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+GNU General Public License for more details.
-+
-+You should have received a copy of the GNU General Public License
-+along with GCC; see the file COPYING. If not, write to
-+the Free Software Foundation, 59 Temple Place - Suite 330,
-+Boston, MA 02111-1307, USA. */
-+
-+/* As a special exception, if you link this library with files
-+ compiled with GCC to produce an executable, this does not cause
-+ the resulting executable to be covered by the GNU General Public License.
-+ This exception does not however invalidate any other reasons why
-+ the executable file might be covered by the GNU General Public License. */
-+
-+/*
-+ * This file supplies function epilogues for the .init and .fini sections.
-+ * It is linked in after all other files.
-+ */
-+
-+ .file "crtn.o"
-+ .ident "GNU C crtn.o"
-+
-+ .section .init
-+#ifdef __UBICOM32_FDPIC__
-+ move.4 a0, (sp)4++
-+#endif
-+ ret (sp)4++
-+
-+ .section .fini
-+#ifdef __UBICOM32_FDPIC__
-+ move.4 a0, (sp)4++
-+#endif
-+ ret (sp)4++
---- /dev/null
-+++ b/gcc/config/ubicom32/elf.h
-@@ -0,0 +1,29 @@
-+#undef STARTFILE_SPEC
-+#define STARTFILE_SPEC "\
-+%{msim:%{!shared:crt0%O%s}} \
-+crti%O%s crtbegin%O%s"
-+
-+#undef ENDFILE_SPEC
-+#define ENDFILE_SPEC "crtend%O%s crtn%O%s"
-+
-+#ifdef __UBICOM32_FDPIC__
-+#define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC) \
-+ asm (SECTION_OP); \
-+ asm ("move.4 a0, 0(sp);\n\t" \
-+ "call a5," USER_LABEL_PREFIX #FUNC ";"); \
-+ asm (TEXT_SECTION_ASM_OP);
-+#endif
-+
-+#undef SUBTARGET_DRIVER_SELF_SPECS
-+#define SUBTARGET_DRIVER_SELF_SPECS \
-+ "%{mfdpic:-msim} "
-+
-+#define NO_IMPLICIT_EXTERN_C
-+
-+/*
-+ * We need this to compile crtbegin/crtend. This should really be picked
-+ * up from elfos.h but at the moment including elfos.h causes other more
-+ * serous linker issues.
-+ */
-+#define INIT_SECTION_ASM_OP "\t.section\t.init"
-+#define FINI_SECTION_ASM_OP "\t.section\t.fini"
---- /dev/null
-+++ b/gcc/config/ubicom32/linux.h
-@@ -0,0 +1,80 @@
-+/* Definitions of target machine for Ubicom32-uclinux
-+
-+ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
-+ 2009 Free Software Foundation, Inc.
-+ Contributed by Ubicom, Inc.
-+
-+ This file is part of GCC.
-+
-+ GCC is free software; you can redistribute it and/or modify it
-+ under the terms of the GNU General Public License as published
-+ by the Free Software Foundation; either version 3, or (at your
-+ option) any later version.
-+
-+ GCC is distributed in the hope that it will be useful, but WITHOUT
-+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
-+ License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with GCC; see the file COPYING3. If not see
-+ <http://www.gnu.org/licenses/>. */
-+
-+/* Don't assume anything about the header files. */
-+#define NO_IMPLICIT_EXTERN_C
-+
-+#undef LIB_SPEC
-+#define LIB_SPEC \
-+ "%{pthread:-lpthread} " \
-+ "-lc"
-+
-+#undef LINK_GCC_C_SEQUENCE_SPEC
-+#define LINK_GCC_C_SEQUENCE_SPEC \
-+ "%{static:--start-group} %G %L %{static:--end-group} " \
-+ "%{!static: %G}"
-+
-+#undef STARTFILE_SPEC
-+#define STARTFILE_SPEC \
-+ "%{!shared: %{pg|p|profile:gcrt1%O%s;pie:Scrt1%O%s;:crt1%O%s}} " \
-+ "crtreloc%O%s crti%O%s %{shared|pie:crtbeginS%O%s;:crtbegin%O%s}"
-+
-+#undef ENDFILE_SPEC
-+#define ENDFILE_SPEC \
-+ "%{shared|pie:crtendS%O%s;:crtend%O%s} crtn%O%s"
-+
-+/* taken from linux.h */
-+/* The GNU C++ standard library requires that these macros be defined. */
-+#undef CPLUSPLUS_CPP_SPEC
-+#define CPLUSPLUS_CPP_SPEC "-D_GNU_SOURCE %(cpp)"
-+
-+#define TARGET_OS_CPP_BUILTINS() \
-+ do { \
-+ builtin_define_std ("__UBICOM32__"); \
-+ builtin_define_std ("__ubicom32__"); \
-+ builtin_define ("__gnu_linux__"); \
-+ builtin_define_std ("linux"); \
-+ builtin_define_std ("unix"); \
-+ builtin_assert ("system=linux"); \
-+ builtin_assert ("system=unix"); \
-+ builtin_assert ("system=posix"); \
-+ } while (0)
-+
-+#define OBJECT_FORMAT_ELF
-+
-+
-+#undef DRIVER_SELF_SPECS
-+#define DRIVER_SELF_SPECS \
-+ "%{!mno-fdpic:-mfdpic}"
-+
-+#undef LINK_SPEC
-+#define LINK_SPEC "%{mfdpic: -m elf32ubicom32fdpic -z text } %{shared} %{pie} \
-+ %{static:-dn -Bstatic} \
-+ %{shared:-G -Bdynamic} \
-+ %{!shared: %{!static: \
-+ %{rdynamic:-export-dynamic} \
-+ %{!dynamic-linker:-dynamic-linker /lib/ld-uClibc.so.0}} \
-+ %{static}} "
-+
-+/*
-+#define MD_UNWIND_SUPPORT "config/bfin/linux-unwind.h"
-+*/
---- /dev/null
-+++ b/gcc/config/ubicom32/predicates.md
-@@ -0,0 +1,327 @@
-+; Predicate definitions for Ubicom32.
-+
-+; Copyright (C) 2009 Free Software Foundation, Inc.
-+; Contributed by Ubicom, Inc.
-+
-+; This file is part of GCC.
-+
-+; GCC is free software; you can redistribute it and/or modify it
-+; under the terms of the GNU General Public License as published
-+; by the Free Software Foundation; either version 3, or (at your
-+; option) any later version.
-+
-+; GCC is distributed in the hope that it will be useful, but WITHOUT
-+; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-+; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
-+; License for more details.
-+
-+; You should have received a copy of the GNU General Public License
-+; along with GCC; see the file COPYING3. If not see
-+; <http://www.gnu.org/licenses/>.
-+
-+(define_predicate "ubicom32_move_operand"
-+ (match_code "const_int, const_double, const, mem, subreg, reg, lo_sum")
-+{
-+ if (CONST_INT_P (op))
-+ return true;
-+
-+ if (GET_CODE (op) == CONST_DOUBLE)
-+ return true;
-+
-+ if (GET_CODE (op) == CONST)
-+ return memory_address_p (mode, op);
-+
-+ if (GET_MODE (op) != mode)
-+ return false;
-+
-+ if (MEM_P (op))
-+ return memory_address_p (mode, XEXP (op, 0));
-+
-+ if (GET_CODE (op) == SUBREG) {
-+ op = SUBREG_REG (op);
-+
-+ if (REG_P (op))
-+ return true;
-+
-+ if (! MEM_P (op))
-+ return false;
-+
-+ /* Paradoxical SUBREG. */
-+ if (GET_MODE_SIZE (mode) > GET_MODE_SIZE (GET_MODE (op)))
-+ return false;
-+
-+ return memory_address_p (GET_MODE (op), XEXP (op, 0));
-+ }
-+
-+ return register_operand (op, mode);
-+})
-+
-+;; Returns true if OP is either a symbol reference or a sum of a
-+;; symbol reference and a constant.
-+
-+(define_predicate "ubicom32_symbolic_address_operand"
-+ (match_code "symbol_ref, label_ref, const")
-+{
-+ switch (GET_CODE (op))
-+ {
-+ case SYMBOL_REF:
-+ case LABEL_REF:
-+ return true;
-+
-+ case CONST:
-+ op = XEXP (op, 0);
-+ return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
-+ || GET_CODE (XEXP (op, 0)) == LABEL_REF)
-+ && CONST_INT_P (XEXP (op, 1)));
-+
-+ default:
-+ return false;
-+ }
-+})
-+
-+;; Return true if operand is the uClinux FD-PIC register.
-+
-+(define_predicate "ubicom32_fdpic_operand"
-+ (match_code "reg")
-+{
-+ if (! TARGET_FDPIC)
-+ return false;
-+
-+ if (!REG_P (op))
-+ return false;
-+
-+ if (GET_MODE (op) != mode && mode != VOIDmode)
-+ return false;
-+
-+ if (REGNO (op) != FDPIC_REGNUM && REGNO (op) < FIRST_PSEUDO_REGISTER)
-+ return false;
-+
-+ return true;
-+})
-+
-+(define_predicate "ubicom32_fdpic_got_offset_operand"
-+ (match_code "unspec")
-+{
-+ if (! TARGET_FDPIC)
-+ return false;
-+
-+ if (GET_CODE (op) != UNSPEC)
-+ return false;
-+
-+ if (XINT (op, 1) != UNSPEC_FDPIC_GOT
-+ && XINT (op, 1) != UNSPEC_FDPIC_GOT_FUNCDESC)
-+ return false;
-+
-+ return true;
-+})
-+
-+(define_predicate "ubicom32_arith_operand"
-+ (match_code "subreg, reg, const_int, lo_sum, mem")
-+{
-+ return (ubicom32_move_operand (op, mode)
-+ && ! ubicom32_symbolic_address_operand (op, mode)
-+ && (! CONST_INT_P (op)
-+ || satisfies_constraint_I (op)));
-+})
-+
-+(define_predicate "ubicom32_arith_operand_dot1"
-+ (match_code "subreg, reg, const_int, lo_sum, mem")
-+{
-+ return (ubicom32_move_operand (op, mode)
-+ && ! ubicom32_symbolic_address_operand (op, mode)
-+ && (! CONST_INT_P (op)
-+ || satisfies_constraint_Q (op)));
-+})
-+
-+(define_predicate "ubicom32_arith_operand_dot2"
-+ (match_code "subreg, reg, const_int, lo_sum, mem")
-+{
-+ return (ubicom32_move_operand (op, mode)
-+ && ! ubicom32_symbolic_address_operand (op, mode)
-+ && (! CONST_INT_P (op)
-+ || satisfies_constraint_R (op)));
-+})
-+
-+(define_predicate "ubicom32_compare_operand"
-+ (match_code "subreg, reg, const_int, lo_sum, mem")
-+{
-+ return (ubicom32_move_operand (op, mode)
-+ && ! ubicom32_symbolic_address_operand (op, mode)
-+ && (! CONST_INT_P (op)
-+ || satisfies_constraint_N (op)));
-+})
-+
-+(define_predicate "ubicom32_compare_operator"
-+ (match_code "compare"))
-+
-+(define_predicate "ubicom32_and_or_si3_operand"
-+ (match_code "subreg, reg, const_int, lo_sum, mem")
-+{
-+ return (ubicom32_arith_operand (op, mode)
-+ || (CONST_INT_P (op)
-+ && ((exact_log2 (INTVAL (op) + 1) != -1
-+ && exact_log2 (INTVAL (op) + 1) <= 31)
-+ || (exact_log2 (INTVAL (op)) != -1
-+ && exact_log2 (INTVAL (op)) <= 31)
-+ || (exact_log2 (~INTVAL (op)) != -1
-+ && exact_log2 (~INTVAL (op)) <= 31))));
-+})
-+
-+(define_predicate "ubicom32_and_or_hi3_operand"
-+ (match_code "subreg, reg, const_int, lo_sum, mem")
-+{
-+ return (ubicom32_arith_operand (op, mode)
-+ || (CONST_INT_P (op)
-+ && exact_log2 (INTVAL (op) + 1) != -1
-+ && exact_log2 (INTVAL (op) + 1) <= 15));
-+})
-+
-+(define_predicate "ubicom32_mem_or_address_register_operand"
-+ (match_code "subreg, reg, mem")
-+{
-+ unsigned int regno;
-+
-+ if (MEM_P (op)
-+ && memory_operand (op, mode))
-+ return true;
-+
-+ if (REG_P (op))
-+ regno = REGNO (op);
-+ else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
-+ {
-+ int offset;
-+ if (REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER)
-+ offset = SUBREG_BYTE (op) / (GET_MODE_SIZE (GET_MODE (op)));
-+ else
-+ offset = subreg_regno_offset (REGNO (SUBREG_REG (op)),
-+ GET_MODE (SUBREG_REG (op)),
-+ SUBREG_BYTE (op),
-+ GET_MODE (op));
-+ regno = REGNO (SUBREG_REG (op)) + offset;
-+ }
-+ else
-+ return false;
-+
-+ return (regno >= FIRST_PSEUDO_REGISTER
-+ || REGNO_REG_CLASS (regno) == FDPIC_REG
-+ || REGNO_REG_CLASS (regno) == ADDRESS_REGS);
-+})
-+
-+(define_predicate "ubicom32_data_register_operand"
-+ (match_code "subreg, reg")
-+{
-+ unsigned int regno;
-+
-+ if (REG_P (op))
-+ regno = REGNO (op);
-+ else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
-+ {
-+ int offset;
-+ if (REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER)
-+ offset = SUBREG_BYTE (op) / (GET_MODE_SIZE (GET_MODE (op)));
-+ else
-+ offset = subreg_regno_offset (REGNO (SUBREG_REG (op)),
-+ GET_MODE (SUBREG_REG (op)),
-+ SUBREG_BYTE (op),
-+ GET_MODE (op));
-+ regno = REGNO (SUBREG_REG (op)) + offset;
-+ }
-+ else
-+ return false;
-+
-+ return ((regno >= FIRST_PSEUDO_REGISTER
-+ && regno != REGNO (virtual_stack_vars_rtx))
-+ || REGNO_REG_CLASS (regno) == DATA_REGS);
-+})
-+
-+(define_predicate "ubicom32_address_register_operand"
-+ (match_code "subreg, reg")
-+{
-+ unsigned int regno;
-+
-+ if (REG_P (op))
-+ regno = REGNO (op);
-+ else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
-+ {
-+ int offset;
-+ if (REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER)
-+ offset = SUBREG_BYTE (op) / (GET_MODE_SIZE (GET_MODE (op)));
-+ else
-+ offset = subreg_regno_offset (REGNO (SUBREG_REG (op)),
-+ GET_MODE (SUBREG_REG (op)),
-+ SUBREG_BYTE (op),
-+ GET_MODE (op));
-+ regno = REGNO (SUBREG_REG (op)) + offset;
-+ }
-+ else
-+ return false;
-+
-+ return (regno >= FIRST_PSEUDO_REGISTER
-+ || REGNO_REG_CLASS (regno) == FDPIC_REG
-+ || REGNO_REG_CLASS (regno) == ADDRESS_REGS);
-+})
-+
-+(define_predicate "ubicom32_acc_lo_register_operand"
-+ (match_code "subreg, reg")
-+{
-+ unsigned int regno;
-+
-+ if (REG_P (op))
-+ regno = REGNO (op);
-+ else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
-+ {
-+ int offset;
-+ if (REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER)
-+ offset = SUBREG_BYTE (op) / (GET_MODE_SIZE (GET_MODE (op)));
-+ else
-+ offset = subreg_regno_offset (REGNO (SUBREG_REG (op)),
-+ GET_MODE (SUBREG_REG (op)),
-+ SUBREG_BYTE (op),
-+ GET_MODE (op));
-+ regno = REGNO (SUBREG_REG (op)) + offset;
-+ }
-+ else
-+ return false;
-+
-+ return ((regno >= FIRST_PSEUDO_REGISTER
-+ && regno != REGNO (virtual_stack_vars_rtx))
-+ || REGNO_REG_CLASS (regno) == ACC_LO_REGS);
-+})
-+
-+(define_predicate "ubicom32_acc_hi_register_operand"
-+ (match_code "subreg, reg")
-+{
-+ unsigned int regno;
-+
-+ if (REG_P (op))
-+ regno = REGNO (op);
-+ else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
-+ {
-+ int offset;
-+ if (REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER)
-+ offset = SUBREG_BYTE (op) / (GET_MODE_SIZE (GET_MODE (op)));
-+ else
-+ offset = subreg_regno_offset (REGNO (SUBREG_REG (op)),
-+ GET_MODE (SUBREG_REG (op)),
-+ SUBREG_BYTE (op),
-+ GET_MODE (op));
-+ regno = REGNO (SUBREG_REG (op)) + offset;
-+ }
-+ else
-+ return false;
-+
-+ return ((regno >= FIRST_PSEUDO_REGISTER
-+ && regno != REGNO (virtual_stack_vars_rtx))
-+ || REGNO_REG_CLASS (regno) == ACC_REGS);
-+})
-+
-+(define_predicate "ubicom32_call_address_operand"
-+ (match_code "symbol_ref, subreg, reg")
-+{
-+ return (GET_CODE (op) == SYMBOL_REF || REG_P (op));
-+})
-+
-+(define_special_predicate "ubicom32_cc_register_operand"
-+ (and (match_code "reg")
-+ (match_test "REGNO (op) == CC_REGNUM")))
-+
---- /dev/null
-+++ b/gcc/config/ubicom32/t-ubicom32
-@@ -0,0 +1,52 @@
-+# Name of assembly file containing libgcc1 functions.
-+# This entry must be present, but it can be empty if the target does
-+# not need any assembler functions to support its code generation.
-+CROSS_LIBGCC1 =
-+
-+# Alternatively if assembler functions *are* needed then define the
-+# entries below:
-+# CROSS_LIBGCC1 = libgcc1-asm.a
-+
-+LIB2FUNCS_EXTRA = \
-+ $(srcdir)/config/udivmodsi4.c \
-+ $(srcdir)/config/divmod.c \
-+ $(srcdir)/config/udivmod.c
-+
-+# If any special flags are necessary when building libgcc2 put them here.
-+#
-+# TARGET_LIBGCC2_CFLAGS =
-+
-+# 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
-+
-+fp-bit.c: $(srcdir)/config/fp-bit.c
-+ echo '#define FLOAT' > fp-bit.c
-+ cat $(srcdir)/config/fp-bit.c >> fp-bit.c
-+
-+dp-bit.c: $(srcdir)/config/fp-bit.c
-+ cat $(srcdir)/config/fp-bit.c > dp-bit.c
-+
-+# Commented out to speed up compiler development!
-+#
-+# MULTILIB_OPTIONS = march=ubicom32v1/march=ubicom32v2/march=ubicom32v3/march=ubicom32v4
-+# MULTILIB_DIRNAMES = ubicom32v1 ubicom32v2 ubicom32v3 ubicom32v4
-+
-+MULTILIB_OPTIONS = march=ubicom32v3/march=ubicom32v4
-+MULTILIB_OPTIONS += mfdpic
-+MULTILIB_OPTIONS += mno-ipos-abi/mipos-abi
-+MULTILIB_OPTIONS += fno-leading-underscore/fleading-underscore
-+
-+# Assemble startup files.
-+$(T)crti.o: $(srcdir)/config/ubicom32/crti.S $(GCC_PASSES)
-+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) \
-+ -c -o $(T)crti.o -x assembler-with-cpp $(srcdir)/config/ubicom32/crti.S
-+
-+$(T)crtn.o: $(srcdir)/config/ubicom32/crtn.S $(GCC_PASSES)
-+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) \
-+ -c -o $(T)crtn.o -x assembler-with-cpp $(srcdir)/config/ubicom32/crtn.S
-+
-+# these parts are required because uClibc ldso needs them to link.
-+# they are not in the specfile so they will not be included automatically.
-+EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o crtbeginS.o crtendS.o crti.o crtn.o
---- /dev/null
-+++ b/gcc/config/ubicom32/t-ubicom32-linux
-@@ -0,0 +1,35 @@
-+# Name of assembly file containing libgcc1 functions.
-+# This entry must be present, but it can be empty if the target does
-+# not need any assembler functions to support its code generation.
-+CROSS_LIBGCC1 =
-+
-+# Alternatively if assembler functions *are* needed then define the
-+# entries below:
-+# CROSS_LIBGCC1 = libgcc1-asm.a
-+
-+LIB2FUNCS_EXTRA = \
-+ $(srcdir)/config/udivmodsi4.c \
-+ $(srcdir)/config/divmod.c \
-+ $(srcdir)/config/udivmod.c
-+
-+# If any special flags are necessary when building libgcc2 put them here.
-+#
-+# TARGET_LIBGCC2_CFLAGS =
-+
-+# 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
-+
-+fp-bit.c: $(srcdir)/config/fp-bit.c
-+ echo '#define FLOAT' > fp-bit.c
-+ cat $(srcdir)/config/fp-bit.c >> fp-bit.c
-+
-+dp-bit.c: $(srcdir)/config/fp-bit.c
-+ cat $(srcdir)/config/fp-bit.c > dp-bit.c
-+
-+# We only support v3 and v4 ISAs for uClinux.
-+
-+MULTILIB_OPTIONS = march=ubicom32v3/march=ubicom32v4
-+
-+#EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o crtbeginS.o crtendS.o
---- /dev/null
-+++ b/gcc/config/ubicom32/t-ubicom32-uclinux
-@@ -0,0 +1,35 @@
-+# Name of assembly file containing libgcc1 functions.
-+# This entry must be present, but it can be empty if the target does
-+# not need any assembler functions to support its code generation.
-+CROSS_LIBGCC1 =
-+
-+# Alternatively if assembler functions *are* needed then define the
-+# entries below:
-+# CROSS_LIBGCC1 = libgcc1-asm.a
-+
-+LIB2FUNCS_EXTRA = \
-+ $(srcdir)/config/udivmodsi4.c \
-+ $(srcdir)/config/divmod.c \
-+ $(srcdir)/config/udivmod.c
-+
-+# If any special flags are necessary when building libgcc2 put them here.
-+#
-+# TARGET_LIBGCC2_CFLAGS =
-+
-+# 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
-+
-+fp-bit.c: $(srcdir)/config/fp-bit.c
-+ echo '#define FLOAT' > fp-bit.c
-+ cat $(srcdir)/config/fp-bit.c >> fp-bit.c
-+
-+dp-bit.c: $(srcdir)/config/fp-bit.c
-+ cat $(srcdir)/config/fp-bit.c > dp-bit.c
-+
-+# We only support v3 and v4 ISAs for uClinux.
-+
-+MULTILIB_OPTIONS = march=ubicom32v3/march=ubicom32v4
-+
-+EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o # crtbeginS.o crtendS.o
---- /dev/null
-+++ b/gcc/config/ubicom32/ubicom32-modes.def
-@@ -0,0 +1,30 @@
-+/* Definitions of target machine for GNU compiler, Ubicom32 architecture.
-+ Copyright (C) 2009 Free Software Foundation, Inc.
-+ Contributed by Ubicom, Inc.
-+
-+ This file is part of GCC.
-+
-+ GCC is free software; you can redistribute it and/or modify it
-+ under the terms of the GNU General Public License as published
-+ by the Free Software Foundation; either version 3, or (at your
-+ option) any later version.
-+
-+ GCC is distributed in the hope that it will be useful, but WITHOUT
-+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
-+ License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with GCC; see the file COPYING3. If not see
-+ <http://www.gnu.org/licenses/>. */
-+
-+/* Some insns set all condition code flags, some only set the Z and N flags, and
-+ some only set the Z flag. */
-+
-+CC_MODE (CCW);
-+CC_MODE (CCWZN);
-+CC_MODE (CCWZ);
-+CC_MODE (CCS);
-+CC_MODE (CCSZN);
-+CC_MODE (CCSZ);
-+
---- /dev/null
-+++ b/gcc/config/ubicom32/ubicom32-protos.h
-@@ -0,0 +1,84 @@
-+/* Function prototypes for Ubicom IP3000.
-+
-+ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
-+ 2009 Free Software Foundation, Inc.
-+ Contributed by Ubicom, Inc.
-+
-+ This file is part of GNU CC.
-+
-+ GNU CC is free software; you can redistribute it and/or modify it under
-+ the terms of the GNU General Public License as published by the Free
-+ Software Foundation; either version 2, or (at your option) any later
-+ version.
-+
-+ GNU CC is distributed in the hope that it will be useful, but WITHOUT
-+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-+ for more details.
-+
-+ You should have received a copy of the GNU General Public License along
-+ with GNU CC; see the file COPYING. If not, write to the Free Software
-+ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-+
-+#ifdef RTX_CODE
-+
-+#ifdef TREE_CODE
-+extern void ubicom32_va_start (tree, rtx);
-+#endif /* TREE_CODE */
-+
-+extern void ubicom32_print_operand (FILE *, rtx, int);
-+extern void ubicom32_print_operand_address (FILE *, rtx);
-+
-+extern void ubicom32_conditional_register_usage (void);
-+extern enum reg_class ubicom32_preferred_reload_class (rtx, enum reg_class);
-+extern int ubicom32_regno_ok_for_index_p (int, int);
-+extern void ubicom32_expand_movsi (rtx *);
-+extern void ubicom32_expand_addsi3 (rtx *);
-+extern int ubicom32_emit_mult_sequence (rtx *);
-+extern void ubicom32_emit_move_const_int (rtx, rtx);
-+extern bool ubicom32_legitimate_constant_p (rtx);
-+extern bool ubicom32_legitimate_address_p (enum machine_mode, rtx, int);
-+extern rtx ubicom32_legitimize_address (rtx, rtx, enum machine_mode);
-+extern rtx ubicom32_legitimize_reload_address (rtx, enum machine_mode, int, int);
-+extern void ubicom32_canonicalize_comparison (enum rtx_code *code, rtx *op0, rtx *op1);
-+extern int ubicom32_mode_dependent_address_p (rtx);
-+extern void ubicom32_output_cond_jump (rtx, rtx, rtx);
-+extern void ubicom32_expand_eh_return (rtx *);
-+extern void ubicom32_expand_call_fdpic (rtx *);
-+extern void ubicom32_expand_call_value_fdpic (rtx *);
-+extern enum machine_mode ubicom32_select_cc_mode (RTX_CODE, rtx, rtx);
-+extern rtx ubicom32_gen_compare_reg (RTX_CODE, rtx, rtx);
-+extern int ubicom32_shiftable_const_int (int);
-+#endif /* RTX_CODE */
-+
-+#ifdef TREE_CODE
-+extern void init_cumulative_args (CUMULATIVE_ARGS *cum,
-+ tree fntype,
-+ struct rtx_def *libname,
-+ int indirect);
-+extern struct rtx_def *function_arg (CUMULATIVE_ARGS *,
-+ enum machine_mode, tree, int);
-+extern struct rtx_def *function_incoming_arg (CUMULATIVE_ARGS *,
-+ enum machine_mode,
-+ tree, int);
-+extern int function_arg_partial_nregs (CUMULATIVE_ARGS *,
-+ enum machine_mode, tree, int);
-+extern struct rtx_def *ubicom32_va_arg (tree, tree);
-+extern int ubicom32_reg_parm_stack_space (tree);
-+#endif /* TREE_CODE */
-+
-+extern struct rtx_def * ubicom32_builtin_saveregs (void);
-+extern void asm_file_start (FILE *);
-+extern void ubicom32_expand_prologue (void);
-+extern void ubicom32_expand_epilogue (void);
-+extern int ubicom32_initial_elimination_offset (int, int);
-+extern int ubicom32_regno_ok_for_base_p (int, int);
-+extern bool ubicom32_hard_regno_mode_ok (unsigned int, enum machine_mode);
-+extern int ubicom32_can_use_return_insn_p (void);
-+extern rtx ubicom32_return_addr_rtx (int, rtx);
-+extern void ubicom32_optimization_options (int, int);
-+extern void ubicom32_override_options (void);
-+extern bool ubicom32_match_cc_mode (rtx, enum machine_mode);
-+
-+extern int ubicom32_reorg_completed;
-+
---- /dev/null
-+++ b/gcc/config/ubicom32/ubicom32.c
-@@ -0,0 +1,2881 @@
-+/* Subroutines for insn-output.c for Ubicom32
-+
-+ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
-+ 2009 Free Software Foundation, Inc.
-+ Contributed by Ubicom, Inc.
-+
-+ This file is part of GCC.
-+
-+ GCC is free software; you can redistribute it and/or modify it
-+ under the terms of the GNU General Public License as published
-+ by the Free Software Foundation; either version 3, or (at your
-+ option) any later version.
-+
-+ GCC is distributed in the hope that it will be useful, but WITHOUT
-+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
-+ License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with GCC; see the file COPYING3. If not see
-+ <http://www.gnu.org/licenses/>. */
-+
-+#include "config.h"
-+#include "system.h"
-+#include "coretypes.h"
-+#include "tm.h"
-+#include "rtl.h"
-+#include "tree.h"
-+#include "regs.h"
-+#include "hard-reg-set.h"
-+#include "real.h"
-+#include "insn-config.h"
-+#include "conditions.h"
-+#include "insn-flags.h"
-+#include "output.h"
-+#include "insn-attr.h"
-+#include "insn-codes.h"
-+#include "flags.h"
-+#include "recog.h"
-+#include "expr.h"
-+#include "function.h"
-+#include "obstack.h"
-+#include "toplev.h"
-+#include "tm_p.h"
-+#include "tm-constrs.h"
-+#include "basic-block.h"
-+#include "integrate.h"
-+#include "target.h"
-+#include "target-def.h"
-+#include "reload.h"
-+#include "df.h"
-+#include "langhooks.h"
-+#include "optabs.h"
-+
-+static tree ubicom32_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
-+static void ubicom32_layout_frame (void);
-+static void ubicom32_function_prologue (FILE *, HOST_WIDE_INT);
-+static void ubicom32_function_epilogue (FILE *, HOST_WIDE_INT);
-+static bool ubicom32_rtx_costs (rtx, int, int, int *, bool speed);
-+static bool ubicom32_fixed_condition_code_regs (unsigned int *,
-+ unsigned int *);
-+static enum machine_mode ubicom32_cc_modes_compatible (enum machine_mode,
-+ enum machine_mode);
-+static int ubicom32_naked_function_p (void);
-+static void ubicom32_machine_dependent_reorg (void);
-+static bool ubicom32_assemble_integer (rtx, unsigned int, int);
-+static void ubicom32_asm_init_sections (void);
-+static int ubicom32_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,tree,
-+ bool);
-+static bool ubicom32_pass_by_reference (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
-+ enum machine_mode mode, const_tree type,
-+ bool named ATTRIBUTE_UNUSED);
-+static bool ubicom32_callee_copies (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
-+ enum machine_mode mode, const_tree type,
-+ bool named ATTRIBUTE_UNUSED);
-+
-+static bool ubicom32_return_in_memory (const_tree type,
-+ const_tree fntype ATTRIBUTE_UNUSED);
-+static bool ubicom32_is_base_reg (rtx, int);
-+static void ubicom32_init_builtins (void);
-+static rtx ubicom32_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
-+static tree ubicom32_fold_builtin (tree, tree, bool);
-+static int ubicom32_get_valid_offset_mask (enum machine_mode);
-+static bool ubicom32_cannot_force_const_mem (rtx);
-+
-+/* Case values threshold */
-+int ubicom32_case_values_threshold = 6;
-+
-+/* Nonzero if this chip supports the Ubicom32 v3 ISA. */
-+int ubicom32_v3 = 1;
-+
-+/* Nonzero if this chip supports the Ubicom32 v4 ISA. */
-+int ubicom32_v4 = 1;
-+
-+/* Valid attributes:
-+ naked - don't generate function prologue/epilogue and `ret' command. */
-+const struct attribute_spec ubicom32_attribute_table[] =
-+{
-+ /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
-+ { "naked", 0, 0, true, false, false, ubicom32_handle_fndecl_attribute },
-+ { NULL, 0, 0, false, false, false, NULL }
-+};
-+
-+#undef TARGET_ASM_FUNCTION_PROLOGUE
-+#define TARGET_ASM_FUNCTION_PROLOGUE ubicom32_function_prologue
-+
-+#undef TARGET_ASM_FUNCTION_EPILOGUE
-+#define TARGET_ASM_FUNCTION_EPILOGUE ubicom32_function_epilogue
-+
-+#undef TARGET_ATTRIBUTE_TABLE
-+#define TARGET_ATTRIBUTE_TABLE ubicom32_attribute_table
-+
-+/* All addresses cost the same amount. */
-+#undef TARGET_ADDRESS_COST
-+#define TARGET_ADDRESS_COST hook_int_rtx_bool_0
-+
-+#undef TARGET_RTX_COSTS
-+#define TARGET_RTX_COSTS ubicom32_rtx_costs
-+
-+#undef TARGET_FIXED_CONDITION_CODE_REGS
-+#define TARGET_FIXED_CONDITION_CODE_REGS ubicom32_fixed_condition_code_regs
-+
-+#undef TARGET_CC_MODES_COMPATIBLE
-+#define TARGET_CC_MODES_COMPATIBLE ubicom32_cc_modes_compatible
-+
-+#undef TARGET_MACHINE_DEPENDENT_REORG
-+#define TARGET_MACHINE_DEPENDENT_REORG ubicom32_machine_dependent_reorg
-+
-+#undef TARGET_ASM_INTEGER
-+#define TARGET_ASM_INTEGER ubicom32_assemble_integer
-+
-+#undef TARGET_ASM_INIT_SECTIONS
-+#define TARGET_ASM_INIT_SECTIONS ubicom32_asm_init_sections
-+
-+#undef TARGET_ARG_PARTIAL_BYTES
-+#define TARGET_ARG_PARTIAL_BYTES ubicom32_arg_partial_bytes
-+
-+#undef TARGET_PASS_BY_REFERENCE
-+#define TARGET_PASS_BY_REFERENCE ubicom32_pass_by_reference
-+
-+#undef TARGET_CALLEE_COPIES
-+#define TARGET_CALLEE_COPIES ubicom32_callee_copies
-+
-+#undef TARGET_RETURN_IN_MEMORY
-+#define TARGET_RETURN_IN_MEMORY ubicom32_return_in_memory
-+
-+#undef TARGET_INIT_BUILTINS
-+#define TARGET_INIT_BUILTINS ubicom32_init_builtins
-+
-+#undef TARGET_EXPAND_BUILTIN
-+#define TARGET_EXPAND_BUILTIN ubicom32_expand_builtin
-+
-+#undef TARGET_FOLD_BUILTIN
-+#define TARGET_FOLD_BUILTIN ubicom32_fold_builtin
-+
-+#undef TARGET_CANNOT_FORCE_CONST_MEM
-+#define TARGET_CANNOT_FORCE_CONST_MEM ubicom32_cannot_force_const_mem
-+
-+struct gcc_target targetm = TARGET_INITIALIZER;
-+
-+static char save_regs[FIRST_PSEUDO_REGISTER];
-+static int nregs;
-+static int frame_size;
-+int ubicom32_stack_size = 0; /* size of allocated stack (including frame) */
-+int ubicom32_can_use_calli_to_ret;
-+
-+#define STACK_UNIT_BOUNDARY (STACK_BOUNDARY / BITS_PER_UNIT)
-+#define ROUND_CALL_BLOCK_SIZE(BYTES) \
-+ (((BYTES) + (STACK_UNIT_BOUNDARY - 1)) & ~(STACK_UNIT_BOUNDARY - 1))
-+
-+/* In case of a PRE_INC, POST_INC, PRE_DEC, POST_DEC memory reference, we
-+ must report the mode of the memory reference from PRINT_OPERAND to
-+ PRINT_OPERAND_ADDRESS. */
-+enum machine_mode output_memory_reference_mode;
-+
-+/* Flag for some split insns from the ubicom32.md. */
-+int ubicom32_reorg_completed;
-+
-+enum reg_class const ubicom32_regclass_map[FIRST_PSEUDO_REGISTER] =
-+{
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ FDPIC_REG,
-+ ADDRESS_REGS,
-+ ADDRESS_REGS,
-+ ADDRESS_REGS,
-+ ADDRESS_REGS,
-+ ADDRESS_REGS,
-+ ADDRESS_REGS,
-+ ADDRESS_REGS,
-+ ACC_REGS,
-+ ACC_LO_REGS,
-+ ACC_REGS,
-+ ACC_LO_REGS,
-+ SOURCE3_REG,
-+ ADDRESS_REGS,
-+ NO_REGS, /* CC_REG must be NO_REGS */
-+ SPECIAL_REGS,
-+ SPECIAL_REGS,
-+ SPECIAL_REGS,
-+ SPECIAL_REGS,
-+ SPECIAL_REGS,
-+ SPECIAL_REGS,
-+ SPECIAL_REGS,
-+ SPECIAL_REGS
-+};
-+
-+rtx ubicom32_compare_op0;
-+rtx ubicom32_compare_op1;
-+
-+/* Handle command line option overrides. */
-+
-+void
-+ubicom32_override_options (void)
-+{
-+ flag_pic = 0;
-+
-+ if (strcmp (ubicom32_arch_name, "ubicom32v1") == 0) {
-+ /* If we have a version 1 architecture then we want to avoid using jump
-+ tables. */
-+ ubicom32_case_values_threshold = 30000;
-+ ubicom32_v3 = 0;
-+ ubicom32_v4 = 0;
-+ } else if (strcmp (ubicom32_arch_name, "ubicom32v2") == 0) {
-+ ubicom32_v3 = 0;
-+ ubicom32_v4 = 0;
-+ } else if (strcmp (ubicom32_arch_name, "ubicom32v3") == 0) {
-+ ubicom32_v3 = 1;
-+ ubicom32_v4 = 0;
-+ } else if (strcmp (ubicom32_arch_name, "ubicom32v4") == 0) {
-+ ubicom32_v3 = 1;
-+ ubicom32_v4 = 1;
-+ }
-+
-+ /* There is no single unaligned SI op for PIC code. Sometimes we
-+ need to use ".4byte" and sometimes we need to use ".picptr".
-+ See ubicom32_assemble_integer for details. */
-+ if (TARGET_FDPIC)
-+ targetm.asm_out.unaligned_op.si = 0;
-+}
-+
-+void
-+ubicom32_conditional_register_usage (void)
-+{
-+ /* If we're using the old ipOS ABI we need to make D10 through D13
-+ caller-clobbered. */
-+ if (TARGET_IPOS_ABI)
-+ {
-+ call_used_regs[D10_REGNUM] = 1;
-+ call_used_regs[D11_REGNUM] = 1;
-+ call_used_regs[D12_REGNUM] = 1;
-+ call_used_regs[D13_REGNUM] = 1;
-+ }
-+}
-+
-+/* We have some number of optimizations that don't really work for the Ubicom32
-+ architecture so we deal with them here. */
-+
-+void
-+ubicom32_optimization_options (int level ATTRIBUTE_UNUSED,
-+ int size ATTRIBUTE_UNUSED)
-+{
-+ /* The tree IVOPTs pass seems to do really bad things for the Ubicom32
-+ architecture - it tends to turn things that would happily use pre/post
-+ increment/decrement into operations involving unecessary loop
-+ indicies. */
-+ flag_ivopts = 0;
-+
-+ /* We have problems where DSE at the RTL level misses partial stores
-+ to the stack. For now we disable it to avoid this. */
-+ flag_dse = 0;
-+}
-+
-+/* Print operand X using operand code CODE to assembly language output file
-+ FILE. */
-+
-+void
-+ubicom32_print_operand (FILE *file, rtx x, int code)
-+{
-+ switch (code)
-+ {
-+ case 'A':
-+ /* Identify the correct accumulator to use. */
-+ if (REGNO (x) == ACC0_HI_REGNUM || REGNO (x) == ACC0_LO_REGNUM)
-+ fprintf (file, "acc0");
-+ else if (REGNO (x) == ACC1_HI_REGNUM || REGNO (x) == ACC1_LO_REGNUM)
-+ fprintf (file, "acc1");
-+ else
-+ abort ();
-+ break;
-+
-+ case 'b':
-+ case 'B':
-+ {
-+ enum machine_mode mode;
-+
-+ mode = GET_MODE (XEXP (x, 0));
-+
-+ /* These are normal and reversed branches. */
-+ switch (code == 'b' ? GET_CODE (x) : reverse_condition (GET_CODE (x)))
-+ {
-+ case NE:
-+ fprintf (file, "ne");
-+ break;
-+
-+ case EQ:
-+ fprintf (file, "eq");
-+ break;
-+
-+ case GE:
-+ if (mode == CCSZNmode || mode == CCWZNmode)
-+ fprintf (file, "pl");
-+ else
-+ fprintf (file, "ge");
-+ break;
-+
-+ case GT:
-+ fprintf (file, "gt");
-+ break;
-+
-+ case LE:
-+ fprintf (file, "le");
-+ break;
-+
-+ case LT:
-+ if (mode == CCSZNmode || mode == CCWZNmode)
-+ fprintf (file, "mi");
-+ else
-+ fprintf (file, "lt");
-+ break;
-+
-+ case GEU:
-+ fprintf (file, "cs");
-+ break;
-+
-+ case GTU:
-+ fprintf (file, "hi");
-+ break;
-+
-+ case LEU:
-+ fprintf (file, "ls");
-+ break;
-+
-+ case LTU:
-+ fprintf (file, "cc");
-+ break;
-+
-+ default:
-+ abort ();
-+ }
-+ }
-+ break;
-+
-+ case 'C':
-+ /* This is used for the operand to a call instruction;
-+ if it's a REG, enclose it in parens, else output
-+ the operand normally. */
-+ if (REG_P (x))
-+ {
-+ fputc ('(', file);
-+ ubicom32_print_operand (file, x, 0);
-+ fputc (')', file);
-+ }
-+ else
-+ ubicom32_print_operand (file, x, 0);
-+ break;
-+
-+ case 'd':
-+ /* Bit operations we need bit numbers. */
-+ fprintf (file, "%d", exact_log2 (INTVAL (x)));
-+ break;
-+
-+ case 'D':
-+ /* Bit operations we need bit numbers. */
-+ fprintf (file, "%d", exact_log2 (~ INTVAL (x)));
-+ break;
-+
-+ case 'E':
-+ /* For lea, which we use to add address registers.
-+ We don't want the '#' on a constant. */
-+ if (CONST_INT_P (x))
-+ {
-+ fprintf (file, "%ld", INTVAL (x));
-+ break;
-+ }
-+ /* FALL THROUGH */
-+
-+ default:
-+ switch (GET_CODE (x))
-+ {
-+ case MEM:
-+ output_memory_reference_mode = GET_MODE (x);
-+ output_address (XEXP (x, 0));
-+ break;
-+
-+ case PLUS:
-+ output_address (x);
-+ break;
-+
-+ case REG:
-+ fprintf (file, "%s", reg_names[REGNO (x)]);
-+ break;
-+
-+ case SUBREG:
-+ fprintf (file, "%s", reg_names[subreg_regno (x)]);
-+ break;
-+
-+ /* This will only be single precision.... */
-+ case CONST_DOUBLE:
-+ {
-+ unsigned long val;
-+ REAL_VALUE_TYPE rv;
-+
-+ REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
-+ REAL_VALUE_TO_TARGET_SINGLE (rv, val);
-+ fprintf (file, "0x%lx", val);
-+ break;
-+ }
-+
-+ case CONST_INT:
-+ case SYMBOL_REF:
-+ case CONST:
-+ case LABEL_REF:
-+ case CODE_LABEL:
-+ case LO_SUM:
-+ ubicom32_print_operand_address (file, x);
-+ break;
-+
-+ case HIGH:
-+ fprintf (file, "#%%hi(");
-+ ubicom32_print_operand_address (file, XEXP (x, 0));
-+ fprintf (file, ")");
-+ break;
-+
-+ case UNSPEC:
-+ switch (XINT (x, 1))
-+ {
-+ case UNSPEC_FDPIC_GOT:
-+ fprintf (file, "#%%got_lo(");
-+ ubicom32_print_operand_address (file, XVECEXP (x, 0, 0));
-+ fprintf (file, ")");
-+ break;
-+
-+ case UNSPEC_FDPIC_GOT_FUNCDESC:
-+ fprintf (file, "#%%got_funcdesc_lo(");
-+ ubicom32_print_operand_address (file, XVECEXP (x, 0, 0));
-+ fprintf (file, ")");
-+ break;
-+
-+ default:
-+ abort ();
-+ }
-+ break;
-+
-+ default:
-+ abort ();
-+ }
-+ break;
-+ }
-+}
-+
-+/* Output assembly language output for the address ADDR to FILE. */
-+
-+void
-+ubicom32_print_operand_address (FILE *file, rtx addr)
-+{
-+ switch (GET_CODE (addr))
-+ {
-+ case POST_INC:
-+ ubicom32_print_operand_address (file, XEXP (addr, 0));
-+ fprintf (file, "%d++", GET_MODE_SIZE (output_memory_reference_mode));
-+ break;
-+
-+ case PRE_INC:
-+ fprintf (file, "%d", GET_MODE_SIZE (output_memory_reference_mode));
-+ ubicom32_print_operand_address (file, XEXP (addr, 0));
-+ fprintf (file, "++");
-+ break;
-+
-+ case POST_DEC:
-+ ubicom32_print_operand_address (file, XEXP (addr, 0));
-+ fprintf (file, "%d++", -GET_MODE_SIZE (output_memory_reference_mode));
-+ break;
-+
-+ case PRE_DEC:
-+ fprintf (file, "%d", -GET_MODE_SIZE (output_memory_reference_mode));
-+ ubicom32_print_operand_address (file, XEXP (addr, 0));
-+ fprintf (file, "++");
-+ break;
-+
-+ case POST_MODIFY:
-+ ubicom32_print_operand_address (file, XEXP (addr, 0));
-+ fprintf (file, "%ld++", INTVAL (XEXP (XEXP (addr,1), 1)));
-+ break;
-+
-+ case PRE_MODIFY:
-+ fprintf (file, "%ld", INTVAL (XEXP (XEXP (addr,1), 1)));
-+ ubicom32_print_operand_address (file, XEXP (addr, 0));
-+ fprintf (file, "++");
-+ break;
-+
-+ case REG:
-+ fputc ('(', file);
-+ fprintf (file, "%s", reg_names[REGNO (addr)]);
-+ fputc (')', file);
-+ break;
-+
-+ case PLUS:
-+ {
-+ rtx base = XEXP (addr, 0);
-+ rtx index = XEXP (addr, 1);
-+
-+ /* Switch around addresses of the form index * scaling + base. */
-+ if (! ubicom32_is_base_reg (base, 1))
-+ {
-+ rtx tmp = base;
-+ base = index;
-+ index = tmp;
-+ }
-+
-+ if (CONST_INT_P (index))
-+ {
-+ fprintf (file, "%ld", INTVAL (index));
-+ fputc ('(', file);
-+ fputs (reg_names[REGNO (base)], file);
-+ }
-+ else if (GET_CODE (index) == MULT
-+ || REG_P (index))
-+ {
-+ if (GET_CODE (index) == MULT)
-+ index = XEXP (index, 0);
-+ fputc ('(', file);
-+ fputs (reg_names[REGNO (base)], file);
-+ fputc (',', file);
-+ fputs (reg_names[REGNO (index)], file);
-+ }
-+ else
-+ abort ();
-+
-+ fputc (')', file);
-+ break;
-+ }
-+
-+ case LO_SUM:
-+ fprintf (file, "%%lo(");
-+ ubicom32_print_operand (file, XEXP (addr, 1), 'L');
-+ fprintf (file, ")(");
-+ ubicom32_print_operand (file, XEXP (addr, 0), 0);
-+ fprintf (file, ")");
-+ break;
-+
-+ case CONST_INT:
-+ fputc ('#', file);
-+ output_addr_const (file, addr);
-+ break;
-+
-+ default:
-+ output_addr_const (file, addr);
-+ break;
-+ }
-+}
-+
-+/* X and Y are two things to compare using CODE. Emit the compare insn and
-+ return the rtx for the cc reg in the proper mode. */
-+
-+rtx
-+ubicom32_gen_compare_reg (enum rtx_code code, rtx x, rtx y)
-+{
-+ enum machine_mode mode = SELECT_CC_MODE (code, x, y);
-+ rtx cc_reg;
-+
-+ cc_reg = gen_rtx_REG (mode, CC_REGNUM);
-+
-+ emit_insn (gen_rtx_SET (VOIDmode, cc_reg,
-+ gen_rtx_COMPARE (mode, x, y)));
-+
-+ return cc_reg;
-+}
-+
-+/* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
-+ return the mode to be used for the comparison. */
-+
-+enum machine_mode
-+ubicom32_select_cc_mode (enum rtx_code op, rtx x, rtx y)
-+{
-+ /* Is this a short compare? */
-+ if (GET_MODE (x) == QImode
-+ || GET_MODE (x) == HImode
-+ || GET_MODE (y) == QImode
-+ || GET_MODE (y) == HImode)
-+ {
-+ switch (op)
-+ {
-+ case EQ :
-+ case NE :
-+ return CCSZmode;
-+
-+ case GE:
-+ case LT:
-+ if (y == const0_rtx)
-+ return CCSZNmode;
-+
-+ default :
-+ return CCSmode;
-+ }
-+ }
-+
-+ /* We have a word compare. */
-+ switch (op)
-+ {
-+ case EQ :
-+ case NE :
-+ return CCWZmode;
-+
-+ case GE :
-+ case LT :
-+ if (y == const0_rtx)
-+ return CCWZNmode;
-+
-+ default :
-+ return CCWmode;
-+ }
-+}
-+
-+/* Return TRUE or FALSE depending on whether the first SET in INSN
-+ has source and destination with matching CC modes, and that the
-+ CC mode is at least as constrained as REQ_MODE. */
-+bool
-+ubicom32_match_cc_mode (rtx insn, enum machine_mode req_mode)
-+{
-+ rtx set;
-+ enum machine_mode set_mode;
-+
-+ set = PATTERN (insn);
-+ if (GET_CODE (set) == PARALLEL)
-+ set = XVECEXP (set, 0, 0);
-+ gcc_assert (GET_CODE (set) == SET);
-+ gcc_assert (GET_CODE (SET_SRC (set)) == COMPARE);
-+
-+ /* SET_MODE is the mode we have in the instruction. This must either
-+ be the same or less restrictive that the required mode REQ_MODE. */
-+ set_mode = GET_MODE (SET_DEST (set));
-+
-+ switch (req_mode)
-+ {
-+ case CCSZmode:
-+ if (set_mode != CCSZmode)
-+ return 0;
-+ break;
-+
-+ case CCSZNmode:
-+ if (set_mode != CCSZmode
-+ && set_mode != CCSZNmode)
-+ return 0;
-+ break;
-+
-+ case CCSmode:
-+ if (set_mode != CCSmode
-+ && set_mode != CCSZmode
-+ && set_mode != CCSZNmode)
-+ return 0;
-+ break;
-+
-+ case CCWZmode:
-+ if (set_mode != CCWZmode)
-+ return 0;
-+ break;
-+
-+ case CCWZNmode:
-+ if (set_mode != CCWZmode
-+ && set_mode != CCWZNmode)
-+ return 0;
-+ break;
-+
-+ case CCWmode:
-+ if (set_mode != CCWmode
-+ && set_mode != CCWZmode
-+ && set_mode != CCWZNmode)
-+ return 0;
-+ break;
-+
-+ default:
-+ gcc_unreachable ();
-+ }
-+
-+ return (GET_MODE (SET_SRC (set)) == set_mode);
-+}
-+
-+/* Replace the comparison OP0 CODE OP1 by a semantically equivalent one
-+ that we can implement more efficiently. */
-+
-+void
-+ubicom32_canonicalize_comparison (enum rtx_code *code, rtx *op0, rtx *op1)
-+{
-+ /* If we have a REG and a MEM then compare the MEM with the REG and not
-+ the other way round. */
-+ if (REG_P (*op0) && MEM_P (*op1))
-+ {
-+ rtx tem = *op0;
-+ *op0 = *op1;
-+ *op1 = tem;
-+ *code = swap_condition (*code);
-+ return;
-+ }
-+
-+ /* If we have a REG and a CONST_INT then we may want to reverse things
-+ if the constant can be represented as an "I" constraint. */
-+ if (REG_P (*op0) && CONST_INT_P (*op1) && satisfies_constraint_I (*op1))
-+ {
-+ rtx tem = *op0;
-+ *op0 = *op1;
-+ *op1 = tem;
-+ *code = swap_condition (*code);
-+ return;
-+ }
-+}
-+
-+/* Return the fixed registers used for condition codes. */
-+
-+static bool
-+ubicom32_fixed_condition_code_regs (unsigned int *p1, unsigned int *p2)
-+{
-+ *p1 = CC_REGNUM;
-+ *p2 = INVALID_REGNUM;
-+
-+ return true;
-+}
-+
-+/* If two condition code modes are compatible, return a condition code
-+ mode which is compatible with both. Otherwise, return
-+ VOIDmode. */
-+
-+static enum machine_mode
-+ubicom32_cc_modes_compatible (enum machine_mode m1, enum machine_mode m2)
-+{
-+ if (m1 == m2)
-+ return m1;
-+
-+ if (GET_MODE_CLASS (m1) != MODE_CC || GET_MODE_CLASS (m2) != MODE_CC)
-+ return VOIDmode;
-+
-+ switch (m1)
-+ {
-+ case CCWmode:
-+ if (m2 == CCWZNmode || m2 == CCWZmode)
-+ return m1;
-+
-+ return VOIDmode;
-+
-+ case CCWZNmode:
-+ if (m2 == CCWmode)
-+ return m2;
-+
-+ if (m2 == CCWZmode)
-+ return m1;
-+
-+ return VOIDmode;
-+
-+ case CCWZmode:
-+ if (m2 == CCWmode || m2 == CCWZNmode)
-+ return m2;
-+
-+ return VOIDmode;
-+
-+ case CCSmode:
-+ if (m2 == CCSZNmode || m2 == CCSZmode)
-+ return m1;
-+
-+ return VOIDmode;
-+
-+ case CCSZNmode:
-+ if (m2 == CCSmode)
-+ return m2;
-+
-+ if (m2 == CCSZmode)
-+ return m1;
-+
-+ return VOIDmode;
-+
-+ case CCSZmode:
-+ if (m2 == CCSmode || m2 == CCSZNmode)
-+ return m2;
-+
-+ return VOIDmode;
-+
-+ default:
-+ gcc_unreachable ();
-+ }
-+}
-+
-+static rtx
-+ubicom32_legitimize_fdpic_address_symbol (rtx orig, rtx reg, rtx fdpic_reg)
-+{
-+ int unspec;
-+ rtx got_offs;
-+ rtx got_offs_scaled;
-+ rtx plus_scaled;
-+ rtx tmp;
-+ rtx new_rtx;
-+
-+ gcc_assert (reg != 0);
-+
-+ if (GET_CODE (orig) == SYMBOL_REF
-+ && SYMBOL_REF_FUNCTION_P (orig))
-+ unspec = UNSPEC_FDPIC_GOT_FUNCDESC;
-+ else
-+ unspec = UNSPEC_FDPIC_GOT;
-+
-+ got_offs = gen_reg_rtx (SImode);
-+ tmp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, orig), unspec);
-+ emit_move_insn (got_offs, tmp);
-+
-+ got_offs_scaled = gen_rtx_MULT (SImode, got_offs, GEN_INT (4));
-+ plus_scaled = gen_rtx_PLUS (Pmode, fdpic_reg, got_offs_scaled);
-+ new_rtx = gen_const_mem (Pmode, plus_scaled);
-+ emit_move_insn (reg, new_rtx);
-+
-+ return reg;
-+}
-+
-+static rtx
-+ubicom32_legitimize_fdpic_address (rtx orig, rtx reg, rtx fdpic_reg)
-+{
-+ rtx addr = orig;
-+ rtx new_rtx = orig;
-+
-+ if (GET_CODE (addr) == CONST || GET_CODE (addr) == PLUS)
-+ {
-+ rtx base;
-+
-+ if (GET_CODE (addr) == CONST)
-+ {
-+ addr = XEXP (addr, 0);
-+ gcc_assert (GET_CODE (addr) == PLUS);
-+ }
-+
-+ base = ubicom32_legitimize_fdpic_address_symbol (XEXP (addr, 0), reg, fdpic_reg);
-+ return gen_rtx_PLUS (Pmode, base, XEXP (addr, 1));
-+ }
-+
-+ return new_rtx;
-+}
-+
-+/* Code generation. */
-+
-+void
-+ubicom32_expand_movsi (rtx *operands)
-+{
-+ if (GET_CODE (operands[1]) == SYMBOL_REF
-+ || (GET_CODE (operands[1]) == CONST
-+ && GET_CODE (XEXP (operands[1], 0)) == PLUS
-+ && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
-+ || CONSTANT_ADDRESS_P (operands[1]))
-+ {
-+ if (TARGET_FDPIC)
-+ {
-+ rtx tmp;
-+ rtx fdpic_reg;
-+
-+ gcc_assert (can_create_pseudo_p ());
-+ tmp = gen_reg_rtx (Pmode);
-+ fdpic_reg = get_hard_reg_initial_val (SImode, FDPIC_REGNUM);
-+ if (GET_CODE (operands[1]) == SYMBOL_REF
-+ || GET_CODE (operands[1]) == LABEL_REF)
-+ operands[1] = ubicom32_legitimize_fdpic_address_symbol (operands[1], tmp, fdpic_reg);
-+ else
-+ operands[1] = ubicom32_legitimize_fdpic_address (operands[1], tmp, fdpic_reg);
-+ }
-+ else
-+ {
-+ rtx tmp;
-+ enum machine_mode mode;
-+
-+ /* We want to avoid reusing operand 0 if we can because it limits
-+ our ability to optimize later. */
-+ tmp = ! can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
-+
-+ mode = GET_MODE (operands[0]);
-+ emit_insn (gen_rtx_SET (VOIDmode, tmp,
-+ gen_rtx_HIGH (mode, operands[1])));
-+ operands[1] = gen_rtx_LO_SUM (mode, tmp, operands[1]);
-+ if (can_create_pseudo_p() && ! REG_P (operands[0]))
-+ {
-+ tmp = gen_reg_rtx (mode);
-+ emit_insn (gen_rtx_SET (VOIDmode, tmp, operands[1]));
-+ operands[1] = tmp;
-+ }
-+ }
-+ }
-+}
-+
-+/* Emit code for addsi3. */
-+
-+void
-+ubicom32_expand_addsi3 (rtx *operands)
-+{
-+ rtx op, clob;
-+
-+ if (can_create_pseudo_p ())
-+ {
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (SImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (SImode, operands[2]);
-+ }
-+
-+ /* Emit the instruction. */
-+
-+ op = gen_rtx_SET (VOIDmode, operands[0],
-+ gen_rtx_PLUS (SImode, operands[1], operands[2]));
-+
-+ if (! can_create_pseudo_p ())
-+ {
-+ /* Reload doesn't know about the flags register, and doesn't know that
-+ it doesn't want to clobber it. We can only do this with PLUS. */
-+ emit_insn (op);
-+ }
-+ else
-+ {
-+ clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM));
-+ emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, op, clob)));
-+ }
-+}
-+
-+/* Emit code for mulsi3. Return 1 if we have generated all the code
-+ necessary to do the multiplication. */
-+
-+int
-+ubicom32_emit_mult_sequence (rtx *operands)
-+{
-+ if (! ubicom32_v4)
-+ {
-+ rtx a1, a1_1, a2;
-+ rtx b1, b1_1, b2;
-+ rtx mac_lo_rtx;
-+ rtx t1, t2, t3;
-+
-+ /* Give up if we cannot create new pseudos. */
-+ if (!can_create_pseudo_p())
-+ return 0;
-+
-+ /* Synthesize 32-bit multiplication using 16-bit operations:
-+
-+ a1 = highpart (a)
-+ a2 = lowpart (a)
-+
-+ b1 = highpart (b)
-+ b2 = lowpart (b)
-+
-+ c = (a1 * b1) << 32 + (a1 * b2) << 16 + (a2 * b1) << 16 + a2 * b2
-+ = 0 + (a1 * b2) << 16 + (a2 * b1) << 16 + a2 * b2
-+ ^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^ ^^^^^^^
-+ Signed Signed Unsigned */
-+
-+ if (!ubicom32_data_register_operand (operands[1], GET_MODE (operands[1])))
-+ {
-+ rtx op1;
-+
-+ op1 = gen_reg_rtx (SImode);
-+ emit_move_insn (op1, operands[1]);
-+ operands[1] = op1;
-+ }
-+
-+ if (!ubicom32_data_register_operand (operands[2], GET_MODE (operands[2])))
-+ {
-+ rtx op2;
-+
-+ op2 = gen_reg_rtx (SImode);
-+ emit_move_insn (op2, operands[2]);
-+ operands[2] = op2;
-+ }
-+
-+ /* a1 = highpart (a) */
-+ a1 = gen_reg_rtx (HImode);
-+ a1_1 = gen_reg_rtx (SImode);
-+ emit_insn (gen_ashrsi3 (a1_1, operands[1], GEN_INT (16)));
-+ emit_move_insn (a1, gen_lowpart (HImode, a1_1));
-+
-+ /* a2 = lowpart (a) */
-+ a2 = gen_reg_rtx (HImode);
-+ emit_move_insn (a2, gen_lowpart (HImode, operands[1]));
-+
-+ /* b1 = highpart (b) */
-+ b1 = gen_reg_rtx (HImode);
-+ b1_1 = gen_reg_rtx (SImode);
-+ emit_insn (gen_ashrsi3 (b1_1, operands[2], GEN_INT (16)));
-+ emit_move_insn (b1, gen_lowpart (HImode, b1_1));
-+
-+ /* b2 = lowpart (b) */
-+ b2 = gen_reg_rtx (HImode);
-+ emit_move_insn (b2, gen_lowpart (HImode, operands[2]));
-+
-+ /* t1 = (a1 * b2) << 16 */
-+ t1 = gen_reg_rtx (SImode);
-+ mac_lo_rtx = gen_rtx_REG (SImode, ACC0_LO_REGNUM);
-+ emit_insn (gen_mulhisi3 (mac_lo_rtx, a1, b2));
-+ emit_insn (gen_ashlsi3 (t1, mac_lo_rtx, GEN_INT (16)));
-+
-+ /* t2 = (a2 * b1) << 16 */
-+ t2 = gen_reg_rtx (SImode);
-+ emit_insn (gen_mulhisi3 (mac_lo_rtx, a2, b1));
-+ emit_insn (gen_ashlsi3 (t2, mac_lo_rtx, GEN_INT (16)));
-+
-+ /* mac_lo = a2 * b2 */
-+ emit_insn (gen_umulhisi3 (mac_lo_rtx, a2, b2));
-+
-+ /* t3 = t1 + t2 */
-+ t3 = gen_reg_rtx (SImode);
-+ emit_insn (gen_addsi3 (t3, t1, t2));
-+
-+ /* c = t3 + mac_lo_rtx */
-+ emit_insn (gen_addsi3 (operands[0], mac_lo_rtx, t3));
-+
-+ return 1;
-+ }
-+ else
-+ {
-+ rtx acc_rtx;
-+
-+ /* Give up if we cannot create new pseudos. */
-+ if (!can_create_pseudo_p())
-+ return 0;
-+
-+ if (!ubicom32_data_register_operand (operands[1], GET_MODE (operands[1])))
-+ {
-+ rtx op1;
-+
-+ op1 = gen_reg_rtx (SImode);
-+ emit_move_insn (op1, operands[1]);
-+ operands[1] = op1;
-+ }
-+
-+ if (!ubicom32_data_register_operand (operands[2], GET_MODE (operands[2])))
-+ {
-+ rtx op2;
-+
-+ op2 = gen_reg_rtx (SImode);
-+ emit_move_insn (op2, operands[2]);
-+ operands[2] = op2;
-+ }
-+
-+ acc_rtx = gen_reg_rtx (DImode);
-+ emit_insn (gen_umulsidi3 (acc_rtx, operands[1], operands[2]));
-+ emit_move_insn (operands[0], gen_lowpart (SImode, acc_rtx));
-+
-+ return 1;
-+ }
-+}
-+
-+/* Move the integer value VAL into OPERANDS[0]. */
-+
-+void
-+ubicom32_emit_move_const_int (rtx dest, rtx imm)
-+{
-+ rtx xoperands[2];
-+
-+ xoperands[0] = dest;
-+ xoperands[1] = imm;
-+
-+ /* Treat mem destinations separately. Values must be explicitly sign
-+ extended. */
-+ if (MEM_P (dest))
-+ {
-+ rtx low_hword_mem;
-+ rtx low_hword_addr;
-+
-+ /* Emit shorter sequence for signed 7-bit quantities. */
-+ if (satisfies_constraint_I (imm))
-+ {
-+ output_asm_insn ("move.4\t%0, %1", xoperands);
-+ return;
-+ }
-+
-+ /* Special case for pushing constants. */
-+ if (GET_CODE (XEXP (dest, 0)) == PRE_DEC
-+ && XEXP (XEXP (dest, 0), 0) == stack_pointer_rtx)
-+ {
-+ output_asm_insn ("movei\t-4(sp)++, #%%hi(%E1)", xoperands);
-+ output_asm_insn ("movei\t2(sp), #%%lo(%E1)", xoperands);
-+ return;
-+ }
-+
-+ /* See if we can add 2 to the original address. This is only
-+ possible if the original address is of the form REG or
-+ REG+const. */
-+ low_hword_addr = plus_constant (XEXP (dest, 0), 2);
-+ if (ubicom32_legitimate_address_p (HImode, low_hword_addr, 1))
-+ {
-+ low_hword_mem = gen_rtx_MEM (HImode, low_hword_addr);
-+ MEM_COPY_ATTRIBUTES (low_hword_mem, dest);
-+ output_asm_insn ("movei\t%0, #%%hi(%E1)", xoperands);
-+ xoperands[0] = low_hword_mem;
-+ output_asm_insn ("movei\t%0, #%%lo(%E1)", xoperands);
-+ return;
-+ }
-+
-+ /* The original address is too complex. We need to use a
-+ scratch memory by (sp) and move that to the original
-+ destination. */
-+ if (! reg_mentioned_p (stack_pointer_rtx, dest))
-+ {
-+ output_asm_insn ("movei\t-4(sp)++, #%%hi(%E1)", xoperands);
-+ output_asm_insn ("movei\t2(sp), #%%lo(%E1)", xoperands);
-+ output_asm_insn ("move.4\t%0, (sp)4++", xoperands);
-+ return;
-+ }
-+
-+ /* Our address mentions the stack pointer so we need to
-+ use our scratch data register here as well as scratch
-+ memory. */
-+ output_asm_insn ("movei\t-4(sp)++, #%%hi(%E1)", xoperands);
-+ output_asm_insn ("movei\t2(sp), #%%lo(%E1)", xoperands);
-+ output_asm_insn ("move.4\td15, (sp)4++", xoperands);
-+ output_asm_insn ("move.4\t%0, d15", xoperands);
-+ return;
-+ }
-+
-+ /* Move into registers are zero extended by default. */
-+ if (! REG_P (dest))
-+ abort ();
-+
-+ if (satisfies_constraint_N (imm))
-+ {
-+ output_asm_insn ("movei\t%0, %1", xoperands);
-+ return;
-+ }
-+
-+ if (INTVAL (xoperands[1]) >= 0xff80
-+ && INTVAL (xoperands[1]) < 0x10000)
-+ {
-+ xoperands[1] = GEN_INT (INTVAL (xoperands[1]) - 0x10000);
-+ output_asm_insn ("move.2\t%0, %1", xoperands);
-+ return;
-+ }
-+
-+ if ((REGNO_REG_CLASS (REGNO (xoperands[0])) == ADDRESS_REGS
-+ || REGNO_REG_CLASS (REGNO (xoperands[0])) == FDPIC_REG)
-+ && ((INTVAL (xoperands[1]) & 0x80000000) == 0))
-+ {
-+ output_asm_insn ("moveai\t%0, #%%hi(%E1)", xoperands);
-+ if ((INTVAL (xoperands[1]) & 0x7f) != 0)
-+ output_asm_insn ("lea.1\t%0, %%lo(%E1)(%0)", xoperands);
-+ return;
-+ }
-+
-+ if ((INTVAL (xoperands[1]) & 0xffff0000) == 0)
-+ {
-+ output_asm_insn ("movei\t%0, #%%lo(%E1)", xoperands);
-+ output_asm_insn ("move.2\t%0, %0", xoperands);
-+ return;
-+ }
-+
-+ /* This is very expensive. The constant is so large that we
-+ need to use the stack to do the load. */
-+ output_asm_insn ("movei\t-4(sp)++, #%%hi(%E1)", xoperands);
-+ output_asm_insn ("movei\t2(sp), #%%lo(%E1)", xoperands);
-+ output_asm_insn ("move.4\t%0, (sp)4++", xoperands);
-+}
-+
-+/* Stack layout. Prologue/Epilogue. */
-+
-+static int save_regs_size;
-+
-+static void
-+ubicom32_layout_frame (void)
-+{
-+ int regno;
-+
-+ memset ((char *) &save_regs[0], 0, sizeof (save_regs));
-+ nregs = 0;
-+ frame_size = get_frame_size ();
-+
-+ if (frame_pointer_needed || df_regs_ever_live_p (FRAME_POINTER_REGNUM))
-+ {
-+ save_regs[FRAME_POINTER_REGNUM] = 1;
-+ ++nregs;
-+ }
-+
-+ if (current_function_is_leaf && ! df_regs_ever_live_p (LINK_REGNO))
-+ ubicom32_can_use_calli_to_ret = 1;
-+ else
-+ {
-+ ubicom32_can_use_calli_to_ret = 0;
-+ save_regs[LINK_REGNO] = 1;
-+ ++nregs;
-+ }
-+
-+ /* Figure out which register(s) needs to be saved. */
-+ for (regno = 0; regno <= LAST_ADDRESS_REGNUM; regno++)
-+ if (df_regs_ever_live_p(regno)
-+ && ! call_used_regs[regno]
-+ && ! fixed_regs[regno]
-+ && ! save_regs[regno])
-+ {
-+ save_regs[regno] = 1;
-+ ++nregs;
-+ }
-+
-+ save_regs_size = 4 * nregs;
-+}
-+
-+static void
-+ubicom32_emit_add_movsi (int regno, int adj)
-+{
-+ rtx x;
-+ rtx reg = gen_rtx_REG (SImode, regno);
-+
-+ adj += 4;
-+ if (adj > 8 * 4)
-+ {
-+ x = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
-+ GEN_INT (-adj)));
-+ RTX_FRAME_RELATED_P (x) = 1;
-+ x = emit_move_insn (gen_rtx_MEM (SImode, stack_pointer_rtx), reg);
-+ }
-+ else
-+ {
-+ rtx addr = gen_rtx_PRE_MODIFY (Pmode, stack_pointer_rtx,
-+ gen_rtx_PLUS (Pmode, stack_pointer_rtx,
-+ GEN_INT (-adj)));
-+ x = emit_move_insn (gen_rtx_MEM (SImode, addr), reg);
-+ }
-+ RTX_FRAME_RELATED_P (x) = 1;
-+}
-+
-+void
-+ubicom32_expand_prologue (void)
-+{
-+ rtx x;
-+ int regno;
-+ int outgoing_args_size = crtl->outgoing_args_size;
-+ int adj;
-+
-+ if (ubicom32_naked_function_p ())
-+ return;
-+
-+ ubicom32_builtin_saveregs ();
-+
-+ ubicom32_layout_frame ();
-+ adj = (outgoing_args_size + get_frame_size () + save_regs_size
-+ + crtl->args.pretend_args_size);
-+
-+ if (!adj)
-+ ;
-+ else if (outgoing_args_size + save_regs_size < 508
-+ && get_frame_size () + save_regs_size > 508)
-+ {
-+ int i = 0;
-+ x = gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
-+ GEN_INT (-adj));
-+ x = emit_insn (x);
-+ RTX_FRAME_RELATED_P (x) = 1;
-+
-+ for (regno = LAST_ADDRESS_REGNUM; regno >= 0; --regno)
-+ if (save_regs[regno] && regno != LINK_REGNO)
-+ {
-+ x = gen_rtx_MEM (SImode,
-+ gen_rtx_PLUS (Pmode,
-+ stack_pointer_rtx,
-+ GEN_INT (i * 4 + outgoing_args_size)));
-+ x = emit_move_insn (x, gen_rtx_REG (SImode, regno));
-+ RTX_FRAME_RELATED_P (x) = 1;
-+ ++i;
-+ }
-+ if (save_regs[LINK_REGNO])
-+ {
-+ x = gen_rtx_MEM (SImode,
-+ gen_rtx_PLUS (Pmode,
-+ stack_pointer_rtx,
-+ GEN_INT (i * 4 + outgoing_args_size)));
-+ x = emit_move_insn (x, gen_rtx_REG (SImode, LINK_REGNO));
-+ RTX_FRAME_RELATED_P (x) = 1;
-+ }
-+ }
-+ else
-+ {
-+ int regno;
-+ int adj = get_frame_size () + crtl->args.pretend_args_size;
-+ int i = 0;
-+
-+ if (save_regs[LINK_REGNO])
-+ {
-+ ubicom32_emit_add_movsi (LINK_REGNO, adj);
-+ ++i;
-+ }
-+
-+ for (regno = 0; regno <= LAST_ADDRESS_REGNUM; ++regno)
-+ if (save_regs[regno] && regno != LINK_REGNO)
-+ {
-+ if (i)
-+ {
-+ rtx mem = gen_rtx_MEM (SImode,
-+ gen_rtx_PRE_DEC (Pmode,
-+ stack_pointer_rtx));
-+ x = emit_move_insn (mem, gen_rtx_REG (SImode, regno));
-+ RTX_FRAME_RELATED_P (x) = 1;
-+ }
-+ else
-+ ubicom32_emit_add_movsi (regno, adj);
-+ ++i;
-+ }
-+
-+ if (outgoing_args_size || (!i && adj))
-+ {
-+ x = gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
-+ GEN_INT (-outgoing_args_size - (i ? 0 : adj)));
-+ x = emit_insn (x);
-+ RTX_FRAME_RELATED_P (x) = 1;
-+ }
-+ }
-+
-+ if (frame_pointer_needed)
-+ {
-+ int fp_adj = save_regs_size + outgoing_args_size;
-+ x = gen_addsi3 (frame_pointer_rtx, stack_pointer_rtx,
-+ GEN_INT (fp_adj));
-+ x = emit_insn (x);
-+ RTX_FRAME_RELATED_P (x) = 1;
-+ }
-+}
-+
-+void
-+ubicom32_expand_epilogue (void)
-+{
-+ rtx x;
-+ int regno;
-+ int outgoing_args_size = crtl->outgoing_args_size;
-+ int adj;
-+ int i;
-+
-+ if (ubicom32_naked_function_p ())
-+ {
-+ emit_jump_insn (gen_return_internal (gen_rtx_REG (SImode,
-+ LINK_REGNO)));
-+ return;
-+ }
-+
-+ if (cfun->calls_alloca)
-+ {
-+ x = gen_addsi3 (stack_pointer_rtx, frame_pointer_rtx,
-+ GEN_INT (-save_regs_size));
-+ emit_insn (x);
-+ outgoing_args_size = 0;
-+ }
-+
-+ if (outgoing_args_size)
-+ {
-+ x = gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
-+ GEN_INT (outgoing_args_size));
-+ emit_insn (x);
-+ }
-+
-+ i = 0;
-+ for (regno = LAST_ADDRESS_REGNUM; regno >= 0; --regno)
-+ if (save_regs[regno] && regno != LINK_REGNO)
-+ {
-+ x = gen_rtx_MEM (SImode, gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
-+ emit_move_insn (gen_rtx_REG (SImode, regno), x);
-+ ++i;
-+ }
-+
-+ /* Do we have to adjust the stack after we've finished restoring regs? */
-+ adj = get_frame_size() + crtl->args.pretend_args_size;
-+ if (cfun->stdarg)
-+ adj += UBICOM32_FUNCTION_ARG_REGS * UNITS_PER_WORD;
-+
-+#if 0
-+ if (crtl->calls_eh_return && 0)
-+ {
-+ if (save_regs[LINK_REGNO])
-+ {
-+ x = gen_rtx_MEM (SImode, gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
-+ emit_move_insn (gen_rtx_REG (SImode, LINK_REGNO), x);
-+ }
-+
-+ if (adj)
-+ {
-+ x = gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
-+ GEN_INT (adj));
-+ x = emit_insn (x);
-+ }
-+
-+ /* Perform the additional bump for __throw. */
-+ emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
-+ EH_RETURN_STACKADJ_RTX));
-+ emit_jump_insn (gen_eh_return_internal ());
-+ return;
-+ }
-+#endif
-+
-+ if (save_regs[LINK_REGNO])
-+ {
-+ if (adj >= 4 && adj <= (6 * 4))
-+ {
-+ x = GEN_INT (adj + 4);
-+ emit_jump_insn (gen_return_from_post_modify_sp (x));
-+ return;
-+ }
-+
-+ if (adj == 0)
-+ {
-+ x = gen_rtx_MEM (SImode, gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
-+ emit_jump_insn (gen_return_internal (x));
-+ return;
-+ }
-+
-+ x = gen_rtx_MEM (SImode, gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
-+ emit_move_insn (gen_rtx_REG (SImode, LINK_REGNO), x);
-+ }
-+
-+ if (adj)
-+ {
-+ x = gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
-+ GEN_INT (adj));
-+ x = emit_insn (x);
-+ adj = 0;
-+ }
-+
-+ /* Given that we've just done all the hard work here we may as well use
-+ a calli to return. */
-+ ubicom32_can_use_calli_to_ret = 1;
-+ emit_jump_insn (gen_return_internal (gen_rtx_REG (SImode, LINK_REGNO)));
-+}
-+
-+void
-+ubicom32_expand_call_fdpic (rtx *operands)
-+{
-+ rtx c;
-+ rtx addr;
-+ rtx fdpic_reg = get_hard_reg_initial_val (SImode, FDPIC_REGNUM);
-+
-+ addr = XEXP (operands[0], 0);
-+
-+ c = gen_call_fdpic (addr, operands[1], fdpic_reg);
-+ emit_call_insn (c);
-+}
-+
-+void
-+ubicom32_expand_call_value_fdpic (rtx *operands)
-+{
-+ rtx c;
-+ rtx addr;
-+ rtx fdpic_reg = get_hard_reg_initial_val (SImode, FDPIC_REGNUM);
-+
-+ addr = XEXP (operands[1], 0);
-+
-+ c = gen_call_value_fdpic (operands[0], addr, operands[2], fdpic_reg);
-+ emit_call_insn (c);
-+}
-+
-+void
-+ubicom32_expand_eh_return (rtx *operands)
-+{
-+ if (REG_P (operands[0])
-+ || REGNO (operands[0]) != EH_RETURN_STACKADJ_REGNO)
-+ {
-+ rtx sp = EH_RETURN_STACKADJ_RTX;
-+ emit_move_insn (sp, operands[0]);
-+ operands[0] = sp;
-+ }
-+
-+ if (REG_P (operands[1])
-+ || REGNO (operands[1]) != EH_RETURN_HANDLER_REGNO)
-+ {
-+ rtx ra = EH_RETURN_HANDLER_RTX;
-+ emit_move_insn (ra, operands[1]);
-+ operands[1] = ra;
-+ }
-+}
-+
-+/* Compute the offsets between eliminable registers. */
-+
-+int
-+ubicom32_initial_elimination_offset (int from, int to)
-+{
-+ ubicom32_layout_frame ();
-+ if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
-+ return save_regs_size + crtl->outgoing_args_size;
-+
-+ if (from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
-+ return get_frame_size ()/* + save_regs_size */;
-+
-+ if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
-+ return get_frame_size ()
-+ + crtl->outgoing_args_size
-+ + save_regs_size;
-+
-+ return 0;
-+}
-+
-+/* Return 1 if it is appropriate to emit `ret' instructions in the
-+ body of a function. Do this only if the epilogue is simple, needing a
-+ couple of insns. Prior to reloading, we can't tell how many registers
-+ must be saved, so return 0 then. Return 0 if there is no frame
-+ marker to de-allocate.
-+
-+ If NON_SAVING_SETJMP is defined and true, then it is not possible
-+ for the epilogue to be simple, so return 0. This is a special case
-+ since NON_SAVING_SETJMP will not cause regs_ever_live to change
-+ until final, but jump_optimize may need to know sooner if a
-+ `return' is OK. */
-+
-+int
-+ubicom32_can_use_return_insn_p (void)
-+{
-+ if (! reload_completed || frame_pointer_needed)
-+ return 0;
-+
-+ return 1;
-+}
-+
-+/* Attributes and CC handling. */
-+
-+/* Handle an attribute requiring a FUNCTION_DECL; arguments as in
-+ struct attribute_spec.handler. */
-+static tree
-+ubicom32_handle_fndecl_attribute (tree *node, tree name,
-+ tree args ATTRIBUTE_UNUSED,
-+ int flags ATTRIBUTE_UNUSED,
-+ bool *no_add_attrs)
-+{
-+ if (TREE_CODE (*node) != FUNCTION_DECL)
-+ {
-+ warning ("'%s' attribute only applies to functions",
-+ IDENTIFIER_POINTER (name));
-+ *no_add_attrs = true;
-+ }
-+
-+ return NULL_TREE;
-+}
-+
-+/* A C expression that places additional restrictions on the register class to
-+ use when it is necessary to copy value X into a register in class CLASS.
-+ The value is a register class; perhaps CLASS, or perhaps another, smaller
-+ class. On many machines, the following definition is safe:
-+
-+ #define PREFERRED_RELOAD_CLASS(X,CLASS) CLASS
-+
-+ Sometimes returning a more restrictive class makes better code. For
-+ example, on the 68000, when X is an integer constant that is in range for a
-+ `moveq' instruction, the value of this macro is always `DATA_REGS' as long
-+ as CLASS includes the data registers. Requiring a data register guarantees
-+ that a `moveq' will be used.
-+
-+ If X is a `const_double', by returning `NO_REGS' you can force X into a
-+ memory constant. This is useful on certain machines where immediate
-+ floating values cannot be loaded into certain kinds of registers. */
-+
-+enum reg_class
-+ubicom32_preferred_reload_class (rtx x, enum reg_class class)
-+{
-+ /* If a symbolic constant, HIGH or a PLUS is reloaded,
-+ it is most likely being used as an address, so
-+ prefer ADDRESS_REGS. If 'class' is not a superset
-+ of ADDRESS_REGS, e.g. DATA_REGS, then reject this reload. */
-+ if (GET_CODE (x) == PLUS
-+ || GET_CODE (x) == HIGH
-+ || GET_CODE (x) == LABEL_REF
-+ || GET_CODE (x) == SYMBOL_REF
-+ || GET_CODE (x) == CONST)
-+ {
-+ if (reg_class_subset_p (ALL_ADDRESS_REGS, class))
-+ return ALL_ADDRESS_REGS;
-+
-+ return NO_REGS;
-+ }
-+
-+ return class;
-+}
-+
-+/* Function arguments and varargs. */
-+
-+int
-+ubicom32_reg_parm_stack_space (tree fndecl)
-+{
-+ return 0;
-+
-+ if (fndecl
-+ && TYPE_ARG_TYPES (TREE_TYPE (fndecl)) != 0
-+ && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (TREE_TYPE (fndecl))))
-+ != void_type_node))
-+ return UBICOM32_FUNCTION_ARG_REGS * UNITS_PER_WORD;
-+
-+ return 0;
-+}
-+
-+/* Flush the argument registers to the stack for a stdarg function;
-+ return the new argument pointer. */
-+
-+rtx
-+ubicom32_builtin_saveregs (void)
-+{
-+ int regno;
-+
-+ if (! cfun->stdarg)
-+ return 0;
-+
-+ for (regno = UBICOM32_FUNCTION_ARG_REGS - 1; regno >= 0; --regno)
-+ emit_move_insn (gen_rtx_MEM (SImode,
-+ gen_rtx_PRE_DEC (SImode,
-+ stack_pointer_rtx)),
-+ gen_rtx_REG (SImode, regno));
-+
-+ return stack_pointer_rtx;
-+}
-+
-+void
-+ubicom32_va_start (tree valist, rtx nextarg)
-+{
-+ std_expand_builtin_va_start (valist, nextarg);
-+}
-+
-+rtx
-+ubicom32_va_arg (tree valist, tree type)
-+{
-+ HOST_WIDE_INT size, rsize;
-+ tree addr, incr, tmp;
-+ rtx addr_rtx;
-+ int indirect = 0;
-+
-+ /* Round up sizeof(type) to a word. */
-+ size = int_size_in_bytes (type);
-+ rsize = (size + UNITS_PER_WORD - 1) & -UNITS_PER_WORD;
-+
-+ /* Large types are passed by reference. */
-+ if (size > 8)
-+ {
-+ indirect = 1;
-+ size = rsize = UNITS_PER_WORD;
-+ }
-+
-+ incr = valist;
-+ addr = incr = save_expr (incr);
-+
-+ /* FIXME Nat's version - is it correct? */
-+ tmp = fold_convert (ptr_type_node, size_int (rsize));
-+ tmp = build2 (PLUS_EXPR, ptr_type_node, incr, tmp);
-+ incr = fold (tmp);
-+
-+ /* FIXME Nat's version - is it correct? */
-+ incr = build2 (MODIFY_EXPR, ptr_type_node, valist, incr);
-+
-+ TREE_SIDE_EFFECTS (incr) = 1;
-+ expand_expr (incr, const0_rtx, VOIDmode, EXPAND_NORMAL);
-+
-+ addr_rtx = expand_expr (addr, NULL, Pmode, EXPAND_NORMAL);
-+
-+ if (size < UNITS_PER_WORD)
-+ emit_insn (gen_addsi3 (addr_rtx, addr_rtx,
-+ GEN_INT (UNITS_PER_WORD - size)));
-+
-+ if (indirect)
-+ {
-+ addr_rtx = force_reg (Pmode, addr_rtx);
-+ addr_rtx = gen_rtx_MEM (Pmode, addr_rtx);
-+ set_mem_alias_set (addr_rtx, get_varargs_alias_set ());
-+ }
-+
-+ return addr_rtx;
-+}
-+
-+void
-+init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype, rtx libname,
-+ int indirect ATTRIBUTE_UNUSED)
-+{
-+ cum->nbytes = 0;
-+
-+ if (!libname)
-+ {
-+ cum->stdarg = (TYPE_ARG_TYPES (fntype) != 0
-+ && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
-+ != void_type_node));
-+ }
-+}
-+
-+/* Return an RTX to represent where a value in mode MODE will be passed
-+ to a function. If the result is 0, the argument will be pushed. */
-+
-+rtx
-+function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
-+ int named ATTRIBUTE_UNUSED)
-+{
-+ rtx result = 0;
-+ int size, align;
-+ int nregs = UBICOM32_FUNCTION_ARG_REGS;
-+
-+ /* Figure out the size of the object to be passed. */
-+ if (mode == BLKmode)
-+ size = int_size_in_bytes (type);
-+ else
-+ size = GET_MODE_SIZE (mode);
-+
-+ /* Figure out the alignment of the object to be passed. */
-+ align = size;
-+
-+ cum->nbytes = (cum->nbytes + 3) & ~3;
-+
-+ /* Don't pass this arg via a register if all the argument registers
-+ are used up. */
-+ if (cum->nbytes >= nregs * UNITS_PER_WORD)
-+ return 0;
-+
-+ /* Don't pass this arg via a register if it would be split between
-+ registers and memory. */
-+ result = gen_rtx_REG (mode, cum->nbytes / UNITS_PER_WORD);
-+
-+ return result;
-+}
-+
-+rtx
-+function_incoming_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
-+ int named ATTRIBUTE_UNUSED)
-+{
-+ if (cfun->stdarg)
-+ return 0;
-+
-+ return function_arg (cum, mode, type, named);
-+}
-+
-+
-+/* Implement hook TARGET_ARG_PARTIAL_BYTES.
-+
-+ Returns the number of bytes at the beginning of an argument that
-+ must be put in registers. The value must be zero for arguments
-+ that are passed entirely in registers or that are entirely pushed
-+ on the stack. */
-+static int
-+ubicom32_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
-+ tree type, bool named ATTRIBUTE_UNUSED)
-+{
-+ int size, diff;
-+
-+ int nregs = UBICOM32_FUNCTION_ARG_REGS;
-+
-+ /* round up to full word */
-+ cum->nbytes = (cum->nbytes + 3) & ~3;
-+
-+ if (targetm.calls.pass_by_reference (cum, mode, type, named))
-+ return 0;
-+
-+ /* number of bytes left in registers */
-+ diff = nregs*UNITS_PER_WORD - cum->nbytes;
-+
-+ /* regs all used up */
-+ if (diff <= 0)
-+ return 0;
-+
-+ /* Figure out the size of the object to be passed. */
-+ if (mode == BLKmode)
-+ size = int_size_in_bytes (type);
-+ else
-+ size = GET_MODE_SIZE (mode);
-+
-+ /* enough space left in regs for size */
-+ if (size <= diff)
-+ return 0;
-+
-+ /* put diff bytes in regs and rest on stack */
-+ return diff;
-+
-+}
-+
-+static bool
-+ubicom32_pass_by_reference (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
-+ enum machine_mode mode, const_tree type,
-+ bool named ATTRIBUTE_UNUSED)
-+{
-+ int size;
-+
-+ if (type)
-+ size = int_size_in_bytes (type);
-+ else
-+ size = GET_MODE_SIZE (mode);
-+
-+ return size <= 0 || size > 8;
-+}
-+
-+static bool
-+ubicom32_callee_copies (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
-+ enum machine_mode mode, const_tree type,
-+ bool named ATTRIBUTE_UNUSED)
-+{
-+ int size;
-+
-+ if (type)
-+ size = int_size_in_bytes (type);
-+ else
-+ size = GET_MODE_SIZE (mode);
-+
-+ return size <= 0 || size > 8;
-+}
-+
-+static bool
-+ubicom32_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
-+{
-+ int size, mode;
-+
-+ if (!type)
-+ return true;
-+
-+ size = int_size_in_bytes(type);
-+ if (size > 8)
-+ return true;
-+
-+ mode = TYPE_MODE(type);
-+ if (mode == BLKmode)
-+ return true;
-+
-+ return false;
-+}
-+
-+/* Return true if a given register number REGNO is acceptable for machine
-+ mode MODE. */
-+bool
-+ubicom32_hard_regno_mode_ok (unsigned int regno, enum machine_mode mode)
-+{
-+ /* If we're not at least a v3 ISA then ACC0_HI is only 16 bits. */
-+ if (! ubicom32_v3)
-+ {
-+ if (regno == ACC0_HI_REGNUM)
-+ return (mode == QImode || mode == HImode);
-+ }
-+
-+ /* Only the flags reg can hold CCmode. */
-+ if (GET_MODE_CLASS (mode) == MODE_CC)
-+ return regno == CC_REGNUM;
-+
-+ /* We restrict the choice of DImode registers to only being address,
-+ data or accumulator regs. We also restrict them to only start on
-+ even register numbers so we never have to worry about partial
-+ overlaps between operands in instructions. */
-+ if (GET_MODE_SIZE (mode) > 4)
-+ {
-+ switch (REGNO_REG_CLASS (regno))
-+ {
-+ case ADDRESS_REGS:
-+ case DATA_REGS:
-+ case ACC_REGS:
-+ return (regno & 1) == 0;
-+
-+ default:
-+ return false;
-+ }
-+ }
-+
-+ return true;
-+}
-+
-+/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
-+ and check its validity for a certain class.
-+ We have two alternate definitions for each of them.
-+ The usual definition accepts all pseudo regs; the other rejects
-+ them unless they have been allocated suitable hard regs.
-+ The symbol REG_OK_STRICT causes the latter definition to be used.
-+
-+ Most source files want to accept pseudo regs in the hope that
-+ they will get allocated to the class that the insn wants them to be in.
-+ Source files for reload pass need to be strict.
-+ After reload, it makes no difference, since pseudo regs have
-+ been eliminated by then.
-+
-+ These assume that REGNO is a hard or pseudo reg number.
-+ They give nonzero only if REGNO is a hard reg of the suitable class
-+ or a pseudo reg currently allocated to a suitable hard reg.
-+ Since they use reg_renumber, they are safe only once reg_renumber
-+ has been allocated, which happens in local-alloc.c. */
-+
-+int
-+ubicom32_regno_ok_for_base_p (int regno, int strict)
-+{
-+ if ((regno >= FIRST_ADDRESS_REGNUM && regno <= STACK_POINTER_REGNUM)
-+ || (!strict
-+ && (regno >= FIRST_PSEUDO_REGISTER
-+ || regno == ARG_POINTER_REGNUM))
-+ || (strict && (reg_renumber
-+ && reg_renumber[regno] >= FIRST_ADDRESS_REGNUM
-+ && reg_renumber[regno] <= STACK_POINTER_REGNUM)))
-+ return 1;
-+
-+ return 0;
-+}
-+
-+int
-+ubicom32_regno_ok_for_index_p (int regno, int strict)
-+{
-+ if ((regno >= FIRST_DATA_REGNUM && regno <= LAST_DATA_REGNUM)
-+ || (!strict && regno >= FIRST_PSEUDO_REGISTER)
-+ || (strict && (reg_renumber
-+ && reg_renumber[regno] >= FIRST_DATA_REGNUM
-+ && reg_renumber[regno] <= LAST_DATA_REGNUM)))
-+ return 1;
-+
-+ return 0;
-+}
-+
-+/* Returns 1 if X is a valid index register. STRICT is 1 if only hard
-+ registers should be accepted. Accept either REG or SUBREG where a
-+ register is valid. */
-+
-+static bool
-+ubicom32_is_index_reg (rtx x, int strict)
-+{
-+ if ((REG_P (x) && ubicom32_regno_ok_for_index_p (REGNO (x), strict))
-+ || (GET_CODE (x) == SUBREG && REG_P (SUBREG_REG (x))
-+ && ubicom32_regno_ok_for_index_p (REGNO (SUBREG_REG (x)), strict)))
-+ return true;
-+
-+ return false;
-+}
-+
-+/* Return 1 if X is a valid index for a memory address. */
-+
-+static bool
-+ubicom32_is_index_expr (enum machine_mode mode, rtx x, int strict)
-+{
-+ /* Immediate index must be an unsigned 7-bit offset multiple of 1, 2
-+ or 4 depending on mode. */
-+ if (CONST_INT_P (x))
-+ {
-+ switch (mode)
-+ {
-+ case QImode:
-+ return satisfies_constraint_J (x);
-+
-+ case HImode:
-+ return satisfies_constraint_K (x);
-+
-+ case SImode:
-+ case SFmode:
-+ return satisfies_constraint_L (x);
-+
-+ case DImode:
-+ return satisfies_constraint_L (x)
-+ && satisfies_constraint_L (GEN_INT (INTVAL (x) + 4));
-+
-+ default:
-+ return false;
-+ }
-+ }
-+
-+ if (mode != SImode && mode != HImode && mode != QImode)
-+ return false;
-+
-+ /* Register index scaled by mode of operand: REG + REG * modesize.
-+ Valid scaled index registers are:
-+
-+ SImode (mult (dreg) 4))
-+ HImode (mult (dreg) 2))
-+ QImode (mult (dreg) 1)) */
-+ if (GET_CODE (x) == MULT
-+ && ubicom32_is_index_reg (XEXP (x, 0), strict)
-+ && CONST_INT_P (XEXP (x, 1))
-+ && INTVAL (XEXP (x, 1)) == (HOST_WIDE_INT)GET_MODE_SIZE (mode))
-+ return true;
-+
-+ /* REG + REG addressing is allowed for QImode. */
-+ if (ubicom32_is_index_reg (x, strict) && mode == QImode)
-+ return true;
-+
-+ return false;
-+}
-+
-+static bool
-+ubicom32_is_valid_offset (enum machine_mode mode, HOST_WIDE_INT offs)
-+{
-+ if (offs < 0)
-+ return false;
-+
-+ switch (mode)
-+ {
-+ case QImode:
-+ return offs <= 127;
-+
-+ case HImode:
-+ return offs <= 254;
-+
-+ case SImode:
-+ case SFmode:
-+ return offs <= 508;
-+
-+ case DImode:
-+ return offs <= 504;
-+
-+ default:
-+ return false;
-+ }
-+}
-+
-+static int
-+ubicom32_get_valid_offset_mask (enum machine_mode mode)
-+{
-+ switch (mode)
-+ {
-+ case QImode:
-+ return 127;
-+
-+ case HImode:
-+ return 255;
-+
-+ case SImode:
-+ case SFmode:
-+ return 511;
-+
-+ case DImode:
-+ return 255;
-+
-+ default:
-+ return 0;
-+ }
-+}
-+
-+/* Returns 1 if X is a valid base register. STRICT is 1 if only hard
-+ registers should be accepted. Accept either REG or SUBREG where a
-+ register is valid. */
-+
-+static bool
-+ubicom32_is_base_reg (rtx x, int strict)
-+{
-+ if ((REG_P (x) && ubicom32_regno_ok_for_base_p (REGNO (x), strict))
-+ || (GET_CODE (x) == SUBREG && REG_P (SUBREG_REG (x))
-+ && ubicom32_regno_ok_for_base_p (REGNO (SUBREG_REG (x)), strict)))
-+ return true;
-+
-+ return false;
-+}
-+
-+static bool
-+ubicom32_cannot_force_const_mem (rtx x ATTRIBUTE_UNUSED)
-+{
-+ return TARGET_FDPIC;
-+}
-+
-+/* Determine if X is a legitimate constant. */
-+
-+bool
-+ubicom32_legitimate_constant_p (rtx x)
-+{
-+ /* Among its other duties, LEGITIMATE_CONSTANT_P decides whether
-+ a constant can be entered into reg_equiv_constant[]. If we return true,
-+ reload can create new instances of the constant whenever it likes.
-+
-+ The idea is therefore to accept as many constants as possible (to give
-+ reload more freedom) while rejecting constants that can only be created
-+ at certain times. In particular, anything with a symbolic component will
-+ require use of the pseudo FDPIC register, which is only available before
-+ reload. */
-+ if (TARGET_FDPIC)
-+ {
-+ if (GET_CODE (x) == SYMBOL_REF
-+ || (GET_CODE (x) == CONST
-+ && GET_CODE (XEXP (x, 0)) == PLUS
-+ && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF)
-+ || CONSTANT_ADDRESS_P (x))
-+ return false;
-+
-+ return true;
-+ }
-+
-+ /* For non-PIC code anything goes! */
-+ return true;
-+}
-+
-+/* Address validation. */
-+
-+bool
-+ubicom32_legitimate_address_p (enum machine_mode mode, rtx x, int strict)
-+{
-+ if (TARGET_DEBUG_ADDRESS)
-+ {
-+ fprintf (stderr, "\n==> GO_IF_LEGITIMATE_ADDRESS%s\n",
-+ (strict) ? " (STRICT)" : "");
-+ debug_rtx (x);
-+ }
-+
-+ if (CONSTANT_ADDRESS_P (x))
-+ return false;
-+
-+ if (ubicom32_is_base_reg (x, strict))
-+ return true;
-+
-+ if ((GET_CODE (x) == POST_INC
-+ || GET_CODE (x) == PRE_INC
-+ || GET_CODE (x) == POST_DEC
-+ || GET_CODE (x) == PRE_DEC)
-+ && REG_P (XEXP (x, 0))
-+ && ubicom32_is_base_reg (XEXP (x, 0), strict)
-+ && mode != DImode)
-+ return true;
-+
-+ if ((GET_CODE (x) == PRE_MODIFY || GET_CODE (x) == POST_MODIFY)
-+ && ubicom32_is_base_reg (XEXP (x, 0), strict)
-+ && GET_CODE (XEXP (x, 1)) == PLUS
-+ && rtx_equal_p (XEXP (x, 0), XEXP (XEXP (x, 1), 0))
-+ && CONST_INT_P (XEXP (XEXP (x, 1), 1))
-+ && mode != DImode)
-+ {
-+ HOST_WIDE_INT disp = INTVAL (XEXP (XEXP (x, 1), 1));
-+ switch (mode)
-+ {
-+ case QImode:
-+ return disp >= -8 && disp <= 7;
-+
-+ case HImode:
-+ return disp >= -16 && disp <= 14 && ! (disp & 1);
-+
-+ case SImode:
-+ return disp >= -32 && disp <= 28 && ! (disp & 3);
-+
-+ default:
-+ return false;
-+ }
-+ }
-+
-+ /* Accept base + index * scale. */
-+ if (GET_CODE (x) == PLUS
-+ && ubicom32_is_base_reg (XEXP (x, 0), strict)
-+ && ubicom32_is_index_expr (mode, XEXP (x, 1), strict))
-+ return true;
-+
-+ /* Accept index * scale + base. */
-+ if (GET_CODE (x) == PLUS
-+ && ubicom32_is_base_reg (XEXP (x, 1), strict)
-+ && ubicom32_is_index_expr (mode, XEXP (x, 0), strict))
-+ return true;
-+
-+ if (! TARGET_FDPIC)
-+ {
-+ /* Accept (lo_sum (reg) (symbol_ref)) that can be used as a mem+7bits
-+ displacement operand:
-+
-+ moveai a1, #%hi(SYM)
-+ move.4 d3, %lo(SYM)(a1) */
-+ if (GET_CODE (x) == LO_SUM
-+ && ubicom32_is_base_reg (XEXP (x, 0), strict)
-+ && (GET_CODE (XEXP (x, 1)) == SYMBOL_REF
-+ || GET_CODE (XEXP (x, 1)) == LABEL_REF /* FIXME: wrong */)
-+ && mode != DImode)
-+ return true;
-+ }
-+
-+ if (TARGET_DEBUG_ADDRESS)
-+ fprintf (stderr, "\nNot a legitimate address.\n");
-+
-+ return false;
-+}
-+
-+rtx
-+ubicom32_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
-+ enum machine_mode mode)
-+{
-+ if (mode == BLKmode)
-+ return NULL_RTX;
-+
-+ if (GET_CODE (x) == PLUS
-+ && REG_P (XEXP (x, 0))
-+ && ! REGNO_PTR_FRAME_P (REGNO (XEXP (x, 0)))
-+ && CONST_INT_P (XEXP (x, 1))
-+ && ! ubicom32_is_valid_offset (mode, INTVAL (XEXP (x, 1))))
-+ {
-+ rtx base;
-+ rtx plus;
-+ rtx new_rtx;
-+ HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
-+ HOST_WIDE_INT low = val & ubicom32_get_valid_offset_mask (mode);
-+ HOST_WIDE_INT high = val ^ low;
-+
-+ if (val < 0)
-+ return NULL_RTX;
-+
-+ if (! low)
-+ return NULL_RTX;
-+
-+ /* Reload the high part into a base reg; leave the low part
-+ in the mem directly. */
-+ base = XEXP (x, 0);
-+ if (! ubicom32_is_base_reg (base, 0))
-+ base = copy_to_mode_reg (Pmode, base);
-+
-+ plus = expand_simple_binop (Pmode, PLUS,
-+ gen_int_mode (high, Pmode),
-+ base, NULL, 0, OPTAB_WIDEN);
-+ new_rtx = plus_constant (plus, low);
-+
-+ return new_rtx;
-+ }
-+
-+ return NULL_RTX;
-+}
-+
-+/* Try a machine-dependent way of reloading an illegitimate address AD
-+ operand. If we find one, push the reload and and return the new address.
-+
-+ MODE is the mode of the enclosing MEM. OPNUM is the operand number
-+ and TYPE is the reload type of the current reload. */
-+
-+rtx
-+ubicom32_legitimize_reload_address (rtx ad, enum machine_mode mode,
-+ int opnum, int type)
-+{
-+ /* Is this an address that we've already fixed up? If it is then
-+ recognize it and move on. */
-+ if (GET_CODE (ad) == PLUS
-+ && GET_CODE (XEXP (ad, 0)) == PLUS
-+ && REG_P (XEXP (XEXP (ad, 0), 0))
-+ && CONST_INT_P (XEXP (XEXP (ad, 0), 1))
-+ && CONST_INT_P (XEXP (ad, 1)))
-+ {
-+ push_reload (XEXP (ad, 0), NULL_RTX, &XEXP (ad, 0), NULL,
-+ BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
-+ opnum, (enum reload_type) type);
-+ return ad;
-+ }
-+
-+ /* Have we got an address where the offset is simply out of range? If
-+ yes then reload the range as a high part and smaller offset. */
-+ if (GET_CODE (ad) == PLUS
-+ && REG_P (XEXP (ad, 0))
-+ && REGNO (XEXP (ad, 0)) < FIRST_PSEUDO_REGISTER
-+ && REGNO_OK_FOR_BASE_P (REGNO (XEXP (ad, 0)))
-+ && CONST_INT_P (XEXP (ad, 1))
-+ && ! ubicom32_is_valid_offset (mode, INTVAL (XEXP (ad, 1))))
-+ {
-+ rtx temp;
-+ rtx new_rtx;
-+
-+ HOST_WIDE_INT val = INTVAL (XEXP (ad, 1));
-+ HOST_WIDE_INT low = val & ubicom32_get_valid_offset_mask (mode);
-+ HOST_WIDE_INT high = val ^ low;
-+
-+ /* Reload the high part into a base reg; leave the low part
-+ in the mem directly. */
-+ temp = gen_rtx_PLUS (Pmode, XEXP (ad, 0), GEN_INT (high));
-+ new_rtx = gen_rtx_PLUS (Pmode, temp, GEN_INT (low));
-+
-+ push_reload (XEXP (new_rtx, 0), NULL_RTX, &XEXP (new_rtx, 0), NULL,
-+ BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
-+ opnum, (enum reload_type) type);
-+ return new_rtx;
-+ }
-+
-+ /* If we're presented with an pre/post inc/dec then we must force this
-+ to be done in an address register. The register allocator should
-+ work this out for itself but at times ends up trying to use the wrong
-+ class. If we get the wrong class then reload will end up generating
-+ at least 3 instructions whereas this way we can hopefully keep it to
-+ just 2. */
-+ if ((GET_CODE (ad) == POST_INC
-+ || GET_CODE (ad) == PRE_INC
-+ || GET_CODE (ad) == POST_DEC
-+ || GET_CODE (ad) == PRE_DEC)
-+ && REG_P (XEXP (ad, 0))
-+ && REGNO (XEXP (ad, 0)) < FIRST_PSEUDO_REGISTER
-+ && ! REGNO_OK_FOR_BASE_P (REGNO (XEXP (ad, 0))))
-+ {
-+ push_reload (XEXP (ad, 0), XEXP (ad, 0), &XEXP (ad, 0), &XEXP (ad, 0),
-+ BASE_REG_CLASS, GET_MODE (XEXP (ad, 0)), GET_MODE (XEXP (ad, 0)), 0, 0,
-+ opnum, RELOAD_OTHER);
-+ return ad;
-+ }
-+
-+ return NULL_RTX;
-+}
-+
-+/* Compute a (partial) cost for rtx X. Return true if the complete
-+ cost has been computed, and false if subexpressions should be
-+ scanned. In either case, *TOTAL contains the cost result. */
-+
-+static bool
-+ubicom32_rtx_costs (rtx x, int code, int outer_code, int *total,
-+ bool speed ATTRIBUTE_UNUSED)
-+{
-+ enum machine_mode mode = GET_MODE (x);
-+
-+ switch (code)
-+ {
-+ case CONST_INT:
-+ /* Very short constants often fold into instructions so
-+ we pretend that they don't cost anything! This is
-+ really important as regards zero values as otherwise
-+ the compiler has a nasty habit of wanting to reuse
-+ zeroes that are in regs but that tends to pessimize
-+ the code. */
-+ if (satisfies_constraint_I (x))
-+ {
-+ *total = 0;
-+ return true;
-+ }
-+
-+ /* Bit clearing costs nothing */
-+ if (outer_code == AND
-+ && exact_log2 (~INTVAL (x)) != -1)
-+ {
-+ *total = 0;
-+ return true;
-+ }
-+
-+ /* Masking the lower set of bits costs nothing. */
-+ if (outer_code == AND
-+ && exact_log2 (INTVAL (x) + 1) != -1)
-+ {
-+ *total = 0;
-+ return true;
-+ }
-+
-+ /* Bit setting costs nothing. */
-+ if (outer_code == IOR
-+ && exact_log2 (INTVAL (x)) != -1)
-+ {
-+ *total = 0;
-+ return true;
-+ }
-+
-+ /* Larger constants that can be loaded via movei aren't too
-+ bad. If we're just doing a set they cost nothing extra. */
-+ if (satisfies_constraint_N (x))
-+ {
-+ if (mode == DImode)
-+ *total = COSTS_N_INSNS (2);
-+ else
-+ *total = COSTS_N_INSNS (1);
-+ return true;
-+ }
-+
-+ if (mode == DImode)
-+ *total = COSTS_N_INSNS (5);
-+ else
-+ *total = COSTS_N_INSNS (3);
-+ return true;
-+
-+ case CONST_DOUBLE:
-+ /* We don't optimize CONST_DOUBLEs well nor do we relax them well,
-+ so their cost is very high. */
-+ *total = COSTS_N_INSNS (6);
-+ return true;
-+
-+ case CONST:
-+ case SYMBOL_REF:
-+ case MEM:
-+ *total = 0;
-+ return true;
-+
-+ case IF_THEN_ELSE:
-+ *total = COSTS_N_INSNS (1);
-+ return true;
-+
-+ case LABEL_REF:
-+ case HIGH:
-+ case LO_SUM:
-+ case BSWAP:
-+ case PLUS:
-+ case MINUS:
-+ case AND:
-+ case IOR:
-+ case XOR:
-+ case ASHIFT:
-+ case ASHIFTRT:
-+ case LSHIFTRT:
-+ case NEG:
-+ case NOT:
-+ case SIGN_EXTEND:
-+ case ZERO_EXTEND:
-+ case ZERO_EXTRACT:
-+ if (outer_code == SET)
-+ {
-+ if (mode == DImode)
-+ *total = COSTS_N_INSNS (2);
-+ else
-+ *total = COSTS_N_INSNS (1);
-+ }
-+ return true;
-+
-+ case COMPARE:
-+ if (outer_code == SET)
-+ {
-+ if (GET_MODE (XEXP (x, 0)) == DImode
-+ || GET_MODE (XEXP (x, 1)) == DImode)
-+ *total = COSTS_N_INSNS (2);
-+ else
-+ *total = COSTS_N_INSNS (1);
-+ }
-+ return true;
-+
-+ case UMOD:
-+ case UDIV:
-+ case MOD:
-+ case DIV:
-+ if (outer_code == SET)
-+ {
-+ if (mode == DImode)
-+ *total = COSTS_N_INSNS (600);
-+ else
-+ *total = COSTS_N_INSNS (200);
-+ }
-+ return true;
-+
-+ case MULT:
-+ if (outer_code == SET)
-+ {
-+ if (! ubicom32_v4)
-+ {
-+ if (mode == DImode)
-+ *total = COSTS_N_INSNS (15);
-+ else
-+ *total = COSTS_N_INSNS (5);
-+ }
-+ else
-+ {
-+ if (mode == DImode)
-+ *total = COSTS_N_INSNS (6);
-+ else
-+ *total = COSTS_N_INSNS (2);
-+ }
-+ }
-+ return true;
-+
-+ case UNSPEC:
-+ if (XINT (x, 1) == UNSPEC_FDPIC_GOT
-+ || XINT (x, 1) == UNSPEC_FDPIC_GOT_FUNCDESC)
-+ *total = 0;
-+ return true;
-+
-+ default:
-+ return false;
-+ }
-+}
-+
-+/* Return 1 if ADDR can have different meanings depending on the machine
-+ mode of the memory reference it is used for or if the address is
-+ valid for some modes but not others.
-+
-+ Autoincrement and autodecrement addresses typically have
-+ mode-dependent effects because the amount of the increment or
-+ decrement is the size of the operand being addressed. Some machines
-+ have other mode-dependent addresses. Many RISC machines have no
-+ mode-dependent addresses.
-+
-+ You may assume that ADDR is a valid address for the machine. */
-+
-+int
-+ubicom32_mode_dependent_address_p (rtx addr)
-+{
-+ if (GET_CODE (addr) == POST_INC
-+ || GET_CODE (addr) == PRE_INC
-+ || GET_CODE (addr) == POST_DEC
-+ || GET_CODE (addr) == PRE_DEC
-+ || GET_CODE (addr) == POST_MODIFY
-+ || GET_CODE (addr) == PRE_MODIFY)
-+ return 1;
-+
-+ return 0;
-+}
-+
-+static void
-+ubicom32_function_prologue (FILE *file, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
-+{
-+ fprintf (file, "/* frame/pretend: %ld/%d save_regs: %d out_args: %d %s */\n",
-+ get_frame_size (), crtl->args.pretend_args_size,
-+ save_regs_size, crtl->outgoing_args_size,
-+ current_function_is_leaf ? "leaf" : "nonleaf");
-+}
-+
-+static void
-+ubicom32_function_epilogue (FILE *file ATTRIBUTE_UNUSED,
-+ HOST_WIDE_INT size ATTRIBUTE_UNUSED)
-+{
-+ ubicom32_reorg_completed = 0;
-+}
-+
-+static void
-+ubicom32_machine_dependent_reorg (void)
-+{
-+#if 0 /* Commenting out this optimization until it is fixed */
-+ if (optimize)
-+ {
-+ compute_bb_for_insn ();
-+
-+ /* Do a very simple CSE pass over just the hard registers. */
-+ reload_cse_regs (get_insns ());
-+
-+ /* Reload_cse_regs can eliminate potentially-trapping MEMs.
-+ Remove any EH edges associated with them. */
-+ if (flag_non_call_exceptions)
-+ purge_all_dead_edges ();
-+ }
-+#endif
-+ ubicom32_reorg_completed = 1;
-+}
-+
-+void
-+ubicom32_output_cond_jump (rtx insn, rtx cond, rtx target)
-+{
-+ rtx note;
-+ int mostly_false_jump;
-+ rtx xoperands[2];
-+ rtx cc_reg;
-+
-+ note = find_reg_note (insn, REG_BR_PROB, 0);
-+ mostly_false_jump = !note || (INTVAL (XEXP (note, 0))
-+ <= REG_BR_PROB_BASE / 2);
-+
-+ xoperands[0] = target;
-+ xoperands[1] = cond;
-+ cc_reg = XEXP (cond, 0);
-+
-+ if (GET_MODE (cc_reg) == CCWmode
-+ || GET_MODE (cc_reg) == CCWZmode
-+ || GET_MODE (cc_reg) == CCWZNmode)
-+ {
-+ if (mostly_false_jump)
-+ output_asm_insn ("jmp%b1.w.f\t%0", xoperands);
-+ else
-+ output_asm_insn ("jmp%b1.w.t\t%0", xoperands);
-+ return;
-+ }
-+
-+ if (GET_MODE (cc_reg) == CCSmode
-+ || GET_MODE (cc_reg) == CCSZmode
-+ || GET_MODE (cc_reg) == CCSZNmode)
-+ {
-+ if (mostly_false_jump)
-+ output_asm_insn ("jmp%b1.s.f\t%0", xoperands);
-+ else
-+ output_asm_insn ("jmp%b1.s.t\t%0", xoperands);
-+ return;
-+ }
-+
-+ abort ();
-+}
-+
-+/* Return non-zero if FUNC is a naked function. */
-+
-+static int
-+ubicom32_naked_function_p (void)
-+{
-+ return lookup_attribute ("naked", DECL_ATTRIBUTES (current_function_decl)) != NULL_TREE;
-+}
-+
-+/* Return an RTX indicating where the return address to the
-+ calling function can be found. */
-+rtx
-+ubicom32_return_addr_rtx (int count, rtx frame ATTRIBUTE_UNUSED)
-+{
-+ if (count != 0)
-+ return NULL_RTX;
-+
-+ return get_hard_reg_initial_val (Pmode, LINK_REGNO);
-+}
-+
-+/*
-+ * ubicom32_readonly_data_section: This routtine handles code
-+ * at the start of readonly data sections
-+ */
-+static void
-+ubicom32_readonly_data_section (const void *data ATTRIBUTE_UNUSED)
-+{
-+ static int num = 0;
-+ if (in_section == readonly_data_section){
-+ fprintf (asm_out_file, "%s", DATA_SECTION_ASM_OP);
-+ if (flag_data_sections){
-+ fprintf (asm_out_file, ".rodata%d", num);
-+ fprintf (asm_out_file, ",\"a\"");
-+ }
-+ fprintf (asm_out_file, "\n");
-+ }
-+ num++;
-+}
-+
-+/*
-+ * ubicom32_text_section: not in readonly section
-+ */
-+static void
-+ubicom32_text_section(const void *data ATTRIBUTE_UNUSED)
-+{
-+ fprintf (asm_out_file, "%s\n", TEXT_SECTION_ASM_OP);
-+}
-+
-+/*
-+ * ubicom32_data_section: not in readonly section
-+ */
-+static void
-+ubicom32_data_section(const void *data ATTRIBUTE_UNUSED)
-+{
-+ fprintf (asm_out_file, "%s\n", DATA_SECTION_ASM_OP);
-+}
-+
-+/*
-+ * ubicom32_asm_init_sections: This routine implements special
-+ * section handling
-+ */
-+static void
-+ubicom32_asm_init_sections(void)
-+{
-+ text_section = get_unnamed_section(SECTION_CODE, ubicom32_text_section, NULL);
-+
-+ data_section = get_unnamed_section(SECTION_WRITE, ubicom32_data_section, NULL);
-+
-+ readonly_data_section = get_unnamed_section(0, ubicom32_readonly_data_section, NULL);
-+}
-+
-+/*
-+ * ubicom32_profiler: This routine would call
-+ * mcount to support prof and gprof if mcount
-+ * was supported. Currently, do nothing.
-+ */
-+void
-+ubicom32_profiler(void)
-+{
-+}
-+
-+/* Initialise the builtin functions. Start by initialising
-+ descriptions of different types of functions (e.g., void fn(int),
-+ int fn(void)), and then use these to define the builtins. */
-+static void
-+ubicom32_init_builtins (void)
-+{
-+ tree endlink;
-+ tree short_unsigned_endlink;
-+ tree unsigned_endlink;
-+ tree short_unsigned_ftype_short_unsigned;
-+ tree unsigned_ftype_unsigned;
-+
-+ endlink = void_list_node;
-+
-+ short_unsigned_endlink
-+ = tree_cons (NULL_TREE, short_unsigned_type_node, endlink);
-+
-+ unsigned_endlink
-+ = tree_cons (NULL_TREE, unsigned_type_node, endlink);
-+
-+ short_unsigned_ftype_short_unsigned
-+ = build_function_type (short_unsigned_type_node, short_unsigned_endlink);
-+
-+ unsigned_ftype_unsigned
-+ = build_function_type (unsigned_type_node, unsigned_endlink);
-+
-+ /* Initialise the byte swap function. */
-+ add_builtin_function ("__builtin_ubicom32_swapb_2",
-+ short_unsigned_ftype_short_unsigned,
-+ UBICOM32_BUILTIN_UBICOM32_SWAPB_2,
-+ BUILT_IN_MD, NULL,
-+ NULL_TREE);
-+
-+ /* Initialise the byte swap function. */
-+ add_builtin_function ("__builtin_ubicom32_swapb_4",
-+ unsigned_ftype_unsigned,
-+ UBICOM32_BUILTIN_UBICOM32_SWAPB_4,
-+ BUILT_IN_MD, NULL,
-+ NULL_TREE);
-+}
-+
-+/* Given a builtin function taking 2 operands (i.e., target + source),
-+ emit the RTL for the underlying instruction. */
-+static rtx
-+ubicom32_expand_builtin_2op (enum insn_code icode, tree arglist, rtx target)
-+{
-+ tree arg0;
-+ rtx op0, pat;
-+ enum machine_mode tmode, mode0;
-+
-+ /* Grab the incoming argument and emit its RTL. */
-+ arg0 = TREE_VALUE (arglist);
-+ op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
-+
-+ /* Determine the modes of the instruction operands. */
-+ tmode = insn_data[icode].operand[0].mode;
-+ mode0 = insn_data[icode].operand[1].mode;
-+
-+ /* Ensure that the incoming argument RTL is in a register of the
-+ correct mode. */
-+ if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
-+ op0 = copy_to_mode_reg (mode0, op0);
-+
-+ /* If there isn't a suitable target, emit a target register. */
-+ if (target == 0
-+ || GET_MODE (target) != tmode
-+ || !(*insn_data[icode].operand[0].predicate) (target, tmode))
-+ target = gen_reg_rtx (tmode);
-+
-+ /* Emit and return the new instruction. */
-+ pat = GEN_FCN (icode) (target, op0);
-+ if (!pat)
-+ return 0;
-+ emit_insn (pat);
-+
-+ return target;
-+}
-+
-+/* Expand a call to a builtin function. */
-+static rtx
-+ubicom32_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
-+ enum machine_mode mode ATTRIBUTE_UNUSED,
-+ int ignore ATTRIBUTE_UNUSED)
-+{
-+ tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
-+ tree arglist = CALL_EXPR_ARGS(exp);
-+ int fcode = DECL_FUNCTION_CODE (fndecl);
-+
-+ switch (fcode)
-+ {
-+ case UBICOM32_BUILTIN_UBICOM32_SWAPB_2:
-+ return ubicom32_expand_builtin_2op (CODE_FOR_bswaphi, arglist, target);
-+
-+ case UBICOM32_BUILTIN_UBICOM32_SWAPB_4:
-+ return ubicom32_expand_builtin_2op (CODE_FOR_bswapsi, arglist, target);
-+
-+ default:
-+ gcc_unreachable();
-+ }
-+
-+ /* Should really do something sensible here. */
-+ return NULL_RTX;
-+}
-+
-+/* Fold any constant argument for a swapb.2 instruction. */
-+static tree
-+ubicom32_fold_builtin_ubicom32_swapb_2 (tree fndecl, tree arglist)
-+{
-+ tree arg0;
-+
-+ arg0 = TREE_VALUE (arglist);
-+
-+ /* Optimize constant value. */
-+ if (TREE_CODE (arg0) == INTEGER_CST)
-+ {
-+ HOST_WIDE_INT v;
-+ HOST_WIDE_INT res;
-+
-+ v = TREE_INT_CST_LOW (arg0);
-+ res = ((v >> 8) & 0xff)
-+ | ((v & 0xff) << 8);
-+
-+ return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), res);
-+ }
-+
-+ return NULL_TREE;
-+}
-+
-+/* Fold any constant argument for a swapb.4 instruction. */
-+static tree
-+ubicom32_fold_builtin_ubicom32_swapb_4 (tree fndecl, tree arglist)
-+{
-+ tree arg0;
-+
-+ arg0 = TREE_VALUE (arglist);
-+
-+ /* Optimize constant value. */
-+ if (TREE_CODE (arg0) == INTEGER_CST)
-+ {
-+ unsigned HOST_WIDE_INT v;
-+ unsigned HOST_WIDE_INT res;
-+
-+ v = TREE_INT_CST_LOW (arg0);
-+ res = ((v >> 24) & 0xff)
-+ | (((v >> 16) & 0xff) << 8)
-+ | (((v >> 8) & 0xff) << 16)
-+ | ((v & 0xff) << 24);
-+
-+ return build_int_cst_wide (TREE_TYPE (TREE_TYPE (fndecl)), res, 0);
-+ }
-+
-+ return NULL_TREE;
-+}
-+
-+/* Fold any constant arguments for builtin functions. */
-+static tree
-+ubicom32_fold_builtin (tree fndecl, tree arglist, bool ignore ATTRIBUTE_UNUSED)
-+{
-+ switch (DECL_FUNCTION_CODE (fndecl))
-+ {
-+ case UBICOM32_BUILTIN_UBICOM32_SWAPB_2:
-+ return ubicom32_fold_builtin_ubicom32_swapb_2 (fndecl, arglist);
-+
-+ case UBICOM32_BUILTIN_UBICOM32_SWAPB_4:
-+ return ubicom32_fold_builtin_ubicom32_swapb_4 (fndecl, arglist);
-+
-+ default:
-+ return NULL;
-+ }
-+}
-+
-+/* Implementation of TARGET_ASM_INTEGER. When using FD-PIC, we need to
-+ tell the assembler to generate pointers to function descriptors in
-+ some cases. */
-+static bool
-+ubicom32_assemble_integer (rtx value, unsigned int size, int aligned_p)
-+{
-+ if (TARGET_FDPIC && size == UNITS_PER_WORD)
-+ {
-+ if (GET_CODE (value) == SYMBOL_REF
-+ && SYMBOL_REF_FUNCTION_P (value))
-+ {
-+ fputs ("\t.picptr\t%funcdesc(", asm_out_file);
-+ output_addr_const (asm_out_file, value);
-+ fputs (")\n", asm_out_file);
-+ return true;
-+ }
-+
-+ if (!aligned_p)
-+ {
-+ /* We've set the unaligned SI op to NULL, so we always have to
-+ handle the unaligned case here. */
-+ assemble_integer_with_op ("\t.4byte\t", value);
-+ return true;
-+ }
-+ }
-+
-+ return default_assemble_integer (value, size, aligned_p);
-+}
-+
-+/* If the constant I can be constructed by shifting a source-1 immediate
-+ by a constant number of bits then return the bit count. If not
-+ return 0. */
-+
-+int
-+ubicom32_shiftable_const_int (int i)
-+{
-+ int shift = 0;
-+
-+ /* Note that any constant that can be represented as an immediate to
-+ a movei instruction is automatically ignored here in the interests
-+ of the clarity of the output asm code. */
-+ if (i >= -32768 && i <= 32767)
-+ return 0;
-+
-+ /* Find the number of trailing zeroes. We could use __builtin_ctz
-+ here but it's not obvious if this is supported on all build
-+ compilers so we err on the side of caution. */
-+ if ((i & 0xffff) == 0)
-+ {
-+ shift += 16;
-+ i >>= 16;
-+ }
-+
-+ if ((i & 0xff) == 0)
-+ {
-+ shift += 8;
-+ i >>= 8;
-+ }
-+
-+ if ((i & 0xf) == 0)
-+ {
-+ shift += 4;
-+ i >>= 4;
-+ }
-+
-+ if ((i & 0x3) == 0)
-+ {
-+ shift += 2;
-+ i >>= 2;
-+ }
-+
-+ if ((i & 0x1) == 0)
-+ {
-+ shift += 1;
-+ i >>= 1;
-+ }
-+
-+ if (i >= -128 && i <= 127)
-+ return shift;
-+
-+ return 0;
-+}
-+
---- /dev/null
-+++ b/gcc/config/ubicom32/ubicom32.h
-@@ -0,0 +1,1564 @@
-+/* Definitions of target machine for Ubicom32
-+
-+ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
-+ 2009 Free Software Foundation, Inc.
-+ Contributed by Ubicom, Inc.
-+
-+ This file is part of GCC.
-+
-+ GCC is free software; you can redistribute it and/or modify it
-+ under the terms of the GNU General Public License as published
-+ by the Free Software Foundation; either version 3, or (at your
-+ option) any later version.
-+
-+ GCC is distributed in the hope that it will be useful, but WITHOUT
-+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
-+ License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with GCC; see the file COPYING3. If not see
-+ <http://www.gnu.org/licenses/>. */
-+
-+\f
-+
-+#define OBJECT_FORMAT_ELF
-+
-+/* Run-time target specifications. */
-+
-+/* Target CPU builtins. */
-+#define TARGET_CPU_CPP_BUILTINS() \
-+ do \
-+ { \
-+ builtin_define_std ("__UBICOM32__"); \
-+ builtin_define_std ("__ubicom32__"); \
-+ \
-+ if (TARGET_FDPIC) \
-+ { \
-+ builtin_define ("__UBICOM32_FDPIC__"); \
-+ builtin_define ("__FDPIC__"); \
-+ } \
-+ } \
-+ while (0)
-+
-+#ifndef TARGET_DEFAULT
-+#define TARGET_DEFAULT 0
-+#endif
-+
-+extern int ubicom32_case_values_threshold;
-+
-+/* Nonzero if this chip supports the Ubicom32 v3 ISA. */
-+extern int ubicom32_v3;
-+
-+/* Nonzero if this chip supports the Ubicom32 v4 ISA. */
-+extern int ubicom32_v4;
-+
-+extern int ubicom32_stack_size;
-+
-+/* Flag for whether we can use calli instead of ret in returns. */
-+extern int ubicom32_can_use_calli_to_ret;
-+
-+/* This macro is a C statement to print on `stderr' a string describing the
-+ particular machine description choice. Every machine description should
-+ define `TARGET_VERSION'. */
-+#define TARGET_VERSION fprintf (stderr, " (UBICOM32)");
-+
-+/* We don't need a frame pointer to debug things. Doing this means
-+ that gcc can turn on -fomit-frame-pointer when '-O' is specified. */
-+#define CAN_DEBUG_WITHOUT_FP
-+
-+/* We need to handle processor-specific options. */
-+#define OVERRIDE_OPTIONS ubicom32_override_options ()
-+
-+#define OPTIMIZATION_OPTIONS(LEVEL, SIZE) \
-+ ubicom32_optimization_options (LEVEL, SIZE)
-+
-+/* For Ubicom32 the least significant bit has the lowest bit number
-+ so we define this to be 0. */
-+#define BITS_BIG_ENDIAN 0
-+
-+/* For Ubicom32 the most significant byte in a word has the lowest
-+ number. */
-+#define BYTES_BIG_ENDIAN 1
-+
-+/* For Ubicom32, in a multiword object, the most signifant word has the
-+ lowest number. */
-+#define WORDS_BIG_ENDIAN 1
-+
-+/* Ubicom32 has 8 bits per byte. */
-+#define BITS_PER_UNIT 8
-+
-+/* Ubicom32 has 32 bits per word. */
-+#define BITS_PER_WORD 32
-+
-+/* Width of a word, in units (bytes). */
-+#define UNITS_PER_WORD 4
-+
-+/* Width of a pointer, in bits. */
-+#define POINTER_SIZE 32
-+
-+/* Alias for pointers. Ubicom32 is a 32-bit architecture so we use
-+ SImode. */
-+#define Pmode SImode
-+
-+/* Normal alignment required for function parameters on the stack, in
-+ bits. */
-+#define PARM_BOUNDARY 32
-+
-+/* We need to maintain the stack on a 32-bit boundary. */
-+#define STACK_BOUNDARY 32
-+
-+/* Alignment required for a function entry point, in bits. */
-+#define FUNCTION_BOUNDARY 32
-+
-+/* Alias for the machine mode used for memory references to functions being
-+ called, in `call' RTL expressions. We use byte-oriented addresses
-+ here. */
-+#define FUNCTION_MODE QImode
-+
-+/* Biggest alignment that any data type can require on this machine,
-+ in bits. */
-+#define BIGGEST_ALIGNMENT 32
-+
-+/* this default to BIGGEST_ALIGNMENT unless defined */
-+/* ART: What's the correct value here? Default is (((unsigned int)1<<28)*8)*/
-+#undef MAX_OFILE_ALIGNMENT
-+#define MAX_OFILE_ALIGNMENT (128 * 8)
-+
-+/* Alignment in bits to be given to a structure bit field that follows an empty
-+ field such as `int : 0;'. */
-+#define EMPTY_FIELD_BOUNDARY 32
-+
-+/* All structures must be a multiple of 32 bits in size. */
-+#define STRUCTURE_SIZE_BOUNDARY 32
-+
-+/* A bit-field declared as `int' forces `int' alignment for the struct. */
-+#define PCC_BITFIELD_TYPE_MATTERS 1
-+
-+/* For Ubicom32 we absolutely require that data be aligned with nominal
-+ alignment. */
-+#define STRICT_ALIGNMENT 1
-+
-+/* Make strcpy of constants fast. */
-+#define CONSTANT_ALIGNMENT(EXP, ALIGN) \
-+ (TREE_CODE (EXP) == STRING_CST \
-+ && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
-+
-+/* Define this macro as an expression for the alignment of a structure
-+ (given by STRUCT as a tree node) if the alignment computed in the
-+ usual way is COMPUTED and the alignment explicitly specified was
-+ SPECIFIED. */
-+#define DATA_ALIGNMENT(TYPE, ALIGN) \
-+ ((((ALIGN) < BITS_PER_WORD) \
-+ && (TREE_CODE (TYPE) == ARRAY_TYPE \
-+ || TREE_CODE (TYPE) == UNION_TYPE \
-+ || TREE_CODE (TYPE) == RECORD_TYPE)) ? BITS_PER_WORD : (ALIGN))
-+
-+#define LOCAL_ALIGNMENT(TYPE,ALIGN) DATA_ALIGNMENT(TYPE,ALIGN)
-+
-+/* For Ubicom32 we default to unsigned chars. */
-+#define DEFAULT_SIGNED_CHAR 0
-+
-+/* Machine-specific data register numbers. */
-+#define FIRST_DATA_REGNUM 0
-+#define D10_REGNUM 10
-+#define D11_REGNUM 11
-+#define D12_REGNUM 12
-+#define D13_REGNUM 13
-+#define LAST_DATA_REGNUM 15
-+
-+/* Machine-specific address register numbers. */
-+#define FIRST_ADDRESS_REGNUM 16
-+#define LAST_ADDRESS_REGNUM 22
-+
-+/* Register numbers used for passing a function's static chain pointer. If
-+ register windows are used, the register number as seen by the called
-+ function is `STATIC_CHAIN_INCOMING_REGNUM', while the register number as
-+ seen by the calling function is `STATIC_CHAIN_REGNUM'. If these registers
-+ are the same, `STATIC_CHAIN_INCOMING_REGNUM' need not be defined.
-+
-+ The static chain register need not be a fixed register.
-+
-+ If the static chain is passed in memory, these macros should not be defined;
-+ instead, the next two macros should be defined. */
-+#define STATIC_CHAIN_REGNUM (FIRST_ADDRESS_REGNUM + 1)
-+
-+/* The register number of the frame pointer register, which is used to access
-+ automatic variables in the stack frame. We generally eliminate this anyway
-+ for Ubicom32 but we make it A6 by default. */
-+#define FRAME_POINTER_REGNUM (LAST_ADDRESS_REGNUM)
-+
-+/* The register number of the stack pointer register, which is also be a
-+ fixed register according to `FIXED_REGISTERS'. For Ubicom32 we don't
-+ have a hardware requirement about which register this is, but by convention
-+ we use A7. */
-+#define STACK_POINTER_REGNUM (LAST_ADDRESS_REGNUM + 1)
-+
-+/* Machine-specific accumulator register numbers. */
-+#define ACC0_HI_REGNUM 24
-+#define ACC0_LO_REGNUM 25
-+#define ACC1_HI_REGNUM 26
-+#define ACC1_LO_REGNUM 27
-+
-+/* source3 register number */
-+#define SOURCE3_REGNUM 28
-+
-+/* The register number of the arg pointer register, which is used to access the
-+ function's argument list. On some machines, this is the same as the frame
-+ pointer register. On some machines, the hardware determines which register
-+ this is. On other machines, you can choose any register you wish for this
-+ purpose. If this is not the same register as the frame pointer register,
-+ then you must mark it as a fixed register according to `FIXED_REGISTERS', or
-+ arrange to be able to eliminate it. */
-+#define ARG_POINTER_REGNUM 29
-+
-+/* Pseudo-reg for condition code. */
-+#define CC_REGNUM 30
-+
-+/* Interrupt set/clear registers. */
-+#define INT_SET0_REGNUM 31
-+#define INT_SET1_REGNUM 32
-+#define INT_CLR0_REGNUM 33
-+#define INT_CLR1_REGNUM 34
-+
-+/* Scratchpad registers. */
-+#define SCRATCHPAD0_REGNUM 35
-+#define SCRATCHPAD1_REGNUM 36
-+#define SCRATCHPAD2_REGNUM 37
-+#define SCRATCHPAD3_REGNUM 38
-+
-+/* FDPIC register. */
-+#define FDPIC_REGNUM 16
-+
-+/* Number of hardware registers known to the compiler. They receive numbers 0
-+ through `FIRST_PSEUDO_REGISTER-1'; thus, the first pseudo register's number
-+ really is assigned the number `FIRST_PSEUDO_REGISTER'. */
-+#define FIRST_PSEUDO_REGISTER 39
-+
-+/* An initializer that says which registers are used for fixed purposes all
-+ throughout the compiled code and are therefore not available for general
-+ allocation. These would include the stack pointer, the frame pointer
-+ (except on machines where that can be used as a general register when no
-+ frame pointer is needed), the program counter on machines where that is
-+ considered one of the addressable registers, and any other numbered register
-+ with a standard use.
-+
-+ This information is expressed as a sequence of numbers, separated by commas
-+ and surrounded by braces. The Nth number is 1 if register N is fixed, 0
-+ otherwise.
-+
-+ The table initialized from this macro, and the table initialized by the
-+ following one, may be overridden at run time either automatically, by the
-+ actions of the macro `CONDITIONAL_REGISTER_USAGE', or by the user with the
-+ command options `-ffixed-REG', `-fcall-used-REG' and `-fcall-saved-REG'. */
-+#define FIXED_REGISTERS \
-+ { \
-+ 0, 0, 0, 0, 0, 0, 0, 0, /* d0 - d7 */ \
-+ 0, 0, 0, 0, 0, 0, 0, 1, /* d8 - d15 */ \
-+ 0, 0, 0, 0, 0, 0, 0, 1, /* a0 - a7 */ \
-+ 0, 0, /* acc0 hi/lo */ \
-+ 0, 0, /* acc1 hi/lo */ \
-+ 0, /* source3 */ \
-+ 1, /* arg */ \
-+ 1, /* cc */ \
-+ 1, 1, /* int_set[01] */ \
-+ 1, 1, /* int_clr[01] */ \
-+ 1, 1, 1, 1 /* scratchpad[0123] */ \
-+ }
-+
-+/* Like `FIXED_REGISTERS' but has 1 for each register that is clobbered (in
-+ general) by function calls as well as for fixed registers. This macro
-+ therefore identifies the registers that are not available for general
-+ allocation of values that must live across function calls.
-+
-+ If a register has 0 in `CALL_USED_REGISTERS', the compiler automatically
-+ saves it on function entry and restores it on function exit, if the register
-+ is used within the function. */
-+#define CALL_USED_REGISTERS \
-+ { \
-+ 1, 1, 1, 1, 1, 1, 1, 1, /* d0 - d7 */ \
-+ 1, 1, 0, 0, 0, 0, 1, 1, /* d8 - d15 */ \
-+ 1, 0, 0, 1, 1, 1, 0, 1, /* a0 - a7 */ \
-+ 1, 1, /* acc0 hi/lo */ \
-+ 1, 1, /* acc1 hi/lo */ \
-+ 1, /* source3 */ \
-+ 1, /* arg */ \
-+ 1, /* cc */ \
-+ 1, 1, /* int_set[01] */ \
-+ 1, 1, /* int_clr[01] */ \
-+ 1, 1, 1, 1 /* scratchpad[0123] */ \
-+ }
-+
-+/* How to refer to registers in assembler output.
-+ This sequence is indexed by compiler's hard-register-number (see above). */
-+
-+/* A C initializer containing the assembler's names for the machine registers,
-+ each one as a C string constant. This is what translates register numbers
-+ in the compiler into assembler language. */
-+#define REGISTER_NAMES \
-+ { \
-+ "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", \
-+ "d8", "d9", "d10", "d11", "d12", "d13", "d14", "d15", \
-+ "a0", "a1", "a2", "a3", "a4", "a5", "a6", "sp", \
-+ "acc0_hi", "acc0_lo", \
-+ "acc1_hi", "acc1_lo", \
-+ "source3", \
-+ "arg", \
-+ "cc", \
-+ "int_set0", "int_set1", \
-+ "int_clr0", "int_clr1", \
-+ "scratchpad0", "scratchpad1", "scratchpad2", "scratchpad3" \
-+ }
-+
-+#define CONDITIONAL_REGISTER_USAGE \
-+ ubicom32_conditional_register_usage ();
-+
-+/* Order of allocation of registers. */
-+
-+/* If defined, an initializer for a vector of integers, containing the numbers
-+ of hard registers in the order in which GNU CC should prefer to use them
-+ (from most preferred to least).
-+
-+ For Ubicom32 we try using caller-clobbered data registers first, then
-+ callee-saved data registers, then caller-clobbered address registers,
-+ then callee-saved address registers and finally everything else.
-+
-+ The caller-clobbered registers are usually slightly cheaper to use because
-+ there's no need to save/restore. */
-+#define REG_ALLOC_ORDER \
-+ { \
-+ 0, 1, 2, 3, 4, /* d0 - d4 */ \
-+ 5, 6, 7, 8, 9, /* d5 - d9 */ \
-+ 14, /* d14 */ \
-+ 10, 11, 12, 13, /* d10 - d13 */ \
-+ 19, 20, 16, 21, /* a3, a4, a0, a5 */ \
-+ 17, 18, 22, /* a1, a2, a6 */ \
-+ 24, 25, /* acc0 hi/lo */ \
-+ 26, 27, /* acc0 hi/lo */ \
-+ 28 /* source3 */ \
-+ }
-+
-+/* C expression for the number of consecutive hard registers, starting at
-+ register number REGNO, required to hold a value of mode MODE. */
-+#define HARD_REGNO_NREGS(REGNO, MODE) \
-+ ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
-+
-+/* Most registers can hold QImode, HImode and SImode values but we have to
-+ be able to indicate any hard registers that cannot hold values with some
-+ modes. */
-+#define HARD_REGNO_MODE_OK(REGNO, MODE) \
-+ ubicom32_hard_regno_mode_ok(REGNO, MODE)
-+
-+/* We can rename most registers aside from the FDPIC register if we're using
-+ FDPIC. */
-+#define HARD_REGNO_RENAME_OK(from, to) (TARGET_FDPIC ? ((to) != FDPIC_REGNUM) : 1)
-+
-+/* A C expression that is nonzero if it is desirable to choose register
-+ allocation so as to avoid move instructions between a value of mode MODE1
-+ and a value of mode MODE2.
-+
-+ If `HARD_REGNO_MODE_OK (R, MODE1)' and `HARD_REGNO_MODE_OK (R, MODE2)' are
-+ ever different for any R, then `MODES_TIEABLE_P (MODE1, MODE2)' must be
-+ zero. */
-+#define MODES_TIEABLE_P(MODE1, MODE2) 1
-+
-+/* An enumeral type that must be defined with all the register class names as
-+ enumeral values. `NO_REGS' must be first. `ALL_REGS' must be the last
-+ register class, followed by one more enumeral value, `LIM_REG_CLASSES',
-+ which is not a register class but rather tells how many classes there are.
-+
-+ Each register class has a number, which is the value of casting the class
-+ name to type `int'. The number serves as an index in many of the tables
-+ described below. */
-+
-+enum reg_class
-+{
-+ NO_REGS,
-+ DATA_REGS,
-+ FDPIC_REG,
-+ ADDRESS_REGS,
-+ ALL_ADDRESS_REGS,
-+ ACC_LO_REGS,
-+ ACC_REGS,
-+ CC_REG,
-+ DATA_ACC_REGS,
-+ SOURCE3_REG,
-+ SPECIAL_REGS,
-+ GENERAL_REGS,
-+ ALL_REGS,
-+ LIM_REG_CLASSES
-+};
-+
-+/* The number of distinct register classes. */
-+#define N_REG_CLASSES (int) LIM_REG_CLASSES
-+
-+/* An initializer containing the names of the register classes as C string
-+ constants. These names are used in writing some of the debugging dumps. */
-+
-+#define REG_CLASS_NAMES \
-+{ \
-+ "NO_REGS", \
-+ "DATA_REGS", \
-+ "FDPIC_REG", \
-+ "ADDRESS_REGS", \
-+ "ALL_ADDRESS_REGS", \
-+ "ACC_LO_REGS", \
-+ "ACC_REGS", \
-+ "CC_REG", \
-+ "DATA_ACC_REGS", \
-+ "SOURCE3_REG", \
-+ "SPECIAL_REGS", \
-+ "GENERAL_REGS", \
-+ "ALL_REGS", \
-+ "LIM_REGS" \
-+}
-+
-+/* An initializer containing the contents of the register classes, as integers
-+ which are bit masks. The Nth integer specifies the contents of class N.
-+ The way the integer MASK is interpreted is that register R is in the class
-+ if `MASK & (1 << R)' is 1.
-+
-+ When the machine has more than 32 registers, an integer does not suffice.
-+ Then the integers are replaced by sub-initializers, braced groupings
-+ containing several integers. Each sub-initializer must be suitable as an
-+ initializer for the type `HARD_REG_SET' which is defined in
-+ `hard-reg-set.h'. */
-+#define REG_CLASS_CONTENTS \
-+{ \
-+ {0x00000000, 0x00000000}, /* No regs */ \
-+ {0x0000ffff, 0x00000000}, /* DATA_REGS */ \
-+ {0x00010000, 0x00000000}, /* FDPIC_REG */ \
-+ {0x20fe0000, 0x00000000}, /* ADDRESS_REGS */ \
-+ {0x20ff0000, 0x00000000}, /* ALL_ADDRESS_REGS */ \
-+ {0x0a000000, 0x00000000}, /* ACC_LO_REGS */ \
-+ {0x0f000000, 0x00000000}, /* ACC_REGS */ \
-+ {0x40000000, 0x00000000}, /* CC_REG */ \
-+ {0x0f00ffff, 0x00000000}, /* DATA_ACC_REGS */ \
-+ {0x10000000, 0x00000000}, /* SOURGE3_REG */ \
-+ {0x80000000, 0x0000007f}, /* SPECIAL_REGS */ \
-+ {0xbfffffff, 0x0000007f}, /* GENERAL_REGS */ \
-+ {0xbfffffff, 0x0000007f} /* ALL_REGS */ \
-+}
-+
-+extern enum reg_class const ubicom32_regclass_map[FIRST_PSEUDO_REGISTER];
-+
-+/* A C expression whose value is a register class containing hard register
-+ REGNO. In general there is more than one such class; choose a class which
-+ is "minimal", meaning that no smaller class also contains the register. */
-+#define REGNO_REG_CLASS(REGNO) (ubicom32_regclass_map[REGNO])
-+
-+#define IRA_COVER_CLASSES \
-+{ \
-+ GENERAL_REGS, \
-+ LIM_REG_CLASSES \
-+}
-+
-+/* Ubicom32 base registers must be address registers since addresses can
-+ only be reached via address registers. */
-+#define BASE_REG_CLASS ALL_ADDRESS_REGS
-+
-+/* Ubicom32 index registers must be data registers since we cannot add
-+ two address registers together to form an address. */
-+#define INDEX_REG_CLASS DATA_REGS
-+
-+/* A C expression which is nonzero if register number NUM is suitable for use
-+ as a base register in operand addresses. It may be either a suitable hard
-+ register or a pseudo register that has been allocated such a hard register. */
-+
-+#ifndef REG_OK_STRICT
-+#define REGNO_OK_FOR_BASE_P(regno) \
-+ ubicom32_regno_ok_for_base_p (regno, 0)
-+#else
-+#define REGNO_OK_FOR_BASE_P(regno) \
-+ ubicom32_regno_ok_for_base_p (regno, 1)
-+#endif
-+
-+/* A C expression which is nonzero if register number NUM is suitable for use
-+ as an index register in operand addresses. It may be either a suitable hard
-+ register or a pseudo register that has been allocated such a hard register.
-+
-+ The difference between an index register and a base register is that the
-+ index register may be scaled. If an address involves the sum of two
-+ registers, neither one of them scaled, then either one may be labeled the
-+ "base" and the other the "index"; but whichever labeling is used must fit
-+ the machine's constraints of which registers may serve in each capacity.
-+ The compiler will try both labelings, looking for one that is valid, and
-+ will reload one or both registers only if neither labeling works. */
-+#ifndef REG_OK_STRICT
-+#define REGNO_OK_FOR_INDEX_P(regno) \
-+ ubicom32_regno_ok_for_index_p (regno, 0)
-+#else
-+#define REGNO_OK_FOR_INDEX_P(regno) \
-+ ubicom32_regno_ok_for_index_p (regno, 1)
-+#endif
-+
-+/* Attempt to restrict the register class we need to copy value X intoto the
-+ would-be register class CLASS. Most things are fine for Ubicom32 but we
-+ have to restrict certain types of address loads. */
-+#define PREFERRED_RELOAD_CLASS(X, CLASS) \
-+ ubicom32_preferred_reload_class (X, CLASS)
-+
-+/* A C expression for the maximum number of consecutive registers of
-+ class CLASS needed to hold a value of mode MODE. For Ubicom32 this
-+ is pretty much identical to HARD_REGNO_NREGS. */
-+#define CLASS_MAX_NREGS(CLASS, MODE) \
-+ ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
-+
-+/* For Ubicom32 the stack grows downwards when we push a word onto the stack
-+ - i.e. it moves to a smaller address. */
-+#define STACK_GROWS_DOWNWARD 1
-+
-+/* Offset from the frame pointer to the first local variable slot to
-+ be allocated. */
-+#define STARTING_FRAME_OFFSET 0
-+
-+/* Offset from the argument pointer register to the first argument's
-+ address. */
-+#define FIRST_PARM_OFFSET(FNDECL) 0
-+
-+/* A C expression whose value is RTL representing the value of the return
-+ address for the frame COUNT steps up from the current frame, after the
-+ prologue. FRAMEADDR is the frame pointer of the COUNT frame, or the frame
-+ pointer of the COUNT - 1 frame if `RETURN_ADDR_IN_PREVIOUS_FRAME' is
-+ defined.
-+
-+ The value of the expression must always be the correct address when COUNT is
-+ zero, but may be `NULL_RTX' if there is not way to determine the return
-+ address of other frames. */
-+#define RETURN_ADDR_RTX(COUNT, FRAME) \
-+ ubicom32_return_addr_rtx (COUNT, FRAME)
-+
-+/* Register That Address the Stack Frame. */
-+
-+/* We don't actually require a frame pointer in most functions with the
-+ Ubicom32 architecture so we allow it to be eliminated. */
-+#define FRAME_POINTER_REQUIRED 0
-+
-+/* Macro that defines a table of register pairs used to eliminate unecessary
-+ registers that point into the stack frame.
-+
-+ For Ubicom32 we don't generally need an arg pointer of a frame pointer
-+ so we allow the arg pointer to be replaced by either the frame pointer or
-+ the stack pointer. We also allow the frame pointer to be replaced by
-+ the stack pointer. */
-+#define ELIMINABLE_REGS \
-+{ \
-+ {ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
-+ {ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM}, \
-+ {FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM} \
-+}
-+
-+/* Let the compiler know that we want to use the ELIMINABLE_REGS macro
-+ above. */
-+#define CAN_ELIMINATE(FROM, TO) 1
-+
-+/* This macro is similar to `INITIAL_FRAME_POINTER_OFFSET'. It specifies the
-+ initial difference between the specified pair of registers. This macro must
-+ be defined if `ELIMINABLE_REGS' is defined. */
-+#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
-+ (OFFSET) = ubicom32_initial_elimination_offset (FROM, TO)
-+
-+/* If defined, the maximum amount of space required for outgoing arguments will
-+ be computed and placed into the variable
-+ `current_function_outgoing_args_size'. No space will be pushed onto the
-+ stack for each call; instead, the function prologue should increase the
-+ stack frame size by this amount.
-+
-+ Defining both `PUSH_ROUNDING' and `ACCUMULATE_OUTGOING_ARGS' is not
-+ proper. */
-+#define ACCUMULATE_OUTGOING_ARGS 1
-+
-+/* Define this macro if functions should assume that stack space has been
-+ allocated for arguments even when their values are passed in registers.
-+
-+ The value of this macro is the size, in bytes, of the area reserved for
-+ arguments passed in registers for the function represented by FNDECL.
-+
-+ This space can be allocated by the caller, or be a part of the
-+ machine-dependent stack frame: `OUTGOING_REG_PARM_STACK_SPACE' says
-+ which. */
-+#define REG_PARM_STACK_SPACE(FNDECL) ubicom32_reg_parm_stack_space(FNDECL)
-+
-+/* A C expression that should indicate the number of bytes of its own arguments
-+ that a function pops on returning, or 0 if the function pops no arguments
-+ and the caller must therefore pop them all after the function returns.
-+
-+ FUNDECL is a C variable whose value is a tree node that describes the
-+ function in question. Normally it is a node of type `FUNCTION_DECL' that
-+ describes the declaration of the function. From this it is possible to
-+ obtain the DECL_MACHINE_ATTRIBUTES of the function.
-+
-+ FUNTYPE is a C variable whose value is a tree node that describes the
-+ function in question. Normally it is a node of type `FUNCTION_TYPE' that
-+ describes the data type of the function. From this it is possible to obtain
-+ the data types of the value and arguments (if known).
-+
-+ When a call to a library function is being considered, FUNTYPE will contain
-+ an identifier node for the library function. Thus, if you need to
-+ distinguish among various library functions, you can do so by their names.
-+ Note that "library function" in this context means a function used to
-+ perform arithmetic, whose name is known specially in the compiler and was
-+ not mentioned in the C code being compiled.
-+
-+ STACK-SIZE is the number of bytes of arguments passed on the stack. If a
-+ variable number of bytes is passed, it is zero, and argument popping will
-+ always be the responsibility of the calling function.
-+
-+ On the Vax, all functions always pop their arguments, so the definition of
-+ this macro is STACK-SIZE. On the 68000, using the standard calling
-+ convention, no functions pop their arguments, so the value of the macro is
-+ always 0 in this case. But an alternative calling convention is available
-+ in which functions that take a fixed number of arguments pop them but other
-+ functions (such as `printf') pop nothing (the caller pops all). When this
-+ convention is in use, FUNTYPE is examined to determine whether a function
-+ takes a fixed number of arguments. */
-+#define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, STACK_SIZE) 0
-+
-+/* A C expression that controls whether a function argument is passed in a
-+ register, and which register.
-+
-+ The arguments are CUM, of type CUMULATIVE_ARGS, which summarizes (in a way
-+ defined by INIT_CUMULATIVE_ARGS and FUNCTION_ARG_ADVANCE) all of the previous
-+ arguments so far passed in registers; MODE, the machine mode of the argument;
-+ TYPE, the data type of the argument as a tree node or 0 if that is not known
-+ (which happens for C support library functions); and NAMED, which is 1 for an
-+ ordinary argument and 0 for nameless arguments that correspond to `...' in the
-+ called function's prototype.
-+
-+ The value of the expression should either be a `reg' RTX for the hard
-+ register in which to pass the argument, or zero to pass the argument on the
-+ stack.
-+
-+ For machines like the Vax and 68000, where normally all arguments are
-+ pushed, zero suffices as a definition.
-+
-+ The usual way to make the ANSI library `stdarg.h' work on a machine where
-+ some arguments are usually passed in registers, is to cause nameless
-+ arguments to be passed on the stack instead. This is done by making
-+ `FUNCTION_ARG' return 0 whenever NAMED is 0.
-+
-+ You may use the macro `MUST_PASS_IN_STACK (MODE, TYPE)' in the definition of
-+ this macro to determine if this argument is of a type that must be passed in
-+ the stack. If `REG_PARM_STACK_SPACE' is not defined and `FUNCTION_ARG'
-+ returns non-zero for such an argument, the compiler will abort. If
-+ `REG_PARM_STACK_SPACE' is defined, the argument will be computed in the
-+ stack and then loaded into a register. */
-+#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
-+ function_arg (&CUM, MODE, TYPE, NAMED)
-+
-+#define FUNCTION_INCOMING_ARG(CUM, MODE, TYPE, NAMED) \
-+ function_incoming_arg (&CUM, MODE, TYPE, NAMED)
-+
-+/* A C expression for the number of words, at the beginning of an argument,
-+ must be put in registers. The value must be zero for arguments that are
-+ passed entirely in registers or that are entirely pushed on the stack.
-+
-+ On some machines, certain arguments must be passed partially in registers
-+ and partially in memory. On these machines, typically the first N words of
-+ arguments are passed in registers, and the rest on the stack. If a
-+ multi-word argument (a `double' or a structure) crosses that boundary, its
-+ first few words must be passed in registers and the rest must be pushed.
-+ This macro tells the compiler when this occurs, and how many of the words
-+ should go in registers.
-+
-+ `FUNCTION_ARG' for these arguments should return the first register to be
-+ used by the caller for this argument; likewise `FUNCTION_INCOMING_ARG', for
-+ the called function. */
-+
-+/* A C expression that indicates when an argument must be passed by reference.
-+ If nonzero for an argument, a copy of that argument is made in memory and a
-+ pointer to the argument is passed instead of the argument itself. The
-+ pointer is passed in whatever way is appropriate for passing a pointer to
-+ that type.
-+
-+ On machines where `REG_PARM_STACK_SPACE' is not defined, a suitable
-+ definition of this macro might be
-+ #define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \
-+ MUST_PASS_IN_STACK (MODE, TYPE) */
-+
-+/* If defined, a C expression that indicates when it is the called function's
-+ responsibility to make a copy of arguments passed by invisible reference.
-+ Normally, the caller makes a copy and passes the address of the copy to the
-+ routine being called. When FUNCTION_ARG_CALLEE_COPIES is defined and is
-+ nonzero, the caller does not make a copy. Instead, it passes a pointer to
-+ the "live" value. The called function must not modify this value. If it
-+ can be determined that the value won't be modified, it need not make a copy;
-+ otherwise a copy must be made. */
-+
-+/* 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
-+ `int' suffices and can hold the number of bytes of argument so far.
-+
-+ There is no need to record in `CUMULATIVE_ARGS' anything about the arguments
-+ that have been passed on the stack. The compiler has other variables to
-+ keep track of that. For target machines on which all arguments are passed
-+ on the stack, there is no need to store anything in `CUMULATIVE_ARGS';
-+ however, the data structure must exist and should not be empty, so use
-+ `int'. */
-+struct cum_arg
-+{
-+ int nbytes;
-+ int reg;
-+ int stdarg;
-+};
-+#define CUMULATIVE_ARGS struct cum_arg
-+
-+/* A C statement (sans semicolon) for initializing the variable CUM for the
-+ state at the beginning of the argument list. The variable has type
-+ `CUMULATIVE_ARGS'. The value of FNTYPE is the tree node for the data type
-+ of the function which will receive the args, or 0 if the args are to a
-+ compiler support library function. The value of INDIRECT is nonzero when
-+ processing an indirect call, for example a call through a function pointer.
-+ The value of INDIRECT is zero for a call to an explicitly named function, a
-+ library function call, or when `INIT_CUMULATIVE_ARGS' is used to find
-+ arguments for the function being compiled.
-+
-+ When processing a call to a compiler support library function, LIBNAME
-+ identifies which one. It is a `symbol_ref' rtx which contains the name of
-+ the function, as a string. LIBNAME is 0 when an ordinary C function call is
-+ being processed. Thus, each time this macro is called, either LIBNAME or
-+ FNTYPE is nonzero, but never both of them at once. */
-+
-+#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT, NAMED_ARGS) \
-+ init_cumulative_args (&(CUM), FNTYPE, LIBNAME, INDIRECT);
-+
-+/* A C statement (sans semicolon) to update the summarizer variable CUM to
-+ advance past an argument in the argument list. The values MODE, TYPE and
-+ NAMED describe that argument. Once this is done, the variable CUM is
-+ suitable for analyzing the *following* argument with `FUNCTION_ARG', etc.
-+
-+ This macro need not do anything if the argument in question was passed on
-+ the stack. The compiler knows how to track the amount of stack space used
-+ for arguments without any special help. */
-+#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
-+ ((CUM).nbytes += ((MODE) != BLKmode \
-+ ? (GET_MODE_SIZE (MODE) + 3) & ~3 \
-+ : (int_size_in_bytes (TYPE) + 3) & ~3))
-+
-+/* For the Ubicom32 we define the upper function argument register here. */
-+#define UBICOM32_FUNCTION_ARG_REGS 10
-+
-+/* A C expression that is nonzero if REGNO is the number of a hard register in
-+ which function arguments are sometimes passed. This does *not* include
-+ implicit arguments such as the static chain and the structure-value address.
-+ On many machines, no registers can be used for this purpose since all
-+ function arguments are pushed on the stack. */
-+#define FUNCTION_ARG_REGNO_P(N) ((N) < UBICOM32_FUNCTION_ARG_REGS)
-+
-+\f
-+/* How Scalar Function Values are Returned. */
-+
-+/* The number of the hard register that is used to return a scalar value from a
-+ function call. */
-+#define RETURN_VALUE_REGNUM 0
-+
-+/* A C expression to create an RTX representing the place where a function
-+ returns a value of data type VALTYPE. VALTYPE is a tree node representing a
-+ data type. Write `TYPE_MODE (VALTYPE)' to get the machine mode used to
-+ represent that type. On many machines, only the mode is relevant.
-+ (Actually, on most machines, scalar values are returned in the same place
-+ regardless of mode).
-+
-+ If `PROMOTE_FUNCTION_RETURN' is defined, you must apply the same promotion
-+ rules specified in `PROMOTE_MODE' if VALTYPE is a scalar type.
-+
-+ If the precise function being called is known, FUNC is a tree node
-+ (`FUNCTION_DECL') for it; otherwise, FUNC is a null pointer. This makes it
-+ possible to use a different value-returning convention for specific
-+ functions when all their calls are known.
-+
-+ `FUNCTION_VALUE' is not used for return vales with aggregate data types,
-+ because these are returned in another way. See `STRUCT_VALUE_REGNUM' and
-+ related macros, below. */
-+#define FUNCTION_VALUE(VALTYPE, FUNC) \
-+ gen_rtx_REG (TYPE_MODE (VALTYPE), FIRST_DATA_REGNUM)
-+
-+/* A C expression to create an RTX representing the place where a library
-+ function returns a value of mode MODE.
-+
-+ Note that "library function" in this context means a compiler support
-+ routine, used to perform arithmetic, whose name is known specially by the
-+ compiler and was not mentioned in the C code being compiled.
-+
-+ The definition of `LIBRARY_VALUE' need not be concerned aggregate data
-+ types, because none of the library functions returns such types. */
-+#define LIBCALL_VALUE(MODE) gen_rtx_REG (MODE, FIRST_DATA_REGNUM)
-+
-+/* A C expression that is nonzero if REGNO is the number of a hard register in
-+ which the values of called function may come back.
-+
-+ A register whose use for returning values is limited to serving as the
-+ second of a pair (for a value of type `double', say) need not be recognized
-+ by this macro. So for most machines, this definition suffices:
-+
-+ #define FUNCTION_VALUE_REGNO_P(N) ((N) == RETURN)
-+
-+ If the machine has register windows, so that the caller and the called
-+ function use different registers for the return value, this macro should
-+ recognize only the caller's register numbers. */
-+#define FUNCTION_VALUE_REGNO_P(N) ((N) == FIRST_DATA_REGNUM)
-+
-+\f
-+/* How Large Values are Returned. */
-+
-+/* A C expression which can inhibit the returning of certain function values in
-+ registers, based on the type of value. A nonzero value says to return the
-+ function value in memory, just as large structures are always returned.
-+ Here TYPE will be a C expression of type `tree', representing the data type
-+ of the value.
-+
-+ Note that values of mode `BLKmode' must be explicitly handled by this macro.
-+ Also, the option `-fpcc-struct-return' takes effect regardless of this
-+ macro. On most systems, it is possible to leave the macro undefined; this
-+ causes a default definition to be used, whose value is the constant 1 for
-+ `BLKmode' values, and 0 otherwise.
-+
-+ Do not use this macro to indicate that structures and unions should always
-+ be returned in memory. You should instead use `DEFAULT_PCC_STRUCT_RETURN'
-+ to indicate this. */
-+#define RETURN_IN_MEMORY(TYPE) \
-+ (int_size_in_bytes (TYPE) > 8 || TYPE_MODE (TYPE) == BLKmode)
-+
-+/* Define this macro to be 1 if all structure and union return values must be
-+ in memory. Since this results in slower code, this should be defined only
-+ if needed for compatibility with other compilers or with an ABI. If you
-+ define this macro to be 0, then the conventions used for structure and union
-+ return values are decided by the `RETURN_IN_MEMORY' macro.
-+
-+ If not defined, this defaults to the value 1. */
-+#define DEFAULT_PCC_STRUCT_RETURN 0
-+
-+/* If the structure value address is not passed in a register, define
-+ `STRUCT_VALUE' as an expression returning an RTX for the place
-+ where the address is passed. If it returns 0, the address is
-+ passed as an "invisible" first argument. */
-+#define STRUCT_VALUE 0
-+
-+/* Define this macro as a C expression that is nonzero if the return
-+ instruction or the function epilogue ignores the value of the stack pointer;
-+ in other words, if it is safe to delete an instruction to adjust the stack
-+ pointer before a return from the function.
-+
-+ Note that this macro's value is relevant only for functions for which frame
-+ pointers are maintained. It is never safe to delete a final stack
-+ adjustment in a function that has no frame pointer, and the compiler knows
-+ this regardless of `EXIT_IGNORE_STACK'. */
-+#define EXIT_IGNORE_STACK 1
-+
-+/* A C statement or compound statement to output to FILE some assembler code to
-+ call the profiling subroutine `mcount'. Before calling, the assembler code
-+ must load the address of a counter variable into a register where `mcount'
-+ expects to find the address. The name of this variable is `LP' followed by
-+ the number LABELNO, so you would generate the name using `LP%d' in a
-+ `fprintf'.
-+
-+ The details of how the address should be passed to `mcount' are determined
-+ by your operating system environment, not by GNU CC. To figure them out,
-+ compile a small program for profiling using the system's installed C
-+ compiler and look at the assembler code that results.
-+
-+ This declaration must be present, but it can be an abort if profiling is
-+ not implemented. */
-+
-+#define FUNCTION_PROFILER(file, labelno) ubicom32_profiler(file, labelno)
-+
-+/* A C statement to output, on the stream FILE, assembler code for a block of
-+ data that contains the constant parts of a trampoline. This code should not
-+ include a label--the label is taken care of automatically. */
-+#if 0
-+#define TRAMPOLINE_TEMPLATE(FILE) \
-+ do { \
-+ fprintf (FILE, "\tadd -4,sp\n"); \
-+ fprintf (FILE, "\t.long 0x0004fffa\n"); \
-+ fprintf (FILE, "\tmov (0,sp),a0\n"); \
-+ fprintf (FILE, "\tadd 4,sp\n"); \
-+ fprintf (FILE, "\tmov (13,a0),a1\n"); \
-+ fprintf (FILE, "\tmov (17,a0),a0\n"); \
-+ fprintf (FILE, "\tjmp (a0)\n"); \
-+ fprintf (FILE, "\t.long 0\n"); \
-+ fprintf (FILE, "\t.long 0\n"); \
-+ } while (0)
-+#endif
-+
-+/* A C expression for the size in bytes of the trampoline, as an integer. */
-+#define TRAMPOLINE_SIZE 0x1b
-+
-+/* Alignment required for trampolines, in bits.
-+
-+ If you don't define this macro, the value of `BIGGEST_ALIGNMENT' is used for
-+ aligning trampolines. */
-+#define TRAMPOLINE_ALIGNMENT 32
-+
-+/* A C statement to initialize the variable parts of a trampoline. ADDR is an
-+ RTX for the address of the trampoline; FNADDR is an RTX for the address of
-+ the nested function; STATIC_CHAIN is an RTX for the static chain value that
-+ should be passed to the function when it is called. */
-+#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
-+{ \
-+ emit_move_insn (gen_rtx_MEM (SImode, plus_constant ((TRAMP), 0x14)), \
-+ (CXT)); \
-+ emit_move_insn (gen_rtx_MEM (SImode, plus_constant ((TRAMP), 0x18)), \
-+ (FNADDR)); \
-+}
-+
-+/* Ubicom32 supports pre and post increment/decrement addressing. */
-+#define HAVE_POST_INCREMENT 1
-+#define HAVE_PRE_INCREMENT 1
-+#define HAVE_POST_DECREMENT 1
-+#define HAVE_PRE_DECREMENT 1
-+
-+/* Ubicom32 supports pre and post address side-effects with constants
-+ other than the size of the memory operand. */
-+#define HAVE_PRE_MODIFY_DISP 1
-+#define HAVE_POST_MODIFY_DISP 1
-+
-+/* A C expression that is 1 if the RTX X is a constant which is a valid
-+ address. On most machines, this can be defined as `CONSTANT_P (X)',
-+ but a few machines are more restrictive in which constant addresses
-+ are supported.
-+
-+ `CONSTANT_P' accepts integer-values expressions whose values are not
-+ explicitly known, such as `symbol_ref', `label_ref', and `high'
-+ expressions and `const' arithmetic expressions, in addition to
-+ `const_int' and `const_double' expressions. */
-+#define CONSTANT_ADDRESS_P(X) \
-+ (GET_CODE (X) == LABEL_REF \
-+ || (GET_CODE (X) == CONST \
-+ && GET_CODE (XEXP (X, 0)) == PLUS \
-+ && GET_CODE (XEXP (XEXP (X, 0), 0)) == LABEL_REF))
-+
-+/* Ubicom32 supports a maximum of 2 registers in a valid memory address.
-+ One is always an address register while a second, optional, one may be a
-+ data register. */
-+#define MAX_REGS_PER_ADDRESS 2
-+
-+/* A C compound statement with a conditional `goto LABEL;' executed if X (an
-+ RTX) is a legitimate memory address on the target machine for a memory
-+ operand of mode MODE.
-+
-+ It usually pays to define several simpler macros to serve as subroutines for
-+ this one. Otherwise it may be too complicated to understand.
-+
-+ This macro must exist in two variants: a strict variant and a non-strict
-+ one. The strict variant is used in the reload pass. It must be defined so
-+ that any pseudo-register that has not been allocated a hard register is
-+ considered a memory reference. In contexts where some kind of register is
-+ required, a pseudo-register with no hard register must be rejected.
-+
-+ The non-strict variant is used in other passes. It must be defined to
-+ accept all pseudo-registers in every context where some kind of register is
-+ required.
-+
-+ Compiler source files that want to use the strict variant of this macro
-+ define the macro `REG_OK_STRICT'. You should use an `#ifdef REG_OK_STRICT'
-+ conditional to define the strict variant in that case and the non-strict
-+ variant otherwise.
-+
-+ Subroutines to check for acceptable registers for various purposes (one for
-+ base registers, one for index registers, and so on) are typically among the
-+ subroutines used to define `GO_IF_LEGITIMATE_ADDRESS'. Then only these
-+ subroutine macros need have two variants; the higher levels of macros may be
-+ the same whether strict or not.
-+
-+ Normally, constant addresses which are the sum of a `symbol_ref' and an
-+ integer are stored inside a `const' RTX to mark them as constant.
-+ Therefore, there is no need to recognize such sums specifically as
-+ legitimate addresses. Normally you would simply recognize any `const' as
-+ legitimate.
-+
-+ Usually `PRINT_OPERAND_ADDRESS' is not prepared to handle constant sums that
-+ are not marked with `const'. It assumes that a naked `plus' indicates
-+ indexing. If so, then you *must* reject such naked constant sums as
-+ illegitimate addresses, so that none of them will be given to
-+ `PRINT_OPERAND_ADDRESS'.
-+
-+ On some machines, whether a symbolic address is legitimate depends on the
-+ section that the address refers to. On these machines, define the macro
-+ `ENCODE_SECTION_INFO' to store the information into the `symbol_ref', and
-+ then check for it here. When you see a `const', you will have to look
-+ inside it to find the `symbol_ref' in order to determine the section.
-+
-+ The best way to modify the name string is by adding text to the beginning,
-+ with suitable punctuation to prevent any ambiguity. Allocate the new name
-+ in `saveable_obstack'. You will have to modify `ASM_OUTPUT_LABELREF' to
-+ remove and decode the added text and output the name accordingly, and define
-+ `STRIP_NAME_ENCODING' to access the original name string.
-+
-+ You can check the information stored here into the `symbol_ref' in the
-+ definitions of the macros `GO_IF_LEGITIMATE_ADDRESS' and
-+ `PRINT_OPERAND_ADDRESS'. */
-+/* On the ubicom32, the value in the address register must be
-+ in the same memory space/segment as the effective address.
-+
-+ This is problematical for reload since it does not understand
-+ that base+index != index+base in a memory reference. */
-+
-+#ifdef REG_OK_STRICT
-+#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
-+ if (ubicom32_legitimate_address_p (MODE, X, 1)) goto ADDR;
-+#else
-+#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
-+ if (ubicom32_legitimate_address_p (MODE, X, 0)) goto ADDR;
-+#endif
-+
-+/* Try machine-dependent ways of modifying an illegitimate address
-+ to be legitimate. If we find one, return the new, valid address.
-+ This macro is used in only one place: `memory_address' in explow.c.
-+
-+ OLDX is the address as it was before break_out_memory_refs was called.
-+ In some cases it is useful to look at this to decide what needs to be done.
-+
-+ MODE and WIN are passed so that this macro can use
-+ GO_IF_LEGITIMATE_ADDRESS.
-+
-+ It is always safe for this macro to do nothing. It exists to recognize
-+ opportunities to optimize the output.
-+
-+ On RS/6000, first check for the sum of a register with a constant
-+ integer that is out of range. If so, generate code to add the
-+ constant with the low-order 16 bits masked to the register and force
-+ this result into another register (this can be done with `cau').
-+ Then generate an address of REG+(CONST&0xffff), allowing for the
-+ possibility of bit 16 being a one.
-+
-+ Then check for the sum of a register and something not constant, try to
-+ load the other things into a register and return the sum. */
-+
-+#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \
-+{ \
-+ rtx result = ubicom32_legitimize_address ((X), (OLDX), (MODE)); \
-+ if (result != NULL_RTX) \
-+ { \
-+ (X) = result; \
-+ goto WIN; \
-+ } \
-+}
-+
-+/* Try a machine-dependent way of reloading an illegitimate address
-+ operand. If we find one, push the reload and jump to WIN. This
-+ macro is used in only one place: `find_reloads_address' in reload.c. */
-+#define LEGITIMIZE_RELOAD_ADDRESS(AD, MODE, OPNUM, TYPE, IND, WIN) \
-+{ \
-+ rtx new_rtx = ubicom32_legitimize_reload_address ((AD), (MODE), (OPNUM), (int)(TYPE)); \
-+ if (new_rtx) \
-+ { \
-+ (AD) = new_rtx; \
-+ goto WIN; \
-+ } \
-+}
-+
-+/* A C statement or compound statement with a conditional `goto LABEL;'
-+ executed if memory address X (an RTX) can have different meanings depending
-+ on the machine mode of the memory reference it is used for or if the address
-+ is valid for some modes but not others.
-+
-+ Autoincrement and autodecrement addresses typically have mode-dependent
-+ effects because the amount of the increment or decrement is the size of the
-+ operand being addressed. Some machines have other mode-dependent addresses.
-+ Many RISC machines have no mode-dependent addresses.
-+
-+ You may assume that ADDR is a valid address for the machine. */
-+#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL) \
-+ if (ubicom32_mode_dependent_address_p (ADDR)) \
-+ goto LABEL;
-+
-+/* A C expression that is nonzero if X is a legitimate constant for an
-+ immediate operand on the target machine. You can assume that X
-+ satisfies `CONSTANT_P', so you need not check this. In fact, `1' is
-+ a suitable definition for this macro on machines where anything
-+ `CONSTANT_P' is valid. */
-+#define LEGITIMATE_CONSTANT_P(X) \
-+ ubicom32_legitimate_constant_p ((X))
-+
-+/* Moves between registers are pretty-much single instructions for
-+ Ubicom32. We make this the default "2" that gcc likes. */
-+#define REGISTER_MOVE_COST(MODE, FROM, TO) 2
-+
-+/* This is a little bit of magic from the S390 port that wins 2% on code
-+ size when building the Linux kernel! Unfortunately while it wins on
-+ that size the user-space apps built using FD-PIC don't improve and the
-+ performance is lower because we put more pressure on the caches. We may
-+ want this back on some future CPU that has higher cache performance. */
-+/* #define IRA_HARD_REGNO_ADD_COST_MULTIPLIER(regno) 0.5 */
-+
-+/* Moves between registers and memory are more expensive than between
-+ registers because we have caches and write buffers that slow things
-+ down! */
-+#define MEMORY_MOVE_COST(MODE, CLASS, IN) 2
-+
-+/* A fall-through branch is very low cost but anything that changes the PC
-+ incurs a major pipeline hazard. We don't make the full extent of this
-+ hazard visible because we hope that multiple threads will absorb much
-+ of the cost and so we don't want a jump being replaced with, say, 7
-+ instructions. */
-+#define BRANCH_COST(SPEED_P, PREDICTABLE_P) \
-+ ((PREDICTABLE_P) ? 1 : 3)
-+
-+/* Define this macro as a C expression which is nonzero if accessing less than
-+ a word of memory (i.e. a `char' or a `short') is no faster than accessing a
-+ word of memory, i.e., if such access require more than one instruction or if
-+ there is no difference in cost between byte and (aligned) word loads.
-+
-+ When this macro is not defined, the compiler will access a field by finding
-+ the smallest containing object; when it is defined, a fullword load will be
-+ used if alignment permits. Unless bytes accesses are faster than word
-+ accesses, using word accesses is preferable since it may eliminate
-+ subsequent memory access if subsequent accesses occur to other fields in the
-+ same word of the structure, but to different bytes. */
-+#define SLOW_BYTE_ACCESS 0
-+
-+/* The number of scalar move insns which should be generated instead of a
-+ string move insn or a library call. Increasing the value will always make
-+ code faster, but eventually incurs high cost in increased code size.
-+
-+ If you don't define this, a reasonable default is used. */
-+/* According to expr.c, a value of around 6 should minimize code size. */
-+#define MOVE_RATIO(SPEED) 6
-+
-+/* We're much better off calling a constant function address with the
-+ Ubicom32 architecture because we have an opcode for doing so. Don't
-+ let the compiler extract function addresses as common subexpressions
-+ into an address register. */
-+#define NO_FUNCTION_CSE
-+
-+#define SELECT_CC_MODE(OP, X, Y) ubicom32_select_cc_mode (OP, X, Y)
-+
-+#define REVERSIBLE_CC_MODE(MODE) 1
-+
-+/* Canonicalize a comparison from one we don't have to one we do have. */
-+#define CANONICALIZE_COMPARISON(CODE, OP0, OP1) \
-+ ubicom32_canonicalize_comparison (&(CODE), &(OP0), &(OP1))
-+
-+/* Dividing the output into sections. */
-+
-+/* A C expression whose value is a string containing the assembler operation
-+ that should precede instructions and read-only data. Normally `".text"' is
-+ right. */
-+#define TEXT_SECTION_ASM_OP "\t.section .text"
-+
-+/* A C expression whose value is a string containing the assembler operation to
-+ identify the following data as writable initialized data. Normally
-+ `".data"' is right. */
-+#define DATA_SECTION_ASM_OP "\t.section .data"
-+
-+
-+/* If defined, a C expression whose value is a string containing the
-+ assembler operation to identify the following data as
-+ uninitialized global data. If not defined, and neither
-+ `ASM_OUTPUT_BSS' nor `ASM_OUTPUT_ALIGNED_BSS' are defined,
-+ uninitialized global data will be output in the data section if
-+ `-fno-common' is passed, otherwise `ASM_OUTPUT_COMMON' will be
-+ used. */
-+#define BSS_SECTION_ASM_OP "\t.section .bss"
-+
-+/* This is how we tell the assembler that a symbol is weak. */
-+
-+#define ASM_WEAKEN_LABEL(FILE, NAME) \
-+ do \
-+ { \
-+ fputs ("\t.weak\t", (FILE)); \
-+ assemble_name ((FILE), (NAME)); \
-+ fputc ('\n', (FILE)); \
-+ } \
-+ while (0)
-+
-+/* The Overall Framework of an Assembler File. */
-+
-+#undef SET_ASM_OP
-+#define SET_ASM_OP "\t.set\t"
-+
-+/* A C string constant describing how to begin a comment in the target
-+ assembler language. The compiler assumes that the comment will end at the
-+ end of the line. */
-+#define ASM_COMMENT_START ";"
-+
-+/* A C string constant for text to be output before each `asm' statement or
-+ group of consecutive ones. Normally this is `"#APP"', which is a comment
-+ that has no effect on most assemblers but tells the GNU assembler that it
-+ must check the lines that follow for all valid assembler constructs. */
-+#define ASM_APP_ON "#APP\n"
-+
-+/* A C string constant for text to be output after each `asm' statement or
-+ group of consecutive ones. Normally this is `"#NO_APP"', which tells the
-+ GNU assembler to resume making the time-saving assumptions that are valid
-+ for ordinary compiler output. */
-+#define ASM_APP_OFF "#NO_APP\n"
-+
-+/* Like `ASM_OUTPUT_BSS' except takes the required alignment as a separate,
-+ explicit argument. If you define this macro, it is used in place of
-+ `ASM_OUTPUT_BSS', and gives you more flexibility in handling the required
-+ alignment of the variable. The alignment is specified as the number of
-+ bits.
-+
-+ Try to use function `asm_output_aligned_bss' defined in file `varasm.c' when
-+ defining this macro. */
-+#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
-+ asm_output_aligned_bss ((FILE), (DECL), (NAME), (SIZE), (ALIGN))
-+
-+/* A C expression to assign to OUTVAR (which is a variable of type `char *') a
-+ newly allocated string made from the string NAME and the number NUMBER, with
-+ some suitable punctuation added. Use `alloca' to get space for the string.
-+
-+ The string will be used as an argument to `ASM_OUTPUT_LABELREF' to produce
-+ an assembler label for an internal static variable whose name is NAME.
-+ Therefore, the string must be such as to result in valid assembler code.
-+ The argument NUMBER is different each time this macro is executed; it
-+ prevents conflicts between similarly-named internal static variables in
-+ different scopes.
-+
-+ Ideally this string should not be a valid C identifier, to prevent any
-+ conflict with the user's own symbols. Most assemblers allow periods or
-+ percent signs in assembler symbols; putting at least one of these between
-+ the name and the number will suffice. */
-+#define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \
-+ ((OUTPUT) = (char *) alloca (strlen ((NAME)) + 10), \
-+ sprintf ((OUTPUT), "%s___%d", (NAME), (LABELNO)))
-+
-+#define ASM_GENERATE_INTERNAL_LABEL(STRING, PREFIX, NUM) \
-+ sprintf (STRING, "*.%s%ld", PREFIX, (long)(NUM))
-+/* A C statement to store into the string STRING a label whose name
-+ is made from the string PREFIX and the number NUM.
-+
-+ This string, when output subsequently by `assemble_name', should
-+ produce the output that `(*targetm.asm_out.internal_label)' would produce
-+ with the same PREFIX and NUM.
-+
-+ If the string begins with `*', then `assemble_name' will output
-+ the rest of the string unchanged. It is often convenient for
-+ `ASM_GENERATE_INTERNAL_LABEL' to use `*' in this way. If the
-+ string doesn't start with `*', then `ASM_OUTPUT_LABELREF' gets to
-+ output the string, and may change it. (Of course,
-+ `ASM_OUTPUT_LABELREF' is also part of your machine description, so
-+ you should know what it does on your machine.) */
-+
-+/* This says how to output assembler code to declare an
-+ uninitialized external linkage data object. Under SVR4,
-+ the linker seems to want the alignment of data objects
-+ to depend on their types. We do exactly that here. */
-+
-+#define COMMON_ASM_OP "\t.comm\t"
-+
-+#undef ASM_OUTPUT_COMMON
-+#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \
-+ do \
-+ { \
-+ fprintf ((FILE), "%s", COMMON_ASM_OP); \
-+ assemble_name ((FILE), (NAME)); \
-+ fprintf ((FILE), ", %u\n", (SIZE)); \
-+ } \
-+ while (0)
-+
-+/* This says how to output assembler code to declare an
-+ uninitialized internal linkage data object. Under SVR4,
-+ the linker seems to want the alignment of data objects
-+ to depend on their types. We do exactly that here. */
-+#define LOCAL_ASM_OP "\t.lcomm\t"
-+
-+#undef ASM_OUTPUT_LOCAL
-+#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \
-+ do \
-+ { \
-+ fprintf ((FILE), "%s", LOCAL_ASM_OP); \
-+ assemble_name ((FILE), (NAME)); \
-+ fprintf ((FILE), ", %u\n", (SIZE)); \
-+ } \
-+ while (0)
-+
-+/* Globalizing directive for a label. */
-+#define GLOBAL_ASM_OP ".global\t"
-+
-+/* Output the operand of an instruction. */
-+#define PRINT_OPERAND(FILE, X, CODE) \
-+ ubicom32_print_operand(FILE, X, CODE)
-+
-+/* Output the address of an operand. */
-+#define PRINT_OPERAND_ADDRESS(FILE, ADDR) \
-+ ubicom32_print_operand_address (FILE, ADDR)
-+
-+/* A C expression to output to STREAM some assembler code which will push hard
-+ register number REGNO onto the stack. The code need not be optimal, since
-+ this macro is used only when profiling. */
-+#define ASM_OUTPUT_REG_PUSH(FILE, REGNO)
-+
-+/* A C expression to output to STREAM some assembler code which will pop hard
-+ register number REGNO off of the stack. The code need not be optimal, since
-+ this macro is used only when profiling. */
-+#define ASM_OUTPUT_REG_POP(FILE, REGNO)
-+
-+/* This macro should be provided on machines where the addresses in a dispatch
-+ table are relative to the table's own address.
-+
-+ The definition should be a C statement to output to the stdio stream STREAM
-+ an assembler pseudo-instruction to generate a difference between two labels.
-+ VALUE and REL are the numbers of two internal labels. The definitions of
-+ these labels are output using `ASM_OUTPUT_INTERNAL_LABEL', and they must be
-+ printed in the same way here. For example,
-+
-+ fprintf (STREAM, "\t.word L%d-L%d\n", VALUE, REL) */
-+#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
-+ fprintf (FILE, "\t%s .L%d-.L%d\n", ".long", VALUE, REL)
-+
-+/* This macro should be provided on machines where the addresses in a dispatch
-+ table are absolute.
-+
-+ The definition should be a C statement to output to the stdio stream STREAM
-+ an assembler pseudo-instruction to generate a reference to a label. VALUE
-+ is the number of an internal label whose definition is output using
-+ `ASM_OUTPUT_INTERNAL_LABEL'. For example,
-+
-+ fprintf (STREAM, "\t.word L%d\n", VALUE) */
-+#define ASM_OUTPUT_ADDR_VEC_ELT(STREAM, VALUE) \
-+ fprintf (STREAM, "\t.word .L%d\n", VALUE)
-+
-+/* Switch into a generic section. */
-+#define TARGET_ASM_NAMED_SECTION default_elf_asm_named_section
-+
-+/* Assembler Commands for Alignment. */
-+
-+#define ASM_OUTPUT_SKIP(STREAM, N) fprintf (STREAM, "\t.skip %d,0\n", N)
-+/* A C statement to output to the stdio stream STREAM an assembler
-+ instruction to advance the location counter by NBYTES bytes.
-+ Those bytes should be zero when loaded. NBYTES will be a C
-+ expression of type `int'. */
-+
-+/* A C statement to output to the stdio stream STREAM an assembler command to
-+ advance the location counter to a multiple of 2 to the POWER bytes. POWER
-+ will be a C expression of type `int'. */
-+#define ASM_OUTPUT_ALIGN(FILE, LOG) \
-+ if ((LOG) != 0) \
-+ fprintf (FILE, "\t.align %d\n", (LOG))
-+
-+/* A C expression that returns the DBX register number for the compiler
-+ register number REGNO. In simple cases, the value of this expression may be
-+ REGNO itself. But sometimes there are some registers that the compiler
-+ knows about and DBX does not, or vice versa. In such cases, some register
-+ may need to have one number in the compiler and another for DBX.
-+
-+ If two registers have consecutive numbers inside GNU CC, and they can be
-+ used as a pair to hold a multiword value, then they *must* have consecutive
-+ numbers after renumbering with `DBX_REGISTER_NUMBER'. Otherwise, debuggers
-+ will be unable to access such a pair, because they expect register pairs to
-+ be consecutive in their own numbering scheme.
-+
-+ If you find yourself defining `DBX_REGISTER_NUMBER' in way that does not
-+ preserve register pairs, then what you must do instead is redefine the
-+ actual register numbering scheme.
-+
-+ This declaration is required. */
-+#define DBX_REGISTER_NUMBER(REGNO) REGNO
-+
-+/* A C expression that returns the integer offset value for an automatic
-+ variable having address X (an RTL expression). The default computation
-+ assumes that X is based on the frame-pointer and gives the offset from the
-+ frame-pointer. This is required for targets that produce debugging output
-+ for DBX or COFF-style debugging output for SDB and allow the frame-pointer
-+ to be eliminated when the `-g' options is used. */
-+#define DEBUGGER_AUTO_OFFSET(X) \
-+ ((GET_CODE (X) == PLUS ? INTVAL (XEXP (X, 1)) : 0) \
-+ + (frame_pointer_needed \
-+ ? 0 : -initial_elimination_offset (FRAME_POINTER_REGNUM, \
-+ STACK_POINTER_REGNUM)))
-+
-+/* A C expression that returns the integer offset value for an argument having
-+ address X (an RTL expression). The nominal offset is OFFSET. */
-+#define DEBUGGER_ARG_OFFSET(OFFSET, X) \
-+ ((GET_CODE (X) == PLUS ? OFFSET : 0) \
-+ + (frame_pointer_needed \
-+ ? 0 : -initial_elimination_offset (ARG_POINTER_REGNUM, \
-+ STACK_POINTER_REGNUM)))
-+
-+/* A C expression that returns the type of debugging output GNU CC produces
-+ when the user specifies `-g' or `-ggdb'. Define this if you have arranged
-+ for GNU CC to support more than one format of debugging output. Currently,
-+ the allowable values are `DBX_DEBUG', `SDB_DEBUG', `DWARF_DEBUG',
-+ `DWARF2_DEBUG', and `XCOFF_DEBUG'.
-+
-+ The value of this macro only affects the default debugging output; the user
-+ can always get a specific type of output by using `-gstabs', `-gcoff',
-+ `-gdwarf-1', `-gdwarf-2', or `-gxcoff'.
-+
-+ Defined in svr4.h.
-+*/
-+#undef PREFERRED_DEBUGGING_TYPE
-+#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
-+
-+/* Define this macro if GNU CC should produce dwarf version 2 format debugging
-+ output in response to the `-g' option.
-+
-+ To support optional call frame debugging information, you must also define
-+ `INCOMING_RETURN_ADDR_RTX' and either set `RTX_FRAME_RELATED_P' on the
-+ prologue insns if you use RTL for the prologue, or call `dwarf2out_def_cfa'
-+ and `dwarf2out_reg_save' as appropriate from `FUNCTION_PROLOGUE' if you
-+ don't.
-+
-+ Defined in svr4.h. */
-+
-+#define DWARF2_DEBUGGING_INFO 1
-+/*#define DWARF2_UNWIND_INFO 1*/
-+#define DWARF2_UNWIND_INFO 0
-+#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (Pmode, LINK_REGNO)
-+#define INCOMING_FRAME_SP_OFFSET 0
-+#define DWARF_FRAME_RETURN_COLUMN DWARF_FRAME_REGNUM (LINK_REGNO)
-+#define EH_RETURN_FIRST 9
-+#define EH_RETURN_DATA_REGNO(N) ((N) < 2 ? (N) + EH_RETURN_FIRST : INVALID_REGNUM)
-+
-+/* The EH_RETURN_STACKADJ_RTX macro returns RTL which describes the
-+ location used to store the amount to ajdust the stack. This is
-+ usually a registers that is available from end of the function's body
-+ to the end of the epilogue. Thus, this cannot be a register used as a
-+ temporary by the epilogue.
-+
-+ This must be an integer register. */
-+#define EH_RETURN_STACKADJ_REGNO 11
-+#define EH_RETURN_STACKADJ_RTX \
-+ gen_rtx_REG (Pmode, EH_RETURN_STACKADJ_REGNO)
-+
-+/* The EH_RETURN_HANDLER_RTX macro returns RTL which describes the
-+ location used to store the address the processor should jump to
-+ catch exception. This is usually a registers that is available from
-+ end of the function's body to the end of the epilogue. Thus, this
-+ cannot be a register used as a temporary by the epilogue.
-+
-+ This must be an address register. */
-+#define EH_RETURN_HANDLER_REGNO 18
-+#define EH_RETURN_HANDLER_RTX \
-+ gen_rtx_REG (Pmode, EH_RETURN_HANDLER_REGNO)
-+
-+/* #define DWARF2_DEBUGGING_INFO */
-+
-+/* Define this macro if GNU CC should produce dwarf version 2-style
-+ line numbers. This usually requires extending the assembler to
-+ support them, and #defining DWARF2_LINE_MIN_INSN_LENGTH in the
-+ assembler configuration header files. */
-+/* #define DWARF2_ASM_LINE_DEBUG_INFO 1 */
-+
-+
-+/* An alias for a machine mode name. This is the machine mode that elements
-+ of a jump-table have. */
-+#define CASE_VECTOR_MODE Pmode
-+
-+/* Smallest number of different values for which it is best to use a
-+ jump-table instead of a tree of conditional branches. For most Ubicom32
-+ targets this is quite small, but for the v1 architecture implementations
-+ we had very little data memory and so heavily prefer the tree approach
-+ rather than the jump tables. */
-+#define CASE_VALUES_THRESHOLD ubicom32_case_values_threshold
-+
-+/* Register operations within the Ubicom32 architecture always operate on
-+ the whole register word and not just the sub-bits required for the opcode
-+ mode size. */
-+#define WORD_REGISTER_OPERATIONS
-+
-+/* The maximum number of bytes that a single instruction can move quickly from
-+ memory to memory. */
-+#define MOVE_MAX 4
-+
-+/* A C expression that is nonzero if on this machine the number of bits
-+ actually used for the count of a shift operation is equal to the number of
-+ bits needed to represent the size of the object being shifted. When this
-+ macro is non-zero, the compiler will assume that it is safe to omit a
-+ sign-extend, zero-extend, and certain bitwise `and' instructions that
-+ truncates the count of a shift operation. On machines that have
-+ instructions that act on bitfields at variable positions, which may include
-+ `bit test' instructions, a nonzero `SHIFT_COUNT_TRUNCATED' also enables
-+ deletion of truncations of the values that serve as arguments to bitfield
-+ instructions.
-+
-+ If both types of instructions truncate the count (for shifts) and position
-+ (for bitfield operations), or if no variable-position bitfield instructions
-+ exist, you should define this macro.
-+
-+ However, on some machines, such as the 80386 and the 680x0, truncation only
-+ applies to shift operations and not the (real or pretended) bitfield
-+ operations. Define `SHIFT_COUNT_TRUNCATED' to be zero on such machines.
-+ Instead, add patterns to the `md' file that include the implied truncation
-+ of the shift instructions.
-+
-+ You need not define this macro if it would always have the value of zero. */
-+#define SHIFT_COUNT_TRUNCATED 1
-+
-+/* A C expression which is nonzero if on this machine it is safe to "convert"
-+ an integer of INPREC bits to one of OUTPREC bits (where OUTPREC is smaller
-+ than INPREC) by merely operating on it as if it had only OUTPREC bits.
-+
-+ On many machines, this expression can be 1.
-+
-+ When `TRULY_NOOP_TRUNCATION' returns 1 for a pair of sizes for modes for
-+ which `MODES_TIEABLE_P' is 0, suboptimal code can result. If this is the
-+ case, making `TRULY_NOOP_TRUNCATION' return 0 in such cases may improve
-+ things. */
-+#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
-+
-+/* A C string constant that tells the GNU CC driver program options to pass
-+ to the assembler. It can also specify how to translate options you give
-+ to GNU CC into options for GNU CC to pass to the assembler. See the
-+ file `sun3.h' for an example of this.
-+
-+ Defined in svr4.h. */
-+#undef ASM_SPEC
-+#define ASM_SPEC \
-+ "%{march=*:-m%*} %{!march=*:-mubicom32v4} %{mfdpic:-mfdpic}"
-+
-+#define LINK_SPEC "\
-+%{h*} %{v:-V} \
-+%{b} \
-+%{mfdpic:-melf32ubicom32fdpic -z text} \
-+%{static:-dn -Bstatic} \
-+%{shared:-G -Bdynamic} \
-+%{symbolic:-Bsymbolic} \
-+%{G*} \
-+%{YP,*} \
-+%{Qy:} %{!Qn:-Qy}"
-+
-+#undef STARTFILE_SPEC
-+#undef ENDFILE_SPEC
-+
-+/* The svr4.h LIB_SPEC with -leval and --*group tacked on */
-+
-+#undef LIB_SPEC
-+#define LIB_SPEC "%{!shared:%{!symbolic:--start-group -lc -leval -lgcc --end-group}}"
-+
-+#undef HAVE_GAS_SHF_MERGE
-+#define HAVE_GAS_SHF_MERGE 0
-+
-+#define HANDLE_SYSV_PRAGMA 1
-+#undef HANDLE_PRAGMA_PACK
-+
-+typedef void (*ubicom32_func_ptr) (void);
-+
-+/* Define builtins for selected special-purpose instructions. */
-+enum ubicom32_builtins
-+{
-+ UBICOM32_BUILTIN_UBICOM32_SWAPB_2,
-+ UBICOM32_BUILTIN_UBICOM32_SWAPB_4
-+};
-+
-+extern rtx ubicom32_compare_op0;
-+extern rtx ubicom32_compare_op1;
-+
-+#define TYPE_ASM_OP "\t.type\t"
-+#define TYPE_OPERAND_FMT "@%s"
-+
-+#ifndef ASM_DECLARE_RESULT
-+#define ASM_DECLARE_RESULT(FILE, RESULT)
-+#endif
-+
-+/* These macros generate the special .type and .size directives which
-+ are used to set the corresponding fields of the linker symbol table
-+ entries in an ELF object file under SVR4. These macros also output
-+ the starting labels for the relevant functions/objects. */
-+
-+/* Write the extra assembler code needed to declare a function properly.
-+ Some svr4 assemblers need to also have something extra said about the
-+ function's return value. We allow for that here. */
-+
-+#ifndef ASM_DECLARE_FUNCTION_NAME
-+#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \
-+ do \
-+ { \
-+ ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "function"); \
-+ ASM_DECLARE_RESULT (FILE, DECL_RESULT (DECL)); \
-+ ASM_OUTPUT_LABEL (FILE, NAME); \
-+ } \
-+ while (0)
-+#endif
---- /dev/null
-+++ b/gcc/config/ubicom32/ubicom32.md
-@@ -0,0 +1,3753 @@
-+; GCC machine description for Ubicom32
-+;
-+; Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Free Software
-+; Foundation, Inc.
-+; Contributed by Ubicom, Inc.
-+;
-+; This file is part of GCC.
-+;
-+; GCC is free software; you can redistribute it and/or modify
-+; it under the terms of the GNU General Public License as published by
-+; the Free Software Foundation; either version 3, or (at your option)
-+; any later version.
-+;
-+; GCC is distributed in the hope that it will be useful,
-+; but WITHOUT ANY WARRANTY; without even the implied warranty of
-+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+; GNU General Public License for more details.
-+;
-+; You should have received a copy of the GNU General Public License
-+; along with GCC; see the file COPYING3. If not see
-+; <http://www.gnu.org/licenses/>.
-+
-+(define_constants
-+ [(AUX_DATA_REGNO 15)
-+ (LINK_REGNO 21)
-+ (SP_REGNO 23)
-+ (ACC0_HI_REGNO 24)
-+ (ACC1_HI_REGNO 26)
-+ (CC_REGNO 30)])
-+
-+(define_constants
-+ [(UNSPEC_FDPIC_GOT 0)
-+ (UNSPEC_FDPIC_GOT_FUNCDESC 1)])
-+
-+(define_constants
-+ [(UNSPEC_VOLATILE_LOAD_FDPIC_FUNCDESC 0)])
-+
-+;; Types of instructions (for scheduling purposes).
-+
-+(define_attr "type" "mul,addr,other"
-+ (const_string "other"))
-+
-+; Define instruction scheduling characteristics. We can only issue
-+; one instruction per clock so we don't need to define CPU units.
-+;
-+(define_automaton "ubicom32")
-+
-+(define_cpu_unit "i_pipeline" "ubicom32");
-+
-+; We have a 4 cycle hazard associated with address calculations which
-+; seems rather tricky to avoid so we go with a defensive assumption
-+; that almost anything can be used to generate addresses.
-+;
-+;(define_insn_reservation "ubicom32_other" 4
-+; (eq_attr "type" "other")
-+; "i_pipeline")
-+
-+; Some moves don't generate hazards.
-+;
-+;(define_insn_reservation "ubicom32_addr" 1
-+; (eq_attr "type" "addr")
-+; "i_pipeline")
-+
-+; We need 3 cycles between a multiply instruction and any use of the
-+; matching accumulator register(s).
-+;
-+(define_insn_reservation "ubicom32_mul" 4
-+ (eq_attr "type" "mul")
-+ "i_pipeline")
-+
-+(define_attr "length" ""
-+ (const_int 4))
-+
-+(include "predicates.md")
-+(include "constraints.md")
-+
-+; 8-bit move with no change to the flags reg.
-+;
-+(define_insn "movqi"
-+ [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
-+ (match_operand:QI 1 "ubicom32_move_operand" "g"))]
-+ ""
-+ "move.1\\t%0, %1")
-+
-+; Combiner-generated 8-bit move with the zero flag set accordingly.
-+;
-+(define_insn "movqi_ccszn"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:QI 0 "nonimmediate_operand" "rm")
-+ (const_int 0)))
-+ (set (match_operand:QI 1 "nonimmediate_operand" "=rm")
-+ (match_dup 0))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "ext.1\\t%1, %0")
-+
-+; Combine isn't very good at merging some types of operations so we
-+; have to make do with a peephole. It's not as effective but it's better
-+; than doing nothing.
-+;
-+(define_peephole2
-+ [(set (match_operand:QI 0 "nonimmediate_operand" "")
-+ (match_operand:QI 1 "nonimmediate_operand" ""))
-+ (set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (match_operator 3 "ubicom32_compare_operator"
-+ [(match_dup 0)
-+ (const_int 0)]))]
-+ "(GET_MODE (operands[2]) == CCSZNmode
-+ || GET_MODE (operands[2]) == CCSZmode)"
-+ [(parallel
-+ [(set (match_dup 2)
-+ (match_op_dup 3
-+ [(match_dup 1)
-+ (const_int 0)]))
-+ (set (match_dup 0)
-+ (match_dup 1))])]
-+ "")
-+
-+; Combine isn't very good at merging some types of operations so we
-+; have to make do with a peephole. It's not as effective but it's better
-+; than doing nothing.
-+;
-+(define_peephole2
-+ [(set (match_operand:QI 0 "nonimmediate_operand" "")
-+ (match_operand:QI 1 "nonimmediate_operand" ""))
-+ (set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (match_operator 3 "ubicom32_compare_operator"
-+ [(match_dup 1)
-+ (const_int 0)]))]
-+ "(GET_MODE (operands[2]) == CCSZNmode
-+ || GET_MODE (operands[2]) == CCSZmode)"
-+ [(parallel
-+ [(set (match_dup 2)
-+ (match_op_dup 3
-+ [(match_dup 1)
-+ (const_int 0)]))
-+ (set (match_dup 0)
-+ (match_dup 1))])]
-+ "")
-+
-+; 16-bit move with no change to the flags reg.
-+;
-+(define_insn "movhi"
-+ [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
-+ (match_operand:HI 1 "ubicom32_move_operand" "g"))]
-+ ""
-+ "*
-+ {
-+ if (CONST_INT_P (operands[1]))
-+ return \"movei\\t%0, %1\";
-+
-+ return \"move.2\\t%0, %1\";
-+ }")
-+
-+; Combiner-generated 16-bit move with the zero flag set accordingly.
-+;
-+(define_insn "movhi_ccszn"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:HI 0 "nonimmediate_operand" "rm")
-+ (const_int 0)))
-+ (set (match_operand:HI 1 "nonimmediate_operand" "=rm")
-+ (match_dup 0))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "ext.2\\t%1, %0")
-+
-+; Combine isn't very good at merging some types of operations so we
-+; have to make do with a peephole. It's not as effective but it's better
-+; than doing nothing.
-+;
-+(define_peephole2
-+ [(set (match_operand:HI 0 "nonimmediate_operand" "")
-+ (match_operand:HI 1 "nonimmediate_operand" ""))
-+ (set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (match_operator 3 "ubicom32_compare_operator"
-+ [(match_dup 0)
-+ (const_int 0)]))]
-+ "(GET_MODE (operands[2]) == CCSZNmode
-+ || GET_MODE (operands[2]) == CCSZmode)"
-+ [(parallel
-+ [(set (match_dup 2)
-+ (match_op_dup 3
-+ [(match_dup 1)
-+ (const_int 0)]))
-+ (set (match_dup 0)
-+ (match_dup 1))])]
-+ "")
-+
-+; Combine isn't very good at merging some types of operations so we
-+; have to make do with a peephole. It's not as effective but it's better
-+; than doing nothing.
-+;
-+(define_peephole2
-+ [(set (match_operand:HI 0 "nonimmediate_operand" "")
-+ (match_operand:HI 1 "nonimmediate_operand" ""))
-+ (set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (match_operator 3 "ubicom32_compare_operator"
-+ [(match_dup 1)
-+ (const_int 0)]))]
-+ "(GET_MODE (operands[2]) == CCSZNmode
-+ || GET_MODE (operands[2]) == CCSZmode)"
-+ [(parallel
-+ [(set (match_dup 2)
-+ (match_op_dup 3
-+ [(match_dup 1)
-+ (const_int 0)]))
-+ (set (match_dup 0)
-+ (match_dup 1))])]
-+ "")
-+
-+; 32-bit move with no change to the flags reg.
-+;
-+(define_expand "movsi"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
-+ (match_operand:SI 1 "general_operand" ""))]
-+ ""
-+ "{
-+ /* Convert any complexities in operand 1 into something that can just
-+ fall into the default expander code. */
-+ ubicom32_expand_movsi (operands);
-+ }")
-+
-+(define_insn "movsi_high"
-+ [(set (match_operand:SI 0 "ubicom32_address_register_operand" "=a")
-+ (high:SI (match_operand:SI 1 "ubicom32_symbolic_address_operand" "s")))]
-+ ""
-+ "moveai\\t%0, #%%hi(%E1)")
-+
-+(define_insn "movsi_lo_sum"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (lo_sum:SI (match_operand:SI 1 "ubicom32_address_register_operand" "a")
-+ (match_operand:SI 2 "immediate_operand" "s")))]
-+ ""
-+ "lea.1\\t%0, %%lo(%E2)(%1)")
-+
-+(define_insn "movsi_internal"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (match_operand:SI 1 "ubicom32_move_operand" "rmnY"))]
-+ ""
-+ "*
-+ {
-+ if (CONST_INT_P (operands[1]))
-+ {
-+ ubicom32_emit_move_const_int (operands[0], operands[1]);
-+ return \"\";
-+ }
-+
-+ if (GET_CODE (operands[1]) == CONST_DOUBLE)
-+ {
-+ HOST_WIDE_INT i = CONST_DOUBLE_LOW (operands[1]);
-+
-+ ubicom32_emit_move_const_int (operands[0], GEN_INT (i));
-+ return \"\";
-+ }
-+
-+ if (ubicom32_address_register_operand (operands[0], VOIDmode)
-+ && register_operand (operands[1], VOIDmode))
-+ {
-+ if (ubicom32_address_register_operand (operands[1], VOIDmode))
-+ return \"lea.1\\t%0, 0(%1)\";
-+
-+ /* Use movea here to utilize the hazard bypass in the >= v4 ISA. */
-+ if (ubicom32_v4)
-+ return \"movea\\t%0, %1\";
-+
-+ return \"move.4\\t%0, %1\";
-+ }
-+
-+ return \"move.4\\t%0, %1\";
-+ }")
-+
-+; If we're not dependent on the state of the condition codes we can construct
-+; constants of value 2^n by using a bset.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(exact_log2 (INTVAL (operands[1])) > 14
-+ && peep2_regno_dead_p (0, CC_REGNO))"
-+ [(parallel
-+ [(set (match_dup 0)
-+ (ior:SI (const_int 0)
-+ (match_dup 1)))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "")
-+
-+; If we're not dependent on the state of the condition codes we can construct
-+; constants of value ~(2^n) by using a bclr.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(exact_log2 (~INTVAL (operands[1])) > 14
-+ && peep2_regno_dead_p (0, CC_REGNO))"
-+ [(parallel
-+ [(set (match_dup 0)
-+ (and:SI (const_int -1)
-+ (match_dup 1)))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "")
-+
-+; For 32-bit constants that have bits 0 through 24 and bit 31 set the same
-+; we can use swapb.4!
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(ubicom32_v4
-+ && (INTVAL (operands[1]) & 0xffffffff) != 0xffffffff
-+ && (INTVAL (operands[1]) & 0xffffffff) != 0
-+ && ((INTVAL (operands[1]) & 0x80ffffff) == 0
-+ || (INTVAL (operands[1]) & 0x80ffffff) == 0x80ffffff))"
-+ [(set (match_dup 0)
-+ (bswap:SI (match_dup 2)))]
-+ "{
-+ operands[2] = GEN_INT (INTVAL (operands[1]) >> 24);
-+ }")
-+
-+; If this is a write of a constant to memory look to see if we can usefully
-+; transform this into 2 smaller writes.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "memory_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "! satisfies_constraint_I (operands[1])
-+ && ubicom32_legitimate_address_p (HImode, plus_constant (XEXP (operands[0], 0), 2), 1)"
-+ [(set (match_dup 4) (match_dup 2))
-+ (set (match_dup 5) (match_dup 3))]
-+ "{
-+ rtx low_hword_addr;
-+
-+ operands[2] = gen_highpart_mode (HImode, SImode, operands[1]);
-+ operands[3] = gen_lowpart (HImode, operands[1]);
-+
-+ operands[4] = gen_rtx_MEM (HImode, XEXP (operands[0], 0));
-+ MEM_COPY_ATTRIBUTES (operands[4], operands[0]);
-+
-+ low_hword_addr = plus_constant (XEXP (operands[0], 0), 2);
-+ operands[5] = gen_rtx_MEM (HImode, low_hword_addr);
-+ MEM_COPY_ATTRIBUTES (operands[5], operands[0]);
-+ }")
-+
-+; If we're writing memory and we've not found a better way to do this then
-+; try loading into a D register and then copying to memory. This will
-+; perform the fewest possible memory read/writes.
-+;
-+(define_peephole2
-+ [(match_scratch:SI 2 "d")
-+ (set (match_operand:SI 0 "memory_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "! satisfies_constraint_I (operands[1])"
-+ [(set (match_dup 2) (match_dup 1))
-+ (set (match_dup 0) (match_dup 2))]
-+ "")
-+
-+; If we're not dependent on the state of the condition codes we can construct
-+; constants of value (2^n - 1) by using an lsr.4.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(exact_log2 (INTVAL (operands[1]) + 1) > 14
-+ && peep2_regno_dead_p (0, CC_REGNO))"
-+ [(parallel
-+ [(set (match_dup 0)
-+ (lshiftrt:SI (const_int -1)
-+ (match_dup 2)))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "{
-+ operands[2] = GEN_INT (32 - exact_log2 (INTVAL (operands[1]) + 1));
-+ }")
-+
-+; If we're not dependent on the state of the condition codes we can construct
-+; constants of value (2^n - 1) by using an lsr.4.
-+;
-+(define_peephole2
-+ [(match_scratch:SI 2 "d")
-+ (set (match_operand:SI 0 "nonimmediate_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(exact_log2 (INTVAL (operands[1]) + 1) > 14
-+ && peep2_regno_dead_p (0, CC_REGNO))"
-+ [(parallel
-+ [(set (match_dup 2)
-+ (lshiftrt:SI (const_int -1)
-+ (match_dup 3)))
-+ (clobber (reg:CC CC_REGNO))])
-+ (set (match_dup 0)
-+ (match_dup 2))]
-+ "{
-+ operands[3] = GEN_INT (32 - exact_log2 (INTVAL (operands[1]) + 1));
-+ }")
-+
-+; If we're not dependent on the state of the condition codes we can construct
-+; some other constants by using an lsl.4 to shift 7 bits left by some
-+; constant.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(ubicom32_shiftable_const_int (INTVAL (operands[1]))
-+ && peep2_regno_dead_p (0, CC_REGNO))"
-+ [(parallel
-+ [(set (match_dup 0)
-+ (ashift:SI (match_dup 2)
-+ (match_dup 3)))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "{
-+ int shift = ubicom32_shiftable_const_int (INTVAL (operands[1]));
-+ operands[2] = GEN_INT (INTVAL (operands[1]) >> shift);
-+ operands[3] = GEN_INT (shift);
-+ }")
-+
-+; If we're not dependent on the state of the condition codes we can construct
-+; some other constants by using an lsl.4 to shift 7 bits left by some
-+; constant.
-+;
-+(define_peephole2
-+ [(match_scratch:SI 2 "d")
-+ (set (match_operand:SI 0 "nonimmediate_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(ubicom32_shiftable_const_int (INTVAL (operands[1]))
-+ && peep2_regno_dead_p (0, CC_REGNO))"
-+ [(parallel
-+ [(set (match_dup 2)
-+ (ashift:SI (match_dup 3)
-+ (match_dup 4)))
-+ (clobber (reg:CC CC_REGNO))])
-+ (set (match_dup 0)
-+ (match_dup 2))]
-+ "{
-+ int shift = ubicom32_shiftable_const_int (INTVAL (operands[1]));
-+ operands[3] = GEN_INT (INTVAL (operands[1]) >> shift);
-+ operands[4] = GEN_INT (shift);
-+ }")
-+
-+; For some 16-bit unsigned constants that have bit 15 set we can use
-+; swapb.2!
-+;
-+; Note that the movsi code emits the same sequence but by using a peephole2
-+; we split the pattern early enough to allow instruction scheduling to
-+; occur.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(ubicom32_v4
-+ && (INTVAL (operands[1]) & 0xffff80ff) == 0x80ff)"
-+ [(set (match_dup 0)
-+ (zero_extend:SI (bswap:HI (match_dup 2))))]
-+ "{
-+ HOST_WIDE_INT i = INTVAL (operands[1]) >> 8;
-+ if (i >= 0x80)
-+ i -= 0x100;
-+ operands[2] = GEN_INT (i);
-+ }")
-+
-+; In general for a 16-bit unsigned constant that has bit 15 set
-+; then we need a movei/move.2 pair unless we can represent it
-+; via just a move.2.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(INTVAL (operands[1]) & 0xffff8000) == 0x8000
-+ && (INTVAL (operands[1]) & 0xffff) < 0xff80"
-+ [(set (match_dup 2)
-+ (match_dup 1))
-+ (set (match_dup 0)
-+ (zero_extend:SI (match_dup 2)))]
-+ "{
-+ operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));
-+ }")
-+
-+; If we're not dependent on the state of the condition codes we can construct
-+; 32-bit constants that have bits 16 through 31 set to arbitrary values
-+; and have bits 0 through 15 set to something representable as a default
-+; source-1 immediate - we use movei/shmrg.2
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(((INTVAL (operands[1]) >= 0x8000
-+ && INTVAL (operands[1]) < 0xff80)
-+ || INTVAL (operands[1]) >= 0x10000
-+ || INTVAL (operands[1]) < -0x8000)
-+ && ((INTVAL (operands[1]) & 0xffff) >= 0xff80
-+ || (INTVAL (operands[1]) & 0xffff) < 0x80)
-+ && peep2_regno_dead_p (0, CC_REGNO))"
-+ [(set (match_dup 0)
-+ (match_dup 2))
-+ (parallel
-+ [(set (match_dup 0)
-+ (ior:SI
-+ (ashift:SI (match_dup 0)
-+ (const_int 16))
-+ (zero_extend:SI
-+ (match_dup 3))))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "{
-+ operands[2] = gen_highpart_mode (HImode, SImode, operands[1]);
-+ operands[3] = gen_lowpart (HImode, operands[1]);
-+ }")
-+
-+; Exactly the same as the peephole2 preceding except that this targets a
-+; general register instead of D register. Hopefully the later optimization
-+; passes will notice that the value ended up in a D register first here
-+; and eliminate away the other register!
-+;
-+(define_peephole2
-+ [(match_scratch:SI 2 "d")
-+ (set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(((INTVAL (operands[1]) >= 0x8000
-+ && INTVAL (operands[1]) < 0xff80)
-+ || INTVAL (operands[1]) >= 0x10000
-+ || INTVAL (operands[1]) < -0x8000)
-+ && ((INTVAL (operands[1]) & 0xffff) >= 0xff80
-+ || (INTVAL (operands[1]) & 0xffff) < 0x80)
-+ && peep2_regno_dead_p (0, CC_REGNO))"
-+ [(set (match_dup 2)
-+ (match_dup 3))
-+ (parallel
-+ [(set (match_dup 2)
-+ (ior:SI
-+ (ashift:SI (match_dup 2)
-+ (const_int 16))
-+ (zero_extend:SI
-+ (match_dup 4))))
-+ (clobber (reg:CC CC_REGNO))])
-+ (set (match_dup 0)
-+ (match_dup 2))]
-+ "{
-+ operands[3] = gen_highpart_mode (HImode, SImode, operands[1]);
-+ operands[4] = gen_lowpart (HImode, operands[1]);
-+ }")
-+
-+; If we have a load of a large integer constant which does not have bit 31
-+; set and we have a spare A reg then construct it with a moveai/lea.1 pair
-+; instead. This avoids constructing it in 3 instructions on the stack.
-+;
-+; Note that we have to be careful not to match anything that matches
-+; something we can do in a single instruction! There aren't many such
-+; constants but there are some.
-+;
-+(define_peephole2
-+ [(match_scratch:SI 2 "a")
-+ (set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(! (INTVAL (operands[1]) & 0x80000000)
-+ && ((INTVAL (operands[1]) >= 0x8000
-+ && INTVAL (operands[1]) < 0xff80)
-+ || INTVAL (operands[1]) >= 0x10000))"
-+ [(set (match_dup 2)
-+ (match_dup 3))
-+ (set (match_dup 0)
-+ (plus:SI (match_dup 2)
-+ (match_dup 4)))]
-+ "{
-+ HOST_WIDE_INT i = INTVAL (operands[1]);
-+ operands[3] = GEN_INT (i & 0xffffff80);
-+ operands[4] = GEN_INT (i & 0x7f);
-+ }")
-+
-+; If we're not dependent on the state of the condition codes we can construct
-+; a 32-bit constant with a movei/movei/shmrg.2 sequence if possible.
-+;
-+(define_peephole2
-+ [(match_scratch:HI 2 "d")
-+ (set (match_operand:SI 0 "ubicom32_data_register_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))
-+ (match_dup 2)]
-+ "(INTVAL (operands[1]) & 0x80000000
-+ && INTVAL (operands[1]) < -0x8000
-+ && peep2_regno_dead_p (0, CC_REGNO))"
-+ [(set (match_dup 0)
-+ (match_dup 3))
-+ (set (match_dup 2)
-+ (match_dup 4))
-+ (parallel
-+ [(set (match_dup 0)
-+ (ior:SI
-+ (ashift:SI (match_dup 0)
-+ (const_int 16))
-+ (zero_extend:SI
-+ (match_dup 2))))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "{
-+ operands[3] = gen_highpart_mode (HImode, SImode, operands[1]);
-+ operands[4] = gen_lowpart (HImode, operands[1]);
-+ }")
-+
-+; Exactly the same as the peephole2 preceding except that this targets a
-+; general register instead of D register. Hopefully the later optimization
-+; passes will notice that the value ended up in a D register first here
-+; and eliminate away the other register!
-+;
-+(define_peephole2
-+ [(match_scratch:SI 2 "d")
-+ (match_scratch:HI 3 "d")
-+ (set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))
-+ (match_dup 3)]
-+ "(INTVAL (operands[1]) & 0x80000000
-+ && INTVAL (operands[1]) < -0x8000
-+ && peep2_regno_dead_p (0, CC_REGNO))"
-+ [(set (match_dup 2)
-+ (match_dup 4))
-+ (set (match_dup 3)
-+ (match_dup 5))
-+ (parallel
-+ [(set (match_dup 2)
-+ (ior:SI
-+ (ashift:SI (match_dup 2)
-+ (const_int 16))
-+ (zero_extend:SI
-+ (match_dup 3))))
-+ (clobber (reg:CC CC_REGNO))])
-+ (set (match_dup 0)
-+ (match_dup 2))]
-+ "{
-+ operands[4] = gen_highpart_mode (HImode, SImode, operands[1]);
-+ operands[5] = gen_lowpart (HImode, operands[1]);
-+ }")
-+
-+(define_insn "movsi_fdpic_got_offset"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (match_operand:SI 1 "ubicom32_fdpic_got_offset_operand" "Y"))]
-+ ""
-+ "movei\\t%0, %1")
-+
-+; The explicit MEM inside the UNSPEC prevents the compiler from moving
-+; the load before a branch after a NULL test, or before a store that
-+; initializes a function descriptor.
-+
-+(define_insn_and_split "load_fdpic_funcdesc"
-+ [(set (match_operand:SI 0 "ubicom32_address_register_operand" "=a")
-+ (unspec_volatile:SI [(mem:SI (match_operand:SI 1 "address_operand" "p"))]
-+ UNSPEC_VOLATILE_LOAD_FDPIC_FUNCDESC))]
-+ ""
-+ "#"
-+ "reload_completed"
-+ [(set (match_dup 0)
-+ (mem:SI (match_dup 1)))])
-+
-+; Combiner-generated 32-bit move with the zero flag set accordingly.
-+;
-+(define_insn "movsi_ccwzn"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:SI 0 "nonimmediate_operand" "rm, d")
-+ (const_int 0)))
-+ (set (match_operand:SI 1 "nonimmediate_operand" "=d,rm")
-+ (match_dup 0))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "@
-+ lsl.4\\t%1, %0, #0
-+ add.4\\t%1, #0, %0")
-+
-+; Combiner-generated 32-bit move with all flags set accordingly.
-+;
-+(define_insn "movsi_ccw"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:SI 0 "ubicom32_data_register_operand" "d")
-+ (const_int 0)))
-+ (set (match_operand:SI 1 "nonimmediate_operand" "=rm")
-+ (match_dup 0))]
-+ "ubicom32_match_cc_mode(insn, CCWmode)"
-+ "add.4\\t%1, #0, %0")
-+
-+; Combine isn't very good at merging some types of operations so we
-+; have to make do with a peephole. It's not as effective but it's better
-+; than doing nothing.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "")
-+ (match_operand:SI 1 "nonimmediate_operand" ""))
-+ (parallel
-+ [(set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (match_operator 3 "ubicom32_compare_operator"
-+ [(match_dup 0)
-+ (const_int 0)]))
-+ (clobber (match_operand:SI 4 "ubicom32_data_register_operand" ""))])]
-+ "(GET_MODE (operands[2]) == CCWZNmode
-+ || GET_MODE (operands[2]) == CCWZmode)"
-+ [(parallel
-+ [(set (match_dup 2)
-+ (match_op_dup 3
-+ [(match_dup 1)
-+ (const_int 0)]))
-+ (set (match_dup 0)
-+ (match_dup 1))])]
-+ "")
-+
-+; Combine isn't very good at merging some types of operations so we
-+; have to make do with a peephole. It's not as effective but it's better
-+; than doing nothing.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
-+ (match_operand:SI 1 "ubicom32_data_register_operand" ""))
-+ (parallel
-+ [(set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (match_operator 3 "ubicom32_compare_operator"
-+ [(match_dup 1)
-+ (const_int 0)]))
-+ (clobber (match_operand:SI 4 "ubicom32_data_register_operand" ""))])]
-+ "(GET_MODE (operands[2]) == CCWZNmode
-+ || GET_MODE (operands[2]) == CCWZmode)"
-+ [(parallel
-+ [(set (match_dup 2)
-+ (match_op_dup 3
-+ [(match_dup 1)
-+ (const_int 0)]))
-+ (set (match_dup 0)
-+ (match_dup 1))])]
-+ "")
-+
-+; Combine isn't very good at merging some types of operations so we
-+; have to make do with a peephole. It's not as effective but it's better
-+; than doing nothing.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "nonimmediate_operand" ""))
-+ (parallel
-+ [(set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (match_operator 3 "ubicom32_compare_operator"
-+ [(match_dup 0)
-+ (const_int 0)]))
-+ (set (match_operand:SI 4 "ubicom32_data_register_operand" "")
-+ (match_dup 0))])]
-+ "(peep2_reg_dead_p (2, operands[0])
-+ && (GET_MODE (operands[2]) == CCWZNmode
-+ || GET_MODE (operands[2]) == CCWZmode))"
-+ [(parallel
-+ [(set (match_dup 2)
-+ (match_op_dup 3
-+ [(match_dup 1)
-+ (const_int 0)]))
-+ (set (match_dup 4)
-+ (match_dup 1))])]
-+ "")
-+
-+; Register renaming may make a general reg into a D reg in which case
-+; we may be able to simplify a compare.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "nonimmediate_operand" ""))
-+ (parallel
-+ [(set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (match_operator 3 "ubicom32_compare_operator"
-+ [(match_dup 0)
-+ (const_int 0)]))
-+ (clobber (match_operand:SI 4 "ubicom32_data_register_operand" ""))])]
-+ "(peep2_reg_dead_p (2, operands[0])
-+ && (GET_MODE (operands[2]) == CCWZNmode
-+ || GET_MODE (operands[2]) == CCWZmode))"
-+ [(parallel
-+ [(set (match_dup 2)
-+ (match_op_dup 3
-+ [(match_dup 1)
-+ (const_int 0)]))
-+ (clobber (match_dup 4))])]
-+ "")
-+
-+(define_insn_and_split "movdi"
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
-+ (match_operand:DI 1 "general_operand" "rmi,ri"))]
-+ ""
-+ "#"
-+ "reload_completed"
-+ [(set (match_dup 2) (match_dup 3))
-+ (set (match_dup 4) (match_dup 5))]
-+ "{
-+ rtx dest_low;
-+ rtx src_low;
-+
-+ dest_low = gen_lowpart (SImode, operands[0]);
-+ src_low = gen_lowpart (SImode, operands[1]);
-+
-+ if (REG_P (operands[0])
-+ && REG_P (operands[1])
-+ && REGNO (operands[0]) < REGNO (operands[1]))
-+ {
-+ operands[2] = gen_highpart (SImode, operands[0]);
-+ operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
-+ operands[4] = dest_low;
-+ operands[5] = src_low;
-+ }
-+ else if (reg_mentioned_p (dest_low, src_low))
-+ {
-+ operands[2] = gen_highpart (SImode, operands[0]);
-+ operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
-+ operands[4] = dest_low;
-+ operands[5] = src_low;
-+ }
-+ else
-+ {
-+ operands[2] = dest_low;
-+ operands[3] = src_low;
-+ operands[4] = gen_highpart (SImode, operands[0]);
-+ operands[5] = gen_highpart_mode (SImode, DImode, operands[1]);
-+ }
-+ }"
-+ [(set_attr "length" "8")])
-+
-+; Combiner-generated 64-bit move with all flags set accordingly.
-+;
-+(define_insn "movdi_ccwzn"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:DI 0 "nonimmediate_operand" "d, m, r")
-+ (const_int 0)))
-+ (set (match_operand:DI 1 "nonimmediate_operand" "=&rm,rm,!&rm")
-+ (match_dup 0))
-+ (clobber (match_scratch:SI 2 "=X, d, d"))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "*
-+ {
-+ operands[3] = gen_lowpart (SImode, operands[0]);
-+ operands[4] = gen_lowpart (SImode, operands[1]);
-+ operands[5] = gen_highpart (SImode, operands[0]);
-+ operands[6] = gen_highpart (SImode, operands[1]);
-+
-+ if (ubicom32_data_register_operand (operands[0], VOIDmode))
-+ return \"add.4\\t%4, #0, %3\;addc\\t%6, #0, %5\";
-+
-+ return \"movei\\t%2, #0\;add.4\\t%4, %3, %2\;addc\\t%6, %5, %2\";
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_insn "movdi_ccw"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:DI 0 "nonimmediate_operand" "d, m, r")
-+ (const_int 0)))
-+ (set (match_operand:DI 1 "nonimmediate_operand" "=&rm,rm,!&rm")
-+ (match_dup 0))
-+ (clobber (match_scratch:SI 2 "=X, d, d"))]
-+ "ubicom32_match_cc_mode(insn, CCWmode)"
-+ "*
-+ {
-+ operands[3] = gen_lowpart (SImode, operands[0]);
-+ operands[4] = gen_lowpart (SImode, operands[1]);
-+ operands[5] = gen_highpart (SImode, operands[0]);
-+ operands[6] = gen_highpart (SImode, operands[1]);
-+
-+ if (ubicom32_data_register_operand (operands[0], VOIDmode))
-+ return \"add.4\\t%4, #0, %3\;addc\\t%6, #0, %5\";
-+
-+ return \"movei\\t%2, #0\;add.4\\t%4, %3, %2\;addc\\t%6, %5, %2\";
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_insn "movsf"
-+ [(set (match_operand:SF 0 "nonimmediate_operand" "=!d,*rm")
-+ (match_operand:SF 1 "ubicom32_move_operand" "rmF,rmF"))]
-+ ""
-+ "*
-+ {
-+ if (GET_CODE (operands[1]) == CONST_DOUBLE)
-+ {
-+ HOST_WIDE_INT val;
-+ REAL_VALUE_TYPE rv;
-+
-+ REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
-+ REAL_VALUE_TO_TARGET_SINGLE (rv, val);
-+
-+ ubicom32_emit_move_const_int (operands[0], GEN_INT (val));
-+ return \"\";
-+ }
-+
-+ return \"move.4\\t%0, %1\";
-+ }")
-+
-+(define_insn "zero_extendqihi2"
-+ [(set (match_operand:HI 0 "register_operand" "=r")
-+ (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
-+ ""
-+ "move.1\\t%0, %1")
-+
-+(define_insn "zero_extendqisi2"
-+ [(set (match_operand:SI 0 "register_operand" "=r")
-+ (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
-+ ""
-+ "move.1\\t%0, %1")
-+
-+(define_insn "zero_extendqisi2_ccwz_1"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "rm"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (zero_extend:SI (match_dup 1)))]
-+ "ubicom32_match_cc_mode(insn, CCWZmode)"
-+ "shmrg.1\\t%0, %1, #0")
-+
-+(define_insn "zero_extendhisi2"
-+ [(set (match_operand:SI 0 "register_operand" "=r")
-+ (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
-+ ""
-+ "move.2\\t%0, %1")
-+
-+(define_insn "zero_extendhisi2_ccwz_1"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (zero_extend:SI (match_dup 1)))]
-+ "ubicom32_match_cc_mode(insn, CCWZmode)"
-+ "shmrg.2\\t%0, %1, #0")
-+
-+(define_insn_and_split "zero_extendqidi2"
-+ [(set (match_operand:DI 0 "register_operand" "=r")
-+ (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
-+ ""
-+ "#"
-+ "reload_completed"
-+ [(set (match_dup 2)
-+ (zero_extend:SI (match_dup 1)))
-+ (set (match_dup 3)
-+ (const_int 0))]
-+ "{
-+ operands[2] = gen_lowpart (SImode, operands[0]);
-+ operands[3] = gen_highpart (SImode, operands[0]);
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_insn_and_split "zero_extendhidi2"
-+ [(set (match_operand:DI 0 "register_operand" "=r")
-+ (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
-+ ""
-+ "#"
-+ "reload_completed"
-+ [(set (match_dup 2)
-+ (zero_extend:SI (match_dup 1)))
-+ (set (match_dup 3)
-+ (const_int 0))]
-+ "{
-+ operands[2] = gen_lowpart (SImode, operands[0]);
-+ operands[3] = gen_highpart (SImode, operands[0]);
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_insn_and_split "zero_extendsidi2"
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
-+ (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
-+ ""
-+ "#"
-+ "reload_completed"
-+ [(set (match_dup 2)
-+ (match_dup 1))
-+ (set (match_dup 3)
-+ (const_int 0))]
-+ "{
-+ operands[2] = gen_lowpart (SImode, operands[0]);
-+ operands[3] = gen_highpart (SImode, operands[0]);
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_insn "extendqihi2"
-+ [(set (match_operand:HI 0 "register_operand" "=r")
-+ (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "rm")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "ext.1\\t%0, %1")
-+
-+(define_insn "extendqisi2"
-+ [(set (match_operand:SI 0 "register_operand" "=r")
-+ (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "rm")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "ext.1\\t%0, %1")
-+
-+(define_insn "extendhisi2"
-+ [(set (match_operand:SI 0 "register_operand" "=r")
-+ (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "ext.2\\t%0, %1")
-+
-+(define_insn_and_split "extendsidi2"
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "=d")
-+ (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "#"
-+ "reload_completed"
-+ [(set (match_dup 2)
-+ (match_dup 1))
-+ (parallel
-+ [(set (match_dup 3)
-+ (ashiftrt:SI (match_dup 2)
-+ (const_int 31)))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "{
-+ operands[2] = gen_lowpart (SImode, operands[0]);
-+ operands[3] = gen_highpart (SImode, operands[0]);
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_insn "bswaphi"
-+ [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
-+ (bswap:HI (match_operand:HI 1 "ubicom32_arith_operand" "rmI")))]
-+ "(ubicom32_v4)"
-+ "swapb.2\\t%0, %1");
-+
-+(define_insn "bswaphisi"
-+ [(set (match_operand:SI 0 "register_operand" "=r")
-+ (zero_extend:SI
-+ (bswap:HI (match_operand:HI 1 "ubicom32_arith_operand" "rmI"))))]
-+ "(ubicom32_v4)"
-+ "swapb.2\\t%0, %1");
-+
-+(define_insn "bswapsi"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (bswap:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")))]
-+ "(ubicom32_v4)"
-+ "swapb.4\\t%0, %1");
-+
-+(define_insn "tstqi_ext1"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:QI 0 "nonimmediate_operand" "rm")
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "ext.1\\t#0, %0")
-+
-+(define_expand "cmpqi"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:QI 0 "ubicom32_arith_operand" "")
-+ (match_operand:QI 1 "ubicom32_data_register_operand" "")))]
-+ "(ubicom32_v4)"
-+ "{
-+ ubicom32_compare_op0 = operands[0];
-+ ubicom32_compare_op1 = operands[1];
-+ DONE;
-+ }")
-+
-+(define_insn "sub1_ccs"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:QI 0 "ubicom32_arith_operand" "rmI")
-+ (match_operand:QI 1 "ubicom32_data_register_operand" "d")))]
-+ "(ubicom32_v4)"
-+ "sub.1\\t#0, %0, %1")
-+
-+; If we're testing for equality we don't have to worry about reversing conditions.
-+;
-+(define_insn "sub1_ccsz_1"
-+ [(set (reg:CCSZ CC_REGNO)
-+ (compare:CCSZ (match_operand:QI 0 "nonimmediate_operand" "rm")
-+ (match_operand:QI 1 "ubicom32_data_register_operand" "d")))]
-+ "(ubicom32_v4)"
-+ "sub.1\\t#0, %0, %1")
-+
-+(define_insn "sub1_ccsz_2"
-+ [(set (reg:CCSZ CC_REGNO)
-+ (compare:CCSZ (match_operand:QI 0 "ubicom32_data_register_operand" "d")
-+ (match_operand:QI 1 "ubicom32_arith_operand" "rmI")))]
-+ "(ubicom32_v4)"
-+ "sub.1\\t#0, %1, %0")
-+
-+; When the combiner runs it doesn't have any insight into whether or not an argument
-+; to a compare is spilled to the stack and therefore can't swap the comparison in
-+; an attempt to use sub.1 more effectively. We peephole this case here.
-+;
-+(define_peephole2
-+ [(set (match_operand:QI 0 "register_operand" "")
-+ (match_operand:QI 1 "ubicom32_arith_operand" ""))
-+ (set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (compare (match_operand:QI 3 "ubicom32_data_register_operand" "")
-+ (match_dup 0)))
-+ (set (pc)
-+ (if_then_else (match_operator 4 "comparison_operator"
-+ [(match_dup 2)
-+ (const_int 0)])
-+ (label_ref (match_operand 5 "" ""))
-+ (pc)))]
-+ "(peep2_reg_dead_p (2, operands[0])
-+ && peep2_regno_dead_p (3, CC_REGNO))"
-+ [(set (match_dup 2)
-+ (compare (match_dup 1)
-+ (match_dup 3)))
-+ (set (pc)
-+ (if_then_else (match_op_dup 6
-+ [(match_dup 2)
-+ (const_int 0)])
-+ (label_ref (match_dup 5))
-+ (pc)))]
-+ "{
-+ rtx cc_reg;
-+
-+ cc_reg = gen_rtx_REG (GET_MODE (operands[2]), CC_REGNO);
-+ operands[6] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[4])),
-+ GET_MODE (operands[4]),
-+ cc_reg,
-+ const0_rtx);
-+ }")
-+
-+(define_insn "tsthi_ext2"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:HI 0 "nonimmediate_operand" "rm")
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "ext.2\\t#0, %0")
-+
-+(define_expand "cmphi"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:HI 0 "ubicom32_arith_operand" "")
-+ (match_operand:HI 1 "ubicom32_compare_operand" "")))]
-+ ""
-+ "{
-+ do
-+ {
-+ /* Is this a cmpi? */
-+ if (CONST_INT_P (operands[1]))
-+ break;
-+
-+ /* Must be a sub.2 - if necessary copy an operand into a reg. */
-+ if (! ubicom32_data_register_operand (operands[1], HImode))
-+ operands[1] = copy_to_mode_reg (HImode, operands[1]);
-+ }
-+ while (0);
-+
-+ ubicom32_compare_op0 = operands[0];
-+ ubicom32_compare_op1 = operands[1];
-+ DONE;
-+ }")
-+
-+(define_insn "cmpi"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:HI 0 "nonimmediate_operand" "rm")
-+ (match_operand 1 "const_int_operand" "N")))]
-+ ""
-+ "cmpi\\t%0, %1")
-+
-+(define_insn "sub2_ccs"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:HI 0 "ubicom32_arith_operand" "rmI")
-+ (match_operand:HI 1 "ubicom32_data_register_operand" "d")))]
-+ ""
-+ "sub.2\\t#0, %0, %1")
-+
-+; If we're testing for equality we don't have to worry about reversing conditions.
-+;
-+(define_insn "sub2_ccsz_1"
-+ [(set (reg:CCSZ CC_REGNO)
-+ (compare:CCSZ (match_operand:HI 0 "nonimmediate_operand" "rm")
-+ (match_operand:HI 1 "ubicom32_data_register_operand" "d")))]
-+ ""
-+ "sub.2\\t#0, %0, %1")
-+
-+(define_insn "sub2_ccsz_2"
-+ [(set (reg:CCSZ CC_REGNO)
-+ (compare:CCSZ (match_operand:HI 0 "ubicom32_data_register_operand" "d")
-+ (match_operand:HI 1 "ubicom32_arith_operand" "rmI")))]
-+ ""
-+ "sub.2\\t#0, %1, %0")
-+
-+; When the combiner runs it doesn't have any insight into whether or not an argument
-+; to a compare is spilled to the stack and therefore can't swap the comparison in
-+; an attempt to use sub.2 more effectively. We peephole this case here.
-+;
-+(define_peephole2
-+ [(set (match_operand:HI 0 "register_operand" "")
-+ (match_operand:HI 1 "ubicom32_arith_operand" ""))
-+ (set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (compare (match_operand:HI 3 "ubicom32_data_register_operand" "")
-+ (match_dup 0)))
-+ (set (pc)
-+ (if_then_else (match_operator 4 "comparison_operator"
-+ [(match_dup 2)
-+ (const_int 0)])
-+ (label_ref (match_operand 5 "" ""))
-+ (pc)))]
-+ "(peep2_reg_dead_p (2, operands[0])
-+ && peep2_regno_dead_p (3, CC_REGNO))"
-+ [(set (match_dup 2)
-+ (compare (match_dup 1)
-+ (match_dup 3)))
-+ (set (pc)
-+ (if_then_else (match_op_dup 6
-+ [(match_dup 2)
-+ (const_int 0)])
-+ (label_ref (match_dup 5))
-+ (pc)))]
-+ "{
-+ rtx cc_reg;
-+
-+ cc_reg = gen_rtx_REG (GET_MODE (operands[2]), CC_REGNO);
-+ operands[6] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[4])),
-+ GET_MODE (operands[4]),
-+ cc_reg,
-+ const0_rtx);
-+ }")
-+
-+(define_insn_and_split "tstsi_lsl4"
-+ [(set (match_operand 0 "ubicom32_cc_register_operand" "=r")
-+ (match_operator 1 "ubicom32_compare_operator"
-+ [(match_operand:SI 2 "nonimmediate_operand" "rm")
-+ (const_int 0)]))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "#"
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ [(parallel
-+ [(set (match_dup 0)
-+ (match_op_dup 1
-+ [(match_dup 2)
-+ (const_int 0)]))
-+ (clobber (match_dup 3))])]
-+ "{
-+ operands[3] = gen_reg_rtx (SImode);
-+ }")
-+
-+(define_insn "tstsi_lsl4_d"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:SI 0 "nonimmediate_operand" "rm")
-+ (const_int 0)))
-+ (clobber (match_operand:SI 1 "ubicom32_data_register_operand" "=d"))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "lsl.4\\t%1, %0, #0")
-+
-+; Comparison for equality with -1.
-+;
-+(define_insn "cmpsi_not4_ccwz"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:SI 0 "nonimmediate_operand" "rm")
-+ (const_int -1)))]
-+ "ubicom32_match_cc_mode(insn, CCWZmode)"
-+ "not.4\\t#0, %0")
-+
-+(define_expand "cmpsi"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:SI 0 "ubicom32_arith_operand" "")
-+ (match_operand:SI 1 "ubicom32_compare_operand" "")))]
-+ ""
-+ "{
-+ do
-+ {
-+ /* Is this a cmpi? We can't take a memory address as cmpi takes
-+ 16-bit operands. */
-+ if (register_operand (operands[0], SImode)
-+ && CONST_INT_P (operands[1])
-+ && satisfies_constraint_N (operands[1]))
-+ break;
-+
-+ /* Must be a sub.4 - if necessary copy an operand into a reg. */
-+ if (! ubicom32_data_register_operand (operands[1], SImode))
-+ operands[1] = copy_to_mode_reg (SImode, operands[1]);
-+ }
-+ while (0);
-+
-+ ubicom32_compare_op0 = operands[0];
-+ ubicom32_compare_op1 = operands[1];
-+ DONE;
-+ }")
-+
-+(define_insn "cmpsi_cmpi"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:SI 0 "register_operand" "r")
-+ (match_operand 1 "const_int_operand" "N")))]
-+ "(satisfies_constraint_N (operands[1]))"
-+ "cmpi\\t%0, %1")
-+
-+(define_insn "cmpsi_sub4"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:SI 0 "ubicom32_arith_operand" "rmI")
-+ (match_operand:SI 1 "ubicom32_data_register_operand" "d")))]
-+ ""
-+ "sub.4\\t#0, %0, %1")
-+
-+; If we're testing for equality we don't have to worry about reversing conditions.
-+;
-+(define_insn "cmpsi_sub4_ccwz_1"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:SI 0 "nonimmediate_operand" "rm")
-+ (match_operand:SI 1 "ubicom32_data_register_operand" "d")))]
-+ "ubicom32_match_cc_mode(insn, CCWZmode)"
-+ "sub.4\\t#0, %0, %1")
-+
-+(define_insn "cmpsi_sub4_ccwz_2"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:SI 0 "ubicom32_data_register_operand" "d")
-+ (match_operand:SI 1 "nonimmediate_operand" "rm")))]
-+ "ubicom32_match_cc_mode(insn, CCWZmode)"
-+ "sub.4\\t#0, %1, %0")
-+
-+; When the combiner runs it doesn't have any insight into whether or not an argument
-+; to a compare is spilled to the stack and therefore can't swap the comparison in
-+; an attempt to use sub.4 more effectively. We peephole this case here.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "ubicom32_arith_operand" ""))
-+ (set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (compare (match_operand:SI 3 "ubicom32_data_register_operand" "")
-+ (match_dup 0)))
-+ (set (pc)
-+ (if_then_else (match_operator 4 "comparison_operator"
-+ [(match_dup 2)
-+ (const_int 0)])
-+ (label_ref (match_operand 5 "" ""))
-+ (pc)))]
-+ "(peep2_reg_dead_p (2, operands[0])
-+ && peep2_regno_dead_p (3, CC_REGNO))"
-+ [(set (match_dup 2)
-+ (compare (match_dup 1)
-+ (match_dup 3)))
-+ (set (pc)
-+ (if_then_else (match_op_dup 6
-+ [(match_dup 2)
-+ (const_int 0)])
-+ (label_ref (match_dup 5))
-+ (pc)))]
-+ "{
-+ rtx cc_reg;
-+
-+ cc_reg = gen_rtx_REG (GET_MODE (operands[2]), CC_REGNO);
-+ operands[6] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[4])),
-+ GET_MODE (operands[4]),
-+ cc_reg,
-+ const0_rtx);
-+ }")
-+
-+(define_insn_and_split "tstdi_or4"
-+ [(set (reg:CCWZ CC_REGNO)
-+ (compare:CCWZ (match_operand:DI 0 "nonimmediate_operand" "rm")
-+ (const_int 0)))]
-+ ""
-+ "#"
-+ ""
-+ [(parallel
-+ [(set (reg:CCWZ CC_REGNO)
-+ (compare:CCWZ (match_dup 0)
-+ (const_int 0)))
-+ (clobber (match_dup 1))])]
-+ "{
-+ operands[1] = gen_reg_rtx (SImode);
-+ }")
-+
-+(define_insn "tstdi_or4_d"
-+ [(set (reg:CCWZ CC_REGNO)
-+ (compare:CCWZ (match_operand:DI 0 "nonimmediate_operand" "rm")
-+ (const_int 0)))
-+ (clobber (match_operand:SI 1 "ubicom32_data_register_operand" "=d"))]
-+ ""
-+ "*
-+ {
-+ operands[2] = gen_lowpart (SImode, operands[0]);
-+ operands[3] = gen_highpart_mode (SImode, DImode, operands[0]);
-+
-+ if (ubicom32_data_register_operand (operands[0], GET_MODE (operands[0])))
-+ return \"or.4\\t#0, %2, %3\";
-+
-+ return \"move.4\\t%1, %2\;or.4\\t%1, %3, %1\";
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_expand "cmpdi"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:DI 0 "ubicom32_arith_operand" "")
-+ (match_operand:DI 1 "ubicom32_data_register_operand" "")))]
-+ ""
-+ "{
-+ ubicom32_compare_op0 = operands[0];
-+ ubicom32_compare_op1 = operands[1];
-+ DONE;
-+ }")
-+
-+(define_insn "cmpdi_sub4subc"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:DI 0 "ubicom32_arith_operand" "rmI")
-+ (match_operand:DI 1 "ubicom32_data_register_operand" "d")))]
-+ ""
-+ "*
-+ {
-+ operands[2] = gen_lowpart (SImode, operands[0]);
-+ operands[3] = gen_lowpart (SImode, operands[1]);
-+ operands[4] = gen_highpart_mode (SImode, DImode, operands[0]);
-+ operands[5] = gen_highpart_mode (SImode, DImode, operands[1]);
-+
-+ return \"sub.4\\t#0, %2, %3\;subc\\t#0, %4, %5\";
-+ }"
-+ [(set_attr "length" "8")])
-+
-+; When the combiner runs it doesn't have any insight into whether or not an argument
-+; to a compare is spilled to the stack and therefore can't swap the comparison in
-+; an attempt to use sub.4/subc more effectively. We peephole this case here.
-+;
-+(define_peephole2
-+ [(set (match_operand:DI 0 "register_operand" "")
-+ (match_operand:DI 1 "ubicom32_arith_operand" ""))
-+ (set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (compare (match_operand:DI 3 "ubicom32_data_register_operand" "")
-+ (match_dup 0)))
-+ (set (pc)
-+ (if_then_else (match_operator 4 "comparison_operator"
-+ [(match_dup 2)
-+ (const_int 0)])
-+ (label_ref (match_operand 5 "" ""))
-+ (pc)))]
-+ "(peep2_reg_dead_p (2, operands[0])
-+ && peep2_regno_dead_p (3, CC_REGNO))"
-+ [(set (match_dup 2)
-+ (compare (match_dup 1)
-+ (match_dup 3)))
-+ (set (pc)
-+ (if_then_else (match_op_dup 6
-+ [(match_dup 2)
-+ (const_int 0)])
-+ (label_ref (match_dup 5))
-+ (pc)))]
-+ "{
-+ rtx cc_reg;
-+
-+ cc_reg = gen_rtx_REG (GET_MODE (operands[2]), CC_REGNO);
-+ operands[6] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[4])),
-+ GET_MODE (operands[4]),
-+ cc_reg,
-+ const0_rtx);
-+ }")
-+
-+(define_insn "btst"
-+ [(set (reg:CCWZ CC_REGNO)
-+ (compare:CCWZ
-+ (zero_extract:SI
-+ (match_operand:SI 0 "nonimmediate_operand" "rm")
-+ (const_int 1)
-+ (match_operand:SI 1 "ubicom32_arith_operand" "dM"))
-+ (const_int 0)))]
-+ ""
-+ "btst\\t%0, %1")
-+
-+(define_insn "bfextu_ccwz_null"
-+ [(set (reg:CCWZ CC_REGNO)
-+ (compare:CCWZ
-+ (zero_extract:SI
-+ (match_operand:SI 0 "nonimmediate_operand" "rm")
-+ (match_operand 1 "const_int_operand" "M")
-+ (const_int 0))
-+ (const_int 0)))
-+ (clobber (match_scratch:SI 2 "=d"))]
-+ ""
-+ "bfextu\\t%2, %0, %1")
-+
-+(define_expand "addqi3"
-+ [(parallel
-+ [(set (match_operand:QI 0 "memory_operand" "")
-+ (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
-+ (match_operand:QI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "(ubicom32_v4)"
-+ "{
-+ if (!memory_operand (operands[0], QImode))
-+ FAIL;
-+
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (QImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (QImode, operands[2]);
-+ }")
-+
-+(define_insn "addqi3_add1"
-+ [(set (match_operand:QI 0 "memory_operand" "=m, m")
-+ (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:QI 2 "ubicom32_arith_operand" "rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4)"
-+ "@
-+ add.1\\t%0, %2, %1
-+ add.1\\t%0, %1, %2")
-+
-+(define_insn "addqi3_add1_ccszn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (neg:QI (match_operand:QI 0 "nonimmediate_operand" "%d,rm"))
-+ (match_operand:QI 1 "ubicom32_arith_operand" "rmI, d")))]
-+ "(ubicom32_v4
-+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
-+ "@
-+ add.1\\t#0, %1, %0
-+ add.1\\t#0, %0, %1")
-+
-+(define_expand "addhi3"
-+ [(parallel
-+ [(set (match_operand:HI 0 "memory_operand" "")
-+ (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
-+ (match_operand:HI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ ""
-+ "{
-+ if (!memory_operand (operands[0], HImode))
-+ FAIL;
-+
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (HImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (HImode, operands[2]);
-+ }")
-+
-+(define_insn "addhi3_add2"
-+ [(set (match_operand:HI 0 "memory_operand" "=m, m")
-+ (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:HI 2 "ubicom32_arith_operand" "rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "@
-+ add.2\\t%0, %2, %1
-+ add.2\\t%0, %1, %2")
-+
-+(define_insn "addhi3_add2_ccszn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (neg:HI (match_operand:HI 0 "nonimmediate_operand" "%d,rm"))
-+ (match_operand:HI 1 "ubicom32_arith_operand" "rmI, d")))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "@
-+ add.2\\t#0, %1, %0
-+ add.2\\t#0, %0, %1")
-+
-+(define_expand "addsi3"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
-+ (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
-+ (match_operand:SI 2 "ubicom32_move_operand" "")))]
-+ ""
-+ "{
-+ ubicom32_expand_addsi3 (operands);
-+ DONE;
-+ }")
-+
-+; We start with an instruction pattern that can do all sorts of interesting
-+; things but we split out any uses of lea or pdec instructions because
-+; those instructions don't clobber the condition codes.
-+;
-+(define_insn_and_split "addsi3_1"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm,rm,rm,rm, rm,rm")
-+ (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%a, a, a, a, a, d,rm")
-+ (match_operand:SI 2 "ubicom32_move_operand" "L, K, J, P, d,rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "@
-+ #
-+ #
-+ #
-+ #
-+ #
-+ add.4\\t%0, %2, %1
-+ add.4\\t%0, %1, %2"
-+ "(reload_completed
-+ && ubicom32_address_register_operand (operands[1], GET_MODE (operands[1])))"
-+ [(set (match_dup 0)
-+ (plus:SI (match_dup 1)
-+ (match_dup 2)))]
-+ ""
-+)
-+
-+(define_insn "addsi3_1_ccwzn"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
-+ (plus:SI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "@
-+ add.4\\t%0, %2, %1
-+ add.4\\t%0, %1, %2")
-+
-+(define_insn "addsi3_1_ccwzn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (neg:SI (match_operand:SI 0 "nonimmediate_operand" "%d,rm"))
-+ (match_operand:SI 1 "ubicom32_arith_operand" "rmI, d")))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "@
-+ add.4\\t#0, %1, %0
-+ add.4\\t#0, %0, %1")
-+
-+(define_insn_and_split "addsi3_2"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm,rm,rm,rm,rm")
-+ (plus:SI (match_operand:SI 1 "ubicom32_address_register_operand" "%a, a, a, a, a, a")
-+ (match_operand:SI 2 "ubicom32_move_operand" "L, K, J, P, d, n")))]
-+ ""
-+ "@
-+ lea.4\\t%0, %E2(%1)
-+ lea.2\\t%0, %E2(%1)
-+ lea.1\\t%0, %E2(%1)
-+ pdec\\t%0, %n2(%1)
-+ lea.1\\t%0, (%1,%2)
-+ #"
-+ "(reload_completed
-+ && ! satisfies_constraint_L (operands[2])
-+ && ! satisfies_constraint_K (operands[2])
-+ && ! satisfies_constraint_J (operands[2])
-+ && ! satisfies_constraint_P (operands[2])
-+ && ! ubicom32_data_register_operand (operands[2], GET_MODE (operands[2])))"
-+ [(set (reg:SI AUX_DATA_REGNO)
-+ (match_dup 2))
-+ (set (match_dup 0)
-+ (plus:SI (match_dup 1)
-+ (reg:SI AUX_DATA_REGNO)))]
-+ ""
-+)
-+
-+(define_insn "lea_2"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (plus:SI (mult:SI (match_operand:SI 1 "ubicom32_data_register_operand" "d")
-+ (const_int 2))
-+ (match_operand:SI 2 "ubicom32_address_register_operand" "a")))]
-+ ""
-+ "lea.2\\t%0, (%2,%1)")
-+
-+(define_insn "lea_4"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (plus:SI (mult:SI (match_operand:SI 1 "ubicom32_data_register_operand" "d")
-+ (const_int 4))
-+ (match_operand:SI 2 "ubicom32_address_register_operand" "a")))]
-+ ""
-+ "lea.4\\t%0, (%2,%1)")
-+
-+(define_expand "adddi3"
-+ [(parallel
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "")
-+ (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
-+ (match_operand:DI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ ""
-+ "{
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (DImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (DImode, operands[2]);
-+ }")
-+
-+; We construct a 64-bit add from 32-bit operations. Note that we use the
-+; & constraint to prevent overlapping registers being allocated. We do
-+; allow identical registers though as that won't break anything.
-+;
-+(define_insn "adddi3_add4addc"
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,&r,rm, d, m, m")
-+ (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%d,rm, 0, 0, d,rm")
-+ (match_operand:DI 2 "ubicom32_arith_operand" "rmI, d, d,rmI,rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "*
-+ {
-+ operands[3] = gen_lowpart (SImode, operands[0]);
-+ operands[4] = gen_lowpart (SImode, operands[1]);
-+ operands[5] = gen_lowpart (SImode, operands[2]);
-+ operands[6] = gen_highpart (SImode, operands[0]);
-+ operands[7] = gen_highpart (SImode, operands[1]);
-+ operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
-+
-+ if (ubicom32_data_register_operand (operands[2], GET_MODE (operands[2])))
-+ return \"add.4\\t%3, %4, %5\;addc\\t%6, %7, %8\";
-+
-+ return \"add.4\\t%3, %5, %4\;addc\\t%6, %8, %7\";
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_insn "adddi3_ccwz"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%d,rm, 0, 0, d,rm")
-+ (match_operand:DI 2 "ubicom32_arith_operand" "rmI, d, d,rmI,rmI, d"))
-+ (const_int 0)))
-+ (set (match_operand:DI 0 "nonimmediate_operand" "=&r,&r,rm, d, m, m")
-+ (plus:DI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "*
-+ {
-+ operands[3] = gen_lowpart (SImode, operands[0]);
-+ operands[6] = gen_highpart (SImode, operands[0]);
-+
-+ if (ubicom32_data_register_operand (operands[1], GET_MODE (operands[1])))
-+ {
-+ operands[4] = gen_lowpart (SImode, operands[1]);
-+ operands[5] = gen_lowpart (SImode, operands[2]);
-+ operands[7] = gen_highpart (SImode, operands[1]);
-+ operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
-+ }
-+ else
-+ {
-+ operands[4] = gen_lowpart (SImode, operands[2]);
-+ operands[5] = gen_lowpart (SImode, operands[1]);
-+ operands[7] = gen_highpart (SImode, operands[2]);
-+ operands[8] = gen_highpart (SImode, operands[1]);
-+ }
-+
-+ return \"add.4\\t%3, %5, %4\;addc\\t%6, %8, %7\";
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_insn "adddi3_ccwz_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (neg:DI (match_operand:DI 0 "nonimmediate_operand" "%d,rm"))
-+ (match_operand:DI 1 "ubicom32_arith_operand" "rmI, d")))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "*
-+ {
-+ if (ubicom32_data_register_operand (operands[0], GET_MODE (operands[0])))
-+ {
-+ operands[2] = gen_lowpart (SImode, operands[0]);
-+ operands[3] = gen_lowpart (SImode, operands[1]);
-+ operands[4] = gen_highpart (SImode, operands[0]);
-+ operands[5] = gen_highpart_mode (SImode, DImode, operands[1]);
-+ }
-+ else
-+ {
-+ operands[2] = gen_lowpart (SImode, operands[1]);
-+ operands[3] = gen_lowpart (SImode, operands[0]);
-+ operands[4] = gen_highpart (SImode, operands[1]);
-+ operands[5] = gen_highpart (SImode, operands[0]);
-+ }
-+
-+ return \"add.4\\t#0, %3, %2\;addc\\t#0, %5, %4\";
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_expand "subqi3"
-+ [(parallel
-+ [(set (match_operand:QI 0 "memory_operand" "")
-+ (minus:QI (match_operand:QI 1 "ubicom32_arith_operand" "")
-+ (match_operand:QI 2 "ubicom32_data_register_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "(ubicom32_v4)"
-+ "{
-+ if (!memory_operand (operands[0], QImode))
-+ FAIL;
-+ }")
-+
-+(define_insn "subqi3_sub1"
-+ [(set (match_operand:QI 0 "memory_operand" "=m")
-+ (minus:QI (match_operand:QI 1 "ubicom32_arith_operand" "rmI")
-+ (match_operand:QI 2 "ubicom32_data_register_operand" "d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4)"
-+ "sub.1\\t%0, %1, %2")
-+
-+(define_expand "subhi3"
-+ [(parallel
-+ [(set (match_operand:HI 0 "memory_operand" "")
-+ (minus:HI (match_operand:HI 1 "ubicom32_arith_operand" "")
-+ (match_operand:HI 2 "ubicom32_data_register_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "(ubicom32_v4)"
-+ "{
-+ if (!memory_operand (operands[0], HImode))
-+ FAIL;
-+ }")
-+
-+(define_insn "subhi3_sub2"
-+ [(set (match_operand:HI 0 "memory_operand" "=m")
-+ (minus:HI (match_operand:HI 1 "ubicom32_arith_operand" "rmI")
-+ (match_operand:HI 2 "ubicom32_data_register_operand" "d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "sub.2\\t%0, %1, %2")
-+
-+(define_insn "subsi3"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (minus:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")
-+ (match_operand:SI 2 "ubicom32_data_register_operand" "d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "sub.4\\t%0, %1, %2")
-+
-+(define_insn "subsi3_ccwz"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (minus:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")
-+ (match_operand:SI 2 "ubicom32_data_register_operand" "d"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (minus:SI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "sub.4\\t%0, %1, %2")
-+
-+; We construct a 64-bit add from 32-bit operations. Note that we use the
-+; & constraint to prevent overlapping registers being allocated. We do
-+; allow identical registers though as that won't break anything.
-+;
-+(define_insn "subdi3"
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,r, d, m")
-+ (minus:DI (match_operand:DI 1 "ubicom32_arith_operand" "rmI,0,rmI,rmI")
-+ (match_operand:DI 2 "ubicom32_data_register_operand" "d,d, 0, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "*
-+ {
-+ operands[3] = gen_lowpart (SImode, operands[0]);
-+ operands[4] = gen_lowpart (SImode, operands[1]);
-+ operands[5] = gen_lowpart (SImode, operands[2]);
-+ operands[6] = gen_highpart (SImode, operands[0]);
-+ operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
-+ operands[8] = gen_highpart (SImode, operands[2]);
-+
-+ return \"sub.4\\t%3, %4, %5\;subc\\t%6, %7, %8\";
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_insn "subdi3_ccwz"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (minus:DI (match_operand:DI 1 "ubicom32_arith_operand" "rmI,rmI")
-+ (match_operand:DI 2 "ubicom32_data_register_operand" "d, d"))
-+ (const_int 0)))
-+ (set (match_operand:DI 0 "nonimmediate_operand" "=&r, m")
-+ (minus:DI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "*
-+ {
-+ operands[3] = gen_lowpart (SImode, operands[0]);
-+ operands[4] = gen_lowpart (SImode, operands[1]);
-+ operands[5] = gen_lowpart (SImode, operands[2]);
-+ operands[6] = gen_highpart (SImode, operands[0]);
-+ operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
-+ operands[8] = gen_highpart (SImode, operands[2]);
-+
-+ return \"sub.4\\t%3, %4, %5\;subc\\t%6, %7, %8\";
-+ }"
-+ [(set_attr "length" "8")])
-+
-+;(define_insn "negqi2"
-+; [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
-+; (neg:QI (match_operand:QI 1 "ubicom32_data_register_operand" "d")))
-+; (clobber (reg:CC CC_REGNO))]
-+; "(ubicom32_v4)"
-+; "sub.1\\t%0, #0, %1")
-+
-+;(define_insn "neghi2"
-+; [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
-+; (neg:HI (match_operand:HI 1 "ubicom32_data_register_operand" "d")))
-+; (clobber (reg:CC CC_REGNO))]
-+; ""
-+; "sub.2\\t%0, #0, %1")
-+
-+(define_insn "negsi2"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (neg:SI (match_operand:SI 1 "ubicom32_data_register_operand" "d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "sub.4\\t%0, #0, %1")
-+
-+(define_insn_and_split "negdi2"
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "=&rm")
-+ (neg:DI (match_operand:DI 1 "ubicom32_data_register_operand" "d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "#"
-+ "reload_completed"
-+ [(parallel [(set (match_dup 0)
-+ (minus:DI (const_int 0)
-+ (match_dup 1)))
-+ (clobber (reg:CC CC_REGNO))])]
-+ ""
-+ [(set_attr "length" "8")])
-+
-+(define_insn "umulhisi3"
-+ [(set (match_operand:SI 0 "ubicom32_acc_lo_register_operand" "=l, l")
-+ (mult:SI
-+ (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "%d,rm"))
-+ (zero_extend:SI (match_operand:HI 2 "nonimmediate_operand" "rm, d"))))
-+ (clobber (reg:HI ACC0_HI_REGNO))
-+ (clobber (reg:HI ACC1_HI_REGNO))]
-+ ""
-+ "@
-+ mulu\\t%A0, %2, %1
-+ mulu\\t%A0, %1, %2"
-+ [(set_attr "type" "mul,mul")])
-+
-+(define_insn "mulhisi3"
-+ [(set (match_operand:SI 0 "ubicom32_acc_lo_register_operand" "=l, l")
-+ (mult:SI
-+ (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "%d,rm"))
-+ (sign_extend:SI (match_operand:HI 2 "nonimmediate_operand" "rm, d"))))
-+ (clobber (reg:HI ACC0_HI_REGNO))
-+ (clobber (reg:HI ACC1_HI_REGNO))]
-+ ""
-+ "@
-+ muls\\t%A0, %2, %1
-+ muls\\t%A0, %1, %2"
-+ [(set_attr "type" "mul,mul")])
-+
-+(define_expand "mulsi3"
-+ [(set (match_operand:SI 0 "ubicom32_acc_hi_register_operand" "")
-+ (mult:SI (match_operand:SI 1 "ubicom32_arith_operand" "")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "")))]
-+ ""
-+ "{
-+ if (ubicom32_emit_mult_sequence (operands))
-+ DONE;
-+ }")
-+
-+(define_insn "umulsidi3"
-+ [(set (match_operand:DI 0 "ubicom32_acc_hi_register_operand" "=h, h")
-+ (mult:DI
-+ (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%d,rm"))
-+ (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm, d"))))]
-+ "(ubicom32_v4)"
-+ "@
-+ mulu.4\\t%A0, %2, %1
-+ mulu.4\\t%A0, %1, %2"
-+ [(set_attr "type" "mul,mul")])
-+
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "nonimmediate_operand" ""))
-+ (set (match_operand:DI 2 "ubicom32_acc_hi_register_operand" "")
-+ (mult:DI
-+ (zero_extend:DI (match_dup 0))
-+ (zero_extend:DI (match_operand:SI 3 "ubicom32_data_register_operand" ""))))]
-+ "(peep2_reg_dead_p (2, operands[0])
-+ || REGNO (operands[0]) == REGNO (operands[2])
-+ || REGNO (operands[0]) == REGNO (operands[2]) + 1)
-+ && ! rtx_equal_p (operands[0], operands[3])"
-+ [(set (match_dup 2)
-+ (mult:DI
-+ (zero_extend:DI (match_dup 1))
-+ (zero_extend:DI (match_dup 3))))]
-+ "")
-+
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "nonimmediate_operand" ""))
-+ (set (match_operand:DI 2 "ubicom32_acc_hi_register_operand" "")
-+ (mult:DI
-+ (zero_extend:DI (match_operand:SI 3 "ubicom32_data_register_operand" ""))
-+ (zero_extend:DI (match_dup 0))))]
-+ "(peep2_reg_dead_p (2, operands[0])
-+ || REGNO (operands[0]) == REGNO (operands[2])
-+ || REGNO (operands[0]) == REGNO (operands[2]) + 1)
-+ && ! rtx_equal_p (operands[0], operands[3])"
-+ [(set (match_dup 2)
-+ (mult:DI
-+ (zero_extend:DI (match_dup 1))
-+ (zero_extend:DI (match_dup 3))))]
-+ "")
-+
-+(define_insn "umulsidi3_const"
-+ [(set (match_operand:DI 0 "ubicom32_acc_hi_register_operand" "=h")
-+ (mult:DI
-+ (zero_extend:DI (match_operand:SI 1 "ubicom32_data_register_operand" "%d"))
-+ (match_operand 2 "const_int_operand" "I")))]
-+ "(ubicom32_v4 && satisfies_constraint_I (operands[2]))"
-+ "mulu.4\\t%A0, %2, %1"
-+ [(set_attr "type" "mul")])
-+
-+(define_insn "mulsidi3"
-+ [(set (match_operand:DI 0 "ubicom32_acc_hi_register_operand" "=h, h")
-+ (mult:DI
-+ (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%d,rm"))
-+ (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm, d"))))]
-+ "(ubicom32_v4)"
-+ "@
-+ muls.4\\t%A0, %2, %1
-+ muls.4\\t%A0, %1, %2"
-+ [(set_attr "type" "mul,mul")])
-+
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "nonimmediate_operand" ""))
-+ (set (match_operand:DI 2 "ubicom32_acc_hi_register_operand" "")
-+ (mult:DI
-+ (sign_extend:DI (match_dup 0))
-+ (sign_extend:DI (match_operand:SI 3 "ubicom32_data_register_operand" ""))))]
-+ "(peep2_reg_dead_p (2, operands[0])
-+ || REGNO (operands[0]) == REGNO (operands[2])
-+ || REGNO (operands[0]) == REGNO (operands[2]) + 1)
-+ && ! rtx_equal_p (operands[0], operands[3])"
-+ [(set (match_dup 2)
-+ (mult:DI
-+ (sign_extend:DI (match_dup 1))
-+ (sign_extend:DI (match_dup 3))))]
-+ "")
-+
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "nonimmediate_operand" ""))
-+ (set (match_operand:DI 2 "ubicom32_acc_hi_register_operand" "")
-+ (mult:DI
-+ (sign_extend:DI (match_operand:SI 3 "ubicom32_data_register_operand" ""))
-+ (sign_extend:DI (match_dup 0))))]
-+ "(peep2_reg_dead_p (2, operands[0])
-+ || REGNO (operands[0]) == REGNO (operands[2])
-+ || REGNO (operands[0]) == REGNO (operands[2]) + 1)
-+ && ! rtx_equal_p (operands[0], operands[3])"
-+ [(set (match_dup 2)
-+ (mult:DI
-+ (sign_extend:DI (match_dup 1))
-+ (sign_extend:DI (match_dup 3))))]
-+ "")
-+
-+(define_insn "mulsidi3_const"
-+ [(set (match_operand:DI 0 "ubicom32_acc_hi_register_operand" "=h")
-+ (mult:DI
-+ (sign_extend:DI (match_operand:SI 1 "ubicom32_data_register_operand" "%d"))
-+ (match_operand 2 "const_int_operand" "I")))]
-+ "(ubicom32_v4 && satisfies_constraint_I (operands[2]))"
-+ "muls.4\\t%A0, %2, %1"
-+ [(set_attr "type" "mul")])
-+
-+(define_expand "andqi3"
-+ [(parallel
-+ [(set (match_operand:QI 0 "memory_operand" "")
-+ (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
-+ (match_operand:QI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "(ubicom32_v4)"
-+ "{
-+ if (!memory_operand (operands[0], QImode))
-+ FAIL;
-+
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (QImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (QImode, operands[2]);
-+ }")
-+
-+(define_insn "andqi3_and1"
-+ [(set (match_operand:QI 0 "memory_operand" "=m, m")
-+ (and:QI (match_operand:QI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:QI 2 "ubicom32_arith_operand" "rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4)"
-+ "@
-+ and.1\\t%0, %2, %1
-+ and.1\\t%0, %1, %2")
-+
-+(define_insn "andqi3_and1_ccszn"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (and:QI (match_operand:QI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:QI 2 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))
-+ (set (match_operand:QI 0 "memory_operand" "=m, m")
-+ (and:QI (match_dup 1)
-+ (match_dup 2)))]
-+ "(ubicom32_v4
-+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
-+ "@
-+ and.1\\t%0, %2, %1
-+ and.1\\t%0, %1, %2")
-+
-+(define_insn "andqi3_and1_ccszn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (and:QI (match_operand:QI 0 "nonimmediate_operand" "%d,rm")
-+ (match_operand:QI 1 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))]
-+ "(ubicom32_v4
-+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
-+ "@
-+ and.1\\t#0, %1, %0
-+ and.1\\t#0, %0, %1")
-+
-+(define_insn "and1_ccszn_null_1"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:QI
-+ (and:SI (match_operand:SI 0 "ubicom32_data_register_operand" "%d")
-+ (match_operand:SI 1 "ubicom32_arith_operand" "rI"))
-+ 3)
-+ (const_int 0)))]
-+ "(ubicom32_v4
-+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
-+ "and.1\\t#0, %1, %0")
-+
-+(define_insn "and1_ccszn_null_2"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:QI
-+ (and:SI (match_operand:SI 0 "ubicom32_data_register_operand" "d")
-+ (subreg:SI
-+ (match_operand:QI 1 "memory_operand" "m")
-+ 0))
-+ 3)
-+ (const_int 0)))]
-+ "(ubicom32_v4
-+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
-+ "and.1\\t#0, %1, %0")
-+
-+(define_insn "and1_ccszn_null_3"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:QI
-+ (and:SI (subreg:SI
-+ (match_operand:QI 0 "memory_operand" "m")
-+ 0)
-+ (match_operand:SI 1 "ubicom32_data_register_operand" "d"))
-+ 3)
-+ (const_int 0)))]
-+ "(ubicom32_v4
-+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
-+ "and.1\\t#0, %0, %1")
-+
-+(define_expand "andhi3"
-+ [(parallel
-+ [(set (match_operand:HI 0 "memory_operand" "")
-+ (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
-+ (match_operand:HI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ ""
-+ "{
-+ if (!memory_operand (operands[0], HImode))
-+ FAIL;
-+
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (HImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (HImode, operands[2]);
-+ }")
-+
-+(define_insn "andhi3_and2"
-+ [(set (match_operand:HI 0 "memory_operand" "=m, m")
-+ (and:HI (match_operand:HI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:HI 2 "ubicom32_arith_operand" "rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "@
-+ and.2\\t%0, %2, %1
-+ and.2\\t%0, %1, %2")
-+
-+(define_insn "andhi3_and2_ccszn"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (and:HI (match_operand:HI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:HI 2 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))
-+ (set (match_operand:HI 0 "memory_operand" "=m, m")
-+ (and:HI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "@
-+ and.2\\t%0, %2, %1
-+ and.2\\t%0, %1, %2")
-+
-+(define_insn "andhi3_and2_ccszn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (and:HI (match_operand:HI 0 "nonimmediate_operand" "%d,rm")
-+ (match_operand:HI 1 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "@
-+ and.2\\t#0, %1, %0
-+ and.2\\t#0, %0, %1")
-+
-+(define_insn "and2_ccszn_null_1"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:HI
-+ (and:SI (match_operand:SI 0 "ubicom32_data_register_operand" "%d")
-+ (match_operand:SI 1 "ubicom32_arith_operand" "rI"))
-+ 2)
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "and.2\\t#0, %1, %0")
-+
-+(define_insn "and2_ccszn_null_2"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:HI
-+ (and:SI (match_operand:SI 0 "ubicom32_data_register_operand" "d")
-+ (subreg:SI
-+ (match_operand:HI 1 "memory_operand" "m")
-+ 0))
-+ 2)
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "and.2\\t#0, %1, %0")
-+
-+(define_insn "and2_ccszn_null_3"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:HI
-+ (and:SI (subreg:SI
-+ (match_operand:HI 0 "memory_operand" "m")
-+ 0)
-+ (match_operand:SI 1 "ubicom32_data_register_operand" "d"))
-+ 2)
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "and.2\\t#0, %0, %1")
-+
-+(define_expand "andsi3"
-+ [(parallel
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
-+ (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
-+ (match_operand:SI 2 "ubicom32_and_or_si3_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ ""
-+ "{
-+ do
-+ {
-+ /* Is this a bfextu? */
-+ if (ubicom32_data_register_operand (operands[0], SImode)
-+ && CONST_INT_P (operands[2])
-+ && exact_log2 (INTVAL (operands[2]) + 1) != -1)
-+ break;
-+
-+ /* Is this a bclr? */
-+ if (CONST_INT_P (operands[2])
-+ && exact_log2 (~INTVAL (operands[2])) != -1)
-+ break;
-+
-+ /* Must be an and.4 */
-+ if (!ubicom32_data_register_operand (operands[1], SImode))
-+ operands[1] = copy_to_mode_reg (SImode, operands[1]);
-+
-+ if (!ubicom32_arith_operand (operands[2], SImode))
-+ operands[2] = copy_to_mode_reg (SImode, operands[2]);
-+ }
-+ while (0);
-+ }")
-+
-+(define_insn "andsi3_bfextu"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (and:SI (match_operand:SI 1 "nonimmediate_operand" "%rm")
-+ (match_operand:SI 2 "const_int_operand" "O")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(satisfies_constraint_O (operands[2]))"
-+ "*
-+ {
-+ operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2]) + 1));
-+
-+ return \"bfextu\\t%0, %1, %3\";
-+ }")
-+
-+(define_insn "andsi3_bfextu_ccwz"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (and:SI (match_operand:SI 1 "nonimmediate_operand" "%rm")
-+ (match_operand:SI 2 "const_int_operand" "O"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (and:SI (match_dup 1)
-+ (match_dup 2)))]
-+ "(satisfies_constraint_O (operands[2])
-+ && ubicom32_match_cc_mode(insn, CCWZmode))"
-+ "*
-+ {
-+ operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2]) + 1));
-+
-+ return \"bfextu\\t%0, %1, %3\";
-+ }")
-+
-+(define_insn "andsi3_bfextu_ccwz_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (and:SI (match_operand:SI 0 "nonimmediate_operand" "%rm")
-+ (match_operand:SI 1 "const_int_operand" "O"))
-+ (const_int 0)))
-+ (clobber (match_scratch:SI 2 "=d"))]
-+ "(satisfies_constraint_O (operands[1])
-+ && ubicom32_match_cc_mode(insn, CCWZmode))"
-+ "*
-+ {
-+ operands[3] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1));
-+
-+ return \"bfextu\\t%2, %0, %3\";
-+ }")
-+
-+(define_insn "andsi3_bclr"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (and:SI (match_operand:SI 1 "ubicom32_arith_operand" "%rmI")
-+ (match_operand:SI 2 "const_int_operand" "n")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(exact_log2 (~INTVAL (operands[2])) != -1)"
-+ "bclr\\t%0, %1, #%D2")
-+
-+(define_insn "andsi3_and4"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
-+ (and:SI (match_operand:SI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "@
-+ and.4\\t%0, %2, %1
-+ and.4\\t%0, %1, %2")
-+
-+(define_insn "andsi3_and4_ccwzn"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (and:SI (match_operand:SI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
-+ (and:SI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "@
-+ and.4\\t%0, %2, %1
-+ and.4\\t%0, %1, %2")
-+
-+(define_insn "andsi3_and4_ccwzn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (and:SI (match_operand:SI 0 "nonimmediate_operand" "%d,rm")
-+ (match_operand:SI 1 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "@
-+ and.4\\t#0, %1, %0
-+ and.4\\t#0, %0, %1")
-+
-+(define_insn "andsi3_lsr4_ccwz_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (and:SI (match_operand:SI 0 "nonimmediate_operand" "%rm")
-+ (match_operand:SI 1 "const_int_operand" "n"))
-+ (const_int 0)))
-+ (clobber (match_scratch:SI 2 "=d"))]
-+ "(exact_log2 ((~(INTVAL (operands[1]))) + 1) != -1
-+ && ubicom32_match_cc_mode(insn, CCWZmode))"
-+ "*
-+ {
-+ operands[3] = GEN_INT (exact_log2 ((~(INTVAL (operands[1]))) + 1));
-+
-+ return \"lsr.4\\t%2, %0, %3\";
-+ }")
-+
-+; We really would like the combiner to recognize this scenario and deal with
-+; it but unfortunately it tries to canonicalize zero_extract ops on MEMs
-+; into QImode operations and we can't match them in any useful way.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))
-+ (set (reg:CCWZ CC_REGNO)
-+ (compare:CCWZ
-+ (and:SI (match_operand:SI 2 "nonimmediate_operand" "")
-+ (match_dup 0))
-+ (const_int 0)))]
-+ "(exact_log2 (INTVAL (operands[1])) != -1
-+ && peep2_reg_dead_p (2, operands[0]))"
-+ [(set (reg:CCWZ CC_REGNO)
-+ (compare:CCWZ
-+ (zero_extract:SI
-+ (match_dup 2)
-+ (const_int 1)
-+ (match_dup 3))
-+ (const_int 0)))]
-+ "{
-+ operands[3] = GEN_INT (exact_log2 (INTVAL (operands[1])));
-+ }")
-+
-+(define_expand "anddi3"
-+ [(parallel
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "")
-+ (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
-+ (match_operand:DI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ ""
-+ "{
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (DImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (DImode, operands[2]);
-+ }")
-+
-+(define_insn_and_split "anddi3_and4"
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,&r, d,rm, m, m")
-+ (and:DI (match_operand:DI 1 "nonimmediate_operand" "%d,rm, 0, 0, d,rm")
-+ (match_operand:DI 2 "ubicom32_arith_operand" "rmI, d,rmI, d,rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "#"
-+ "reload_completed"
-+ [(parallel [(set (match_dup 3)
-+ (and:SI (match_dup 4)
-+ (match_dup 5)))
-+ (clobber (reg:CC CC_REGNO))])
-+ (parallel [(set (match_dup 6)
-+ (and:SI (match_dup 7)
-+ (match_dup 8)))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "{
-+ operands[3] = gen_lowpart (SImode, operands[0]);
-+ operands[4] = gen_lowpart (SImode, operands[1]);
-+ operands[5] = gen_lowpart (SImode, operands[2]);
-+ operands[6] = gen_highpart (SImode, operands[0]);
-+ operands[7] = gen_highpart (SImode, operands[1]);
-+ operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_expand "iorqi3"
-+ [(parallel
-+ [(set (match_operand:QI 0 "memory_operand" "")
-+ (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
-+ (match_operand:QI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "(ubicom32_v4)"
-+ "{
-+ if (!memory_operand (operands[0], QImode))
-+ FAIL;
-+
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (QImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (QImode, operands[2]);
-+ }")
-+
-+(define_insn "iorqi3_or1"
-+ [(set (match_operand:QI 0 "memory_operand" "=m, m")
-+ (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:QI 2 "ubicom32_arith_operand" "rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4)"
-+ "@
-+ or.1\\t%0, %2, %1
-+ or.1\\t%0, %1, %2")
-+
-+(define_expand "iorhi3"
-+ [(parallel
-+ [(set (match_operand:HI 0 "memory_operand" "")
-+ (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
-+ (match_operand:HI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ ""
-+ "{
-+ if (!memory_operand (operands[0], HImode))
-+ FAIL;
-+
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (HImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (HImode, operands[2]);
-+ }")
-+
-+(define_insn "iorhi3_or2"
-+ [(set (match_operand:HI 0 "memory_operand" "=m, m")
-+ (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:HI 2 "ubicom32_arith_operand" "rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "@
-+ or.2\\t%0, %2, %1
-+ or.2\\t%0, %1, %2")
-+
-+(define_expand "iorsi3"
-+ [(parallel
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
-+ (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
-+ (match_operand:SI 2 "ubicom32_and_or_si3_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ ""
-+ "{
-+ do
-+ {
-+ /* Is this a bset? */
-+ if (CONST_INT_P (operands[2])
-+ && exact_log2 (INTVAL (operands[2])) != -1)
-+ break;
-+
-+ /* Must be an or.4 */
-+ if (!ubicom32_data_register_operand (operands[1], SImode))
-+ operands[1] = copy_to_mode_reg (SImode, operands[1]);
-+
-+ if (!ubicom32_arith_operand (operands[2], SImode))
-+ operands[2] = copy_to_mode_reg (SImode, operands[2]);
-+ }
-+ while (0);
-+ }")
-+
-+(define_insn "iorsi3_bset"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (ior:SI (match_operand:SI 1 "ubicom32_arith_operand" "%rmI")
-+ (match_operand 2 "const_int_operand" "n")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(exact_log2 (INTVAL (operands[2])) != -1)"
-+ "bset\\t%0, %1, #%d2")
-+
-+(define_insn "iorsi3_or4"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
-+ (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "@
-+ or.4\\t%0, %2, %1
-+ or.4\\t%0, %1, %2")
-+
-+(define_insn "iorsi3_ccwzn"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
-+ (ior:SI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "@
-+ or.4\\t%0, %2, %1
-+ or.4\\t%0, %1, %2")
-+
-+(define_insn "iorsi3_ccwzn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (ior:SI (match_operand:SI 0 "nonimmediate_operand" "%d,rm")
-+ (match_operand:SI 1 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "@
-+ or.4\\t#0, %1, %0
-+ or.4\\t#0, %0, %1")
-+
-+(define_expand "iordi3"
-+ [(parallel
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "")
-+ (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
-+ (match_operand:DI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ ""
-+ "{
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (DImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (DImode, operands[2]);
-+ }")
-+
-+(define_insn_and_split "iordi3_or4"
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,&r, d,rm, m, m")
-+ (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%d,rm, 0, 0, d,rm")
-+ (match_operand:DI 2 "ubicom32_arith_operand" "rmI, d,rmI, d,rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "#"
-+ "reload_completed"
-+ [(parallel [(set (match_dup 3)
-+ (ior:SI (match_dup 4)
-+ (match_dup 5)))
-+ (clobber (reg:CC CC_REGNO))])
-+ (parallel [(set (match_dup 6)
-+ (ior:SI (match_dup 7)
-+ (match_dup 8)))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "{
-+ operands[3] = gen_lowpart (SImode, operands[0]);
-+ operands[4] = gen_lowpart (SImode, operands[1]);
-+ operands[5] = gen_lowpart (SImode, operands[2]);
-+ operands[6] = gen_highpart (SImode, operands[0]);
-+ operands[7] = gen_highpart (SImode, operands[1]);
-+ operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_expand "xorqi3"
-+ [(parallel
-+ [(set (match_operand:QI 0 "memory_operand" "")
-+ (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
-+ (match_operand:QI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "(ubicom32_v4)"
-+ "{
-+ if (!memory_operand (operands[0], QImode))
-+ FAIL;
-+
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (QImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (QImode, operands[2]);
-+ }")
-+
-+(define_insn "xorqi3_xor1"
-+ [(set (match_operand:QI 0 "memory_operand" "=m, m")
-+ (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:QI 2 "ubicom32_arith_operand" "rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4)"
-+ "@
-+ xor.1\\t%0, %2, %1
-+ xor.1\\t%0, %1, %2")
-+
-+(define_insn "xorqi3_xor1_ccszn"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:QI 2 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))
-+ (set (match_operand:QI 0 "memory_operand" "=m, m")
-+ (xor:QI (match_dup 1)
-+ (match_dup 2)))]
-+ "(ubicom32_v4
-+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
-+ "@
-+ xor.1\\t%0, %2, %1
-+ xor.1\\t%0, %1, %2")
-+
-+(define_insn "xorqi3_xor1_ccszn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (xor:QI (match_operand:QI 0 "nonimmediate_operand" "%d,rm")
-+ (match_operand:QI 1 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))]
-+ "(ubicom32_v4
-+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
-+ "@
-+ xor.1\\t#0, %1, %0
-+ xor.1\\t#0, %0, %1")
-+
-+(define_insn "xor1_ccszn_null_1"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:QI
-+ (xor:SI (match_operand:SI 0 "ubicom32_data_register_operand" "%d")
-+ (match_operand:SI 1 "ubicom32_arith_operand" "rI"))
-+ 3)
-+ (const_int 0)))]
-+ "(ubicom32_v4
-+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
-+ "xor.1\\t#0, %1, %0")
-+
-+(define_insn "xor1_ccszn_null_2"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:QI
-+ (xor:SI (match_operand:SI 0 "ubicom32_data_register_operand" "d")
-+ (subreg:SI
-+ (match_operand:QI 1 "memory_operand" "m")
-+ 0))
-+ 3)
-+ (const_int 0)))]
-+ "(ubicom32_v4
-+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
-+ "xor.1\\t#0, %1, %0")
-+
-+(define_insn "xor1_ccwzn_null_3"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:QI
-+ (xor:SI (subreg:SI
-+ (match_operand:QI 0 "memory_operand" "m")
-+ 0)
-+ (match_operand:SI 1 "ubicom32_data_register_operand" "d"))
-+ 3)
-+ (const_int 0)))]
-+ "(ubicom32_v4
-+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
-+ "xor.1\\t#0, %0, %1")
-+
-+(define_expand "xorhi3"
-+ [(parallel
-+ [(set (match_operand:HI 0 "memory_operand" "")
-+ (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
-+ (match_operand:HI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ ""
-+ "{
-+ if (!memory_operand (operands[0], HImode))
-+ FAIL;
-+
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (HImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (HImode, operands[2]);
-+ }")
-+
-+(define_insn "xorhi3_xor2"
-+ [(set (match_operand:HI 0 "memory_operand" "=m, m")
-+ (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:HI 2 "ubicom32_arith_operand" "rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "@
-+ xor.2\\t%0, %2, %1
-+ xor.2\\t%0, %1, %2")
-+
-+(define_insn "xorhi3_xor2_ccszn"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:HI 2 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))
-+ (set (match_operand:HI 0 "memory_operand" "=m, m")
-+ (xor:HI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "@
-+ xor.2\\t%0, %2, %1
-+ xor.2\\t%0, %1, %2")
-+
-+(define_insn "xorhi3_xor2_ccszn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (xor:HI (match_operand:HI 0 "nonimmediate_operand" "%d,rm")
-+ (match_operand:HI 1 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "@
-+ xor.2\\t#0, %1, %0
-+ xor.2\\t#0, %0, %1")
-+
-+(define_insn "xor2_ccszn_null_1"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:HI
-+ (xor:SI (match_operand:SI 0 "ubicom32_data_register_operand" "%d")
-+ (match_operand:SI 1 "ubicom32_arith_operand" "rI"))
-+ 2)
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "xor.2\\t#0, %1, %0")
-+
-+(define_insn "xor2_ccszn_null_2"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:HI
-+ (xor:SI (match_operand:SI 0 "ubicom32_data_register_operand" "d")
-+ (subreg:SI
-+ (match_operand:HI 1 "memory_operand" "m")
-+ 0))
-+ 2)
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "xor.2\\t#0, %1, %0")
-+
-+(define_insn "xor2_ccszn_null_3"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:HI
-+ (xor:SI (subreg:SI
-+ (match_operand:HI 0 "memory_operand" "m")
-+ 0)
-+ (match_operand:SI 1 "ubicom32_data_register_operand" "d"))
-+ 2)
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "xor.2\\t#0, %0, %1")
-+
-+(define_insn "xorsi3"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
-+ (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "@
-+ xor.4\\t%0, %2, %1
-+ xor.4\\t%0, %1, %2")
-+
-+(define_insn "xorsi3_ccwzn"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
-+ (xor:SI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "@
-+ xor.4\\t%0, %2, %1
-+ xor.4\\t%0, %1, %2")
-+
-+(define_insn "xorsi3_ccwzn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (xor:SI (match_operand:SI 0 "nonimmediate_operand" "%d,rm")
-+ (match_operand:SI 1 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "@
-+ xor.4\\t#0, %1, %0
-+ xor.4\\t#0, %0, %1")
-+
-+(define_expand "xordi3"
-+ [(parallel
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "")
-+ (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
-+ (match_operand:DI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ ""
-+ "{
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (DImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (DImode, operands[2]);
-+ }")
-+
-+(define_insn_and_split "xordi3_xor4"
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,&r, d,rm, m, m")
-+ (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%d,rm, 0, 0, d,rm")
-+ (match_operand:DI 2 "ubicom32_arith_operand" "rmI, d,rmI, d,rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "#"
-+ "reload_completed"
-+ [(parallel [(set (match_dup 3)
-+ (xor:SI (match_dup 4)
-+ (match_dup 5)))
-+ (clobber (reg:CC CC_REGNO))])
-+ (parallel [(set (match_dup 6)
-+ (xor:SI (match_dup 7)
-+ (match_dup 8)))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "{
-+ operands[3] = gen_lowpart (SImode, operands[0]);
-+ operands[4] = gen_lowpart (SImode, operands[1]);
-+ operands[5] = gen_lowpart (SImode, operands[2]);
-+ operands[6] = gen_highpart (SImode, operands[0]);
-+ operands[7] = gen_highpart (SImode, operands[1]);
-+ operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_insn "not2_2"
-+ [(set (match_operand:HI 0 "memory_operand" "=m")
-+ (subreg:HI
-+ (not:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI"))
-+ 2))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "not.2\\t%0, %1")
-+
-+(define_insn "one_cmplsi2"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (not:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "not.4\\t%0, %1")
-+
-+(define_insn "one_cmplsi2_ccwzn"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (not:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (not:SI (match_dup 1)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "not.4\\t%0, %1")
-+
-+(define_insn "one_cmplsi2_ccwzn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (not:SI (match_operand:SI 0 "ubicom32_arith_operand" "rmI"))
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "not.4\\t#0, %0")
-+
-+(define_insn_and_split "one_cmpldi2"
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "=&rm")
-+ (not:DI (match_operand:DI 1 "nonimmediate_operand" "rmI0")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "#"
-+ ""
-+ [(parallel [(set (match_dup 2)
-+ (not:SI (match_dup 3)))
-+ (clobber (reg:CC CC_REGNO))])
-+ (parallel [(set (match_dup 4)
-+ (not:SI (match_dup 5)))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "{
-+ operands[2] = gen_lowpart (SImode, operands[0]);
-+ operands[3] = gen_lowpart (SImode, operands[1]);
-+ operands[4] = gen_highpart (SImode, operands[0]);
-+ operands[5] = gen_highpart (SImode, operands[1]);
-+ }"
-+ [(set_attr "length" "8")])
-+
-+; Conditional jump instructions
-+
-+(define_expand "beq"
-+ [(set (pc)
-+ (if_then_else (eq (match_dup 1)
-+ (const_int 0))
-+ (label_ref (match_operand 0 "" ""))
-+ (pc)))]
-+ ""
-+ "{
-+ operands[1] = ubicom32_gen_compare_reg (EQ, ubicom32_compare_op0,
-+ ubicom32_compare_op1);
-+ }")
-+
-+(define_expand "bne"
-+ [(set (pc)
-+ (if_then_else (ne (match_dup 1)
-+ (const_int 0))
-+ (label_ref (match_operand 0 "" ""))
-+ (pc)))]
-+ ""
-+ "{
-+ operands[1] = ubicom32_gen_compare_reg (NE, ubicom32_compare_op0,
-+ ubicom32_compare_op1);
-+ }")
-+
-+(define_expand "bgt"
-+ [(set (pc)
-+ (if_then_else (gt (match_dup 1)
-+ (const_int 0))
-+ (label_ref (match_operand 0 "" ""))
-+ (pc)))]
-+ ""
-+ "{
-+ operands[1] = ubicom32_gen_compare_reg (GT, ubicom32_compare_op0,
-+ ubicom32_compare_op1);
-+ }")
-+
-+(define_expand "ble"
-+ [(set (pc)
-+ (if_then_else (le (match_dup 1)
-+ (const_int 0))
-+ (label_ref (match_operand 0 "" ""))
-+ (pc)))]
-+ ""
-+ "{
-+ operands[1] = ubicom32_gen_compare_reg (LE, ubicom32_compare_op0,
-+ ubicom32_compare_op1);
-+ }")
-+
-+(define_expand "bge"
-+ [(set (pc)
-+ (if_then_else (ge (match_dup 1)
-+ (const_int 0))
-+ (label_ref (match_operand 0 "" ""))
-+ (pc)))]
-+ ""
-+ "{
-+ operands[1] = ubicom32_gen_compare_reg (GE, ubicom32_compare_op0,
-+ ubicom32_compare_op1);
-+ }")
-+
-+(define_expand "blt"
-+ [(set (pc)
-+ (if_then_else (lt (match_dup 1)
-+ (const_int 0))
-+ (label_ref (match_operand 0 "" ""))
-+ (pc)))]
-+ ""
-+ "{
-+ operands[1] = ubicom32_gen_compare_reg (LT, ubicom32_compare_op0,
-+ ubicom32_compare_op1);
-+ }")
-+
-+(define_expand "bgtu"
-+ [(set (pc)
-+ (if_then_else (gtu (match_dup 1)
-+ (const_int 0))
-+ (label_ref (match_operand 0 "" ""))
-+ (pc)))]
-+ ""
-+ "{
-+ operands[1] = ubicom32_gen_compare_reg (GTU, ubicom32_compare_op0,
-+ ubicom32_compare_op1);
-+ }")
-+
-+(define_expand "bleu"
-+ [(set (pc)
-+ (if_then_else (leu (match_dup 1)
-+ (const_int 0))
-+ (label_ref (match_operand 0 "" ""))
-+ (pc)))]
-+ ""
-+ "{
-+ operands[1] = ubicom32_gen_compare_reg (LEU, ubicom32_compare_op0,
-+ ubicom32_compare_op1);
-+ }")
-+
-+(define_expand "bgeu"
-+ [(set (pc)
-+ (if_then_else (geu (match_dup 1)
-+ (const_int 0))
-+ (label_ref (match_operand 0 "" ""))
-+ (pc)))]
-+ ""
-+ "{
-+ operands[1] = ubicom32_gen_compare_reg (GEU, ubicom32_compare_op0,
-+ ubicom32_compare_op1);
-+ }")
-+
-+(define_expand "bltu"
-+ [(set (pc)
-+ (if_then_else (ltu (match_dup 1)
-+ (const_int 0))
-+ (label_ref (match_operand 0 "" ""))
-+ (pc)))]
-+ ""
-+ "{
-+ operands[1] = ubicom32_gen_compare_reg (LTU, ubicom32_compare_op0,
-+ ubicom32_compare_op1);
-+ }")
-+
-+(define_insn "jcc"
-+ [(set (pc)
-+ (if_then_else (match_operator 1 "comparison_operator"
-+ [(match_operand 2 "ubicom32_cc_register_operand" "")
-+ (const_int 0)])
-+ (label_ref (match_operand 0 "" ""))
-+ (pc)))]
-+ ""
-+ "*
-+ {
-+ ubicom32_output_cond_jump (insn, operands[1], operands[0]);
-+ return \"\";
-+ }")
-+
-+; Reverse branch - reverse our comparison condition so that we can
-+; branch in the opposite sense.
-+;
-+(define_insn_and_split "jcc_reverse"
-+ [(set (pc)
-+ (if_then_else (match_operator 1 "comparison_operator"
-+ [(match_operand 2 "ubicom32_cc_register_operand" "")
-+ (const_int 0)])
-+ (pc)
-+ (label_ref (match_operand 0 "" ""))))]
-+ ""
-+ "#"
-+ "reload_completed"
-+ [(set (pc)
-+ (if_then_else (match_dup 3)
-+ (label_ref (match_dup 0))
-+ (pc)))]
-+ "{
-+ rtx cc_reg;
-+
-+ cc_reg = gen_rtx_REG (GET_MODE (operands[2]), CC_REGNO);
-+ operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[1])),
-+ GET_MODE (operands[1]),
-+ cc_reg,
-+ const0_rtx);
-+ }")
-+
-+(define_insn "jump"
-+ [(set (pc)
-+ (label_ref (match_operand 0 "" "")))]
-+ ""
-+ "jmpt\\t%l0")
-+
-+(define_expand "indirect_jump"
-+ [(parallel [(set (pc)
-+ (match_operand:SI 0 "register_operand" ""))
-+ (clobber (match_dup 0))])]
-+ ""
-+ "")
-+
-+(define_insn "indirect_jump_internal"
-+ [(set (pc)
-+ (match_operand:SI 0 "register_operand" "a"))
-+ (clobber (match_dup 0))]
-+ ""
-+ "calli\\t%0,0(%0)")
-+
-+; Program Space: The table contains instructions, typically jumps.
-+; CALL An,TABLE_SIZE(PC) ;An = Jump Table Base Address.
-+; <Jump Table is Here> ;An -> Here.
-+; LEA Ak, (An,Dn) ;Ak -> Table Entry
-+; JMP/CALL (Ak)
-+
-+(define_expand "tablejump"
-+ [(parallel [(set (pc)
-+ (match_operand:SI 0 "nonimmediate_operand" ""))
-+ (use (label_ref (match_operand 1 "" "")))])]
-+ ""
-+ "")
-+
-+(define_insn "tablejump_internal"
-+ [(set (pc)
-+ (match_operand:SI 0 "nonimmediate_operand" "rm"))
-+ (use (label_ref (match_operand 1 "" "")))]
-+ ""
-+ "ret\\t%0")
-+
-+; Call subroutine with no return value.
-+;
-+(define_expand "call"
-+ [(call (match_operand:QI 0 "general_operand" "")
-+ (match_operand:SI 1 "general_operand" ""))]
-+ ""
-+ "{
-+ if (TARGET_FDPIC)
-+ {
-+ ubicom32_expand_call_fdpic (operands);
-+ DONE;
-+ }
-+
-+ if (! ubicom32_call_address_operand (XEXP (operands[0], 0), VOIDmode))
-+ XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
-+ }")
-+
-+; We expand to a simple form that doesn't clobber the link register and
-+; then split to a form that does. This allows the RTL optimizers that
-+; run before the splitter to have the opportunity to eliminate the call
-+; without marking A5 as being clobbered and this in turn avoids saves
-+; and returns in a number of cases.
-+;
-+(define_insn_and_split "call_1"
-+ [(call (mem:QI (match_operand:SI 0 "ubicom32_call_address_operand" "a,S"))
-+ (match_operand:SI 1 "general_operand" "g,g"))]
-+ "! TARGET_FDPIC"
-+ "#"
-+ ""
-+ [(parallel
-+ [(call (mem:QI (match_dup 0))
-+ (match_dup 1))
-+ (clobber (reg:SI LINK_REGNO))])]
-+ "")
-+
-+(define_insn "call_slow"
-+ [(call (mem:QI (match_operand:SI 0 "ubicom32_call_address_operand" "a,S"))
-+ (match_operand:SI 1 "general_operand" "g,g"))
-+ (clobber (reg:SI LINK_REGNO))]
-+ "(! TARGET_FDPIC && ! TARGET_FASTCALL)"
-+ "@
-+ calli\\ta5, 0(%0)
-+ moveai\\ta5, #%%hi(%C0)\;calli\\ta5, %%lo(%C0)(a5)")
-+
-+(define_insn "call_fast"
-+ [(call (mem:QI (match_operand:SI 0 "ubicom32_call_address_operand" "a,S"))
-+ (match_operand:SI 1 "general_operand" "g,g"))
-+ (clobber (reg:SI LINK_REGNO))]
-+ "(! TARGET_FDPIC && TARGET_FASTCALL)"
-+ "@
-+ calli\\ta5, 0(%0)
-+ call\\ta5, %C0")
-+
-+; We expand to a simple form that doesn't clobber the link register and
-+; then split to a form that does. This allows the RTL optimizers that
-+; run before the splitter to have the opportunity to eliminate the call
-+; without marking A5 as being clobbered and this in turn avoids saves
-+; and returns in a number of cases.
-+;
-+(define_insn_and_split "call_fdpic"
-+ [(call (mem:QI (match_operand:SI 0 "ubicom32_call_address_operand" "a,S"))
-+ (match_operand:SI 1 "general_operand" "g,g"))
-+ (use (match_operand:SI 2 "ubicom32_fdpic_operand" "Z,Z"))]
-+ "TARGET_FDPIC"
-+ "#"
-+ ""
-+ [(parallel
-+ [(call (mem:QI (match_dup 0))
-+ (match_dup 1))
-+ (use (match_dup 2))
-+ (clobber (reg:SI LINK_REGNO))])]
-+ "")
-+
-+(define_insn "call_fdpic_clobber"
-+ [(call (mem:QI (match_operand:SI 0 "ubicom32_call_address_operand" "a,S"))
-+ (match_operand:SI 1 "general_operand" "g,g"))
-+ (use (match_operand:SI 2 "ubicom32_fdpic_operand" "Z,Z"))
-+ (clobber (reg:SI LINK_REGNO))]
-+ "TARGET_FDPIC"
-+ "@
-+ move.4\\ta5, 0(%0)\;move.4\\t%2, 4(%0)\;calli\\ta5, 0(a5)
-+ call\\ta5, %C0")
-+
-+; Call subroutine, returning value in operand 0
-+; (which must be a hard register).
-+;
-+(define_expand "call_value"
-+ [(set (match_operand 0 "" "")
-+ (call (match_operand:QI 1 "general_operand" "")
-+ (match_operand:SI 2 "general_operand" "")))]
-+ ""
-+ "{
-+ if (TARGET_FDPIC)
-+ {
-+ ubicom32_expand_call_value_fdpic (operands);
-+ DONE;
-+ }
-+
-+ if (! ubicom32_call_address_operand (XEXP (operands[1], 0), VOIDmode))
-+ XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
-+ }")
-+
-+; We expand to a simple form that doesn't clobber the link register and
-+; then split to a form that does. This allows the RTL optimizers that
-+; run before the splitter to have the opportunity to eliminate the call
-+; without marking A5 as being clobbered and this in turn avoids saves
-+; and returns in a number of cases.
-+;
-+(define_insn_and_split "call_value_1"
-+ [(set (match_operand 0 "register_operand" "=r,r")
-+ (call (mem:QI (match_operand:SI 1 "ubicom32_call_address_operand" "a,S"))
-+ (match_operand:SI 2 "general_operand" "g,g")))]
-+ "! TARGET_FDPIC"
-+ "#"
-+ ""
-+ [(parallel
-+ [(set (match_dup 0)
-+ (call (mem:QI (match_dup 1))
-+ (match_dup 2)))
-+ (clobber (reg:SI LINK_REGNO))])]
-+ "")
-+
-+(define_insn "call_value_slow"
-+ [(set (match_operand 0 "register_operand" "=r,r")
-+ (call (mem:QI (match_operand:SI 1 "ubicom32_call_address_operand" "a,S"))
-+ (match_operand:SI 2 "general_operand" "g,g")))
-+ (clobber (reg:SI LINK_REGNO))]
-+ "(! TARGET_FDPIC && ! TARGET_FASTCALL)"
-+ "@
-+ calli\\ta5, 0(%1)
-+ moveai\\ta5, #%%hi(%C1)\;calli\\ta5, %%lo(%C1)(a5)")
-+
-+(define_insn "call_value_fast"
-+ [(set (match_operand 0 "register_operand" "=r,r")
-+ (call (mem:QI (match_operand:SI 1 "ubicom32_call_address_operand" "a,S"))
-+ (match_operand:SI 2 "general_operand" "g,g")))
-+ (clobber (reg:SI LINK_REGNO))]
-+ "(! TARGET_FDPIC && TARGET_FASTCALL)"
-+ "@
-+ calli\\ta5, 0(%1)
-+ call\\ta5, %C1")
-+
-+; We expand to a simple form that doesn't clobber the link register and
-+; then split to a form that does. This allows the RTL optimizers that
-+; run before the splitter to have the opportunity to eliminate the call
-+; without marking A5 as being clobbered and this in turn avoids saves
-+; and returns in a number of cases.
-+;
-+(define_insn_and_split "call_value_fdpic"
-+ [(set (match_operand 0 "register_operand" "=r,r")
-+ (call (mem:QI (match_operand:SI 1 "ubicom32_call_address_operand" "a,S"))
-+ (match_operand:SI 2 "general_operand" "g,g")))
-+ (use (match_operand:SI 3 "ubicom32_fdpic_operand" "Z,Z"))]
-+ "TARGET_FDPIC"
-+ "#"
-+ ""
-+ [(parallel
-+ [(set (match_dup 0)
-+ (call (mem:QI (match_dup 1))
-+ (match_dup 2)))
-+ (use (match_dup 3))
-+ (clobber (reg:SI LINK_REGNO))])]
-+ "")
-+
-+(define_insn "call_value_fdpic_clobber"
-+ [(set (match_operand 0 "register_operand" "=r,r")
-+ (call (mem:QI (match_operand:SI 1 "ubicom32_call_address_operand" "a,S"))
-+ (match_operand:SI 2 "general_operand" "g,g")))
-+ (use (match_operand:SI 3 "ubicom32_fdpic_operand" "Z,Z"))
-+ (clobber (reg:SI LINK_REGNO))]
-+ "TARGET_FDPIC"
-+ "@
-+ move.4\\ta5, 0(%1)\;move.4\\t%3, 4(%1)\;calli\\ta5, 0(a5)
-+ call\\ta5, %C1")
-+
-+(define_expand "untyped_call"
-+ [(parallel [(call (match_operand 0 "" "")
-+ (const_int 0))
-+ (match_operand 1 "" "")
-+ (match_operand 2 "" "")])]
-+ ""
-+ "{
-+ int i;
-+
-+ emit_call_insn (gen_call (operands[0], const0_rtx));
-+
-+ for (i = 0; i < XVECLEN (operands[2], 0); i++)
-+ {
-+ rtx set = XVECEXP (operands[2], 0, i);
-+ emit_move_insn (SET_DEST (set), SET_SRC (set));
-+ }
-+ DONE;
-+ }")
-+
-+(define_insn "lsl1_1"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (ashift:SI (subreg:SI
-+ (match_operand:QI 1 "memory_operand" "m")
-+ 0)
-+ (match_operand:SI 2 "ubicom32_arith_operand" "dM")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4)"
-+ "lsl.1\\t%0, %1, %2")
-+
-+; The combiner gets rather creative about left shifts of sub-word memory
-+; operands because it's uncertain about whether the memory is sign or
-+; zero extended. It only wants zero-extended behaviour and so throws
-+; in an extra and operation.
-+;
-+(define_insn "lsl1_2"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (and:SI
-+ (ashift:SI (subreg:SI
-+ (match_operand:QI 1 "memory_operand" "m")
-+ 0)
-+ (match_operand:SI 2 "const_int_operand" "M"))
-+ (match_operand:SI 3 "const_int_operand" "n")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4
-+ && INTVAL (operands[3]) == (0xff << INTVAL (operands[2])))"
-+ "lsl.1\\t%0, %1, %2")
-+
-+(define_insn "lsl2_1"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (ashift:SI (subreg:SI
-+ (match_operand:HI 1 "memory_operand" "m")
-+ 0)
-+ (match_operand:SI 2 "ubicom32_arith_operand" "dM")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4)"
-+ "lsl.2\\t%0, %1, %2")
-+
-+; The combiner gets rather creative about left shifts of sub-word memory
-+; operands because it's uncertain about whether the memory is sign or
-+; zero extended. It only wants zero-extended behaviour and so throws
-+; in an extra and operation.
-+;
-+(define_insn "lsl2_2"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (and:SI
-+ (ashift:SI (subreg:SI
-+ (match_operand:HI 1 "memory_operand" "m")
-+ 0)
-+ (match_operand:SI 2 "const_int_operand" "M"))
-+ (match_operand:SI 3 "const_int_operand" "n")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4
-+ && INTVAL (operands[3]) == (0xffff << INTVAL (operands[2])))"
-+ "lsl.2\\t%0, %1, %2")
-+
-+(define_insn "ashlsi3"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (ashift:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "dM")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "lsl.4\\t%0, %1, %2")
-+
-+(define_insn "lshlsi3_ccwz"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (ashift:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "dM"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (ashift:SI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCWZmode)"
-+ "lsl.4\\t%0, %1, %2")
-+
-+(define_insn "lshlsi3_ccwz_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (ashift:SI (match_operand:SI 0 "ubicom32_arith_operand" "rmI")
-+ (match_operand:SI 1 "ubicom32_arith_operand" "dM"))
-+ (const_int 0)))
-+ (clobber (match_scratch:SI 2 "=d"))]
-+ "ubicom32_match_cc_mode(insn, CCWZmode)"
-+ "lsl.4\\t%2, %0, %1")
-+
-+; The combiner finds this canonical form for what is in essence a right
-+; shift.
-+;
-+(define_insn "asr1_2"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (sign_extract:SI (match_operand:QI 1 "memory_operand" "m")
-+ (match_operand:SI 2 "const_int_operand" "M")
-+ (match_operand:SI 3 "const_int_operand" "M")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4
-+ && (INTVAL (operands[2]) + INTVAL (operands[3]) == 8))"
-+ "asr.1\\t%0, %1, %3")
-+
-+; The combiner finds this canonical form for what is in essence a right
-+; shift.
-+;
-+(define_insn "asr2_2"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (sign_extract:SI (match_operand:HI 1 "memory_operand" "m")
-+ (match_operand:SI 2 "const_int_operand" "M")
-+ (match_operand:SI 3 "const_int_operand" "M")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4
-+ && (INTVAL (operands[2]) + INTVAL (operands[3]) == 16))"
-+ "asr.2\\t%0, %1, %3")
-+
-+(define_insn "ashrsi3"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (ashiftrt:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmJ")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "dM")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "asr.4\\t%0, %1, %2")
-+
-+(define_insn "ashrsi3_ccwzn"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (ashiftrt:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmJ")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "dM"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (ashiftrt:SI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "asr.4\\t%0, %1, %2")
-+
-+(define_insn "ashrsi3_ccwzn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (ashiftrt:SI (match_operand:SI 0 "ubicom32_arith_operand" "rmJ")
-+ (match_operand:SI 1 "ubicom32_arith_operand" "dM"))
-+ (const_int 0)))
-+ (clobber (match_scratch:SI 2 "=d"))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "asr.4\\t%2, %0, %1")
-+
-+(define_insn "lsr1_1"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (lshiftrt:SI (subreg:SI
-+ (match_operand:QI 1 "memory_operand" "m")
-+ 0)
-+ (match_operand:SI 2 "ubicom32_arith_operand" "dM")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4)"
-+ "lsr.1\\t%0, %1, %2")
-+
-+; The combiner finds this canonical form for what is in essence a right
-+; shift.
-+;
-+(define_insn "lsr1_2"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (zero_extract:SI (match_operand:QI 1 "memory_operand" "m")
-+ (match_operand:SI 2 "const_int_operand" "M")
-+ (match_operand:SI 3 "const_int_operand" "M")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4
-+ && (INTVAL (operands[2]) + INTVAL (operands[3]) == 8))"
-+ "lsr.1\\t%0, %1, %3")
-+
-+(define_insn "lsr2_1"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (lshiftrt:SI (subreg:SI
-+ (match_operand:HI 1 "memory_operand" "m")
-+ 0)
-+ (match_operand:SI 2 "ubicom32_arith_operand" "dM")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4)"
-+ "lsr.2\\t%0, %1, %2")
-+
-+; The combiner finds this canonical form for what is in essence a right
-+; shift.
-+;
-+(define_insn "lsr2_2"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (zero_extract:SI (match_operand:HI 1 "memory_operand" "m")
-+ (match_operand:SI 2 "const_int_operand" "M")
-+ (match_operand:SI 3 "const_int_operand" "M")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4
-+ && (INTVAL (operands[2]) + INTVAL (operands[3]) == 16))"
-+ "lsr.2\\t%0, %1, %3")
-+
-+(define_insn "lshrsi3"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (lshiftrt:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "dM")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "lsr.4\\t%0, %1, %2")
-+
-+(define_insn "lshrsi3_ccwz"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (lshiftrt:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "dM"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (lshiftrt:SI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCWZmode)"
-+ "lsr.4\\t%0, %1, %2")
-+
-+(define_insn "lshrsi3_ccwz_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (lshiftrt:SI (match_operand:SI 0 "ubicom32_arith_operand" "rmI")
-+ (match_operand:SI 1 "ubicom32_arith_operand" "dM"))
-+ (const_int 0)))
-+ (clobber (match_scratch:SI 2 "=d"))]
-+ "ubicom32_match_cc_mode(insn, CCWZmode)"
-+ "lsr.4\\t%2, %0, %1")
-+
-+(define_expand "prologue"
-+ [(const_int 0)]
-+ ""
-+ "{
-+ ubicom32_expand_prologue ();
-+ DONE;
-+ }")
-+
-+(define_expand "epilogue"
-+ [(return)]
-+ ""
-+ "{
-+ ubicom32_expand_epilogue ();
-+ DONE;
-+ }")
-+
-+(define_expand "return"
-+ [(return)]
-+ ""
-+ "{
-+ ubicom32_expand_epilogue ();
-+ DONE;
-+ }")
-+
-+(define_expand "_eh_return"
-+ [(use (match_operand:SI 0 "register_operand" "r"))
-+ (use (match_operand:SI 1 "register_operand" "r"))]
-+ ""
-+ "{
-+ ubicom32_expand_eh_return (operands);
-+ DONE;
-+ }")
-+
-+; XXX - it looks almost certain that we could make return_internal use a Dn
-+; register too. In that instance we'd have to use a ret instruction
-+; rather than a calli but it might save cycles.
-+;
-+(define_insn "return_internal"
-+ [(const_int 2)
-+ (return)
-+ (use (match_operand:SI 0 "ubicom32_mem_or_address_register_operand" "rm"))]
-+ ""
-+ "*
-+ {
-+ if (REG_P (operands[0]) && REGNO (operands[0]) == LINK_REGNO
-+ && ubicom32_can_use_calli_to_ret)
-+ return \"calli\\t%0, 0(%0)\";
-+
-+ return \"ret\\t%0\";
-+ }")
-+
-+(define_insn "return_from_post_modify_sp"
-+ [(parallel
-+ [(const_int 2)
-+ (return)
-+ (use (mem:SI (post_modify:SI
-+ (reg:SI SP_REGNO)
-+ (plus:SI (reg:SI SP_REGNO)
-+ (match_operand:SI 0 "const_int_operand" "n")))))])]
-+ "INTVAL (operands[0]) >= 4 && INTVAL (operands[0]) <= 7 * 4"
-+ "ret\\t(sp)%E0++")
-+
-+;(define_insn "eh_return_internal"
-+; [(const_int 4)
-+; (return)
-+; (use (reg:SI 34))]
-+; ""
-+; "ret\\ta2")
-+
-+; No operation, needed in case the user uses -g but not -O.
-+(define_expand "nop"
-+ [(const_int 0)]
-+ ""
-+ "")
-+
-+(define_insn "nop_internal"
-+ [(const_int 0)]
-+ ""
-+ "nop")
-+
-+; The combiner will generate this pattern given shift and add operations.
-+; The canonical form that the combiner wants to use appears to be multiplies
-+; instead of shifts even if the compiled sources use shifts.
-+;
-+(define_insn "shmrg1_add"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (plus:SI
-+ (mult:SI (match_operand:SI 1 "ubicom32_data_register_operand" "d")
-+ (const_int 256))
-+ (zero_extend:SI
-+ (match_operand:QI 2 "ubicom32_arith_operand" "rmI"))))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "shmrg.1\\t%0, %2, %1")
-+
-+; The combiner will generate this pattern given shift and or operations.
-+;
-+(define_insn "shmrg1_ior"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (ior:SI
-+ (ashift:SI (match_operand:SI 1 "ubicom32_data_register_operand" "d")
-+ (const_int 8))
-+ (zero_extend:SI
-+ (match_operand:QI 2 "ubicom32_arith_operand" "rmI"))))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "shmrg.1\\t%0, %2, %1")
-+
-+; The combiner will generate this pattern given shift and add operations.
-+; The canonical form that the combiner wants to use appears to be multiplies
-+; instead of shifts even if the compiled sources use shifts.
-+;
-+(define_insn "shmrg2_add"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (plus:SI
-+ (mult:SI (match_operand:SI 1 "ubicom32_data_register_operand" "d")
-+ (const_int 65536))
-+ (zero_extend:SI
-+ (match_operand:HI 2 "ubicom32_arith_operand" "rmI"))))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "shmrg.2\\t%0, %2, %1")
-+
-+; The combiner will generate this pattern given shift and or operations.
-+;
-+(define_insn "shmrg2_ior"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (ior:SI
-+ (ashift:SI (match_operand:SI 1 "ubicom32_data_register_operand" "d")
-+ (const_int 16))
-+ (zero_extend:SI
-+ (match_operand:HI 2 "ubicom32_arith_operand" "rmI"))))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "shmrg.2\\t%0, %2, %1")
-+
-+; Match the case where we load a word from the stack but then discard the
-+; upper 16 bits. We turn this into a zero-extended load of that useful
-+; 16 bits direct from the stack where possible.
-+;
-+
-+; XXX - do these peephole2 ops actually work after the CCmode conversion?
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (mem:SI (plus:SI (reg:SI SP_REGNO)
-+ (match_operand:SI 1 "const_int_operand" ""))))
-+ (set (match_operand:SI 2 "nonimmediate_operand" "")
-+ (zero_extend:SI (match_operand:HI 3 "register_operand" "")))]
-+ "(INTVAL (operands[1]) <= 252
-+ && REGNO (operands[3]) == REGNO (operands[0])
-+ && ((peep2_reg_dead_p (2, operands[0])
-+ && ! reg_mentioned_p (operands[0], operands[2]))
-+ || rtx_equal_p (operands[0], operands[2])))"
-+ [(set (match_dup 2)
-+ (zero_extend:SI (mem:HI (plus:SI (reg:SI SP_REGNO)
-+ (match_dup 4)))))]
-+ "{
-+ operands[4] = GEN_INT (INTVAL (operands[1]) + 2);
-+ }")
-+
-+; Match the case where we load a word from the stack but then discard the
-+; upper 16 bits. We turn this into a 16-bit load of that useful
-+; 16 bits direct from the stack where possible.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (mem:SI (plus:SI (reg:SI SP_REGNO)
-+ (match_operand:SI 1 "const_int_operand" ""))))
-+ (set (match_operand:HI 2 "nonimmediate_operand" "")
-+ (match_operand:HI 3 "register_operand" ""))]
-+ "(INTVAL (operands[1]) <= 252
-+ && REGNO (operands[3]) == REGNO (operands[0])
-+ && ((peep2_reg_dead_p (2, operands[0])
-+ && ! reg_mentioned_p (operands[0], operands[2]))
-+ || rtx_equal_p (operands[0], operands[2])))"
-+ [(set (match_dup 2)
-+ (mem:HI (plus:SI (reg:SI SP_REGNO)
-+ (match_dup 4))))]
-+ "{
-+ operands[4] = GEN_INT (INTVAL (operands[1]) + 2);
-+ }")
-+
-+; Match the case where we load a word from the stack but then discard the
-+; upper 24 bits. We turn this into a zero-extended load of that useful
-+; 8 bits direct from the stack where possible.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (mem:SI (plus:SI (reg:SI SP_REGNO)
-+ (match_operand:SI 1 "const_int_operand" ""))))
-+ (set (match_operand:SI 2 "nonimmediate_operand" "")
-+ (zero_extend:SI (match_operand:QI 3 "register_operand" "")))]
-+ "(INTVAL (operands[1]) <= 124
-+ && REGNO (operands[3]) == REGNO (operands[0])
-+ && ((peep2_reg_dead_p (2, operands[0])
-+ && ! reg_mentioned_p (operands[0], operands[2]))
-+ || rtx_equal_p (operands[0], operands[2])))"
-+ [(set (match_dup 2)
-+ (zero_extend:SI (mem:QI (plus:SI (reg:SI SP_REGNO)
-+ (match_dup 4)))))]
-+ "{
-+ operands[4] = GEN_INT (INTVAL (operands[1]) + 3);
-+ }")
-+
-+; Match the case where we load a word from the stack but then discard the
-+; upper 24 bits. We turn this into an 8-bit load of that useful
-+; 8 bits direct from the stack where possible.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (mem:SI (plus:SI (reg:SI SP_REGNO)
-+ (match_operand:SI 1 "const_int_operand" ""))))
-+ (set (match_operand:QI 2 "nonimmediate_operand" "")
-+ (match_operand:QI 3 "register_operand" ""))]
-+ "(INTVAL (operands[1]) <= 124
-+ && REGNO (operands[3]) == REGNO (operands[0])
-+ && ((peep2_reg_dead_p (2, operands[0])
-+ && ! reg_mentioned_p (operands[0], operands[2]))
-+ || rtx_equal_p (operands[0], operands[2])))"
-+ [(set (match_dup 2)
-+ (mem:QI (plus:SI (reg:SI SP_REGNO)
-+ (match_dup 4))))]
-+ "{
-+ operands[4] = GEN_INT (INTVAL (operands[1]) + 3);
-+ }")
-+
---- /dev/null
-+++ b/gcc/config/ubicom32/ubicom32.opt
-@@ -0,0 +1,27 @@
-+mdebug-address
-+Target RejectNegative Report Undocumented Mask(DEBUG_ADDRESS)
-+Debug addresses
-+
-+mdebug-context
-+Target RejectNegative Report Undocumented Mask(DEBUG_CONTEXT)
-+Debug contexts
-+
-+march=
-+Target Report Var(ubicom32_arch_name) Init("ubicom32v4") Joined
-+Specify the name of the target architecture
-+
-+mfdpic
-+Target Report Mask(FDPIC)
-+Enable Function Descriptor PIC mode
-+
-+minline-plt
-+Target Report Mask(INLINE_PLT)
-+Enable inlining of PLT in function calls
-+
-+mfastcall
-+Target Report Mask(FASTCALL)
-+Enable default fast (call) calling sequence for smaller applications
-+
-+mipos-abi
-+Target Report Mask(IPOS_ABI)
-+Enable the ipOS ABI in which D10-D13 are caller-clobbered
---- /dev/null
-+++ b/gcc/config/ubicom32/uclinux.h
-@@ -0,0 +1,67 @@
-+/* Definitions of target machine for Ubicom32-uclinux
-+
-+ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
-+ 2009 Free Software Foundation, Inc.
-+ Contributed by Ubicom, Inc.
-+
-+ This file is part of GCC.
-+
-+ GCC is free software; you can redistribute it and/or modify it
-+ under the terms of the GNU General Public License as published
-+ by the Free Software Foundation; either version 3, or (at your
-+ option) any later version.
-+
-+ GCC is distributed in the hope that it will be useful, but WITHOUT
-+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
-+ License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with GCC; see the file COPYING3. If not see
-+ <http://www.gnu.org/licenses/>. */
-+
-+/* Don't assume anything about the header files. */
-+#define NO_IMPLICIT_EXTERN_C
-+
-+#undef LIB_SPEC
-+#define LIB_SPEC \
-+ "%{pthread:-lpthread} " \
-+ "%{!shared:%{!symbolic: -lc}} "
-+
-+
-+#undef LINK_GCC_C_SEQUENCE_SPEC
-+#define LINK_GCC_C_SEQUENCE_SPEC \
-+ "%{!shared:--start-group} %G %L %{!shared:--end-group}%{shared:%G} "
-+
-+#undef STARTFILE_SPEC
-+#define STARTFILE_SPEC \
-+ "%{!shared: crt1%O%s}" \
-+ " crti%O%s crtbegin%O%s"
-+
-+#undef ENDFILE_SPEC
-+#define ENDFILE_SPEC "crtend%O%s crtn%O%s"
-+
-+/* This macro applies on top of OBJECT_FORMAT_ELF and indicates that
-+ we want to support both flat and ELF output. */
-+#define OBJECT_FORMAT_FLAT
-+
-+#undef DRIVER_SELF_SPECS
-+#define DRIVER_SELF_SPECS \
-+ "%{!mno-fastcall:-mfastcall}"
-+
-+/* taken from linux.h */
-+/* The GNU C++ standard library requires that these macros be defined. */
-+#undef CPLUSPLUS_CPP_SPEC
-+#define CPLUSPLUS_CPP_SPEC "-D_GNU_SOURCE %(cpp)"
-+
-+#define TARGET_OS_CPP_BUILTINS() \
-+ do { \
-+ builtin_define_std ("__UBICOM32__"); \
-+ builtin_define_std ("__ubicom32__"); \
-+ builtin_define ("__gnu_linux__"); \
-+ builtin_define_std ("linux"); \
-+ builtin_define_std ("unix"); \
-+ builtin_assert ("system=linux"); \
-+ builtin_assert ("system=unix"); \
-+ builtin_assert ("system=posix"); \
-+ } while (0)
---- /dev/null
-+++ b/gcc/config/ubicom32/xm-ubicom32.h
-@@ -0,0 +1,36 @@
-+/* Configuration for Ubicom's Ubicom32 architecture.
-+ Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Free Software
-+ Foundation, Inc.
-+ Contributed by Ubicom Inc.
-+
-+This file is part of GNU CC.
-+
-+GNU CC is free software; you can redistribute it and/or modify
-+it under the terms of the GNU General Public License as published by
-+the Free Software Foundation; either version 2, or (at your option)
-+any later version.
-+
-+GNU CC is distributed in the hope that it will be useful,
-+but WITHOUT ANY WARRANTY; without even the implied warranty of
-+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+GNU General Public License for more details.
-+
-+You should have received a copy of the GNU General Public License
-+along with GNU CC; see the file COPYING. If not, write to
-+the Free Software Foundation, 59 Temple Place - Suite 330,
-+Boston, MA 02111-1307, USA. */
-+
-+/* #defines that need visibility everywhere. */
-+#define FALSE 0
-+#define TRUE 1
-+
-+/* This describes the machine the compiler is hosted on. */
-+#define HOST_BITS_PER_CHAR 8
-+#define HOST_BITS_PER_SHORT 16
-+#define HOST_BITS_PER_INT 32
-+#define HOST_BITS_PER_LONG 32
-+#define HOST_BITS_PER_LONGLONG 64
-+
-+/* Arguments to use with `exit'. */
-+#define SUCCESS_EXIT_CODE 0
-+#define FATAL_EXIT_CODE 33
---- a/gcc/config.gcc
-+++ b/gcc/config.gcc
-@@ -2314,6 +2314,34 @@ spu-*-elf*)
- c_target_objs="${c_target_objs} spu-c.o"
- cxx_target_objs="${cxx_target_objs} spu-c.o"
- ;;
-+ubicom32-*-elf)
-+ xm_file=ubicom32/xm-ubicom32.h
-+ tm_file="${tm_file} ubicom32/elf.h" # still need dbxelf.h elfos.h
-+ tmake_file=ubicom32/t-ubicom32
-+ ;;
-+ubicom32-*-uclinux*)
-+ xm_file=ubicom32/xm-ubicom32.h
-+ tm_file="${tm_file} ubicom32/elf.h ubicom32/uclinux.h" # still need dbxelf.h elfos.h linux.h
-+ tm_defines="${tm_defines} UCLIBC_DEFAULT=1"
-+ extra_options="${extra_options} linux.opt"
-+ tmake_file=ubicom32/t-ubicom32-uclinux
-+ use_collect2=no
-+ ;;
-+ubicom32-*-linux-uclibc)
-+ xm_file=ubicom32/xm-ubicom32.h
-+ tm_file="${tm_file} ubicom32/elf.h linux.h ubicom32/linux.h" # still need dbxelf.h elfos.h
-+ tmake_file="t-slibgcc-elf-ver ubicom32/t-ubicom32-linux"
-+ extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
-+ use_collect2=no
-+ ;;
-+ubicom32-*-linux*)
-+ xm_file=ubicom32/xm-ubicom32.h
-+ tm_file="${tm_file} ubicom32/elf.h linux.h ubicom32/linux.h" # still need dbxelf.h elfos.h
-+ tmake_file="t-slibgcc-elf-ver ubicom32/t-ubicom32-linux"
-+ tm_defines="${tm_defines} UCLIBC_DEFAULT=1"
-+ extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
-+ use_collect2=no
-+ ;;
- v850e1-*-*)
- target_cpu_default="TARGET_CPU_v850e1"
- tm_file="dbxelf.h elfos.h svr4.h v850/v850.h"
---- a/libgcc/config.host
-+++ b/libgcc/config.host
-@@ -551,6 +551,15 @@ sparc64-*-netbsd*)
- ;;
- spu-*-elf*)
- ;;
-+ubicom32*-*-elf*)
-+ ;;
-+ubicom32*-*-uclinux*)
-+ ;;
-+ubicom32*-*-linux*)
-+ # No need to build crtbeginT.o on uClibc systems. Should probably
-+ # be moved to the OS specific section above.
-+ extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
-+ ;;
- v850e1-*-*)
- ;;
- v850e-*-*)
+++ /dev/null
---- a/gcc/config/arm/linux-elf.h
-+++ b/gcc/config/arm/linux-elf.h
-@@ -60,7 +60,7 @@
- %{shared:-lc} \
- %{!shared:%{profile:-lc_p}%{!profile:-lc}}"
-
--#define LIBGCC_SPEC "%{msoft-float:-lfloat} %{mfloat-abi=soft*:-lfloat} -lgcc"
-+#define LIBGCC_SPEC "-lgcc"
-
- #define GLIBC_DYNAMIC_LINKER "/lib/ld-linux.so.2"
-
---- a/gcc/config/arm/t-linux
-+++ b/gcc/config/arm/t-linux
-@@ -4,7 +4,10 @@
-
- LIB1ASMSRC = arm/lib1funcs.asm
- LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_lnx _clzsi2 _clzdi2 \
-- _arm_addsubdf3 _arm_addsubsf3
-+ _arm_addsubdf3 _arm_addsubsf3 \
-+ _negdf2 _addsubdf3 _muldivdf3 _cmpdf2 _unorddf2 _fixdfsi _fixunsdfsi \
-+ _truncdfsf2 _negsf2 _addsubsf3 _muldivsf3 _cmpsf2 _unordsf2 \
-+ _fixsfsi _fixunssfsi _floatdidf _floatundidf _floatdisf _floatundisf
-
- # MULTILIB_OPTIONS = mhard-float/msoft-float
- # MULTILIB_DIRNAMES = hard-float soft-float
+++ /dev/null
---- a/libgcc/Makefile.in
-+++ b/libgcc/Makefile.in
-@@ -729,11 +729,12 @@ $(libgcov-objects): %$(objext): $(gcc_sr
-
- # Static libraries.
- libgcc.a: $(libgcc-objects)
-+libgcc_pic.a: $(libgcc-s-objects)
- libgcov.a: $(libgcov-objects)
- libunwind.a: $(libunwind-objects)
- libgcc_eh.a: $(libgcc-eh-objects)
-
--libgcc.a libgcov.a libunwind.a libgcc_eh.a:
-+libgcc.a libgcov.a libunwind.a libgcc_eh.a libgcc_pic.a:
- -rm -f $@
-
- objects="$(objects)"; \
-@@ -755,7 +756,7 @@ libgcc_s$(SHLIB_EXT): libunwind$(SHLIB_E
- endif
-
- ifeq ($(enable_shared),yes)
--all: libgcc_eh.a libgcc_s$(SHLIB_EXT)
-+all: libgcc_eh.a libgcc_pic.a libgcc_s$(SHLIB_EXT)
- ifneq ($(LIBUNWIND),)
- all: libunwind$(SHLIB_EXT)
- endif
-@@ -928,6 +929,10 @@ install-shared:
- chmod 644 $(DESTDIR)$(inst_libdir)/libgcc_eh.a
- $(RANLIB) $(DESTDIR)$(inst_libdir)/libgcc_eh.a
-
-+ $(INSTALL_DATA) libgcc_pic.a $(mapfile) $(DESTDIR)$(inst_libdir)/
-+ chmod 644 $(DESTDIR)$(inst_libdir)/libgcc_pic.a
-+ $(RANLIB) $(DESTDIR)$(inst_libdir)/libgcc_pic.a
-+
- $(subst @multilib_dir@,$(MULTIDIR),$(subst \
- @shlib_base_name@,libgcc_s,$(subst \
- @shlib_slibdir_qual@,$(MULTIOSSUBDIR),$(SHLIB_INSTALL))))
+++ /dev/null
-
- This patch brings over a few features from MirBSD:
- * -fhonour-copts
- If this option is not given, it's warned (depending
- on environment variables). This is to catch errors
- of misbuilt packages which override CFLAGS themselves.
- * -Werror-maybe-reset
- Has the effect of -Wno-error if GCC_NO_WERROR is
- set and not '0', a no-operation otherwise. This is
- to be able to use -Werror in "make" but prevent
- GNU autoconf generated configure scripts from
- freaking out.
- * Make -fno-strict-aliasing and -fno-delete-null-pointer-checks
- the default for -O2/-Os, because they trigger gcc bugs
- and can delete code with security implications.
-
- This patch was authored by Thorsten Glaser <tg at mirbsd.de>
- with copyright assignment to the FSF in effect.
-
---- a/gcc/c-opts.c
-+++ b/gcc/c-opts.c
-@@ -105,6 +105,9 @@
- /* Number of deferred options scanned for -include. */
- static size_t include_cursor;
-
-+/* Check if a port honours COPTS. */
-+static int honour_copts = 0;
-+
- static void set_Wimplicit (int);
- static void handle_OPT_d (const char *);
- static void set_std_cxx98 (int);
-@@ -454,6 +457,14 @@
- enable_warning_as_error ("implicit-function-declaration", value, CL_C | CL_ObjC);
- break;
-
-+ case OPT_Werror_maybe_reset:
-+ {
-+ char *ev = getenv ("GCC_NO_WERROR");
-+ if ((ev != NULL) && (*ev != '0'))
-+ cpp_opts->warnings_are_errors = 0;
-+ }
-+ break;
-+
- case OPT_Wformat:
- set_Wformat (value);
- break;
-@@ -690,6 +701,12 @@
- flag_exceptions = value;
- break;
-
-+ case OPT_fhonour_copts:
-+ if (c_language == clk_c) {
-+ honour_copts++;
-+ }
-+ break;
-+
- case OPT_fimplement_inlines:
- flag_implement_inlines = value;
- break;
-@@ -1209,6 +1226,47 @@
- return false;
- }
-
-+ if (c_language == clk_c) {
-+ char *ev = getenv ("GCC_HONOUR_COPTS");
-+ int evv;
-+ if (ev == NULL)
-+ evv = -1;
-+ else if ((*ev == '0') || (*ev == '\0'))
-+ evv = 0;
-+ else if (*ev == '1')
-+ evv = 1;
-+ else if (*ev == '2')
-+ evv = 2;
-+ else if (*ev == 's')
-+ evv = -1;
-+ else {
-+ warning (0, "unknown GCC_HONOUR_COPTS value, assuming 1");
-+ evv = 1; /* maybe depend this on something like MIRBSD_NATIVE? */
-+ }
-+ if (evv == 1) {
-+ if (honour_copts == 0) {
-+ error ("someone does not honour COPTS at all in lenient mode");
-+ return false;
-+ } else if (honour_copts != 1) {
-+ warning (0, "someone does not honour COPTS correctly, passed %d times",
-+ honour_copts);
-+ }
-+ } else if (evv == 2) {
-+ if (honour_copts == 0) {
-+ error ("someone does not honour COPTS at all in strict mode");
-+ return false;
-+ } else if (honour_copts != 1) {
-+ error ("someone does not honour COPTS correctly, passed %d times",
-+ honour_copts);
-+ return false;
-+ }
-+ } else if (evv == 0) {
-+ if (honour_copts != 1)
-+ inform (0, "someone does not honour COPTS correctly, passed %d times",
-+ honour_copts);
-+ }
-+ }
-+
- return true;
- }
-
---- a/gcc/c.opt
-+++ b/gcc/c.opt
-@@ -215,6 +215,10 @@
- C ObjC RejectNegative Warning
- This switch is deprecated; use -Werror=implicit-function-declaration instead
-
-+Werror-maybe-reset
-+C ObjC C++ ObjC++
-+; Documented in common.opt
-+
- Wfloat-equal
- C ObjC C++ ObjC++ Var(warn_float_equal) Warning
- Warn if testing floating point numbers for equality
-@@ -609,6 +613,9 @@
- fhonor-std
- C++ ObjC++
-
-+fhonour-copts
-+C ObjC C++ ObjC++ RejectNegative
-+
- fhosted
- C ObjC
- Assume normal C execution environment
---- a/gcc/common.opt
-+++ b/gcc/common.opt
-@@ -102,6 +102,10 @@
- Common Joined
- Treat specified warning as error
-
-+Werror-maybe-reset
-+Common
-+If environment variable GCC_NO_WERROR is set, act as -Wno-error
-+
- Wextra
- Common Warning
- Print extra (possibly unwanted) warnings
-@@ -573,6 +577,9 @@
- Common Report Var(flag_guess_branch_prob) Optimization
- Enable guessing of branch probabilities
-
-+fhonour-copts
-+Common RejectNegative
-+
- ; Nonzero means ignore `#ident' directives. 0 means handle them.
- ; Generate position-independent code for executables if possible
- ; On SVR4 targets, it also controls whether or not to emit a
---- a/gcc/opts.c
-+++ b/gcc/opts.c
-@@ -896,9 +896,6 @@
- flag_schedule_insns_after_reload = opt2;
- #endif
- flag_regmove = opt2;
-- flag_strict_aliasing = opt2;
-- flag_strict_overflow = opt2;
-- flag_delete_null_pointer_checks = opt2;
- flag_reorder_blocks = opt2;
- flag_reorder_functions = opt2;
- flag_tree_vrp = opt2;
-@@ -922,6 +919,9 @@
-
- /* -O3 optimizations. */
- opt3 = (optimize >= 3);
-+ flag_strict_aliasing = opt3;
-+ flag_strict_overflow = opt3;
-+ flag_delete_null_pointer_checks = opt3;
- flag_predictive_commoning = opt3;
- flag_inline_functions = opt3;
- flag_unswitch_loops = opt3;
-@@ -1601,6 +1601,17 @@
- enable_warning_as_error (arg, value, lang_mask);
- break;
-
-+ case OPT_Werror_maybe_reset:
-+ {
-+ char *ev = getenv ("GCC_NO_WERROR");
-+ if ((ev != NULL) && (*ev != '0'))
-+ warnings_are_errors = 0;
-+ }
-+ break;
-+
-+ case OPT_fhonour_copts:
-+ break;
-+
- case OPT_Wextra:
- set_Wextra (value);
- break;
---- a/gcc/doc/cppopts.texi
-+++ b/gcc/doc/cppopts.texi
-@@ -164,6 +164,11 @@
- Make all warnings into hard errors. Source code which triggers warnings
- will be rejected.
-
-+ at item -Werror-maybe-reset
-+ at opindex Werror-maybe-reset
-+Act like @samp{-Wno-error} if the @env{GCC_NO_WERROR} environment
-+variable is set to anything other than 0 or empty.
-+
- @item -Wsystem-headers
- @opindex Wsystem-headers
- Issue warnings for code in system headers. These are normally unhelpful
---- a/gcc/doc/invoke.texi
-+++ b/gcc/doc/invoke.texi
-@@ -234,7 +234,7 @@
- -Wconversion -Wcoverage-mismatch -Wno-deprecated @gol
- -Wno-deprecated-declarations -Wdisabled-optimization @gol
- -Wno-div-by-zero -Wempty-body -Wenum-compare -Wno-endif-labels @gol
---Werror -Werror=* @gol
-+-Werror -Werror=* -Werror-maybe-reset @gol
- -Wfatal-errors -Wfloat-equal -Wformat -Wformat=2 @gol
- -Wno-format-contains-nul -Wno-format-extra-args -Wformat-nonliteral @gol
- -Wformat-security -Wformat-y2k @gol
-@@ -4161,6 +4161,22 @@
- @option{-Wall} and by @option{-pedantic}, which can be disabled with
- @option{-Wno-pointer-sign}.
-
-+ at item -Werror-maybe-reset
-+ at opindex Werror-maybe-reset
-+Act like @samp{-Wno-error} if the @env{GCC_NO_WERROR} environment
-+variable is set to anything other than 0 or empty.
-+
-+ at item -fhonour-copts
-+ at opindex fhonour-copts
-+If @env{GCC_HONOUR_COPTS} is set to 1, abort if this option is not
-+given at least once, and warn if it is given more than once.
-+If @env{GCC_HONOUR_COPTS} is set to 2, abort if this option is not
-+given exactly once.
-+If @env{GCC_HONOUR_COPTS} is set to 0 or unset, warn if this option
-+is not given exactly once.
-+The warning is quelled if @env{GCC_HONOUR_COPTS} is set to @samp{s}.
-+This flag and environment variable only affect the C language.
-+
- @item -Wstack-protector
- @opindex Wstack-protector
- @opindex Wno-stack-protector
-@@ -5699,7 +5715,7 @@
- second branch or a point immediately following it, depending on whether
- the condition is known to be true or false.
-
--Enabled at levels @option{-O2}, @option{-O3}, @option{-Os}.
-+Enabled at levels @option{-O3}.
-
- @item -fsplit-wide-types
- @opindex fsplit-wide-types
-@@ -5844,7 +5860,7 @@
- @option{-fno-delete-null-pointer-checks} to disable this optimization
- for programs which depend on that behavior.
-
--Enabled at levels @option{-O2}, @option{-O3}, @option{-Os}.
-+Enabled at levels @option{-O3}.
-
- @item -fexpensive-optimizations
- @opindex fexpensive-optimizations
---- a/gcc/java/jvspec.c
-+++ b/gcc/java/jvspec.c
-@@ -670,6 +670,7 @@
- class name. Append dummy `.c' that can be stripped by set_input so %b
- is correct. */
- set_input (concat (main_class_name, "main.c", NULL));
-+ putenv ("GCC_HONOUR_COPTS=s"); /* XXX hack! */
- err = do_spec (jvgenmain_spec);
- if (err == 0)
- {
+++ /dev/null
---- gcc-4.4.0/gcc/config/arm/arm-protos.h 2009-02-20 16:20:38.000000000 +0100
-+++ gcc-4.4.0.new/gcc/config/arm/arm-protos.h 2009-04-22 16:00:58.000000000 +0200
-@@ -43,10 +43,10 @@
- extern void arm_output_fn_unwind (FILE *, bool);
-
-
--#ifdef RTX_CODE
- extern bool arm_vector_mode_supported_p (enum machine_mode);
- extern int arm_hard_regno_mode_ok (unsigned int, enum machine_mode);
- extern int const_ok_for_arm (HOST_WIDE_INT);
-+#ifdef RTX_CODE
- extern int arm_split_constant (RTX_CODE, enum machine_mode, rtx,
- HOST_WIDE_INT, rtx, rtx, int);
- extern RTX_CODE arm_canonicalize_comparison (RTX_CODE, enum machine_mode,
+++ /dev/null
-Index: gcc-4.4.1/gcc/config.gcc
-===================================================================
---- gcc-4.4.1.orig/gcc/config.gcc 2009-10-21 16:14:24.000000000 +0200
-+++ gcc-4.4.1/gcc/config.gcc 2009-10-21 16:14:25.000000000 +0200
-@@ -1499,6 +1499,7 @@
- if test x$sjlj != x1; then
- tmake_file="$tmake_file m68k/t-slibgcc-elf-ver"
- fi
-+ tmake_file="m68k/t-floatlib m68k/t-m68kbare m68k/t-m68kelf"
- ;;
- m68k-*-rtems*)
- default_m68k_cpu=68020
+++ /dev/null
---- a/contrib/regression/objs-gcc.sh
-+++ b/contrib/regression/objs-gcc.sh
-@@ -106,6 +106,10 @@
- then
- make all-gdb all-dejagnu all-ld || exit 1
- make install-gdb install-dejagnu install-ld || exit 1
-+elif [ $H_REAL_TARGET = $H_REAL_HOST -a $H_REAL_TARGET = i686-pc-linux-uclibc ]
-+ then
-+ make all-gdb all-dejagnu all-ld || exit 1
-+ make install-gdb install-dejagnu install-ld || exit 1
- elif [ $H_REAL_TARGET = $H_REAL_HOST ] ; then
- make bootstrap || exit 1
- make install || exit 1
---- a/libjava/classpath/ltconfig
-+++ b/libjava/classpath/ltconfig
-@@ -603,7 +603,7 @@
-
- # Transform linux* to *-*-linux-gnu*, to support old configure scripts.
- case $host_os in
--linux-gnu*) ;;
-+linux-gnu*|linux-uclibc*) ;;
- linux*) host=`echo $host | sed 's/^\(.*-.*-linux\)\(.*\)$/\1-gnu\2/'`
- esac
-
-@@ -1251,7 +1251,7 @@
- ;;
-
- # This must be Linux ELF.
--linux-gnu*)
-+linux*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
+++ /dev/null
---- a/boehm-gc/include/gc.h
-+++ b/boehm-gc/include/gc.h
-@@ -503,7 +503,7 @@
- #if defined(__linux__) || defined(__GLIBC__)
- # include <features.h>
- # if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1 || __GLIBC__ > 2) \
-- && !defined(__ia64__)
-+ && !defined(__ia64__) && !defined(__UCLIBC__)
- # ifndef GC_HAVE_BUILTIN_BACKTRACE
- # define GC_HAVE_BUILTIN_BACKTRACE
- # endif
+++ /dev/null
---- a/libstdc++-v3/include/c_global/cstdio
-+++ b/libstdc++-v3/include/c_global/cstdio
-@@ -139,7 +139,7 @@
-
- _GLIBCXX_END_NAMESPACE
-
--#if _GLIBCXX_USE_C99
-+#if _GLIBCXX_USE_C99 || defined __UCLIBC__
-
- #undef snprintf
- #undef vfscanf
+++ /dev/null
---- a/libmudflap/mf-hooks2.c
-+++ b/libmudflap/mf-hooks2.c
-@@ -421,7 +421,7 @@
- {
- TRACE ("%s\n", __PRETTY_FUNCTION__);
- MF_VALIDATE_EXTENT(s, n, __MF_CHECK_WRITE, "bzero region");
-- bzero (s, n);
-+ memset (s, 0, n);
- }
-
-
-@@ -431,7 +431,7 @@
- TRACE ("%s\n", __PRETTY_FUNCTION__);
- MF_VALIDATE_EXTENT(src, n, __MF_CHECK_READ, "bcopy src");
- MF_VALIDATE_EXTENT(dest, n, __MF_CHECK_WRITE, "bcopy dest");
-- bcopy (src, dest, n);
-+ memmove (dest, src, n);
- }
-
-
-@@ -441,7 +441,7 @@
- TRACE ("%s\n", __PRETTY_FUNCTION__);
- MF_VALIDATE_EXTENT(s1, n, __MF_CHECK_READ, "bcmp 1st arg");
- MF_VALIDATE_EXTENT(s2, n, __MF_CHECK_READ, "bcmp 2nd arg");
-- return bcmp (s1, s2, n);
-+ return n == 0 ? 0 : memcmp (s1, s2, n);
- }
-
-
-@@ -450,7 +450,7 @@
- size_t n = strlen (s);
- TRACE ("%s\n", __PRETTY_FUNCTION__);
- MF_VALIDATE_EXTENT(s, CLAMPADD(n, 1), __MF_CHECK_READ, "index region");
-- return index (s, c);
-+ return strchr (s, c);
- }
-
-
-@@ -459,7 +459,7 @@
- size_t n = strlen (s);
- TRACE ("%s\n", __PRETTY_FUNCTION__);
- MF_VALIDATE_EXTENT(s, CLAMPADD(n, 1), __MF_CHECK_READ, "rindex region");
-- return rindex (s, c);
-+ return strrchr (s, c);
- }
-
- /* XXX: stpcpy, memccpy */
+++ /dev/null
---- a/config.sub
-+++ b/config.sub
-@@ -283,6 +283,7 @@ case $basic_machine in
- | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
- | spu | strongarm \
- | tahoe | thumb | tic4x | tic80 | tron \
-+ | ubicom32 \
- | v850 | v850e \
- | ubicom32 \
- | we32k \
-@@ -367,6 +368,7 @@ case $basic_machine in
- | tahoe-* | thumb-* \
- | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
- | tron-* \
-+ | ubicom32-* \
- | v850-* | v850e-* | vax-* \
- | ubicom32-* \
- | we32k-* \
---- a/configure
-+++ b/configure
-@@ -2688,6 +2688,9 @@ case "${target}" in
- ip2k-*-*)
- noconfigdirs="$noconfigdirs target-libiberty target-libstdc++-v3 ${libgcj}"
- ;;
-+ ubicom32-*-*)
-+ noconfigdirs="$noconfigdirs target-libffi"
-+ ;;
- *-*-linux* | *-*-gnu* | *-*-k*bsd*-gnu | *-*-kopensolaris*-gnu)
- noconfigdirs="$noconfigdirs target-newlib target-libgloss"
- ;;
---- /dev/null
-+++ b/gcc/config/ubicom32/constraints.md
-@@ -0,0 +1,149 @@
-+; Constraint definitions for Ubicom32
-+
-+; Copyright (C) 2009 Free Software Foundation, Inc.
-+; Contributed by Ubicom, Inc.
-+
-+; This file is part of GCC.
-+
-+; GCC is free software; you can redistribute it and/or modify it
-+; under the terms of the GNU General Public License as published
-+; by the Free Software Foundation; either version 3, or (at your
-+; option) any later version.
-+
-+; GCC is distributed in the hope that it will be useful, but WITHOUT
-+; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-+; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
-+; License for more details.
-+
-+; You should have received a copy of the GNU General Public License
-+; along with GCC; see the file COPYING3. If not see
-+; <http://www.gnu.org/licenses/>.
-+
-+(define_register_constraint "a" "ALL_ADDRESS_REGS"
-+ "An An register.")
-+
-+(define_register_constraint "d" "DATA_REGS"
-+ "A Dn register.")
-+
-+(define_register_constraint "h" "ACC_REGS"
-+ "An accumulator register.")
-+
-+(define_register_constraint "l" "ACC_LO_REGS"
-+ "An accn_lo register.")
-+
-+(define_register_constraint "Z" "FDPIC_REG"
-+ "The FD-PIC GOT pointer: A0.")
-+
-+(define_constraint "I"
-+ "An 8-bit signed constant value."
-+ (and (match_code "const_int")
-+ (match_test "(ival >= -128) && (ival <= 127)")))
-+
-+(define_constraint "Q"
-+ "An 8-bit signed constant value represented as unsigned."
-+ (and (match_code "const_int")
-+ (match_test "(ival >= 0x00) && (ival <= 0xff)")))
-+
-+(define_constraint "R"
-+ "An 8-bit signed constant value represented as unsigned."
-+ (and (match_code "const_int")
-+ (match_test "((ival >= 0x0000) && (ival <= 0x007f)) || ((ival >= 0xff80) && (ival <= 0xffff))")))
-+
-+(define_constraint "J"
-+ "A 7-bit unsigned constant value."
-+ (and (match_code "const_int")
-+ (match_test "(ival >= 0) && (ival <= 127)")))
-+
-+(define_constraint "K"
-+ "A 7-bit unsigned constant value shifted << 1."
-+ (and (match_code "const_int")
-+ (match_test "(ival >= 0) && (ival <= 254) && ((ival & 1) == 0)")))
-+
-+(define_constraint "L"
-+ "A 7-bit unsigned constant value shifted << 2."
-+ (and (match_code "const_int")
-+ (match_test "(ival >= 0) && (ival <= 508) && ((ival & 3) == 0)")))
-+
-+(define_constraint "M"
-+ "A 5-bit unsigned constant value."
-+ (and (match_code "const_int")
-+ (match_test "(ival >= 0) && (ival <= 31)")))
-+
-+(define_constraint "N"
-+ "A signed 16 bit constant value."
-+ (and (match_code "const_int")
-+ (match_test "(ival >= -32768) && (ival <= 32767)")))
-+
-+(define_constraint "O"
-+ "An exact bitmask of contiguous 1 bits starting at bit 0."
-+ (and (match_code "const_int")
-+ (match_test "exact_log2 (ival + 1) != -1")))
-+
-+(define_constraint "P"
-+ "A 7-bit negative constant value shifted << 2."
-+ (and (match_code "const_int")
-+ (match_test "(ival >= -504) && (ival <= 0) && ((ival & 3) == 0)")))
-+
-+(define_constraint "S"
-+ "A symbolic reference."
-+ (match_code "symbol_ref"))
-+
-+(define_constraint "Y"
-+ "An FD-PIC symbolic reference."
-+ (and (match_test "TARGET_FDPIC")
-+ (match_test "GET_CODE (op) == UNSPEC")
-+ (ior (match_test "XINT (op, 1) == UNSPEC_FDPIC_GOT")
-+ (match_test "XINT (op, 1) == UNSPEC_FDPIC_GOT_FUNCDESC"))))
-+
-+(define_memory_constraint "T1"
-+ "A memory operand that can be used for .1 instruction."
-+ (and (match_test "memory_operand (op, GET_MODE(op))")
-+ (match_test "GET_MODE (op) == QImode")))
-+
-+(define_memory_constraint "T2"
-+ "A memory operand that can be used for .2 instruction."
-+ (and (match_test "memory_operand (op, GET_MODE(op))")
-+ (match_test "GET_MODE (op) == HImode")))
-+
-+(define_memory_constraint "T4"
-+ "A memory operand that can be used for .4 instruction."
-+ (and (match_test "memory_operand (op, GET_MODE(op))")
-+ (ior (match_test "GET_MODE (op) == SImode")
-+ (match_test "GET_MODE (op) == DImode")
-+ (match_test "GET_MODE (op) == SFmode"))))
-+
-+(define_memory_constraint "U1"
-+ "An offsettable memory operand that can be used for .1 instruction."
-+ (and (match_test "memory_operand (op, GET_MODE(op))")
-+ (match_test "GET_MODE (op) == QImode")
-+ (match_test "GET_CODE (XEXP (op, 0)) != POST_INC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_INC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != POST_DEC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_DEC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != POST_MODIFY")
-+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_MODIFY")))
-+
-+(define_memory_constraint "U2"
-+ "An offsettable memory operand that can be used for .2 instruction."
-+ (and (match_test "memory_operand (op, GET_MODE(op))")
-+ (match_test "GET_MODE (op) == HImode")
-+ (match_test "GET_CODE (XEXP (op, 0)) != POST_INC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_INC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != POST_DEC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_DEC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != POST_MODIFY")
-+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_MODIFY")))
-+
-+(define_memory_constraint "U4"
-+ "An offsettable memory operand that can be used for .4 instruction."
-+ (and (match_test "memory_operand (op, GET_MODE(op))")
-+ (ior (match_test "GET_MODE (op) == SImode")
-+ (match_test "GET_MODE (op) == DImode")
-+ (match_test "GET_MODE (op) == SFmode"))
-+ (match_test "GET_CODE (XEXP (op, 0)) != POST_INC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_INC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != POST_DEC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_DEC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != POST_MODIFY")
-+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_MODIFY")))
-+
---- /dev/null
-+++ b/gcc/config/ubicom32/crti.S
-@@ -0,0 +1,54 @@
-+/* Specialized code needed to support construction and destruction of
-+ file-scope objects in C++ and Java code, and to support exception handling.
-+ Copyright (C) 1999 Free Software Foundation, Inc.
-+ Contributed by Charles-Antoine Gauthier (charles.gauthier@iit.nrc.ca).
-+
-+This file is part of GCC.
-+
-+GCC is free software; you can redistribute it and/or modify
-+it under the terms of the GNU General Public License as published by
-+the Free Software Foundation; either version 2, or (at your option)
-+any later version.
-+
-+GCC is distributed in the hope that it will be useful,
-+but WITHOUT ANY WARRANTY; without even the implied warranty of
-+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+GNU General Public License for more details.
-+
-+You should have received a copy of the GNU General Public License
-+along with GCC; see the file COPYING. If not, write to
-+the Free Software Foundation, 59 Temple Place - Suite 330,
-+Boston, MA 02111-1307, USA. */
-+
-+/* As a special exception, if you link this library with files
-+ compiled with GCC to produce an executable, this does not cause
-+ the resulting executable to be covered by the GNU General Public License.
-+ This exception does not however invalidate any other reasons why
-+ the executable file might be covered by the GNU General Public License. */
-+
-+/*
-+ * This file just supplies function prologues for the .init and .fini
-+ * sections. It is linked in before crtbegin.o.
-+ */
-+ .file "crti.o"
-+ .ident "GNU C crti.o"
-+
-+ .section .init
-+ .align 2
-+ .globl _init
-+ .type _init, @function
-+_init:
-+ move.4 -4(sp)++, a5
-+#ifdef __UBICOM32_FDPIC__
-+ move.4 -4(sp)++, a0
-+#endif
-+
-+ .section .fini
-+ .align 2
-+ .globl _fini
-+ .type _fini, @function
-+_fini:
-+ move.4 -4(sp)++, a5
-+#ifdef __UBICOM32_FDPIC__
-+ move.4 -4(sp)++, a0
-+#endif
---- /dev/null
-+++ b/gcc/config/ubicom32/crtn.S
-@@ -0,0 +1,47 @@
-+/* Specialized code needed to support construction and destruction of
-+ file-scope objects in C++ and Java code, and to support exception handling.
-+ Copyright (C) 1999 Free Software Foundation, Inc.
-+ Contributed by Charles-Antoine Gauthier (charles.gauthier@iit.nrc.ca).
-+
-+This file is part of GCC.
-+
-+GCC is free software; you can redistribute it and/or modify
-+it under the terms of the GNU General Public License as published by
-+the Free Software Foundation; either version 2, or (at your option)
-+any later version.
-+
-+GCC is distributed in the hope that it will be useful,
-+but WITHOUT ANY WARRANTY; without even the implied warranty of
-+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+GNU General Public License for more details.
-+
-+You should have received a copy of the GNU General Public License
-+along with GCC; see the file COPYING. If not, write to
-+the Free Software Foundation, 59 Temple Place - Suite 330,
-+Boston, MA 02111-1307, USA. */
-+
-+/* As a special exception, if you link this library with files
-+ compiled with GCC to produce an executable, this does not cause
-+ the resulting executable to be covered by the GNU General Public License.
-+ This exception does not however invalidate any other reasons why
-+ the executable file might be covered by the GNU General Public License. */
-+
-+/*
-+ * This file supplies function epilogues for the .init and .fini sections.
-+ * It is linked in after all other files.
-+ */
-+
-+ .file "crtn.o"
-+ .ident "GNU C crtn.o"
-+
-+ .section .init
-+#ifdef __UBICOM32_FDPIC__
-+ move.4 a0, (sp)4++
-+#endif
-+ ret (sp)4++
-+
-+ .section .fini
-+#ifdef __UBICOM32_FDPIC__
-+ move.4 a0, (sp)4++
-+#endif
-+ ret (sp)4++
---- /dev/null
-+++ b/gcc/config/ubicom32/elf.h
-@@ -0,0 +1,29 @@
-+#undef STARTFILE_SPEC
-+#define STARTFILE_SPEC "\
-+%{msim:%{!shared:crt0%O%s}} \
-+crti%O%s crtbegin%O%s"
-+
-+#undef ENDFILE_SPEC
-+#define ENDFILE_SPEC "crtend%O%s crtn%O%s"
-+
-+#ifdef __UBICOM32_FDPIC__
-+#define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC) \
-+ asm (SECTION_OP); \
-+ asm ("move.4 a0, 0(sp);\n\t" \
-+ "call a5," USER_LABEL_PREFIX #FUNC ";"); \
-+ asm (TEXT_SECTION_ASM_OP);
-+#endif
-+
-+#undef SUBTARGET_DRIVER_SELF_SPECS
-+#define SUBTARGET_DRIVER_SELF_SPECS \
-+ "%{mfdpic:-msim} "
-+
-+#define NO_IMPLICIT_EXTERN_C
-+
-+/*
-+ * We need this to compile crtbegin/crtend. This should really be picked
-+ * up from elfos.h but at the moment including elfos.h causes other more
-+ * serous linker issues.
-+ */
-+#define INIT_SECTION_ASM_OP "\t.section\t.init"
-+#define FINI_SECTION_ASM_OP "\t.section\t.fini"
---- /dev/null
-+++ b/gcc/config/ubicom32/linux.h
-@@ -0,0 +1,80 @@
-+/* Definitions of target machine for Ubicom32-uclinux
-+
-+ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
-+ 2009 Free Software Foundation, Inc.
-+ Contributed by Ubicom, Inc.
-+
-+ This file is part of GCC.
-+
-+ GCC is free software; you can redistribute it and/or modify it
-+ under the terms of the GNU General Public License as published
-+ by the Free Software Foundation; either version 3, or (at your
-+ option) any later version.
-+
-+ GCC is distributed in the hope that it will be useful, but WITHOUT
-+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
-+ License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with GCC; see the file COPYING3. If not see
-+ <http://www.gnu.org/licenses/>. */
-+
-+/* Don't assume anything about the header files. */
-+#define NO_IMPLICIT_EXTERN_C
-+
-+#undef LIB_SPEC
-+#define LIB_SPEC \
-+ "%{pthread:-lpthread} " \
-+ "-lc"
-+
-+#undef LINK_GCC_C_SEQUENCE_SPEC
-+#define LINK_GCC_C_SEQUENCE_SPEC \
-+ "%{static:--start-group} %G %L %{static:--end-group} " \
-+ "%{!static: %G}"
-+
-+#undef STARTFILE_SPEC
-+#define STARTFILE_SPEC \
-+ "%{!shared: %{pg|p|profile:gcrt1%O%s;pie:Scrt1%O%s;:crt1%O%s}} " \
-+ "crtreloc%O%s crti%O%s %{shared|pie:crtbeginS%O%s;:crtbegin%O%s}"
-+
-+#undef ENDFILE_SPEC
-+#define ENDFILE_SPEC \
-+ "%{shared|pie:crtendS%O%s;:crtend%O%s} crtn%O%s"
-+
-+/* taken from linux.h */
-+/* The GNU C++ standard library requires that these macros be defined. */
-+#undef CPLUSPLUS_CPP_SPEC
-+#define CPLUSPLUS_CPP_SPEC "-D_GNU_SOURCE %(cpp)"
-+
-+#define TARGET_OS_CPP_BUILTINS() \
-+ do { \
-+ builtin_define_std ("__UBICOM32__"); \
-+ builtin_define_std ("__ubicom32__"); \
-+ builtin_define ("__gnu_linux__"); \
-+ builtin_define_std ("linux"); \
-+ builtin_define_std ("unix"); \
-+ builtin_assert ("system=linux"); \
-+ builtin_assert ("system=unix"); \
-+ builtin_assert ("system=posix"); \
-+ } while (0)
-+
-+#define OBJECT_FORMAT_ELF
-+
-+
-+#undef DRIVER_SELF_SPECS
-+#define DRIVER_SELF_SPECS \
-+ "%{!mno-fdpic:-mfdpic}"
-+
-+#undef LINK_SPEC
-+#define LINK_SPEC "%{mfdpic: -m elf32ubicom32fdpic -z text } %{shared} %{pie} \
-+ %{static:-dn -Bstatic} \
-+ %{shared:-G -Bdynamic} \
-+ %{!shared: %{!static: \
-+ %{rdynamic:-export-dynamic} \
-+ %{!dynamic-linker:-dynamic-linker /lib/ld-uClibc.so.0}} \
-+ %{static}} "
-+
-+/*
-+#define MD_UNWIND_SUPPORT "config/bfin/linux-unwind.h"
-+*/
---- /dev/null
-+++ b/gcc/config/ubicom32/predicates.md
-@@ -0,0 +1,327 @@
-+; Predicate definitions for Ubicom32.
-+
-+; Copyright (C) 2009 Free Software Foundation, Inc.
-+; Contributed by Ubicom, Inc.
-+
-+; This file is part of GCC.
-+
-+; GCC is free software; you can redistribute it and/or modify it
-+; under the terms of the GNU General Public License as published
-+; by the Free Software Foundation; either version 3, or (at your
-+; option) any later version.
-+
-+; GCC is distributed in the hope that it will be useful, but WITHOUT
-+; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-+; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
-+; License for more details.
-+
-+; You should have received a copy of the GNU General Public License
-+; along with GCC; see the file COPYING3. If not see
-+; <http://www.gnu.org/licenses/>.
-+
-+(define_predicate "ubicom32_move_operand"
-+ (match_code "const_int, const_double, const, mem, subreg, reg, lo_sum")
-+{
-+ if (CONST_INT_P (op))
-+ return true;
-+
-+ if (GET_CODE (op) == CONST_DOUBLE)
-+ return true;
-+
-+ if (GET_CODE (op) == CONST)
-+ return memory_address_p (mode, op);
-+
-+ if (GET_MODE (op) != mode)
-+ return false;
-+
-+ if (MEM_P (op))
-+ return memory_address_p (mode, XEXP (op, 0));
-+
-+ if (GET_CODE (op) == SUBREG) {
-+ op = SUBREG_REG (op);
-+
-+ if (REG_P (op))
-+ return true;
-+
-+ if (! MEM_P (op))
-+ return false;
-+
-+ /* Paradoxical SUBREG. */
-+ if (GET_MODE_SIZE (mode) > GET_MODE_SIZE (GET_MODE (op)))
-+ return false;
-+
-+ return memory_address_p (GET_MODE (op), XEXP (op, 0));
-+ }
-+
-+ return register_operand (op, mode);
-+})
-+
-+;; Returns true if OP is either a symbol reference or a sum of a
-+;; symbol reference and a constant.
-+
-+(define_predicate "ubicom32_symbolic_address_operand"
-+ (match_code "symbol_ref, label_ref, const")
-+{
-+ switch (GET_CODE (op))
-+ {
-+ case SYMBOL_REF:
-+ case LABEL_REF:
-+ return true;
-+
-+ case CONST:
-+ op = XEXP (op, 0);
-+ return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
-+ || GET_CODE (XEXP (op, 0)) == LABEL_REF)
-+ && CONST_INT_P (XEXP (op, 1)));
-+
-+ default:
-+ return false;
-+ }
-+})
-+
-+;; Return true if operand is the uClinux FD-PIC register.
-+
-+(define_predicate "ubicom32_fdpic_operand"
-+ (match_code "reg")
-+{
-+ if (! TARGET_FDPIC)
-+ return false;
-+
-+ if (!REG_P (op))
-+ return false;
-+
-+ if (GET_MODE (op) != mode && mode != VOIDmode)
-+ return false;
-+
-+ if (REGNO (op) != FDPIC_REGNUM && REGNO (op) < FIRST_PSEUDO_REGISTER)
-+ return false;
-+
-+ return true;
-+})
-+
-+(define_predicate "ubicom32_fdpic_got_offset_operand"
-+ (match_code "unspec")
-+{
-+ if (! TARGET_FDPIC)
-+ return false;
-+
-+ if (GET_CODE (op) != UNSPEC)
-+ return false;
-+
-+ if (XINT (op, 1) != UNSPEC_FDPIC_GOT
-+ && XINT (op, 1) != UNSPEC_FDPIC_GOT_FUNCDESC)
-+ return false;
-+
-+ return true;
-+})
-+
-+(define_predicate "ubicom32_arith_operand"
-+ (match_code "subreg, reg, const_int, lo_sum, mem")
-+{
-+ return (ubicom32_move_operand (op, mode)
-+ && ! ubicom32_symbolic_address_operand (op, mode)
-+ && (! CONST_INT_P (op)
-+ || satisfies_constraint_I (op)));
-+})
-+
-+(define_predicate "ubicom32_arith_operand_dot1"
-+ (match_code "subreg, reg, const_int, lo_sum, mem")
-+{
-+ return (ubicom32_move_operand (op, mode)
-+ && ! ubicom32_symbolic_address_operand (op, mode)
-+ && (! CONST_INT_P (op)
-+ || satisfies_constraint_Q (op)));
-+})
-+
-+(define_predicate "ubicom32_arith_operand_dot2"
-+ (match_code "subreg, reg, const_int, lo_sum, mem")
-+{
-+ return (ubicom32_move_operand (op, mode)
-+ && ! ubicom32_symbolic_address_operand (op, mode)
-+ && (! CONST_INT_P (op)
-+ || satisfies_constraint_R (op)));
-+})
-+
-+(define_predicate "ubicom32_compare_operand"
-+ (match_code "subreg, reg, const_int, lo_sum, mem")
-+{
-+ return (ubicom32_move_operand (op, mode)
-+ && ! ubicom32_symbolic_address_operand (op, mode)
-+ && (! CONST_INT_P (op)
-+ || satisfies_constraint_N (op)));
-+})
-+
-+(define_predicate "ubicom32_compare_operator"
-+ (match_code "compare"))
-+
-+(define_predicate "ubicom32_and_or_si3_operand"
-+ (match_code "subreg, reg, const_int, lo_sum, mem")
-+{
-+ return (ubicom32_arith_operand (op, mode)
-+ || (CONST_INT_P (op)
-+ && ((exact_log2 (INTVAL (op) + 1) != -1
-+ && exact_log2 (INTVAL (op) + 1) <= 31)
-+ || (exact_log2 (INTVAL (op)) != -1
-+ && exact_log2 (INTVAL (op)) <= 31)
-+ || (exact_log2 (~INTVAL (op)) != -1
-+ && exact_log2 (~INTVAL (op)) <= 31))));
-+})
-+
-+(define_predicate "ubicom32_and_or_hi3_operand"
-+ (match_code "subreg, reg, const_int, lo_sum, mem")
-+{
-+ return (ubicom32_arith_operand (op, mode)
-+ || (CONST_INT_P (op)
-+ && exact_log2 (INTVAL (op) + 1) != -1
-+ && exact_log2 (INTVAL (op) + 1) <= 15));
-+})
-+
-+(define_predicate "ubicom32_mem_or_address_register_operand"
-+ (match_code "subreg, reg, mem")
-+{
-+ unsigned int regno;
-+
-+ if (MEM_P (op)
-+ && memory_operand (op, mode))
-+ return true;
-+
-+ if (REG_P (op))
-+ regno = REGNO (op);
-+ else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
-+ {
-+ int offset;
-+ if (REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER)
-+ offset = SUBREG_BYTE (op) / (GET_MODE_SIZE (GET_MODE (op)));
-+ else
-+ offset = subreg_regno_offset (REGNO (SUBREG_REG (op)),
-+ GET_MODE (SUBREG_REG (op)),
-+ SUBREG_BYTE (op),
-+ GET_MODE (op));
-+ regno = REGNO (SUBREG_REG (op)) + offset;
-+ }
-+ else
-+ return false;
-+
-+ return (regno >= FIRST_PSEUDO_REGISTER
-+ || REGNO_REG_CLASS (regno) == FDPIC_REG
-+ || REGNO_REG_CLASS (regno) == ADDRESS_REGS);
-+})
-+
-+(define_predicate "ubicom32_data_register_operand"
-+ (match_code "subreg, reg")
-+{
-+ unsigned int regno;
-+
-+ if (REG_P (op))
-+ regno = REGNO (op);
-+ else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
-+ {
-+ int offset;
-+ if (REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER)
-+ offset = SUBREG_BYTE (op) / (GET_MODE_SIZE (GET_MODE (op)));
-+ else
-+ offset = subreg_regno_offset (REGNO (SUBREG_REG (op)),
-+ GET_MODE (SUBREG_REG (op)),
-+ SUBREG_BYTE (op),
-+ GET_MODE (op));
-+ regno = REGNO (SUBREG_REG (op)) + offset;
-+ }
-+ else
-+ return false;
-+
-+ return ((regno >= FIRST_PSEUDO_REGISTER
-+ && regno != REGNO (virtual_stack_vars_rtx))
-+ || REGNO_REG_CLASS (regno) == DATA_REGS);
-+})
-+
-+(define_predicate "ubicom32_address_register_operand"
-+ (match_code "subreg, reg")
-+{
-+ unsigned int regno;
-+
-+ if (REG_P (op))
-+ regno = REGNO (op);
-+ else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
-+ {
-+ int offset;
-+ if (REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER)
-+ offset = SUBREG_BYTE (op) / (GET_MODE_SIZE (GET_MODE (op)));
-+ else
-+ offset = subreg_regno_offset (REGNO (SUBREG_REG (op)),
-+ GET_MODE (SUBREG_REG (op)),
-+ SUBREG_BYTE (op),
-+ GET_MODE (op));
-+ regno = REGNO (SUBREG_REG (op)) + offset;
-+ }
-+ else
-+ return false;
-+
-+ return (regno >= FIRST_PSEUDO_REGISTER
-+ || REGNO_REG_CLASS (regno) == FDPIC_REG
-+ || REGNO_REG_CLASS (regno) == ADDRESS_REGS);
-+})
-+
-+(define_predicate "ubicom32_acc_lo_register_operand"
-+ (match_code "subreg, reg")
-+{
-+ unsigned int regno;
-+
-+ if (REG_P (op))
-+ regno = REGNO (op);
-+ else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
-+ {
-+ int offset;
-+ if (REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER)
-+ offset = SUBREG_BYTE (op) / (GET_MODE_SIZE (GET_MODE (op)));
-+ else
-+ offset = subreg_regno_offset (REGNO (SUBREG_REG (op)),
-+ GET_MODE (SUBREG_REG (op)),
-+ SUBREG_BYTE (op),
-+ GET_MODE (op));
-+ regno = REGNO (SUBREG_REG (op)) + offset;
-+ }
-+ else
-+ return false;
-+
-+ return ((regno >= FIRST_PSEUDO_REGISTER
-+ && regno != REGNO (virtual_stack_vars_rtx))
-+ || REGNO_REG_CLASS (regno) == ACC_LO_REGS);
-+})
-+
-+(define_predicate "ubicom32_acc_hi_register_operand"
-+ (match_code "subreg, reg")
-+{
-+ unsigned int regno;
-+
-+ if (REG_P (op))
-+ regno = REGNO (op);
-+ else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
-+ {
-+ int offset;
-+ if (REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER)
-+ offset = SUBREG_BYTE (op) / (GET_MODE_SIZE (GET_MODE (op)));
-+ else
-+ offset = subreg_regno_offset (REGNO (SUBREG_REG (op)),
-+ GET_MODE (SUBREG_REG (op)),
-+ SUBREG_BYTE (op),
-+ GET_MODE (op));
-+ regno = REGNO (SUBREG_REG (op)) + offset;
-+ }
-+ else
-+ return false;
-+
-+ return ((regno >= FIRST_PSEUDO_REGISTER
-+ && regno != REGNO (virtual_stack_vars_rtx))
-+ || REGNO_REG_CLASS (regno) == ACC_REGS);
-+})
-+
-+(define_predicate "ubicom32_call_address_operand"
-+ (match_code "symbol_ref, subreg, reg")
-+{
-+ return (GET_CODE (op) == SYMBOL_REF || REG_P (op));
-+})
-+
-+(define_special_predicate "ubicom32_cc_register_operand"
-+ (and (match_code "reg")
-+ (match_test "REGNO (op) == CC_REGNUM")))
-+
---- /dev/null
-+++ b/gcc/config/ubicom32/t-ubicom32
-@@ -0,0 +1,52 @@
-+# Name of assembly file containing libgcc1 functions.
-+# This entry must be present, but it can be empty if the target does
-+# not need any assembler functions to support its code generation.
-+CROSS_LIBGCC1 =
-+
-+# Alternatively if assembler functions *are* needed then define the
-+# entries below:
-+# CROSS_LIBGCC1 = libgcc1-asm.a
-+
-+LIB2FUNCS_EXTRA = \
-+ $(srcdir)/config/udivmodsi4.c \
-+ $(srcdir)/config/divmod.c \
-+ $(srcdir)/config/udivmod.c
-+
-+# If any special flags are necessary when building libgcc2 put them here.
-+#
-+# TARGET_LIBGCC2_CFLAGS =
-+
-+# 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
-+
-+fp-bit.c: $(srcdir)/config/fp-bit.c
-+ echo '#define FLOAT' > fp-bit.c
-+ cat $(srcdir)/config/fp-bit.c >> fp-bit.c
-+
-+dp-bit.c: $(srcdir)/config/fp-bit.c
-+ cat $(srcdir)/config/fp-bit.c > dp-bit.c
-+
-+# Commented out to speed up compiler development!
-+#
-+# MULTILIB_OPTIONS = march=ubicom32v1/march=ubicom32v2/march=ubicom32v3/march=ubicom32v4
-+# MULTILIB_DIRNAMES = ubicom32v1 ubicom32v2 ubicom32v3 ubicom32v4
-+
-+MULTILIB_OPTIONS = march=ubicom32v3/march=ubicom32v4
-+MULTILIB_OPTIONS += mfdpic
-+MULTILIB_OPTIONS += mno-ipos-abi/mipos-abi
-+MULTILIB_OPTIONS += fno-leading-underscore/fleading-underscore
-+
-+# Assemble startup files.
-+$(T)crti.o: $(srcdir)/config/ubicom32/crti.S $(GCC_PASSES)
-+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) \
-+ -c -o $(T)crti.o -x assembler-with-cpp $(srcdir)/config/ubicom32/crti.S
-+
-+$(T)crtn.o: $(srcdir)/config/ubicom32/crtn.S $(GCC_PASSES)
-+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) \
-+ -c -o $(T)crtn.o -x assembler-with-cpp $(srcdir)/config/ubicom32/crtn.S
-+
-+# these parts are required because uClibc ldso needs them to link.
-+# they are not in the specfile so they will not be included automatically.
-+EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o crtbeginS.o crtendS.o crti.o crtn.o
---- /dev/null
-+++ b/gcc/config/ubicom32/t-ubicom32-linux
-@@ -0,0 +1,35 @@
-+# Name of assembly file containing libgcc1 functions.
-+# This entry must be present, but it can be empty if the target does
-+# not need any assembler functions to support its code generation.
-+CROSS_LIBGCC1 =
-+
-+# Alternatively if assembler functions *are* needed then define the
-+# entries below:
-+# CROSS_LIBGCC1 = libgcc1-asm.a
-+
-+LIB2FUNCS_EXTRA = \
-+ $(srcdir)/config/udivmodsi4.c \
-+ $(srcdir)/config/divmod.c \
-+ $(srcdir)/config/udivmod.c
-+
-+# If any special flags are necessary when building libgcc2 put them here.
-+#
-+# TARGET_LIBGCC2_CFLAGS =
-+
-+# 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
-+
-+fp-bit.c: $(srcdir)/config/fp-bit.c
-+ echo '#define FLOAT' > fp-bit.c
-+ cat $(srcdir)/config/fp-bit.c >> fp-bit.c
-+
-+dp-bit.c: $(srcdir)/config/fp-bit.c
-+ cat $(srcdir)/config/fp-bit.c > dp-bit.c
-+
-+# We only support v3 and v4 ISAs for uClinux.
-+
-+MULTILIB_OPTIONS = march=ubicom32v3/march=ubicom32v4
-+
-+#EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o crtbeginS.o crtendS.o
---- /dev/null
-+++ b/gcc/config/ubicom32/t-ubicom32-uclinux
-@@ -0,0 +1,35 @@
-+# Name of assembly file containing libgcc1 functions.
-+# This entry must be present, but it can be empty if the target does
-+# not need any assembler functions to support its code generation.
-+CROSS_LIBGCC1 =
-+
-+# Alternatively if assembler functions *are* needed then define the
-+# entries below:
-+# CROSS_LIBGCC1 = libgcc1-asm.a
-+
-+LIB2FUNCS_EXTRA = \
-+ $(srcdir)/config/udivmodsi4.c \
-+ $(srcdir)/config/divmod.c \
-+ $(srcdir)/config/udivmod.c
-+
-+# If any special flags are necessary when building libgcc2 put them here.
-+#
-+# TARGET_LIBGCC2_CFLAGS =
-+
-+# 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
-+
-+fp-bit.c: $(srcdir)/config/fp-bit.c
-+ echo '#define FLOAT' > fp-bit.c
-+ cat $(srcdir)/config/fp-bit.c >> fp-bit.c
-+
-+dp-bit.c: $(srcdir)/config/fp-bit.c
-+ cat $(srcdir)/config/fp-bit.c > dp-bit.c
-+
-+# We only support v3 and v4 ISAs for uClinux.
-+
-+MULTILIB_OPTIONS = march=ubicom32v3/march=ubicom32v4
-+
-+EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o # crtbeginS.o crtendS.o
---- /dev/null
-+++ b/gcc/config/ubicom32/ubicom32-modes.def
-@@ -0,0 +1,30 @@
-+/* Definitions of target machine for GNU compiler, Ubicom32 architecture.
-+ Copyright (C) 2009 Free Software Foundation, Inc.
-+ Contributed by Ubicom, Inc.
-+
-+ This file is part of GCC.
-+
-+ GCC is free software; you can redistribute it and/or modify it
-+ under the terms of the GNU General Public License as published
-+ by the Free Software Foundation; either version 3, or (at your
-+ option) any later version.
-+
-+ GCC is distributed in the hope that it will be useful, but WITHOUT
-+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
-+ License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with GCC; see the file COPYING3. If not see
-+ <http://www.gnu.org/licenses/>. */
-+
-+/* Some insns set all condition code flags, some only set the Z and N flags, and
-+ some only set the Z flag. */
-+
-+CC_MODE (CCW);
-+CC_MODE (CCWZN);
-+CC_MODE (CCWZ);
-+CC_MODE (CCS);
-+CC_MODE (CCSZN);
-+CC_MODE (CCSZ);
-+
---- /dev/null
-+++ b/gcc/config/ubicom32/ubicom32-protos.h
-@@ -0,0 +1,84 @@
-+/* Function prototypes for Ubicom IP3000.
-+
-+ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
-+ 2009 Free Software Foundation, Inc.
-+ Contributed by Ubicom, Inc.
-+
-+ This file is part of GNU CC.
-+
-+ GNU CC is free software; you can redistribute it and/or modify it under
-+ the terms of the GNU General Public License as published by the Free
-+ Software Foundation; either version 2, or (at your option) any later
-+ version.
-+
-+ GNU CC is distributed in the hope that it will be useful, but WITHOUT
-+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-+ for more details.
-+
-+ You should have received a copy of the GNU General Public License along
-+ with GNU CC; see the file COPYING. If not, write to the Free Software
-+ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-+
-+#ifdef RTX_CODE
-+
-+#ifdef TREE_CODE
-+extern void ubicom32_va_start (tree, rtx);
-+#endif /* TREE_CODE */
-+
-+extern void ubicom32_print_operand (FILE *, rtx, int);
-+extern void ubicom32_print_operand_address (FILE *, rtx);
-+
-+extern void ubicom32_conditional_register_usage (void);
-+extern enum reg_class ubicom32_preferred_reload_class (rtx, enum reg_class);
-+extern int ubicom32_regno_ok_for_index_p (int, int);
-+extern void ubicom32_expand_movsi (rtx *);
-+extern void ubicom32_expand_addsi3 (rtx *);
-+extern int ubicom32_emit_mult_sequence (rtx *);
-+extern void ubicom32_emit_move_const_int (rtx, rtx);
-+extern bool ubicom32_legitimate_constant_p (rtx);
-+extern bool ubicom32_legitimate_address_p (enum machine_mode, rtx, int);
-+extern rtx ubicom32_legitimize_address (rtx, rtx, enum machine_mode);
-+extern rtx ubicom32_legitimize_reload_address (rtx, enum machine_mode, int, int);
-+extern void ubicom32_canonicalize_comparison (enum rtx_code *code, rtx *op0, rtx *op1);
-+extern int ubicom32_mode_dependent_address_p (rtx);
-+extern void ubicom32_output_cond_jump (rtx, rtx, rtx);
-+extern void ubicom32_expand_eh_return (rtx *);
-+extern void ubicom32_expand_call_fdpic (rtx *);
-+extern void ubicom32_expand_call_value_fdpic (rtx *);
-+extern enum machine_mode ubicom32_select_cc_mode (RTX_CODE, rtx, rtx);
-+extern rtx ubicom32_gen_compare_reg (RTX_CODE, rtx, rtx);
-+extern int ubicom32_shiftable_const_int (int);
-+#endif /* RTX_CODE */
-+
-+#ifdef TREE_CODE
-+extern void init_cumulative_args (CUMULATIVE_ARGS *cum,
-+ tree fntype,
-+ struct rtx_def *libname,
-+ int indirect);
-+extern struct rtx_def *function_arg (CUMULATIVE_ARGS *,
-+ enum machine_mode, tree, int);
-+extern struct rtx_def *function_incoming_arg (CUMULATIVE_ARGS *,
-+ enum machine_mode,
-+ tree, int);
-+extern int function_arg_partial_nregs (CUMULATIVE_ARGS *,
-+ enum machine_mode, tree, int);
-+extern struct rtx_def *ubicom32_va_arg (tree, tree);
-+extern int ubicom32_reg_parm_stack_space (tree);
-+#endif /* TREE_CODE */
-+
-+extern struct rtx_def * ubicom32_builtin_saveregs (void);
-+extern void asm_file_start (FILE *);
-+extern void ubicom32_expand_prologue (void);
-+extern void ubicom32_expand_epilogue (void);
-+extern int ubicom32_initial_elimination_offset (int, int);
-+extern int ubicom32_regno_ok_for_base_p (int, int);
-+extern bool ubicom32_hard_regno_mode_ok (unsigned int, enum machine_mode);
-+extern int ubicom32_can_use_return_insn_p (void);
-+extern rtx ubicom32_return_addr_rtx (int, rtx);
-+extern void ubicom32_optimization_options (int, int);
-+extern void ubicom32_override_options (void);
-+extern bool ubicom32_match_cc_mode (rtx, enum machine_mode);
-+
-+extern int ubicom32_reorg_completed;
-+
---- /dev/null
-+++ b/gcc/config/ubicom32/ubicom32.c
-@@ -0,0 +1,2881 @@
-+/* Subroutines for insn-output.c for Ubicom32
-+
-+ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
-+ 2009 Free Software Foundation, Inc.
-+ Contributed by Ubicom, Inc.
-+
-+ This file is part of GCC.
-+
-+ GCC is free software; you can redistribute it and/or modify it
-+ under the terms of the GNU General Public License as published
-+ by the Free Software Foundation; either version 3, or (at your
-+ option) any later version.
-+
-+ GCC is distributed in the hope that it will be useful, but WITHOUT
-+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
-+ License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with GCC; see the file COPYING3. If not see
-+ <http://www.gnu.org/licenses/>. */
-+
-+#include "config.h"
-+#include "system.h"
-+#include "coretypes.h"
-+#include "tm.h"
-+#include "rtl.h"
-+#include "tree.h"
-+#include "regs.h"
-+#include "hard-reg-set.h"
-+#include "real.h"
-+#include "insn-config.h"
-+#include "conditions.h"
-+#include "insn-flags.h"
-+#include "output.h"
-+#include "insn-attr.h"
-+#include "insn-codes.h"
-+#include "flags.h"
-+#include "recog.h"
-+#include "expr.h"
-+#include "function.h"
-+#include "obstack.h"
-+#include "toplev.h"
-+#include "tm_p.h"
-+#include "tm-constrs.h"
-+#include "basic-block.h"
-+#include "integrate.h"
-+#include "target.h"
-+#include "target-def.h"
-+#include "reload.h"
-+#include "df.h"
-+#include "langhooks.h"
-+#include "optabs.h"
-+
-+static tree ubicom32_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
-+static void ubicom32_layout_frame (void);
-+static void ubicom32_function_prologue (FILE *, HOST_WIDE_INT);
-+static void ubicom32_function_epilogue (FILE *, HOST_WIDE_INT);
-+static bool ubicom32_rtx_costs (rtx, int, int, int *, bool speed);
-+static bool ubicom32_fixed_condition_code_regs (unsigned int *,
-+ unsigned int *);
-+static enum machine_mode ubicom32_cc_modes_compatible (enum machine_mode,
-+ enum machine_mode);
-+static int ubicom32_naked_function_p (void);
-+static void ubicom32_machine_dependent_reorg (void);
-+static bool ubicom32_assemble_integer (rtx, unsigned int, int);
-+static void ubicom32_asm_init_sections (void);
-+static int ubicom32_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,tree,
-+ bool);
-+static bool ubicom32_pass_by_reference (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
-+ enum machine_mode mode, const_tree type,
-+ bool named ATTRIBUTE_UNUSED);
-+static bool ubicom32_callee_copies (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
-+ enum machine_mode mode, const_tree type,
-+ bool named ATTRIBUTE_UNUSED);
-+
-+static bool ubicom32_return_in_memory (const_tree type,
-+ const_tree fntype ATTRIBUTE_UNUSED);
-+static bool ubicom32_is_base_reg (rtx, int);
-+static void ubicom32_init_builtins (void);
-+static rtx ubicom32_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
-+static tree ubicom32_fold_builtin (tree, tree, bool);
-+static int ubicom32_get_valid_offset_mask (enum machine_mode);
-+static bool ubicom32_cannot_force_const_mem (rtx);
-+
-+/* Case values threshold */
-+int ubicom32_case_values_threshold = 6;
-+
-+/* Nonzero if this chip supports the Ubicom32 v3 ISA. */
-+int ubicom32_v3 = 1;
-+
-+/* Nonzero if this chip supports the Ubicom32 v4 ISA. */
-+int ubicom32_v4 = 1;
-+
-+/* Valid attributes:
-+ naked - don't generate function prologue/epilogue and `ret' command. */
-+const struct attribute_spec ubicom32_attribute_table[] =
-+{
-+ /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
-+ { "naked", 0, 0, true, false, false, ubicom32_handle_fndecl_attribute },
-+ { NULL, 0, 0, false, false, false, NULL }
-+};
-+
-+#undef TARGET_ASM_FUNCTION_PROLOGUE
-+#define TARGET_ASM_FUNCTION_PROLOGUE ubicom32_function_prologue
-+
-+#undef TARGET_ASM_FUNCTION_EPILOGUE
-+#define TARGET_ASM_FUNCTION_EPILOGUE ubicom32_function_epilogue
-+
-+#undef TARGET_ATTRIBUTE_TABLE
-+#define TARGET_ATTRIBUTE_TABLE ubicom32_attribute_table
-+
-+/* All addresses cost the same amount. */
-+#undef TARGET_ADDRESS_COST
-+#define TARGET_ADDRESS_COST hook_int_rtx_bool_0
-+
-+#undef TARGET_RTX_COSTS
-+#define TARGET_RTX_COSTS ubicom32_rtx_costs
-+
-+#undef TARGET_FIXED_CONDITION_CODE_REGS
-+#define TARGET_FIXED_CONDITION_CODE_REGS ubicom32_fixed_condition_code_regs
-+
-+#undef TARGET_CC_MODES_COMPATIBLE
-+#define TARGET_CC_MODES_COMPATIBLE ubicom32_cc_modes_compatible
-+
-+#undef TARGET_MACHINE_DEPENDENT_REORG
-+#define TARGET_MACHINE_DEPENDENT_REORG ubicom32_machine_dependent_reorg
-+
-+#undef TARGET_ASM_INTEGER
-+#define TARGET_ASM_INTEGER ubicom32_assemble_integer
-+
-+#undef TARGET_ASM_INIT_SECTIONS
-+#define TARGET_ASM_INIT_SECTIONS ubicom32_asm_init_sections
-+
-+#undef TARGET_ARG_PARTIAL_BYTES
-+#define TARGET_ARG_PARTIAL_BYTES ubicom32_arg_partial_bytes
-+
-+#undef TARGET_PASS_BY_REFERENCE
-+#define TARGET_PASS_BY_REFERENCE ubicom32_pass_by_reference
-+
-+#undef TARGET_CALLEE_COPIES
-+#define TARGET_CALLEE_COPIES ubicom32_callee_copies
-+
-+#undef TARGET_RETURN_IN_MEMORY
-+#define TARGET_RETURN_IN_MEMORY ubicom32_return_in_memory
-+
-+#undef TARGET_INIT_BUILTINS
-+#define TARGET_INIT_BUILTINS ubicom32_init_builtins
-+
-+#undef TARGET_EXPAND_BUILTIN
-+#define TARGET_EXPAND_BUILTIN ubicom32_expand_builtin
-+
-+#undef TARGET_FOLD_BUILTIN
-+#define TARGET_FOLD_BUILTIN ubicom32_fold_builtin
-+
-+#undef TARGET_CANNOT_FORCE_CONST_MEM
-+#define TARGET_CANNOT_FORCE_CONST_MEM ubicom32_cannot_force_const_mem
-+
-+struct gcc_target targetm = TARGET_INITIALIZER;
-+
-+static char save_regs[FIRST_PSEUDO_REGISTER];
-+static int nregs;
-+static int frame_size;
-+int ubicom32_stack_size = 0; /* size of allocated stack (including frame) */
-+int ubicom32_can_use_calli_to_ret;
-+
-+#define STACK_UNIT_BOUNDARY (STACK_BOUNDARY / BITS_PER_UNIT)
-+#define ROUND_CALL_BLOCK_SIZE(BYTES) \
-+ (((BYTES) + (STACK_UNIT_BOUNDARY - 1)) & ~(STACK_UNIT_BOUNDARY - 1))
-+
-+/* In case of a PRE_INC, POST_INC, PRE_DEC, POST_DEC memory reference, we
-+ must report the mode of the memory reference from PRINT_OPERAND to
-+ PRINT_OPERAND_ADDRESS. */
-+enum machine_mode output_memory_reference_mode;
-+
-+/* Flag for some split insns from the ubicom32.md. */
-+int ubicom32_reorg_completed;
-+
-+enum reg_class const ubicom32_regclass_map[FIRST_PSEUDO_REGISTER] =
-+{
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ FDPIC_REG,
-+ ADDRESS_REGS,
-+ ADDRESS_REGS,
-+ ADDRESS_REGS,
-+ ADDRESS_REGS,
-+ ADDRESS_REGS,
-+ ADDRESS_REGS,
-+ ADDRESS_REGS,
-+ ACC_REGS,
-+ ACC_LO_REGS,
-+ ACC_REGS,
-+ ACC_LO_REGS,
-+ SOURCE3_REG,
-+ ADDRESS_REGS,
-+ NO_REGS, /* CC_REG must be NO_REGS */
-+ SPECIAL_REGS,
-+ SPECIAL_REGS,
-+ SPECIAL_REGS,
-+ SPECIAL_REGS,
-+ SPECIAL_REGS,
-+ SPECIAL_REGS,
-+ SPECIAL_REGS,
-+ SPECIAL_REGS
-+};
-+
-+rtx ubicom32_compare_op0;
-+rtx ubicom32_compare_op1;
-+
-+/* Handle command line option overrides. */
-+
-+void
-+ubicom32_override_options (void)
-+{
-+ flag_pic = 0;
-+
-+ if (strcmp (ubicom32_arch_name, "ubicom32v1") == 0) {
-+ /* If we have a version 1 architecture then we want to avoid using jump
-+ tables. */
-+ ubicom32_case_values_threshold = 30000;
-+ ubicom32_v3 = 0;
-+ ubicom32_v4 = 0;
-+ } else if (strcmp (ubicom32_arch_name, "ubicom32v2") == 0) {
-+ ubicom32_v3 = 0;
-+ ubicom32_v4 = 0;
-+ } else if (strcmp (ubicom32_arch_name, "ubicom32v3") == 0) {
-+ ubicom32_v3 = 1;
-+ ubicom32_v4 = 0;
-+ } else if (strcmp (ubicom32_arch_name, "ubicom32v4") == 0) {
-+ ubicom32_v3 = 1;
-+ ubicom32_v4 = 1;
-+ }
-+
-+ /* There is no single unaligned SI op for PIC code. Sometimes we
-+ need to use ".4byte" and sometimes we need to use ".picptr".
-+ See ubicom32_assemble_integer for details. */
-+ if (TARGET_FDPIC)
-+ targetm.asm_out.unaligned_op.si = 0;
-+}
-+
-+void
-+ubicom32_conditional_register_usage (void)
-+{
-+ /* If we're using the old ipOS ABI we need to make D10 through D13
-+ caller-clobbered. */
-+ if (TARGET_IPOS_ABI)
-+ {
-+ call_used_regs[D10_REGNUM] = 1;
-+ call_used_regs[D11_REGNUM] = 1;
-+ call_used_regs[D12_REGNUM] = 1;
-+ call_used_regs[D13_REGNUM] = 1;
-+ }
-+}
-+
-+/* We have some number of optimizations that don't really work for the Ubicom32
-+ architecture so we deal with them here. */
-+
-+void
-+ubicom32_optimization_options (int level ATTRIBUTE_UNUSED,
-+ int size ATTRIBUTE_UNUSED)
-+{
-+ /* The tree IVOPTs pass seems to do really bad things for the Ubicom32
-+ architecture - it tends to turn things that would happily use pre/post
-+ increment/decrement into operations involving unecessary loop
-+ indicies. */
-+ flag_ivopts = 0;
-+
-+ /* We have problems where DSE at the RTL level misses partial stores
-+ to the stack. For now we disable it to avoid this. */
-+ flag_dse = 0;
-+}
-+
-+/* Print operand X using operand code CODE to assembly language output file
-+ FILE. */
-+
-+void
-+ubicom32_print_operand (FILE *file, rtx x, int code)
-+{
-+ switch (code)
-+ {
-+ case 'A':
-+ /* Identify the correct accumulator to use. */
-+ if (REGNO (x) == ACC0_HI_REGNUM || REGNO (x) == ACC0_LO_REGNUM)
-+ fprintf (file, "acc0");
-+ else if (REGNO (x) == ACC1_HI_REGNUM || REGNO (x) == ACC1_LO_REGNUM)
-+ fprintf (file, "acc1");
-+ else
-+ abort ();
-+ break;
-+
-+ case 'b':
-+ case 'B':
-+ {
-+ enum machine_mode mode;
-+
-+ mode = GET_MODE (XEXP (x, 0));
-+
-+ /* These are normal and reversed branches. */
-+ switch (code == 'b' ? GET_CODE (x) : reverse_condition (GET_CODE (x)))
-+ {
-+ case NE:
-+ fprintf (file, "ne");
-+ break;
-+
-+ case EQ:
-+ fprintf (file, "eq");
-+ break;
-+
-+ case GE:
-+ if (mode == CCSZNmode || mode == CCWZNmode)
-+ fprintf (file, "pl");
-+ else
-+ fprintf (file, "ge");
-+ break;
-+
-+ case GT:
-+ fprintf (file, "gt");
-+ break;
-+
-+ case LE:
-+ fprintf (file, "le");
-+ break;
-+
-+ case LT:
-+ if (mode == CCSZNmode || mode == CCWZNmode)
-+ fprintf (file, "mi");
-+ else
-+ fprintf (file, "lt");
-+ break;
-+
-+ case GEU:
-+ fprintf (file, "cs");
-+ break;
-+
-+ case GTU:
-+ fprintf (file, "hi");
-+ break;
-+
-+ case LEU:
-+ fprintf (file, "ls");
-+ break;
-+
-+ case LTU:
-+ fprintf (file, "cc");
-+ break;
-+
-+ default:
-+ abort ();
-+ }
-+ }
-+ break;
-+
-+ case 'C':
-+ /* This is used for the operand to a call instruction;
-+ if it's a REG, enclose it in parens, else output
-+ the operand normally. */
-+ if (REG_P (x))
-+ {
-+ fputc ('(', file);
-+ ubicom32_print_operand (file, x, 0);
-+ fputc (')', file);
-+ }
-+ else
-+ ubicom32_print_operand (file, x, 0);
-+ break;
-+
-+ case 'd':
-+ /* Bit operations we need bit numbers. */
-+ fprintf (file, "%d", exact_log2 (INTVAL (x)));
-+ break;
-+
-+ case 'D':
-+ /* Bit operations we need bit numbers. */
-+ fprintf (file, "%d", exact_log2 (~ INTVAL (x)));
-+ break;
-+
-+ case 'E':
-+ /* For lea, which we use to add address registers.
-+ We don't want the '#' on a constant. */
-+ if (CONST_INT_P (x))
-+ {
-+ fprintf (file, "%ld", INTVAL (x));
-+ break;
-+ }
-+ /* FALL THROUGH */
-+
-+ default:
-+ switch (GET_CODE (x))
-+ {
-+ case MEM:
-+ output_memory_reference_mode = GET_MODE (x);
-+ output_address (XEXP (x, 0));
-+ break;
-+
-+ case PLUS:
-+ output_address (x);
-+ break;
-+
-+ case REG:
-+ fprintf (file, "%s", reg_names[REGNO (x)]);
-+ break;
-+
-+ case SUBREG:
-+ fprintf (file, "%s", reg_names[subreg_regno (x)]);
-+ break;
-+
-+ /* This will only be single precision.... */
-+ case CONST_DOUBLE:
-+ {
-+ unsigned long val;
-+ REAL_VALUE_TYPE rv;
-+
-+ REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
-+ REAL_VALUE_TO_TARGET_SINGLE (rv, val);
-+ fprintf (file, "0x%lx", val);
-+ break;
-+ }
-+
-+ case CONST_INT:
-+ case SYMBOL_REF:
-+ case CONST:
-+ case LABEL_REF:
-+ case CODE_LABEL:
-+ case LO_SUM:
-+ ubicom32_print_operand_address (file, x);
-+ break;
-+
-+ case HIGH:
-+ fprintf (file, "#%%hi(");
-+ ubicom32_print_operand_address (file, XEXP (x, 0));
-+ fprintf (file, ")");
-+ break;
-+
-+ case UNSPEC:
-+ switch (XINT (x, 1))
-+ {
-+ case UNSPEC_FDPIC_GOT:
-+ fprintf (file, "#%%got_lo(");
-+ ubicom32_print_operand_address (file, XVECEXP (x, 0, 0));
-+ fprintf (file, ")");
-+ break;
-+
-+ case UNSPEC_FDPIC_GOT_FUNCDESC:
-+ fprintf (file, "#%%got_funcdesc_lo(");
-+ ubicom32_print_operand_address (file, XVECEXP (x, 0, 0));
-+ fprintf (file, ")");
-+ break;
-+
-+ default:
-+ abort ();
-+ }
-+ break;
-+
-+ default:
-+ abort ();
-+ }
-+ break;
-+ }
-+}
-+
-+/* Output assembly language output for the address ADDR to FILE. */
-+
-+void
-+ubicom32_print_operand_address (FILE *file, rtx addr)
-+{
-+ switch (GET_CODE (addr))
-+ {
-+ case POST_INC:
-+ ubicom32_print_operand_address (file, XEXP (addr, 0));
-+ fprintf (file, "%d++", GET_MODE_SIZE (output_memory_reference_mode));
-+ break;
-+
-+ case PRE_INC:
-+ fprintf (file, "%d", GET_MODE_SIZE (output_memory_reference_mode));
-+ ubicom32_print_operand_address (file, XEXP (addr, 0));
-+ fprintf (file, "++");
-+ break;
-+
-+ case POST_DEC:
-+ ubicom32_print_operand_address (file, XEXP (addr, 0));
-+ fprintf (file, "%d++", -GET_MODE_SIZE (output_memory_reference_mode));
-+ break;
-+
-+ case PRE_DEC:
-+ fprintf (file, "%d", -GET_MODE_SIZE (output_memory_reference_mode));
-+ ubicom32_print_operand_address (file, XEXP (addr, 0));
-+ fprintf (file, "++");
-+ break;
-+
-+ case POST_MODIFY:
-+ ubicom32_print_operand_address (file, XEXP (addr, 0));
-+ fprintf (file, "%ld++", INTVAL (XEXP (XEXP (addr,1), 1)));
-+ break;
-+
-+ case PRE_MODIFY:
-+ fprintf (file, "%ld", INTVAL (XEXP (XEXP (addr,1), 1)));
-+ ubicom32_print_operand_address (file, XEXP (addr, 0));
-+ fprintf (file, "++");
-+ break;
-+
-+ case REG:
-+ fputc ('(', file);
-+ fprintf (file, "%s", reg_names[REGNO (addr)]);
-+ fputc (')', file);
-+ break;
-+
-+ case PLUS:
-+ {
-+ rtx base = XEXP (addr, 0);
-+ rtx index = XEXP (addr, 1);
-+
-+ /* Switch around addresses of the form index * scaling + base. */
-+ if (! ubicom32_is_base_reg (base, 1))
-+ {
-+ rtx tmp = base;
-+ base = index;
-+ index = tmp;
-+ }
-+
-+ if (CONST_INT_P (index))
-+ {
-+ fprintf (file, "%ld", INTVAL (index));
-+ fputc ('(', file);
-+ fputs (reg_names[REGNO (base)], file);
-+ }
-+ else if (GET_CODE (index) == MULT
-+ || REG_P (index))
-+ {
-+ if (GET_CODE (index) == MULT)
-+ index = XEXP (index, 0);
-+ fputc ('(', file);
-+ fputs (reg_names[REGNO (base)], file);
-+ fputc (',', file);
-+ fputs (reg_names[REGNO (index)], file);
-+ }
-+ else
-+ abort ();
-+
-+ fputc (')', file);
-+ break;
-+ }
-+
-+ case LO_SUM:
-+ fprintf (file, "%%lo(");
-+ ubicom32_print_operand (file, XEXP (addr, 1), 'L');
-+ fprintf (file, ")(");
-+ ubicom32_print_operand (file, XEXP (addr, 0), 0);
-+ fprintf (file, ")");
-+ break;
-+
-+ case CONST_INT:
-+ fputc ('#', file);
-+ output_addr_const (file, addr);
-+ break;
-+
-+ default:
-+ output_addr_const (file, addr);
-+ break;
-+ }
-+}
-+
-+/* X and Y are two things to compare using CODE. Emit the compare insn and
-+ return the rtx for the cc reg in the proper mode. */
-+
-+rtx
-+ubicom32_gen_compare_reg (enum rtx_code code, rtx x, rtx y)
-+{
-+ enum machine_mode mode = SELECT_CC_MODE (code, x, y);
-+ rtx cc_reg;
-+
-+ cc_reg = gen_rtx_REG (mode, CC_REGNUM);
-+
-+ emit_insn (gen_rtx_SET (VOIDmode, cc_reg,
-+ gen_rtx_COMPARE (mode, x, y)));
-+
-+ return cc_reg;
-+}
-+
-+/* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
-+ return the mode to be used for the comparison. */
-+
-+enum machine_mode
-+ubicom32_select_cc_mode (enum rtx_code op, rtx x, rtx y)
-+{
-+ /* Is this a short compare? */
-+ if (GET_MODE (x) == QImode
-+ || GET_MODE (x) == HImode
-+ || GET_MODE (y) == QImode
-+ || GET_MODE (y) == HImode)
-+ {
-+ switch (op)
-+ {
-+ case EQ :
-+ case NE :
-+ return CCSZmode;
-+
-+ case GE:
-+ case LT:
-+ if (y == const0_rtx)
-+ return CCSZNmode;
-+
-+ default :
-+ return CCSmode;
-+ }
-+ }
-+
-+ /* We have a word compare. */
-+ switch (op)
-+ {
-+ case EQ :
-+ case NE :
-+ return CCWZmode;
-+
-+ case GE :
-+ case LT :
-+ if (y == const0_rtx)
-+ return CCWZNmode;
-+
-+ default :
-+ return CCWmode;
-+ }
-+}
-+
-+/* Return TRUE or FALSE depending on whether the first SET in INSN
-+ has source and destination with matching CC modes, and that the
-+ CC mode is at least as constrained as REQ_MODE. */
-+bool
-+ubicom32_match_cc_mode (rtx insn, enum machine_mode req_mode)
-+{
-+ rtx set;
-+ enum machine_mode set_mode;
-+
-+ set = PATTERN (insn);
-+ if (GET_CODE (set) == PARALLEL)
-+ set = XVECEXP (set, 0, 0);
-+ gcc_assert (GET_CODE (set) == SET);
-+ gcc_assert (GET_CODE (SET_SRC (set)) == COMPARE);
-+
-+ /* SET_MODE is the mode we have in the instruction. This must either
-+ be the same or less restrictive that the required mode REQ_MODE. */
-+ set_mode = GET_MODE (SET_DEST (set));
-+
-+ switch (req_mode)
-+ {
-+ case CCSZmode:
-+ if (set_mode != CCSZmode)
-+ return 0;
-+ break;
-+
-+ case CCSZNmode:
-+ if (set_mode != CCSZmode
-+ && set_mode != CCSZNmode)
-+ return 0;
-+ break;
-+
-+ case CCSmode:
-+ if (set_mode != CCSmode
-+ && set_mode != CCSZmode
-+ && set_mode != CCSZNmode)
-+ return 0;
-+ break;
-+
-+ case CCWZmode:
-+ if (set_mode != CCWZmode)
-+ return 0;
-+ break;
-+
-+ case CCWZNmode:
-+ if (set_mode != CCWZmode
-+ && set_mode != CCWZNmode)
-+ return 0;
-+ break;
-+
-+ case CCWmode:
-+ if (set_mode != CCWmode
-+ && set_mode != CCWZmode
-+ && set_mode != CCWZNmode)
-+ return 0;
-+ break;
-+
-+ default:
-+ gcc_unreachable ();
-+ }
-+
-+ return (GET_MODE (SET_SRC (set)) == set_mode);
-+}
-+
-+/* Replace the comparison OP0 CODE OP1 by a semantically equivalent one
-+ that we can implement more efficiently. */
-+
-+void
-+ubicom32_canonicalize_comparison (enum rtx_code *code, rtx *op0, rtx *op1)
-+{
-+ /* If we have a REG and a MEM then compare the MEM with the REG and not
-+ the other way round. */
-+ if (REG_P (*op0) && MEM_P (*op1))
-+ {
-+ rtx tem = *op0;
-+ *op0 = *op1;
-+ *op1 = tem;
-+ *code = swap_condition (*code);
-+ return;
-+ }
-+
-+ /* If we have a REG and a CONST_INT then we may want to reverse things
-+ if the constant can be represented as an "I" constraint. */
-+ if (REG_P (*op0) && CONST_INT_P (*op1) && satisfies_constraint_I (*op1))
-+ {
-+ rtx tem = *op0;
-+ *op0 = *op1;
-+ *op1 = tem;
-+ *code = swap_condition (*code);
-+ return;
-+ }
-+}
-+
-+/* Return the fixed registers used for condition codes. */
-+
-+static bool
-+ubicom32_fixed_condition_code_regs (unsigned int *p1, unsigned int *p2)
-+{
-+ *p1 = CC_REGNUM;
-+ *p2 = INVALID_REGNUM;
-+
-+ return true;
-+}
-+
-+/* If two condition code modes are compatible, return a condition code
-+ mode which is compatible with both. Otherwise, return
-+ VOIDmode. */
-+
-+static enum machine_mode
-+ubicom32_cc_modes_compatible (enum machine_mode m1, enum machine_mode m2)
-+{
-+ if (m1 == m2)
-+ return m1;
-+
-+ if (GET_MODE_CLASS (m1) != MODE_CC || GET_MODE_CLASS (m2) != MODE_CC)
-+ return VOIDmode;
-+
-+ switch (m1)
-+ {
-+ case CCWmode:
-+ if (m2 == CCWZNmode || m2 == CCWZmode)
-+ return m1;
-+
-+ return VOIDmode;
-+
-+ case CCWZNmode:
-+ if (m2 == CCWmode)
-+ return m2;
-+
-+ if (m2 == CCWZmode)
-+ return m1;
-+
-+ return VOIDmode;
-+
-+ case CCWZmode:
-+ if (m2 == CCWmode || m2 == CCWZNmode)
-+ return m2;
-+
-+ return VOIDmode;
-+
-+ case CCSmode:
-+ if (m2 == CCSZNmode || m2 == CCSZmode)
-+ return m1;
-+
-+ return VOIDmode;
-+
-+ case CCSZNmode:
-+ if (m2 == CCSmode)
-+ return m2;
-+
-+ if (m2 == CCSZmode)
-+ return m1;
-+
-+ return VOIDmode;
-+
-+ case CCSZmode:
-+ if (m2 == CCSmode || m2 == CCSZNmode)
-+ return m2;
-+
-+ return VOIDmode;
-+
-+ default:
-+ gcc_unreachable ();
-+ }
-+}
-+
-+static rtx
-+ubicom32_legitimize_fdpic_address_symbol (rtx orig, rtx reg, rtx fdpic_reg)
-+{
-+ int unspec;
-+ rtx got_offs;
-+ rtx got_offs_scaled;
-+ rtx plus_scaled;
-+ rtx tmp;
-+ rtx new_rtx;
-+
-+ gcc_assert (reg != 0);
-+
-+ if (GET_CODE (orig) == SYMBOL_REF
-+ && SYMBOL_REF_FUNCTION_P (orig))
-+ unspec = UNSPEC_FDPIC_GOT_FUNCDESC;
-+ else
-+ unspec = UNSPEC_FDPIC_GOT;
-+
-+ got_offs = gen_reg_rtx (SImode);
-+ tmp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, orig), unspec);
-+ emit_move_insn (got_offs, tmp);
-+
-+ got_offs_scaled = gen_rtx_MULT (SImode, got_offs, GEN_INT (4));
-+ plus_scaled = gen_rtx_PLUS (Pmode, fdpic_reg, got_offs_scaled);
-+ new_rtx = gen_const_mem (Pmode, plus_scaled);
-+ emit_move_insn (reg, new_rtx);
-+
-+ return reg;
-+}
-+
-+static rtx
-+ubicom32_legitimize_fdpic_address (rtx orig, rtx reg, rtx fdpic_reg)
-+{
-+ rtx addr = orig;
-+ rtx new_rtx = orig;
-+
-+ if (GET_CODE (addr) == CONST || GET_CODE (addr) == PLUS)
-+ {
-+ rtx base;
-+
-+ if (GET_CODE (addr) == CONST)
-+ {
-+ addr = XEXP (addr, 0);
-+ gcc_assert (GET_CODE (addr) == PLUS);
-+ }
-+
-+ base = ubicom32_legitimize_fdpic_address_symbol (XEXP (addr, 0), reg, fdpic_reg);
-+ return gen_rtx_PLUS (Pmode, base, XEXP (addr, 1));
-+ }
-+
-+ return new_rtx;
-+}
-+
-+/* Code generation. */
-+
-+void
-+ubicom32_expand_movsi (rtx *operands)
-+{
-+ if (GET_CODE (operands[1]) == SYMBOL_REF
-+ || (GET_CODE (operands[1]) == CONST
-+ && GET_CODE (XEXP (operands[1], 0)) == PLUS
-+ && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
-+ || CONSTANT_ADDRESS_P (operands[1]))
-+ {
-+ if (TARGET_FDPIC)
-+ {
-+ rtx tmp;
-+ rtx fdpic_reg;
-+
-+ gcc_assert (can_create_pseudo_p ());
-+ tmp = gen_reg_rtx (Pmode);
-+ fdpic_reg = get_hard_reg_initial_val (SImode, FDPIC_REGNUM);
-+ if (GET_CODE (operands[1]) == SYMBOL_REF
-+ || GET_CODE (operands[1]) == LABEL_REF)
-+ operands[1] = ubicom32_legitimize_fdpic_address_symbol (operands[1], tmp, fdpic_reg);
-+ else
-+ operands[1] = ubicom32_legitimize_fdpic_address (operands[1], tmp, fdpic_reg);
-+ }
-+ else
-+ {
-+ rtx tmp;
-+ enum machine_mode mode;
-+
-+ /* We want to avoid reusing operand 0 if we can because it limits
-+ our ability to optimize later. */
-+ tmp = ! can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
-+
-+ mode = GET_MODE (operands[0]);
-+ emit_insn (gen_rtx_SET (VOIDmode, tmp,
-+ gen_rtx_HIGH (mode, operands[1])));
-+ operands[1] = gen_rtx_LO_SUM (mode, tmp, operands[1]);
-+ if (can_create_pseudo_p() && ! REG_P (operands[0]))
-+ {
-+ tmp = gen_reg_rtx (mode);
-+ emit_insn (gen_rtx_SET (VOIDmode, tmp, operands[1]));
-+ operands[1] = tmp;
-+ }
-+ }
-+ }
-+}
-+
-+/* Emit code for addsi3. */
-+
-+void
-+ubicom32_expand_addsi3 (rtx *operands)
-+{
-+ rtx op, clob;
-+
-+ if (can_create_pseudo_p ())
-+ {
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (SImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (SImode, operands[2]);
-+ }
-+
-+ /* Emit the instruction. */
-+
-+ op = gen_rtx_SET (VOIDmode, operands[0],
-+ gen_rtx_PLUS (SImode, operands[1], operands[2]));
-+
-+ if (! can_create_pseudo_p ())
-+ {
-+ /* Reload doesn't know about the flags register, and doesn't know that
-+ it doesn't want to clobber it. We can only do this with PLUS. */
-+ emit_insn (op);
-+ }
-+ else
-+ {
-+ clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM));
-+ emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, op, clob)));
-+ }
-+}
-+
-+/* Emit code for mulsi3. Return 1 if we have generated all the code
-+ necessary to do the multiplication. */
-+
-+int
-+ubicom32_emit_mult_sequence (rtx *operands)
-+{
-+ if (! ubicom32_v4)
-+ {
-+ rtx a1, a1_1, a2;
-+ rtx b1, b1_1, b2;
-+ rtx mac_lo_rtx;
-+ rtx t1, t2, t3;
-+
-+ /* Give up if we cannot create new pseudos. */
-+ if (!can_create_pseudo_p())
-+ return 0;
-+
-+ /* Synthesize 32-bit multiplication using 16-bit operations:
-+
-+ a1 = highpart (a)
-+ a2 = lowpart (a)
-+
-+ b1 = highpart (b)
-+ b2 = lowpart (b)
-+
-+ c = (a1 * b1) << 32 + (a1 * b2) << 16 + (a2 * b1) << 16 + a2 * b2
-+ = 0 + (a1 * b2) << 16 + (a2 * b1) << 16 + a2 * b2
-+ ^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^ ^^^^^^^
-+ Signed Signed Unsigned */
-+
-+ if (!ubicom32_data_register_operand (operands[1], GET_MODE (operands[1])))
-+ {
-+ rtx op1;
-+
-+ op1 = gen_reg_rtx (SImode);
-+ emit_move_insn (op1, operands[1]);
-+ operands[1] = op1;
-+ }
-+
-+ if (!ubicom32_data_register_operand (operands[2], GET_MODE (operands[2])))
-+ {
-+ rtx op2;
-+
-+ op2 = gen_reg_rtx (SImode);
-+ emit_move_insn (op2, operands[2]);
-+ operands[2] = op2;
-+ }
-+
-+ /* a1 = highpart (a) */
-+ a1 = gen_reg_rtx (HImode);
-+ a1_1 = gen_reg_rtx (SImode);
-+ emit_insn (gen_ashrsi3 (a1_1, operands[1], GEN_INT (16)));
-+ emit_move_insn (a1, gen_lowpart (HImode, a1_1));
-+
-+ /* a2 = lowpart (a) */
-+ a2 = gen_reg_rtx (HImode);
-+ emit_move_insn (a2, gen_lowpart (HImode, operands[1]));
-+
-+ /* b1 = highpart (b) */
-+ b1 = gen_reg_rtx (HImode);
-+ b1_1 = gen_reg_rtx (SImode);
-+ emit_insn (gen_ashrsi3 (b1_1, operands[2], GEN_INT (16)));
-+ emit_move_insn (b1, gen_lowpart (HImode, b1_1));
-+
-+ /* b2 = lowpart (b) */
-+ b2 = gen_reg_rtx (HImode);
-+ emit_move_insn (b2, gen_lowpart (HImode, operands[2]));
-+
-+ /* t1 = (a1 * b2) << 16 */
-+ t1 = gen_reg_rtx (SImode);
-+ mac_lo_rtx = gen_rtx_REG (SImode, ACC0_LO_REGNUM);
-+ emit_insn (gen_mulhisi3 (mac_lo_rtx, a1, b2));
-+ emit_insn (gen_ashlsi3 (t1, mac_lo_rtx, GEN_INT (16)));
-+
-+ /* t2 = (a2 * b1) << 16 */
-+ t2 = gen_reg_rtx (SImode);
-+ emit_insn (gen_mulhisi3 (mac_lo_rtx, a2, b1));
-+ emit_insn (gen_ashlsi3 (t2, mac_lo_rtx, GEN_INT (16)));
-+
-+ /* mac_lo = a2 * b2 */
-+ emit_insn (gen_umulhisi3 (mac_lo_rtx, a2, b2));
-+
-+ /* t3 = t1 + t2 */
-+ t3 = gen_reg_rtx (SImode);
-+ emit_insn (gen_addsi3 (t3, t1, t2));
-+
-+ /* c = t3 + mac_lo_rtx */
-+ emit_insn (gen_addsi3 (operands[0], mac_lo_rtx, t3));
-+
-+ return 1;
-+ }
-+ else
-+ {
-+ rtx acc_rtx;
-+
-+ /* Give up if we cannot create new pseudos. */
-+ if (!can_create_pseudo_p())
-+ return 0;
-+
-+ if (!ubicom32_data_register_operand (operands[1], GET_MODE (operands[1])))
-+ {
-+ rtx op1;
-+
-+ op1 = gen_reg_rtx (SImode);
-+ emit_move_insn (op1, operands[1]);
-+ operands[1] = op1;
-+ }
-+
-+ if (!ubicom32_data_register_operand (operands[2], GET_MODE (operands[2])))
-+ {
-+ rtx op2;
-+
-+ op2 = gen_reg_rtx (SImode);
-+ emit_move_insn (op2, operands[2]);
-+ operands[2] = op2;
-+ }
-+
-+ acc_rtx = gen_reg_rtx (DImode);
-+ emit_insn (gen_umulsidi3 (acc_rtx, operands[1], operands[2]));
-+ emit_move_insn (operands[0], gen_lowpart (SImode, acc_rtx));
-+
-+ return 1;
-+ }
-+}
-+
-+/* Move the integer value VAL into OPERANDS[0]. */
-+
-+void
-+ubicom32_emit_move_const_int (rtx dest, rtx imm)
-+{
-+ rtx xoperands[2];
-+
-+ xoperands[0] = dest;
-+ xoperands[1] = imm;
-+
-+ /* Treat mem destinations separately. Values must be explicitly sign
-+ extended. */
-+ if (MEM_P (dest))
-+ {
-+ rtx low_hword_mem;
-+ rtx low_hword_addr;
-+
-+ /* Emit shorter sequence for signed 7-bit quantities. */
-+ if (satisfies_constraint_I (imm))
-+ {
-+ output_asm_insn ("move.4\t%0, %1", xoperands);
-+ return;
-+ }
-+
-+ /* Special case for pushing constants. */
-+ if (GET_CODE (XEXP (dest, 0)) == PRE_DEC
-+ && XEXP (XEXP (dest, 0), 0) == stack_pointer_rtx)
-+ {
-+ output_asm_insn ("movei\t-4(sp)++, #%%hi(%E1)", xoperands);
-+ output_asm_insn ("movei\t2(sp), #%%lo(%E1)", xoperands);
-+ return;
-+ }
-+
-+ /* See if we can add 2 to the original address. This is only
-+ possible if the original address is of the form REG or
-+ REG+const. */
-+ low_hword_addr = plus_constant (XEXP (dest, 0), 2);
-+ if (ubicom32_legitimate_address_p (HImode, low_hword_addr, 1))
-+ {
-+ low_hword_mem = gen_rtx_MEM (HImode, low_hword_addr);
-+ MEM_COPY_ATTRIBUTES (low_hword_mem, dest);
-+ output_asm_insn ("movei\t%0, #%%hi(%E1)", xoperands);
-+ xoperands[0] = low_hword_mem;
-+ output_asm_insn ("movei\t%0, #%%lo(%E1)", xoperands);
-+ return;
-+ }
-+
-+ /* The original address is too complex. We need to use a
-+ scratch memory by (sp) and move that to the original
-+ destination. */
-+ if (! reg_mentioned_p (stack_pointer_rtx, dest))
-+ {
-+ output_asm_insn ("movei\t-4(sp)++, #%%hi(%E1)", xoperands);
-+ output_asm_insn ("movei\t2(sp), #%%lo(%E1)", xoperands);
-+ output_asm_insn ("move.4\t%0, (sp)4++", xoperands);
-+ return;
-+ }
-+
-+ /* Our address mentions the stack pointer so we need to
-+ use our scratch data register here as well as scratch
-+ memory. */
-+ output_asm_insn ("movei\t-4(sp)++, #%%hi(%E1)", xoperands);
-+ output_asm_insn ("movei\t2(sp), #%%lo(%E1)", xoperands);
-+ output_asm_insn ("move.4\td15, (sp)4++", xoperands);
-+ output_asm_insn ("move.4\t%0, d15", xoperands);
-+ return;
-+ }
-+
-+ /* Move into registers are zero extended by default. */
-+ if (! REG_P (dest))
-+ abort ();
-+
-+ if (satisfies_constraint_N (imm))
-+ {
-+ output_asm_insn ("movei\t%0, %1", xoperands);
-+ return;
-+ }
-+
-+ if (INTVAL (xoperands[1]) >= 0xff80
-+ && INTVAL (xoperands[1]) < 0x10000)
-+ {
-+ xoperands[1] = GEN_INT (INTVAL (xoperands[1]) - 0x10000);
-+ output_asm_insn ("move.2\t%0, %1", xoperands);
-+ return;
-+ }
-+
-+ if ((REGNO_REG_CLASS (REGNO (xoperands[0])) == ADDRESS_REGS
-+ || REGNO_REG_CLASS (REGNO (xoperands[0])) == FDPIC_REG)
-+ && ((INTVAL (xoperands[1]) & 0x80000000) == 0))
-+ {
-+ output_asm_insn ("moveai\t%0, #%%hi(%E1)", xoperands);
-+ if ((INTVAL (xoperands[1]) & 0x7f) != 0)
-+ output_asm_insn ("lea.1\t%0, %%lo(%E1)(%0)", xoperands);
-+ return;
-+ }
-+
-+ if ((INTVAL (xoperands[1]) & 0xffff0000) == 0)
-+ {
-+ output_asm_insn ("movei\t%0, #%%lo(%E1)", xoperands);
-+ output_asm_insn ("move.2\t%0, %0", xoperands);
-+ return;
-+ }
-+
-+ /* This is very expensive. The constant is so large that we
-+ need to use the stack to do the load. */
-+ output_asm_insn ("movei\t-4(sp)++, #%%hi(%E1)", xoperands);
-+ output_asm_insn ("movei\t2(sp), #%%lo(%E1)", xoperands);
-+ output_asm_insn ("move.4\t%0, (sp)4++", xoperands);
-+}
-+
-+/* Stack layout. Prologue/Epilogue. */
-+
-+static int save_regs_size;
-+
-+static void
-+ubicom32_layout_frame (void)
-+{
-+ int regno;
-+
-+ memset ((char *) &save_regs[0], 0, sizeof (save_regs));
-+ nregs = 0;
-+ frame_size = get_frame_size ();
-+
-+ if (frame_pointer_needed || df_regs_ever_live_p (FRAME_POINTER_REGNUM))
-+ {
-+ save_regs[FRAME_POINTER_REGNUM] = 1;
-+ ++nregs;
-+ }
-+
-+ if (current_function_is_leaf && ! df_regs_ever_live_p (LINK_REGNO))
-+ ubicom32_can_use_calli_to_ret = 1;
-+ else
-+ {
-+ ubicom32_can_use_calli_to_ret = 0;
-+ save_regs[LINK_REGNO] = 1;
-+ ++nregs;
-+ }
-+
-+ /* Figure out which register(s) needs to be saved. */
-+ for (regno = 0; regno <= LAST_ADDRESS_REGNUM; regno++)
-+ if (df_regs_ever_live_p(regno)
-+ && ! call_used_regs[regno]
-+ && ! fixed_regs[regno]
-+ && ! save_regs[regno])
-+ {
-+ save_regs[regno] = 1;
-+ ++nregs;
-+ }
-+
-+ save_regs_size = 4 * nregs;
-+}
-+
-+static void
-+ubicom32_emit_add_movsi (int regno, int adj)
-+{
-+ rtx x;
-+ rtx reg = gen_rtx_REG (SImode, regno);
-+
-+ adj += 4;
-+ if (adj > 8 * 4)
-+ {
-+ x = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
-+ GEN_INT (-adj)));
-+ RTX_FRAME_RELATED_P (x) = 1;
-+ x = emit_move_insn (gen_rtx_MEM (SImode, stack_pointer_rtx), reg);
-+ }
-+ else
-+ {
-+ rtx addr = gen_rtx_PRE_MODIFY (Pmode, stack_pointer_rtx,
-+ gen_rtx_PLUS (Pmode, stack_pointer_rtx,
-+ GEN_INT (-adj)));
-+ x = emit_move_insn (gen_rtx_MEM (SImode, addr), reg);
-+ }
-+ RTX_FRAME_RELATED_P (x) = 1;
-+}
-+
-+void
-+ubicom32_expand_prologue (void)
-+{
-+ rtx x;
-+ int regno;
-+ int outgoing_args_size = crtl->outgoing_args_size;
-+ int adj;
-+
-+ if (ubicom32_naked_function_p ())
-+ return;
-+
-+ ubicom32_builtin_saveregs ();
-+
-+ ubicom32_layout_frame ();
-+ adj = (outgoing_args_size + get_frame_size () + save_regs_size
-+ + crtl->args.pretend_args_size);
-+
-+ if (!adj)
-+ ;
-+ else if (outgoing_args_size + save_regs_size < 508
-+ && get_frame_size () + save_regs_size > 508)
-+ {
-+ int i = 0;
-+ x = gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
-+ GEN_INT (-adj));
-+ x = emit_insn (x);
-+ RTX_FRAME_RELATED_P (x) = 1;
-+
-+ for (regno = LAST_ADDRESS_REGNUM; regno >= 0; --regno)
-+ if (save_regs[regno] && regno != LINK_REGNO)
-+ {
-+ x = gen_rtx_MEM (SImode,
-+ gen_rtx_PLUS (Pmode,
-+ stack_pointer_rtx,
-+ GEN_INT (i * 4 + outgoing_args_size)));
-+ x = emit_move_insn (x, gen_rtx_REG (SImode, regno));
-+ RTX_FRAME_RELATED_P (x) = 1;
-+ ++i;
-+ }
-+ if (save_regs[LINK_REGNO])
-+ {
-+ x = gen_rtx_MEM (SImode,
-+ gen_rtx_PLUS (Pmode,
-+ stack_pointer_rtx,
-+ GEN_INT (i * 4 + outgoing_args_size)));
-+ x = emit_move_insn (x, gen_rtx_REG (SImode, LINK_REGNO));
-+ RTX_FRAME_RELATED_P (x) = 1;
-+ }
-+ }
-+ else
-+ {
-+ int regno;
-+ int adj = get_frame_size () + crtl->args.pretend_args_size;
-+ int i = 0;
-+
-+ if (save_regs[LINK_REGNO])
-+ {
-+ ubicom32_emit_add_movsi (LINK_REGNO, adj);
-+ ++i;
-+ }
-+
-+ for (regno = 0; regno <= LAST_ADDRESS_REGNUM; ++regno)
-+ if (save_regs[regno] && regno != LINK_REGNO)
-+ {
-+ if (i)
-+ {
-+ rtx mem = gen_rtx_MEM (SImode,
-+ gen_rtx_PRE_DEC (Pmode,
-+ stack_pointer_rtx));
-+ x = emit_move_insn (mem, gen_rtx_REG (SImode, regno));
-+ RTX_FRAME_RELATED_P (x) = 1;
-+ }
-+ else
-+ ubicom32_emit_add_movsi (regno, adj);
-+ ++i;
-+ }
-+
-+ if (outgoing_args_size || (!i && adj))
-+ {
-+ x = gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
-+ GEN_INT (-outgoing_args_size - (i ? 0 : adj)));
-+ x = emit_insn (x);
-+ RTX_FRAME_RELATED_P (x) = 1;
-+ }
-+ }
-+
-+ if (frame_pointer_needed)
-+ {
-+ int fp_adj = save_regs_size + outgoing_args_size;
-+ x = gen_addsi3 (frame_pointer_rtx, stack_pointer_rtx,
-+ GEN_INT (fp_adj));
-+ x = emit_insn (x);
-+ RTX_FRAME_RELATED_P (x) = 1;
-+ }
-+}
-+
-+void
-+ubicom32_expand_epilogue (void)
-+{
-+ rtx x;
-+ int regno;
-+ int outgoing_args_size = crtl->outgoing_args_size;
-+ int adj;
-+ int i;
-+
-+ if (ubicom32_naked_function_p ())
-+ {
-+ emit_jump_insn (gen_return_internal (gen_rtx_REG (SImode,
-+ LINK_REGNO)));
-+ return;
-+ }
-+
-+ if (cfun->calls_alloca)
-+ {
-+ x = gen_addsi3 (stack_pointer_rtx, frame_pointer_rtx,
-+ GEN_INT (-save_regs_size));
-+ emit_insn (x);
-+ outgoing_args_size = 0;
-+ }
-+
-+ if (outgoing_args_size)
-+ {
-+ x = gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
-+ GEN_INT (outgoing_args_size));
-+ emit_insn (x);
-+ }
-+
-+ i = 0;
-+ for (regno = LAST_ADDRESS_REGNUM; regno >= 0; --regno)
-+ if (save_regs[regno] && regno != LINK_REGNO)
-+ {
-+ x = gen_rtx_MEM (SImode, gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
-+ emit_move_insn (gen_rtx_REG (SImode, regno), x);
-+ ++i;
-+ }
-+
-+ /* Do we have to adjust the stack after we've finished restoring regs? */
-+ adj = get_frame_size() + crtl->args.pretend_args_size;
-+ if (cfun->stdarg)
-+ adj += UBICOM32_FUNCTION_ARG_REGS * UNITS_PER_WORD;
-+
-+#if 0
-+ if (crtl->calls_eh_return && 0)
-+ {
-+ if (save_regs[LINK_REGNO])
-+ {
-+ x = gen_rtx_MEM (SImode, gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
-+ emit_move_insn (gen_rtx_REG (SImode, LINK_REGNO), x);
-+ }
-+
-+ if (adj)
-+ {
-+ x = gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
-+ GEN_INT (adj));
-+ x = emit_insn (x);
-+ }
-+
-+ /* Perform the additional bump for __throw. */
-+ emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
-+ EH_RETURN_STACKADJ_RTX));
-+ emit_jump_insn (gen_eh_return_internal ());
-+ return;
-+ }
-+#endif
-+
-+ if (save_regs[LINK_REGNO])
-+ {
-+ if (adj >= 4 && adj <= (6 * 4))
-+ {
-+ x = GEN_INT (adj + 4);
-+ emit_jump_insn (gen_return_from_post_modify_sp (x));
-+ return;
-+ }
-+
-+ if (adj == 0)
-+ {
-+ x = gen_rtx_MEM (SImode, gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
-+ emit_jump_insn (gen_return_internal (x));
-+ return;
-+ }
-+
-+ x = gen_rtx_MEM (SImode, gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
-+ emit_move_insn (gen_rtx_REG (SImode, LINK_REGNO), x);
-+ }
-+
-+ if (adj)
-+ {
-+ x = gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
-+ GEN_INT (adj));
-+ x = emit_insn (x);
-+ adj = 0;
-+ }
-+
-+ /* Given that we've just done all the hard work here we may as well use
-+ a calli to return. */
-+ ubicom32_can_use_calli_to_ret = 1;
-+ emit_jump_insn (gen_return_internal (gen_rtx_REG (SImode, LINK_REGNO)));
-+}
-+
-+void
-+ubicom32_expand_call_fdpic (rtx *operands)
-+{
-+ rtx c;
-+ rtx addr;
-+ rtx fdpic_reg = get_hard_reg_initial_val (SImode, FDPIC_REGNUM);
-+
-+ addr = XEXP (operands[0], 0);
-+
-+ c = gen_call_fdpic (addr, operands[1], fdpic_reg);
-+ emit_call_insn (c);
-+}
-+
-+void
-+ubicom32_expand_call_value_fdpic (rtx *operands)
-+{
-+ rtx c;
-+ rtx addr;
-+ rtx fdpic_reg = get_hard_reg_initial_val (SImode, FDPIC_REGNUM);
-+
-+ addr = XEXP (operands[1], 0);
-+
-+ c = gen_call_value_fdpic (operands[0], addr, operands[2], fdpic_reg);
-+ emit_call_insn (c);
-+}
-+
-+void
-+ubicom32_expand_eh_return (rtx *operands)
-+{
-+ if (REG_P (operands[0])
-+ || REGNO (operands[0]) != EH_RETURN_STACKADJ_REGNO)
-+ {
-+ rtx sp = EH_RETURN_STACKADJ_RTX;
-+ emit_move_insn (sp, operands[0]);
-+ operands[0] = sp;
-+ }
-+
-+ if (REG_P (operands[1])
-+ || REGNO (operands[1]) != EH_RETURN_HANDLER_REGNO)
-+ {
-+ rtx ra = EH_RETURN_HANDLER_RTX;
-+ emit_move_insn (ra, operands[1]);
-+ operands[1] = ra;
-+ }
-+}
-+
-+/* Compute the offsets between eliminable registers. */
-+
-+int
-+ubicom32_initial_elimination_offset (int from, int to)
-+{
-+ ubicom32_layout_frame ();
-+ if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
-+ return save_regs_size + crtl->outgoing_args_size;
-+
-+ if (from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
-+ return get_frame_size ()/* + save_regs_size */;
-+
-+ if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
-+ return get_frame_size ()
-+ + crtl->outgoing_args_size
-+ + save_regs_size;
-+
-+ return 0;
-+}
-+
-+/* Return 1 if it is appropriate to emit `ret' instructions in the
-+ body of a function. Do this only if the epilogue is simple, needing a
-+ couple of insns. Prior to reloading, we can't tell how many registers
-+ must be saved, so return 0 then. Return 0 if there is no frame
-+ marker to de-allocate.
-+
-+ If NON_SAVING_SETJMP is defined and true, then it is not possible
-+ for the epilogue to be simple, so return 0. This is a special case
-+ since NON_SAVING_SETJMP will not cause regs_ever_live to change
-+ until final, but jump_optimize may need to know sooner if a
-+ `return' is OK. */
-+
-+int
-+ubicom32_can_use_return_insn_p (void)
-+{
-+ if (! reload_completed || frame_pointer_needed)
-+ return 0;
-+
-+ return 1;
-+}
-+
-+/* Attributes and CC handling. */
-+
-+/* Handle an attribute requiring a FUNCTION_DECL; arguments as in
-+ struct attribute_spec.handler. */
-+static tree
-+ubicom32_handle_fndecl_attribute (tree *node, tree name,
-+ tree args ATTRIBUTE_UNUSED,
-+ int flags ATTRIBUTE_UNUSED,
-+ bool *no_add_attrs)
-+{
-+ if (TREE_CODE (*node) != FUNCTION_DECL)
-+ {
-+ warning ("'%s' attribute only applies to functions",
-+ IDENTIFIER_POINTER (name));
-+ *no_add_attrs = true;
-+ }
-+
-+ return NULL_TREE;
-+}
-+
-+/* A C expression that places additional restrictions on the register class to
-+ use when it is necessary to copy value X into a register in class CLASS.
-+ The value is a register class; perhaps CLASS, or perhaps another, smaller
-+ class. On many machines, the following definition is safe:
-+
-+ #define PREFERRED_RELOAD_CLASS(X,CLASS) CLASS
-+
-+ Sometimes returning a more restrictive class makes better code. For
-+ example, on the 68000, when X is an integer constant that is in range for a
-+ `moveq' instruction, the value of this macro is always `DATA_REGS' as long
-+ as CLASS includes the data registers. Requiring a data register guarantees
-+ that a `moveq' will be used.
-+
-+ If X is a `const_double', by returning `NO_REGS' you can force X into a
-+ memory constant. This is useful on certain machines where immediate
-+ floating values cannot be loaded into certain kinds of registers. */
-+
-+enum reg_class
-+ubicom32_preferred_reload_class (rtx x, enum reg_class class)
-+{
-+ /* If a symbolic constant, HIGH or a PLUS is reloaded,
-+ it is most likely being used as an address, so
-+ prefer ADDRESS_REGS. If 'class' is not a superset
-+ of ADDRESS_REGS, e.g. DATA_REGS, then reject this reload. */
-+ if (GET_CODE (x) == PLUS
-+ || GET_CODE (x) == HIGH
-+ || GET_CODE (x) == LABEL_REF
-+ || GET_CODE (x) == SYMBOL_REF
-+ || GET_CODE (x) == CONST)
-+ {
-+ if (reg_class_subset_p (ALL_ADDRESS_REGS, class))
-+ return ALL_ADDRESS_REGS;
-+
-+ return NO_REGS;
-+ }
-+
-+ return class;
-+}
-+
-+/* Function arguments and varargs. */
-+
-+int
-+ubicom32_reg_parm_stack_space (tree fndecl)
-+{
-+ return 0;
-+
-+ if (fndecl
-+ && TYPE_ARG_TYPES (TREE_TYPE (fndecl)) != 0
-+ && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (TREE_TYPE (fndecl))))
-+ != void_type_node))
-+ return UBICOM32_FUNCTION_ARG_REGS * UNITS_PER_WORD;
-+
-+ return 0;
-+}
-+
-+/* Flush the argument registers to the stack for a stdarg function;
-+ return the new argument pointer. */
-+
-+rtx
-+ubicom32_builtin_saveregs (void)
-+{
-+ int regno;
-+
-+ if (! cfun->stdarg)
-+ return 0;
-+
-+ for (regno = UBICOM32_FUNCTION_ARG_REGS - 1; regno >= 0; --regno)
-+ emit_move_insn (gen_rtx_MEM (SImode,
-+ gen_rtx_PRE_DEC (SImode,
-+ stack_pointer_rtx)),
-+ gen_rtx_REG (SImode, regno));
-+
-+ return stack_pointer_rtx;
-+}
-+
-+void
-+ubicom32_va_start (tree valist, rtx nextarg)
-+{
-+ std_expand_builtin_va_start (valist, nextarg);
-+}
-+
-+rtx
-+ubicom32_va_arg (tree valist, tree type)
-+{
-+ HOST_WIDE_INT size, rsize;
-+ tree addr, incr, tmp;
-+ rtx addr_rtx;
-+ int indirect = 0;
-+
-+ /* Round up sizeof(type) to a word. */
-+ size = int_size_in_bytes (type);
-+ rsize = (size + UNITS_PER_WORD - 1) & -UNITS_PER_WORD;
-+
-+ /* Large types are passed by reference. */
-+ if (size > 8)
-+ {
-+ indirect = 1;
-+ size = rsize = UNITS_PER_WORD;
-+ }
-+
-+ incr = valist;
-+ addr = incr = save_expr (incr);
-+
-+ /* FIXME Nat's version - is it correct? */
-+ tmp = fold_convert (ptr_type_node, size_int (rsize));
-+ tmp = build2 (PLUS_EXPR, ptr_type_node, incr, tmp);
-+ incr = fold (tmp);
-+
-+ /* FIXME Nat's version - is it correct? */
-+ incr = build2 (MODIFY_EXPR, ptr_type_node, valist, incr);
-+
-+ TREE_SIDE_EFFECTS (incr) = 1;
-+ expand_expr (incr, const0_rtx, VOIDmode, EXPAND_NORMAL);
-+
-+ addr_rtx = expand_expr (addr, NULL, Pmode, EXPAND_NORMAL);
-+
-+ if (size < UNITS_PER_WORD)
-+ emit_insn (gen_addsi3 (addr_rtx, addr_rtx,
-+ GEN_INT (UNITS_PER_WORD - size)));
-+
-+ if (indirect)
-+ {
-+ addr_rtx = force_reg (Pmode, addr_rtx);
-+ addr_rtx = gen_rtx_MEM (Pmode, addr_rtx);
-+ set_mem_alias_set (addr_rtx, get_varargs_alias_set ());
-+ }
-+
-+ return addr_rtx;
-+}
-+
-+void
-+init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype, rtx libname,
-+ int indirect ATTRIBUTE_UNUSED)
-+{
-+ cum->nbytes = 0;
-+
-+ if (!libname)
-+ {
-+ cum->stdarg = (TYPE_ARG_TYPES (fntype) != 0
-+ && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
-+ != void_type_node));
-+ }
-+}
-+
-+/* Return an RTX to represent where a value in mode MODE will be passed
-+ to a function. If the result is 0, the argument will be pushed. */
-+
-+rtx
-+function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
-+ int named ATTRIBUTE_UNUSED)
-+{
-+ rtx result = 0;
-+ int size, align;
-+ int nregs = UBICOM32_FUNCTION_ARG_REGS;
-+
-+ /* Figure out the size of the object to be passed. */
-+ if (mode == BLKmode)
-+ size = int_size_in_bytes (type);
-+ else
-+ size = GET_MODE_SIZE (mode);
-+
-+ /* Figure out the alignment of the object to be passed. */
-+ align = size;
-+
-+ cum->nbytes = (cum->nbytes + 3) & ~3;
-+
-+ /* Don't pass this arg via a register if all the argument registers
-+ are used up. */
-+ if (cum->nbytes >= nregs * UNITS_PER_WORD)
-+ return 0;
-+
-+ /* Don't pass this arg via a register if it would be split between
-+ registers and memory. */
-+ result = gen_rtx_REG (mode, cum->nbytes / UNITS_PER_WORD);
-+
-+ return result;
-+}
-+
-+rtx
-+function_incoming_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
-+ int named ATTRIBUTE_UNUSED)
-+{
-+ if (cfun->stdarg)
-+ return 0;
-+
-+ return function_arg (cum, mode, type, named);
-+}
-+
-+
-+/* Implement hook TARGET_ARG_PARTIAL_BYTES.
-+
-+ Returns the number of bytes at the beginning of an argument that
-+ must be put in registers. The value must be zero for arguments
-+ that are passed entirely in registers or that are entirely pushed
-+ on the stack. */
-+static int
-+ubicom32_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
-+ tree type, bool named ATTRIBUTE_UNUSED)
-+{
-+ int size, diff;
-+
-+ int nregs = UBICOM32_FUNCTION_ARG_REGS;
-+
-+ /* round up to full word */
-+ cum->nbytes = (cum->nbytes + 3) & ~3;
-+
-+ if (targetm.calls.pass_by_reference (cum, mode, type, named))
-+ return 0;
-+
-+ /* number of bytes left in registers */
-+ diff = nregs*UNITS_PER_WORD - cum->nbytes;
-+
-+ /* regs all used up */
-+ if (diff <= 0)
-+ return 0;
-+
-+ /* Figure out the size of the object to be passed. */
-+ if (mode == BLKmode)
-+ size = int_size_in_bytes (type);
-+ else
-+ size = GET_MODE_SIZE (mode);
-+
-+ /* enough space left in regs for size */
-+ if (size <= diff)
-+ return 0;
-+
-+ /* put diff bytes in regs and rest on stack */
-+ return diff;
-+
-+}
-+
-+static bool
-+ubicom32_pass_by_reference (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
-+ enum machine_mode mode, const_tree type,
-+ bool named ATTRIBUTE_UNUSED)
-+{
-+ int size;
-+
-+ if (type)
-+ size = int_size_in_bytes (type);
-+ else
-+ size = GET_MODE_SIZE (mode);
-+
-+ return size <= 0 || size > 8;
-+}
-+
-+static bool
-+ubicom32_callee_copies (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
-+ enum machine_mode mode, const_tree type,
-+ bool named ATTRIBUTE_UNUSED)
-+{
-+ int size;
-+
-+ if (type)
-+ size = int_size_in_bytes (type);
-+ else
-+ size = GET_MODE_SIZE (mode);
-+
-+ return size <= 0 || size > 8;
-+}
-+
-+static bool
-+ubicom32_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
-+{
-+ int size, mode;
-+
-+ if (!type)
-+ return true;
-+
-+ size = int_size_in_bytes(type);
-+ if (size > 8)
-+ return true;
-+
-+ mode = TYPE_MODE(type);
-+ if (mode == BLKmode)
-+ return true;
-+
-+ return false;
-+}
-+
-+/* Return true if a given register number REGNO is acceptable for machine
-+ mode MODE. */
-+bool
-+ubicom32_hard_regno_mode_ok (unsigned int regno, enum machine_mode mode)
-+{
-+ /* If we're not at least a v3 ISA then ACC0_HI is only 16 bits. */
-+ if (! ubicom32_v3)
-+ {
-+ if (regno == ACC0_HI_REGNUM)
-+ return (mode == QImode || mode == HImode);
-+ }
-+
-+ /* Only the flags reg can hold CCmode. */
-+ if (GET_MODE_CLASS (mode) == MODE_CC)
-+ return regno == CC_REGNUM;
-+
-+ /* We restrict the choice of DImode registers to only being address,
-+ data or accumulator regs. We also restrict them to only start on
-+ even register numbers so we never have to worry about partial
-+ overlaps between operands in instructions. */
-+ if (GET_MODE_SIZE (mode) > 4)
-+ {
-+ switch (REGNO_REG_CLASS (regno))
-+ {
-+ case ADDRESS_REGS:
-+ case DATA_REGS:
-+ case ACC_REGS:
-+ return (regno & 1) == 0;
-+
-+ default:
-+ return false;
-+ }
-+ }
-+
-+ return true;
-+}
-+
-+/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
-+ and check its validity for a certain class.
-+ We have two alternate definitions for each of them.
-+ The usual definition accepts all pseudo regs; the other rejects
-+ them unless they have been allocated suitable hard regs.
-+ The symbol REG_OK_STRICT causes the latter definition to be used.
-+
-+ Most source files want to accept pseudo regs in the hope that
-+ they will get allocated to the class that the insn wants them to be in.
-+ Source files for reload pass need to be strict.
-+ After reload, it makes no difference, since pseudo regs have
-+ been eliminated by then.
-+
-+ These assume that REGNO is a hard or pseudo reg number.
-+ They give nonzero only if REGNO is a hard reg of the suitable class
-+ or a pseudo reg currently allocated to a suitable hard reg.
-+ Since they use reg_renumber, they are safe only once reg_renumber
-+ has been allocated, which happens in local-alloc.c. */
-+
-+int
-+ubicom32_regno_ok_for_base_p (int regno, int strict)
-+{
-+ if ((regno >= FIRST_ADDRESS_REGNUM && regno <= STACK_POINTER_REGNUM)
-+ || (!strict
-+ && (regno >= FIRST_PSEUDO_REGISTER
-+ || regno == ARG_POINTER_REGNUM))
-+ || (strict && (reg_renumber
-+ && reg_renumber[regno] >= FIRST_ADDRESS_REGNUM
-+ && reg_renumber[regno] <= STACK_POINTER_REGNUM)))
-+ return 1;
-+
-+ return 0;
-+}
-+
-+int
-+ubicom32_regno_ok_for_index_p (int regno, int strict)
-+{
-+ if ((regno >= FIRST_DATA_REGNUM && regno <= LAST_DATA_REGNUM)
-+ || (!strict && regno >= FIRST_PSEUDO_REGISTER)
-+ || (strict && (reg_renumber
-+ && reg_renumber[regno] >= FIRST_DATA_REGNUM
-+ && reg_renumber[regno] <= LAST_DATA_REGNUM)))
-+ return 1;
-+
-+ return 0;
-+}
-+
-+/* Returns 1 if X is a valid index register. STRICT is 1 if only hard
-+ registers should be accepted. Accept either REG or SUBREG where a
-+ register is valid. */
-+
-+static bool
-+ubicom32_is_index_reg (rtx x, int strict)
-+{
-+ if ((REG_P (x) && ubicom32_regno_ok_for_index_p (REGNO (x), strict))
-+ || (GET_CODE (x) == SUBREG && REG_P (SUBREG_REG (x))
-+ && ubicom32_regno_ok_for_index_p (REGNO (SUBREG_REG (x)), strict)))
-+ return true;
-+
-+ return false;
-+}
-+
-+/* Return 1 if X is a valid index for a memory address. */
-+
-+static bool
-+ubicom32_is_index_expr (enum machine_mode mode, rtx x, int strict)
-+{
-+ /* Immediate index must be an unsigned 7-bit offset multiple of 1, 2
-+ or 4 depending on mode. */
-+ if (CONST_INT_P (x))
-+ {
-+ switch (mode)
-+ {
-+ case QImode:
-+ return satisfies_constraint_J (x);
-+
-+ case HImode:
-+ return satisfies_constraint_K (x);
-+
-+ case SImode:
-+ case SFmode:
-+ return satisfies_constraint_L (x);
-+
-+ case DImode:
-+ return satisfies_constraint_L (x)
-+ && satisfies_constraint_L (GEN_INT (INTVAL (x) + 4));
-+
-+ default:
-+ return false;
-+ }
-+ }
-+
-+ if (mode != SImode && mode != HImode && mode != QImode)
-+ return false;
-+
-+ /* Register index scaled by mode of operand: REG + REG * modesize.
-+ Valid scaled index registers are:
-+
-+ SImode (mult (dreg) 4))
-+ HImode (mult (dreg) 2))
-+ QImode (mult (dreg) 1)) */
-+ if (GET_CODE (x) == MULT
-+ && ubicom32_is_index_reg (XEXP (x, 0), strict)
-+ && CONST_INT_P (XEXP (x, 1))
-+ && INTVAL (XEXP (x, 1)) == (HOST_WIDE_INT)GET_MODE_SIZE (mode))
-+ return true;
-+
-+ /* REG + REG addressing is allowed for QImode. */
-+ if (ubicom32_is_index_reg (x, strict) && mode == QImode)
-+ return true;
-+
-+ return false;
-+}
-+
-+static bool
-+ubicom32_is_valid_offset (enum machine_mode mode, HOST_WIDE_INT offs)
-+{
-+ if (offs < 0)
-+ return false;
-+
-+ switch (mode)
-+ {
-+ case QImode:
-+ return offs <= 127;
-+
-+ case HImode:
-+ return offs <= 254;
-+
-+ case SImode:
-+ case SFmode:
-+ return offs <= 508;
-+
-+ case DImode:
-+ return offs <= 504;
-+
-+ default:
-+ return false;
-+ }
-+}
-+
-+static int
-+ubicom32_get_valid_offset_mask (enum machine_mode mode)
-+{
-+ switch (mode)
-+ {
-+ case QImode:
-+ return 127;
-+
-+ case HImode:
-+ return 255;
-+
-+ case SImode:
-+ case SFmode:
-+ return 511;
-+
-+ case DImode:
-+ return 255;
-+
-+ default:
-+ return 0;
-+ }
-+}
-+
-+/* Returns 1 if X is a valid base register. STRICT is 1 if only hard
-+ registers should be accepted. Accept either REG or SUBREG where a
-+ register is valid. */
-+
-+static bool
-+ubicom32_is_base_reg (rtx x, int strict)
-+{
-+ if ((REG_P (x) && ubicom32_regno_ok_for_base_p (REGNO (x), strict))
-+ || (GET_CODE (x) == SUBREG && REG_P (SUBREG_REG (x))
-+ && ubicom32_regno_ok_for_base_p (REGNO (SUBREG_REG (x)), strict)))
-+ return true;
-+
-+ return false;
-+}
-+
-+static bool
-+ubicom32_cannot_force_const_mem (rtx x ATTRIBUTE_UNUSED)
-+{
-+ return TARGET_FDPIC;
-+}
-+
-+/* Determine if X is a legitimate constant. */
-+
-+bool
-+ubicom32_legitimate_constant_p (rtx x)
-+{
-+ /* Among its other duties, LEGITIMATE_CONSTANT_P decides whether
-+ a constant can be entered into reg_equiv_constant[]. If we return true,
-+ reload can create new instances of the constant whenever it likes.
-+
-+ The idea is therefore to accept as many constants as possible (to give
-+ reload more freedom) while rejecting constants that can only be created
-+ at certain times. In particular, anything with a symbolic component will
-+ require use of the pseudo FDPIC register, which is only available before
-+ reload. */
-+ if (TARGET_FDPIC)
-+ {
-+ if (GET_CODE (x) == SYMBOL_REF
-+ || (GET_CODE (x) == CONST
-+ && GET_CODE (XEXP (x, 0)) == PLUS
-+ && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF)
-+ || CONSTANT_ADDRESS_P (x))
-+ return false;
-+
-+ return true;
-+ }
-+
-+ /* For non-PIC code anything goes! */
-+ return true;
-+}
-+
-+/* Address validation. */
-+
-+bool
-+ubicom32_legitimate_address_p (enum machine_mode mode, rtx x, int strict)
-+{
-+ if (TARGET_DEBUG_ADDRESS)
-+ {
-+ fprintf (stderr, "\n==> GO_IF_LEGITIMATE_ADDRESS%s\n",
-+ (strict) ? " (STRICT)" : "");
-+ debug_rtx (x);
-+ }
-+
-+ if (CONSTANT_ADDRESS_P (x))
-+ return false;
-+
-+ if (ubicom32_is_base_reg (x, strict))
-+ return true;
-+
-+ if ((GET_CODE (x) == POST_INC
-+ || GET_CODE (x) == PRE_INC
-+ || GET_CODE (x) == POST_DEC
-+ || GET_CODE (x) == PRE_DEC)
-+ && REG_P (XEXP (x, 0))
-+ && ubicom32_is_base_reg (XEXP (x, 0), strict)
-+ && mode != DImode)
-+ return true;
-+
-+ if ((GET_CODE (x) == PRE_MODIFY || GET_CODE (x) == POST_MODIFY)
-+ && ubicom32_is_base_reg (XEXP (x, 0), strict)
-+ && GET_CODE (XEXP (x, 1)) == PLUS
-+ && rtx_equal_p (XEXP (x, 0), XEXP (XEXP (x, 1), 0))
-+ && CONST_INT_P (XEXP (XEXP (x, 1), 1))
-+ && mode != DImode)
-+ {
-+ HOST_WIDE_INT disp = INTVAL (XEXP (XEXP (x, 1), 1));
-+ switch (mode)
-+ {
-+ case QImode:
-+ return disp >= -8 && disp <= 7;
-+
-+ case HImode:
-+ return disp >= -16 && disp <= 14 && ! (disp & 1);
-+
-+ case SImode:
-+ return disp >= -32 && disp <= 28 && ! (disp & 3);
-+
-+ default:
-+ return false;
-+ }
-+ }
-+
-+ /* Accept base + index * scale. */
-+ if (GET_CODE (x) == PLUS
-+ && ubicom32_is_base_reg (XEXP (x, 0), strict)
-+ && ubicom32_is_index_expr (mode, XEXP (x, 1), strict))
-+ return true;
-+
-+ /* Accept index * scale + base. */
-+ if (GET_CODE (x) == PLUS
-+ && ubicom32_is_base_reg (XEXP (x, 1), strict)
-+ && ubicom32_is_index_expr (mode, XEXP (x, 0), strict))
-+ return true;
-+
-+ if (! TARGET_FDPIC)
-+ {
-+ /* Accept (lo_sum (reg) (symbol_ref)) that can be used as a mem+7bits
-+ displacement operand:
-+
-+ moveai a1, #%hi(SYM)
-+ move.4 d3, %lo(SYM)(a1) */
-+ if (GET_CODE (x) == LO_SUM
-+ && ubicom32_is_base_reg (XEXP (x, 0), strict)
-+ && (GET_CODE (XEXP (x, 1)) == SYMBOL_REF
-+ || GET_CODE (XEXP (x, 1)) == LABEL_REF /* FIXME: wrong */)
-+ && mode != DImode)
-+ return true;
-+ }
-+
-+ if (TARGET_DEBUG_ADDRESS)
-+ fprintf (stderr, "\nNot a legitimate address.\n");
-+
-+ return false;
-+}
-+
-+rtx
-+ubicom32_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
-+ enum machine_mode mode)
-+{
-+ if (mode == BLKmode)
-+ return NULL_RTX;
-+
-+ if (GET_CODE (x) == PLUS
-+ && REG_P (XEXP (x, 0))
-+ && ! REGNO_PTR_FRAME_P (REGNO (XEXP (x, 0)))
-+ && CONST_INT_P (XEXP (x, 1))
-+ && ! ubicom32_is_valid_offset (mode, INTVAL (XEXP (x, 1))))
-+ {
-+ rtx base;
-+ rtx plus;
-+ rtx new_rtx;
-+ HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
-+ HOST_WIDE_INT low = val & ubicom32_get_valid_offset_mask (mode);
-+ HOST_WIDE_INT high = val ^ low;
-+
-+ if (val < 0)
-+ return NULL_RTX;
-+
-+ if (! low)
-+ return NULL_RTX;
-+
-+ /* Reload the high part into a base reg; leave the low part
-+ in the mem directly. */
-+ base = XEXP (x, 0);
-+ if (! ubicom32_is_base_reg (base, 0))
-+ base = copy_to_mode_reg (Pmode, base);
-+
-+ plus = expand_simple_binop (Pmode, PLUS,
-+ gen_int_mode (high, Pmode),
-+ base, NULL, 0, OPTAB_WIDEN);
-+ new_rtx = plus_constant (plus, low);
-+
-+ return new_rtx;
-+ }
-+
-+ return NULL_RTX;
-+}
-+
-+/* Try a machine-dependent way of reloading an illegitimate address AD
-+ operand. If we find one, push the reload and and return the new address.
-+
-+ MODE is the mode of the enclosing MEM. OPNUM is the operand number
-+ and TYPE is the reload type of the current reload. */
-+
-+rtx
-+ubicom32_legitimize_reload_address (rtx ad, enum machine_mode mode,
-+ int opnum, int type)
-+{
-+ /* Is this an address that we've already fixed up? If it is then
-+ recognize it and move on. */
-+ if (GET_CODE (ad) == PLUS
-+ && GET_CODE (XEXP (ad, 0)) == PLUS
-+ && REG_P (XEXP (XEXP (ad, 0), 0))
-+ && CONST_INT_P (XEXP (XEXP (ad, 0), 1))
-+ && CONST_INT_P (XEXP (ad, 1)))
-+ {
-+ push_reload (XEXP (ad, 0), NULL_RTX, &XEXP (ad, 0), NULL,
-+ BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
-+ opnum, (enum reload_type) type);
-+ return ad;
-+ }
-+
-+ /* Have we got an address where the offset is simply out of range? If
-+ yes then reload the range as a high part and smaller offset. */
-+ if (GET_CODE (ad) == PLUS
-+ && REG_P (XEXP (ad, 0))
-+ && REGNO (XEXP (ad, 0)) < FIRST_PSEUDO_REGISTER
-+ && REGNO_OK_FOR_BASE_P (REGNO (XEXP (ad, 0)))
-+ && CONST_INT_P (XEXP (ad, 1))
-+ && ! ubicom32_is_valid_offset (mode, INTVAL (XEXP (ad, 1))))
-+ {
-+ rtx temp;
-+ rtx new_rtx;
-+
-+ HOST_WIDE_INT val = INTVAL (XEXP (ad, 1));
-+ HOST_WIDE_INT low = val & ubicom32_get_valid_offset_mask (mode);
-+ HOST_WIDE_INT high = val ^ low;
-+
-+ /* Reload the high part into a base reg; leave the low part
-+ in the mem directly. */
-+ temp = gen_rtx_PLUS (Pmode, XEXP (ad, 0), GEN_INT (high));
-+ new_rtx = gen_rtx_PLUS (Pmode, temp, GEN_INT (low));
-+
-+ push_reload (XEXP (new_rtx, 0), NULL_RTX, &XEXP (new_rtx, 0), NULL,
-+ BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
-+ opnum, (enum reload_type) type);
-+ return new_rtx;
-+ }
-+
-+ /* If we're presented with an pre/post inc/dec then we must force this
-+ to be done in an address register. The register allocator should
-+ work this out for itself but at times ends up trying to use the wrong
-+ class. If we get the wrong class then reload will end up generating
-+ at least 3 instructions whereas this way we can hopefully keep it to
-+ just 2. */
-+ if ((GET_CODE (ad) == POST_INC
-+ || GET_CODE (ad) == PRE_INC
-+ || GET_CODE (ad) == POST_DEC
-+ || GET_CODE (ad) == PRE_DEC)
-+ && REG_P (XEXP (ad, 0))
-+ && REGNO (XEXP (ad, 0)) < FIRST_PSEUDO_REGISTER
-+ && ! REGNO_OK_FOR_BASE_P (REGNO (XEXP (ad, 0))))
-+ {
-+ push_reload (XEXP (ad, 0), XEXP (ad, 0), &XEXP (ad, 0), &XEXP (ad, 0),
-+ BASE_REG_CLASS, GET_MODE (XEXP (ad, 0)), GET_MODE (XEXP (ad, 0)), 0, 0,
-+ opnum, RELOAD_OTHER);
-+ return ad;
-+ }
-+
-+ return NULL_RTX;
-+}
-+
-+/* Compute a (partial) cost for rtx X. Return true if the complete
-+ cost has been computed, and false if subexpressions should be
-+ scanned. In either case, *TOTAL contains the cost result. */
-+
-+static bool
-+ubicom32_rtx_costs (rtx x, int code, int outer_code, int *total,
-+ bool speed ATTRIBUTE_UNUSED)
-+{
-+ enum machine_mode mode = GET_MODE (x);
-+
-+ switch (code)
-+ {
-+ case CONST_INT:
-+ /* Very short constants often fold into instructions so
-+ we pretend that they don't cost anything! This is
-+ really important as regards zero values as otherwise
-+ the compiler has a nasty habit of wanting to reuse
-+ zeroes that are in regs but that tends to pessimize
-+ the code. */
-+ if (satisfies_constraint_I (x))
-+ {
-+ *total = 0;
-+ return true;
-+ }
-+
-+ /* Bit clearing costs nothing */
-+ if (outer_code == AND
-+ && exact_log2 (~INTVAL (x)) != -1)
-+ {
-+ *total = 0;
-+ return true;
-+ }
-+
-+ /* Masking the lower set of bits costs nothing. */
-+ if (outer_code == AND
-+ && exact_log2 (INTVAL (x) + 1) != -1)
-+ {
-+ *total = 0;
-+ return true;
-+ }
-+
-+ /* Bit setting costs nothing. */
-+ if (outer_code == IOR
-+ && exact_log2 (INTVAL (x)) != -1)
-+ {
-+ *total = 0;
-+ return true;
-+ }
-+
-+ /* Larger constants that can be loaded via movei aren't too
-+ bad. If we're just doing a set they cost nothing extra. */
-+ if (satisfies_constraint_N (x))
-+ {
-+ if (mode == DImode)
-+ *total = COSTS_N_INSNS (2);
-+ else
-+ *total = COSTS_N_INSNS (1);
-+ return true;
-+ }
-+
-+ if (mode == DImode)
-+ *total = COSTS_N_INSNS (5);
-+ else
-+ *total = COSTS_N_INSNS (3);
-+ return true;
-+
-+ case CONST_DOUBLE:
-+ /* We don't optimize CONST_DOUBLEs well nor do we relax them well,
-+ so their cost is very high. */
-+ *total = COSTS_N_INSNS (6);
-+ return true;
-+
-+ case CONST:
-+ case SYMBOL_REF:
-+ case MEM:
-+ *total = 0;
-+ return true;
-+
-+ case IF_THEN_ELSE:
-+ *total = COSTS_N_INSNS (1);
-+ return true;
-+
-+ case LABEL_REF:
-+ case HIGH:
-+ case LO_SUM:
-+ case BSWAP:
-+ case PLUS:
-+ case MINUS:
-+ case AND:
-+ case IOR:
-+ case XOR:
-+ case ASHIFT:
-+ case ASHIFTRT:
-+ case LSHIFTRT:
-+ case NEG:
-+ case NOT:
-+ case SIGN_EXTEND:
-+ case ZERO_EXTEND:
-+ case ZERO_EXTRACT:
-+ if (outer_code == SET)
-+ {
-+ if (mode == DImode)
-+ *total = COSTS_N_INSNS (2);
-+ else
-+ *total = COSTS_N_INSNS (1);
-+ }
-+ return true;
-+
-+ case COMPARE:
-+ if (outer_code == SET)
-+ {
-+ if (GET_MODE (XEXP (x, 0)) == DImode
-+ || GET_MODE (XEXP (x, 1)) == DImode)
-+ *total = COSTS_N_INSNS (2);
-+ else
-+ *total = COSTS_N_INSNS (1);
-+ }
-+ return true;
-+
-+ case UMOD:
-+ case UDIV:
-+ case MOD:
-+ case DIV:
-+ if (outer_code == SET)
-+ {
-+ if (mode == DImode)
-+ *total = COSTS_N_INSNS (600);
-+ else
-+ *total = COSTS_N_INSNS (200);
-+ }
-+ return true;
-+
-+ case MULT:
-+ if (outer_code == SET)
-+ {
-+ if (! ubicom32_v4)
-+ {
-+ if (mode == DImode)
-+ *total = COSTS_N_INSNS (15);
-+ else
-+ *total = COSTS_N_INSNS (5);
-+ }
-+ else
-+ {
-+ if (mode == DImode)
-+ *total = COSTS_N_INSNS (6);
-+ else
-+ *total = COSTS_N_INSNS (2);
-+ }
-+ }
-+ return true;
-+
-+ case UNSPEC:
-+ if (XINT (x, 1) == UNSPEC_FDPIC_GOT
-+ || XINT (x, 1) == UNSPEC_FDPIC_GOT_FUNCDESC)
-+ *total = 0;
-+ return true;
-+
-+ default:
-+ return false;
-+ }
-+}
-+
-+/* Return 1 if ADDR can have different meanings depending on the machine
-+ mode of the memory reference it is used for or if the address is
-+ valid for some modes but not others.
-+
-+ Autoincrement and autodecrement addresses typically have
-+ mode-dependent effects because the amount of the increment or
-+ decrement is the size of the operand being addressed. Some machines
-+ have other mode-dependent addresses. Many RISC machines have no
-+ mode-dependent addresses.
-+
-+ You may assume that ADDR is a valid address for the machine. */
-+
-+int
-+ubicom32_mode_dependent_address_p (rtx addr)
-+{
-+ if (GET_CODE (addr) == POST_INC
-+ || GET_CODE (addr) == PRE_INC
-+ || GET_CODE (addr) == POST_DEC
-+ || GET_CODE (addr) == PRE_DEC
-+ || GET_CODE (addr) == POST_MODIFY
-+ || GET_CODE (addr) == PRE_MODIFY)
-+ return 1;
-+
-+ return 0;
-+}
-+
-+static void
-+ubicom32_function_prologue (FILE *file, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
-+{
-+ fprintf (file, "/* frame/pretend: %ld/%d save_regs: %d out_args: %d %s */\n",
-+ get_frame_size (), crtl->args.pretend_args_size,
-+ save_regs_size, crtl->outgoing_args_size,
-+ current_function_is_leaf ? "leaf" : "nonleaf");
-+}
-+
-+static void
-+ubicom32_function_epilogue (FILE *file ATTRIBUTE_UNUSED,
-+ HOST_WIDE_INT size ATTRIBUTE_UNUSED)
-+{
-+ ubicom32_reorg_completed = 0;
-+}
-+
-+static void
-+ubicom32_machine_dependent_reorg (void)
-+{
-+#if 0 /* Commenting out this optimization until it is fixed */
-+ if (optimize)
-+ {
-+ compute_bb_for_insn ();
-+
-+ /* Do a very simple CSE pass over just the hard registers. */
-+ reload_cse_regs (get_insns ());
-+
-+ /* Reload_cse_regs can eliminate potentially-trapping MEMs.
-+ Remove any EH edges associated with them. */
-+ if (flag_non_call_exceptions)
-+ purge_all_dead_edges ();
-+ }
-+#endif
-+ ubicom32_reorg_completed = 1;
-+}
-+
-+void
-+ubicom32_output_cond_jump (rtx insn, rtx cond, rtx target)
-+{
-+ rtx note;
-+ int mostly_false_jump;
-+ rtx xoperands[2];
-+ rtx cc_reg;
-+
-+ note = find_reg_note (insn, REG_BR_PROB, 0);
-+ mostly_false_jump = !note || (INTVAL (XEXP (note, 0))
-+ <= REG_BR_PROB_BASE / 2);
-+
-+ xoperands[0] = target;
-+ xoperands[1] = cond;
-+ cc_reg = XEXP (cond, 0);
-+
-+ if (GET_MODE (cc_reg) == CCWmode
-+ || GET_MODE (cc_reg) == CCWZmode
-+ || GET_MODE (cc_reg) == CCWZNmode)
-+ {
-+ if (mostly_false_jump)
-+ output_asm_insn ("jmp%b1.w.f\t%0", xoperands);
-+ else
-+ output_asm_insn ("jmp%b1.w.t\t%0", xoperands);
-+ return;
-+ }
-+
-+ if (GET_MODE (cc_reg) == CCSmode
-+ || GET_MODE (cc_reg) == CCSZmode
-+ || GET_MODE (cc_reg) == CCSZNmode)
-+ {
-+ if (mostly_false_jump)
-+ output_asm_insn ("jmp%b1.s.f\t%0", xoperands);
-+ else
-+ output_asm_insn ("jmp%b1.s.t\t%0", xoperands);
-+ return;
-+ }
-+
-+ abort ();
-+}
-+
-+/* Return non-zero if FUNC is a naked function. */
-+
-+static int
-+ubicom32_naked_function_p (void)
-+{
-+ return lookup_attribute ("naked", DECL_ATTRIBUTES (current_function_decl)) != NULL_TREE;
-+}
-+
-+/* Return an RTX indicating where the return address to the
-+ calling function can be found. */
-+rtx
-+ubicom32_return_addr_rtx (int count, rtx frame ATTRIBUTE_UNUSED)
-+{
-+ if (count != 0)
-+ return NULL_RTX;
-+
-+ return get_hard_reg_initial_val (Pmode, LINK_REGNO);
-+}
-+
-+/*
-+ * ubicom32_readonly_data_section: This routtine handles code
-+ * at the start of readonly data sections
-+ */
-+static void
-+ubicom32_readonly_data_section (const void *data ATTRIBUTE_UNUSED)
-+{
-+ static int num = 0;
-+ if (in_section == readonly_data_section){
-+ fprintf (asm_out_file, "%s", DATA_SECTION_ASM_OP);
-+ if (flag_data_sections){
-+ fprintf (asm_out_file, ".rodata%d", num);
-+ fprintf (asm_out_file, ",\"a\"");
-+ }
-+ fprintf (asm_out_file, "\n");
-+ }
-+ num++;
-+}
-+
-+/*
-+ * ubicom32_text_section: not in readonly section
-+ */
-+static void
-+ubicom32_text_section(const void *data ATTRIBUTE_UNUSED)
-+{
-+ fprintf (asm_out_file, "%s\n", TEXT_SECTION_ASM_OP);
-+}
-+
-+/*
-+ * ubicom32_data_section: not in readonly section
-+ */
-+static void
-+ubicom32_data_section(const void *data ATTRIBUTE_UNUSED)
-+{
-+ fprintf (asm_out_file, "%s\n", DATA_SECTION_ASM_OP);
-+}
-+
-+/*
-+ * ubicom32_asm_init_sections: This routine implements special
-+ * section handling
-+ */
-+static void
-+ubicom32_asm_init_sections(void)
-+{
-+ text_section = get_unnamed_section(SECTION_CODE, ubicom32_text_section, NULL);
-+
-+ data_section = get_unnamed_section(SECTION_WRITE, ubicom32_data_section, NULL);
-+
-+ readonly_data_section = get_unnamed_section(0, ubicom32_readonly_data_section, NULL);
-+}
-+
-+/*
-+ * ubicom32_profiler: This routine would call
-+ * mcount to support prof and gprof if mcount
-+ * was supported. Currently, do nothing.
-+ */
-+void
-+ubicom32_profiler(void)
-+{
-+}
-+
-+/* Initialise the builtin functions. Start by initialising
-+ descriptions of different types of functions (e.g., void fn(int),
-+ int fn(void)), and then use these to define the builtins. */
-+static void
-+ubicom32_init_builtins (void)
-+{
-+ tree endlink;
-+ tree short_unsigned_endlink;
-+ tree unsigned_endlink;
-+ tree short_unsigned_ftype_short_unsigned;
-+ tree unsigned_ftype_unsigned;
-+
-+ endlink = void_list_node;
-+
-+ short_unsigned_endlink
-+ = tree_cons (NULL_TREE, short_unsigned_type_node, endlink);
-+
-+ unsigned_endlink
-+ = tree_cons (NULL_TREE, unsigned_type_node, endlink);
-+
-+ short_unsigned_ftype_short_unsigned
-+ = build_function_type (short_unsigned_type_node, short_unsigned_endlink);
-+
-+ unsigned_ftype_unsigned
-+ = build_function_type (unsigned_type_node, unsigned_endlink);
-+
-+ /* Initialise the byte swap function. */
-+ add_builtin_function ("__builtin_ubicom32_swapb_2",
-+ short_unsigned_ftype_short_unsigned,
-+ UBICOM32_BUILTIN_UBICOM32_SWAPB_2,
-+ BUILT_IN_MD, NULL,
-+ NULL_TREE);
-+
-+ /* Initialise the byte swap function. */
-+ add_builtin_function ("__builtin_ubicom32_swapb_4",
-+ unsigned_ftype_unsigned,
-+ UBICOM32_BUILTIN_UBICOM32_SWAPB_4,
-+ BUILT_IN_MD, NULL,
-+ NULL_TREE);
-+}
-+
-+/* Given a builtin function taking 2 operands (i.e., target + source),
-+ emit the RTL for the underlying instruction. */
-+static rtx
-+ubicom32_expand_builtin_2op (enum insn_code icode, tree arglist, rtx target)
-+{
-+ tree arg0;
-+ rtx op0, pat;
-+ enum machine_mode tmode, mode0;
-+
-+ /* Grab the incoming argument and emit its RTL. */
-+ arg0 = TREE_VALUE (arglist);
-+ op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
-+
-+ /* Determine the modes of the instruction operands. */
-+ tmode = insn_data[icode].operand[0].mode;
-+ mode0 = insn_data[icode].operand[1].mode;
-+
-+ /* Ensure that the incoming argument RTL is in a register of the
-+ correct mode. */
-+ if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
-+ op0 = copy_to_mode_reg (mode0, op0);
-+
-+ /* If there isn't a suitable target, emit a target register. */
-+ if (target == 0
-+ || GET_MODE (target) != tmode
-+ || !(*insn_data[icode].operand[0].predicate) (target, tmode))
-+ target = gen_reg_rtx (tmode);
-+
-+ /* Emit and return the new instruction. */
-+ pat = GEN_FCN (icode) (target, op0);
-+ if (!pat)
-+ return 0;
-+ emit_insn (pat);
-+
-+ return target;
-+}
-+
-+/* Expand a call to a builtin function. */
-+static rtx
-+ubicom32_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
-+ enum machine_mode mode ATTRIBUTE_UNUSED,
-+ int ignore ATTRIBUTE_UNUSED)
-+{
-+ tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
-+ tree arglist = CALL_EXPR_ARGS(exp);
-+ int fcode = DECL_FUNCTION_CODE (fndecl);
-+
-+ switch (fcode)
-+ {
-+ case UBICOM32_BUILTIN_UBICOM32_SWAPB_2:
-+ return ubicom32_expand_builtin_2op (CODE_FOR_bswaphi, arglist, target);
-+
-+ case UBICOM32_BUILTIN_UBICOM32_SWAPB_4:
-+ return ubicom32_expand_builtin_2op (CODE_FOR_bswapsi, arglist, target);
-+
-+ default:
-+ gcc_unreachable();
-+ }
-+
-+ /* Should really do something sensible here. */
-+ return NULL_RTX;
-+}
-+
-+/* Fold any constant argument for a swapb.2 instruction. */
-+static tree
-+ubicom32_fold_builtin_ubicom32_swapb_2 (tree fndecl, tree arglist)
-+{
-+ tree arg0;
-+
-+ arg0 = TREE_VALUE (arglist);
-+
-+ /* Optimize constant value. */
-+ if (TREE_CODE (arg0) == INTEGER_CST)
-+ {
-+ HOST_WIDE_INT v;
-+ HOST_WIDE_INT res;
-+
-+ v = TREE_INT_CST_LOW (arg0);
-+ res = ((v >> 8) & 0xff)
-+ | ((v & 0xff) << 8);
-+
-+ return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), res);
-+ }
-+
-+ return NULL_TREE;
-+}
-+
-+/* Fold any constant argument for a swapb.4 instruction. */
-+static tree
-+ubicom32_fold_builtin_ubicom32_swapb_4 (tree fndecl, tree arglist)
-+{
-+ tree arg0;
-+
-+ arg0 = TREE_VALUE (arglist);
-+
-+ /* Optimize constant value. */
-+ if (TREE_CODE (arg0) == INTEGER_CST)
-+ {
-+ unsigned HOST_WIDE_INT v;
-+ unsigned HOST_WIDE_INT res;
-+
-+ v = TREE_INT_CST_LOW (arg0);
-+ res = ((v >> 24) & 0xff)
-+ | (((v >> 16) & 0xff) << 8)
-+ | (((v >> 8) & 0xff) << 16)
-+ | ((v & 0xff) << 24);
-+
-+ return build_int_cst_wide (TREE_TYPE (TREE_TYPE (fndecl)), res, 0);
-+ }
-+
-+ return NULL_TREE;
-+}
-+
-+/* Fold any constant arguments for builtin functions. */
-+static tree
-+ubicom32_fold_builtin (tree fndecl, tree arglist, bool ignore ATTRIBUTE_UNUSED)
-+{
-+ switch (DECL_FUNCTION_CODE (fndecl))
-+ {
-+ case UBICOM32_BUILTIN_UBICOM32_SWAPB_2:
-+ return ubicom32_fold_builtin_ubicom32_swapb_2 (fndecl, arglist);
-+
-+ case UBICOM32_BUILTIN_UBICOM32_SWAPB_4:
-+ return ubicom32_fold_builtin_ubicom32_swapb_4 (fndecl, arglist);
-+
-+ default:
-+ return NULL;
-+ }
-+}
-+
-+/* Implementation of TARGET_ASM_INTEGER. When using FD-PIC, we need to
-+ tell the assembler to generate pointers to function descriptors in
-+ some cases. */
-+static bool
-+ubicom32_assemble_integer (rtx value, unsigned int size, int aligned_p)
-+{
-+ if (TARGET_FDPIC && size == UNITS_PER_WORD)
-+ {
-+ if (GET_CODE (value) == SYMBOL_REF
-+ && SYMBOL_REF_FUNCTION_P (value))
-+ {
-+ fputs ("\t.picptr\t%funcdesc(", asm_out_file);
-+ output_addr_const (asm_out_file, value);
-+ fputs (")\n", asm_out_file);
-+ return true;
-+ }
-+
-+ if (!aligned_p)
-+ {
-+ /* We've set the unaligned SI op to NULL, so we always have to
-+ handle the unaligned case here. */
-+ assemble_integer_with_op ("\t.4byte\t", value);
-+ return true;
-+ }
-+ }
-+
-+ return default_assemble_integer (value, size, aligned_p);
-+}
-+
-+/* If the constant I can be constructed by shifting a source-1 immediate
-+ by a constant number of bits then return the bit count. If not
-+ return 0. */
-+
-+int
-+ubicom32_shiftable_const_int (int i)
-+{
-+ int shift = 0;
-+
-+ /* Note that any constant that can be represented as an immediate to
-+ a movei instruction is automatically ignored here in the interests
-+ of the clarity of the output asm code. */
-+ if (i >= -32768 && i <= 32767)
-+ return 0;
-+
-+ /* Find the number of trailing zeroes. We could use __builtin_ctz
-+ here but it's not obvious if this is supported on all build
-+ compilers so we err on the side of caution. */
-+ if ((i & 0xffff) == 0)
-+ {
-+ shift += 16;
-+ i >>= 16;
-+ }
-+
-+ if ((i & 0xff) == 0)
-+ {
-+ shift += 8;
-+ i >>= 8;
-+ }
-+
-+ if ((i & 0xf) == 0)
-+ {
-+ shift += 4;
-+ i >>= 4;
-+ }
-+
-+ if ((i & 0x3) == 0)
-+ {
-+ shift += 2;
-+ i >>= 2;
-+ }
-+
-+ if ((i & 0x1) == 0)
-+ {
-+ shift += 1;
-+ i >>= 1;
-+ }
-+
-+ if (i >= -128 && i <= 127)
-+ return shift;
-+
-+ return 0;
-+}
-+
---- /dev/null
-+++ b/gcc/config/ubicom32/ubicom32.h
-@@ -0,0 +1,1564 @@
-+/* Definitions of target machine for Ubicom32
-+
-+ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
-+ 2009 Free Software Foundation, Inc.
-+ Contributed by Ubicom, Inc.
-+
-+ This file is part of GCC.
-+
-+ GCC is free software; you can redistribute it and/or modify it
-+ under the terms of the GNU General Public License as published
-+ by the Free Software Foundation; either version 3, or (at your
-+ option) any later version.
-+
-+ GCC is distributed in the hope that it will be useful, but WITHOUT
-+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
-+ License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with GCC; see the file COPYING3. If not see
-+ <http://www.gnu.org/licenses/>. */
-+
-+\f
-+
-+#define OBJECT_FORMAT_ELF
-+
-+/* Run-time target specifications. */
-+
-+/* Target CPU builtins. */
-+#define TARGET_CPU_CPP_BUILTINS() \
-+ do \
-+ { \
-+ builtin_define_std ("__UBICOM32__"); \
-+ builtin_define_std ("__ubicom32__"); \
-+ \
-+ if (TARGET_FDPIC) \
-+ { \
-+ builtin_define ("__UBICOM32_FDPIC__"); \
-+ builtin_define ("__FDPIC__"); \
-+ } \
-+ } \
-+ while (0)
-+
-+#ifndef TARGET_DEFAULT
-+#define TARGET_DEFAULT 0
-+#endif
-+
-+extern int ubicom32_case_values_threshold;
-+
-+/* Nonzero if this chip supports the Ubicom32 v3 ISA. */
-+extern int ubicom32_v3;
-+
-+/* Nonzero if this chip supports the Ubicom32 v4 ISA. */
-+extern int ubicom32_v4;
-+
-+extern int ubicom32_stack_size;
-+
-+/* Flag for whether we can use calli instead of ret in returns. */
-+extern int ubicom32_can_use_calli_to_ret;
-+
-+/* This macro is a C statement to print on `stderr' a string describing the
-+ particular machine description choice. Every machine description should
-+ define `TARGET_VERSION'. */
-+#define TARGET_VERSION fprintf (stderr, " (UBICOM32)");
-+
-+/* We don't need a frame pointer to debug things. Doing this means
-+ that gcc can turn on -fomit-frame-pointer when '-O' is specified. */
-+#define CAN_DEBUG_WITHOUT_FP
-+
-+/* We need to handle processor-specific options. */
-+#define OVERRIDE_OPTIONS ubicom32_override_options ()
-+
-+#define OPTIMIZATION_OPTIONS(LEVEL, SIZE) \
-+ ubicom32_optimization_options (LEVEL, SIZE)
-+
-+/* For Ubicom32 the least significant bit has the lowest bit number
-+ so we define this to be 0. */
-+#define BITS_BIG_ENDIAN 0
-+
-+/* For Ubicom32 the most significant byte in a word has the lowest
-+ number. */
-+#define BYTES_BIG_ENDIAN 1
-+
-+/* For Ubicom32, in a multiword object, the most signifant word has the
-+ lowest number. */
-+#define WORDS_BIG_ENDIAN 1
-+
-+/* Ubicom32 has 8 bits per byte. */
-+#define BITS_PER_UNIT 8
-+
-+/* Ubicom32 has 32 bits per word. */
-+#define BITS_PER_WORD 32
-+
-+/* Width of a word, in units (bytes). */
-+#define UNITS_PER_WORD 4
-+
-+/* Width of a pointer, in bits. */
-+#define POINTER_SIZE 32
-+
-+/* Alias for pointers. Ubicom32 is a 32-bit architecture so we use
-+ SImode. */
-+#define Pmode SImode
-+
-+/* Normal alignment required for function parameters on the stack, in
-+ bits. */
-+#define PARM_BOUNDARY 32
-+
-+/* We need to maintain the stack on a 32-bit boundary. */
-+#define STACK_BOUNDARY 32
-+
-+/* Alignment required for a function entry point, in bits. */
-+#define FUNCTION_BOUNDARY 32
-+
-+/* Alias for the machine mode used for memory references to functions being
-+ called, in `call' RTL expressions. We use byte-oriented addresses
-+ here. */
-+#define FUNCTION_MODE QImode
-+
-+/* Biggest alignment that any data type can require on this machine,
-+ in bits. */
-+#define BIGGEST_ALIGNMENT 32
-+
-+/* this default to BIGGEST_ALIGNMENT unless defined */
-+/* ART: What's the correct value here? Default is (((unsigned int)1<<28)*8)*/
-+#undef MAX_OFILE_ALIGNMENT
-+#define MAX_OFILE_ALIGNMENT (128 * 8)
-+
-+/* Alignment in bits to be given to a structure bit field that follows an empty
-+ field such as `int : 0;'. */
-+#define EMPTY_FIELD_BOUNDARY 32
-+
-+/* All structures must be a multiple of 32 bits in size. */
-+#define STRUCTURE_SIZE_BOUNDARY 32
-+
-+/* A bit-field declared as `int' forces `int' alignment for the struct. */
-+#define PCC_BITFIELD_TYPE_MATTERS 1
-+
-+/* For Ubicom32 we absolutely require that data be aligned with nominal
-+ alignment. */
-+#define STRICT_ALIGNMENT 1
-+
-+/* Make strcpy of constants fast. */
-+#define CONSTANT_ALIGNMENT(EXP, ALIGN) \
-+ (TREE_CODE (EXP) == STRING_CST \
-+ && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
-+
-+/* Define this macro as an expression for the alignment of a structure
-+ (given by STRUCT as a tree node) if the alignment computed in the
-+ usual way is COMPUTED and the alignment explicitly specified was
-+ SPECIFIED. */
-+#define DATA_ALIGNMENT(TYPE, ALIGN) \
-+ ((((ALIGN) < BITS_PER_WORD) \
-+ && (TREE_CODE (TYPE) == ARRAY_TYPE \
-+ || TREE_CODE (TYPE) == UNION_TYPE \
-+ || TREE_CODE (TYPE) == RECORD_TYPE)) ? BITS_PER_WORD : (ALIGN))
-+
-+#define LOCAL_ALIGNMENT(TYPE,ALIGN) DATA_ALIGNMENT(TYPE,ALIGN)
-+
-+/* For Ubicom32 we default to unsigned chars. */
-+#define DEFAULT_SIGNED_CHAR 0
-+
-+/* Machine-specific data register numbers. */
-+#define FIRST_DATA_REGNUM 0
-+#define D10_REGNUM 10
-+#define D11_REGNUM 11
-+#define D12_REGNUM 12
-+#define D13_REGNUM 13
-+#define LAST_DATA_REGNUM 15
-+
-+/* Machine-specific address register numbers. */
-+#define FIRST_ADDRESS_REGNUM 16
-+#define LAST_ADDRESS_REGNUM 22
-+
-+/* Register numbers used for passing a function's static chain pointer. If
-+ register windows are used, the register number as seen by the called
-+ function is `STATIC_CHAIN_INCOMING_REGNUM', while the register number as
-+ seen by the calling function is `STATIC_CHAIN_REGNUM'. If these registers
-+ are the same, `STATIC_CHAIN_INCOMING_REGNUM' need not be defined.
-+
-+ The static chain register need not be a fixed register.
-+
-+ If the static chain is passed in memory, these macros should not be defined;
-+ instead, the next two macros should be defined. */
-+#define STATIC_CHAIN_REGNUM (FIRST_ADDRESS_REGNUM + 1)
-+
-+/* The register number of the frame pointer register, which is used to access
-+ automatic variables in the stack frame. We generally eliminate this anyway
-+ for Ubicom32 but we make it A6 by default. */
-+#define FRAME_POINTER_REGNUM (LAST_ADDRESS_REGNUM)
-+
-+/* The register number of the stack pointer register, which is also be a
-+ fixed register according to `FIXED_REGISTERS'. For Ubicom32 we don't
-+ have a hardware requirement about which register this is, but by convention
-+ we use A7. */
-+#define STACK_POINTER_REGNUM (LAST_ADDRESS_REGNUM + 1)
-+
-+/* Machine-specific accumulator register numbers. */
-+#define ACC0_HI_REGNUM 24
-+#define ACC0_LO_REGNUM 25
-+#define ACC1_HI_REGNUM 26
-+#define ACC1_LO_REGNUM 27
-+
-+/* source3 register number */
-+#define SOURCE3_REGNUM 28
-+
-+/* The register number of the arg pointer register, which is used to access the
-+ function's argument list. On some machines, this is the same as the frame
-+ pointer register. On some machines, the hardware determines which register
-+ this is. On other machines, you can choose any register you wish for this
-+ purpose. If this is not the same register as the frame pointer register,
-+ then you must mark it as a fixed register according to `FIXED_REGISTERS', or
-+ arrange to be able to eliminate it. */
-+#define ARG_POINTER_REGNUM 29
-+
-+/* Pseudo-reg for condition code. */
-+#define CC_REGNUM 30
-+
-+/* Interrupt set/clear registers. */
-+#define INT_SET0_REGNUM 31
-+#define INT_SET1_REGNUM 32
-+#define INT_CLR0_REGNUM 33
-+#define INT_CLR1_REGNUM 34
-+
-+/* Scratchpad registers. */
-+#define SCRATCHPAD0_REGNUM 35
-+#define SCRATCHPAD1_REGNUM 36
-+#define SCRATCHPAD2_REGNUM 37
-+#define SCRATCHPAD3_REGNUM 38
-+
-+/* FDPIC register. */
-+#define FDPIC_REGNUM 16
-+
-+/* Number of hardware registers known to the compiler. They receive numbers 0
-+ through `FIRST_PSEUDO_REGISTER-1'; thus, the first pseudo register's number
-+ really is assigned the number `FIRST_PSEUDO_REGISTER'. */
-+#define FIRST_PSEUDO_REGISTER 39
-+
-+/* An initializer that says which registers are used for fixed purposes all
-+ throughout the compiled code and are therefore not available for general
-+ allocation. These would include the stack pointer, the frame pointer
-+ (except on machines where that can be used as a general register when no
-+ frame pointer is needed), the program counter on machines where that is
-+ considered one of the addressable registers, and any other numbered register
-+ with a standard use.
-+
-+ This information is expressed as a sequence of numbers, separated by commas
-+ and surrounded by braces. The Nth number is 1 if register N is fixed, 0
-+ otherwise.
-+
-+ The table initialized from this macro, and the table initialized by the
-+ following one, may be overridden at run time either automatically, by the
-+ actions of the macro `CONDITIONAL_REGISTER_USAGE', or by the user with the
-+ command options `-ffixed-REG', `-fcall-used-REG' and `-fcall-saved-REG'. */
-+#define FIXED_REGISTERS \
-+ { \
-+ 0, 0, 0, 0, 0, 0, 0, 0, /* d0 - d7 */ \
-+ 0, 0, 0, 0, 0, 0, 0, 1, /* d8 - d15 */ \
-+ 0, 0, 0, 0, 0, 0, 0, 1, /* a0 - a7 */ \
-+ 0, 0, /* acc0 hi/lo */ \
-+ 0, 0, /* acc1 hi/lo */ \
-+ 0, /* source3 */ \
-+ 1, /* arg */ \
-+ 1, /* cc */ \
-+ 1, 1, /* int_set[01] */ \
-+ 1, 1, /* int_clr[01] */ \
-+ 1, 1, 1, 1 /* scratchpad[0123] */ \
-+ }
-+
-+/* Like `FIXED_REGISTERS' but has 1 for each register that is clobbered (in
-+ general) by function calls as well as for fixed registers. This macro
-+ therefore identifies the registers that are not available for general
-+ allocation of values that must live across function calls.
-+
-+ If a register has 0 in `CALL_USED_REGISTERS', the compiler automatically
-+ saves it on function entry and restores it on function exit, if the register
-+ is used within the function. */
-+#define CALL_USED_REGISTERS \
-+ { \
-+ 1, 1, 1, 1, 1, 1, 1, 1, /* d0 - d7 */ \
-+ 1, 1, 0, 0, 0, 0, 1, 1, /* d8 - d15 */ \
-+ 1, 0, 0, 1, 1, 1, 0, 1, /* a0 - a7 */ \
-+ 1, 1, /* acc0 hi/lo */ \
-+ 1, 1, /* acc1 hi/lo */ \
-+ 1, /* source3 */ \
-+ 1, /* arg */ \
-+ 1, /* cc */ \
-+ 1, 1, /* int_set[01] */ \
-+ 1, 1, /* int_clr[01] */ \
-+ 1, 1, 1, 1 /* scratchpad[0123] */ \
-+ }
-+
-+/* How to refer to registers in assembler output.
-+ This sequence is indexed by compiler's hard-register-number (see above). */
-+
-+/* A C initializer containing the assembler's names for the machine registers,
-+ each one as a C string constant. This is what translates register numbers
-+ in the compiler into assembler language. */
-+#define REGISTER_NAMES \
-+ { \
-+ "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", \
-+ "d8", "d9", "d10", "d11", "d12", "d13", "d14", "d15", \
-+ "a0", "a1", "a2", "a3", "a4", "a5", "a6", "sp", \
-+ "acc0_hi", "acc0_lo", \
-+ "acc1_hi", "acc1_lo", \
-+ "source3", \
-+ "arg", \
-+ "cc", \
-+ "int_set0", "int_set1", \
-+ "int_clr0", "int_clr1", \
-+ "scratchpad0", "scratchpad1", "scratchpad2", "scratchpad3" \
-+ }
-+
-+#define CONDITIONAL_REGISTER_USAGE \
-+ ubicom32_conditional_register_usage ();
-+
-+/* Order of allocation of registers. */
-+
-+/* If defined, an initializer for a vector of integers, containing the numbers
-+ of hard registers in the order in which GNU CC should prefer to use them
-+ (from most preferred to least).
-+
-+ For Ubicom32 we try using caller-clobbered data registers first, then
-+ callee-saved data registers, then caller-clobbered address registers,
-+ then callee-saved address registers and finally everything else.
-+
-+ The caller-clobbered registers are usually slightly cheaper to use because
-+ there's no need to save/restore. */
-+#define REG_ALLOC_ORDER \
-+ { \
-+ 0, 1, 2, 3, 4, /* d0 - d4 */ \
-+ 5, 6, 7, 8, 9, /* d5 - d9 */ \
-+ 14, /* d14 */ \
-+ 10, 11, 12, 13, /* d10 - d13 */ \
-+ 19, 20, 16, 21, /* a3, a4, a0, a5 */ \
-+ 17, 18, 22, /* a1, a2, a6 */ \
-+ 24, 25, /* acc0 hi/lo */ \
-+ 26, 27, /* acc0 hi/lo */ \
-+ 28 /* source3 */ \
-+ }
-+
-+/* C expression for the number of consecutive hard registers, starting at
-+ register number REGNO, required to hold a value of mode MODE. */
-+#define HARD_REGNO_NREGS(REGNO, MODE) \
-+ ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
-+
-+/* Most registers can hold QImode, HImode and SImode values but we have to
-+ be able to indicate any hard registers that cannot hold values with some
-+ modes. */
-+#define HARD_REGNO_MODE_OK(REGNO, MODE) \
-+ ubicom32_hard_regno_mode_ok(REGNO, MODE)
-+
-+/* We can rename most registers aside from the FDPIC register if we're using
-+ FDPIC. */
-+#define HARD_REGNO_RENAME_OK(from, to) (TARGET_FDPIC ? ((to) != FDPIC_REGNUM) : 1)
-+
-+/* A C expression that is nonzero if it is desirable to choose register
-+ allocation so as to avoid move instructions between a value of mode MODE1
-+ and a value of mode MODE2.
-+
-+ If `HARD_REGNO_MODE_OK (R, MODE1)' and `HARD_REGNO_MODE_OK (R, MODE2)' are
-+ ever different for any R, then `MODES_TIEABLE_P (MODE1, MODE2)' must be
-+ zero. */
-+#define MODES_TIEABLE_P(MODE1, MODE2) 1
-+
-+/* An enumeral type that must be defined with all the register class names as
-+ enumeral values. `NO_REGS' must be first. `ALL_REGS' must be the last
-+ register class, followed by one more enumeral value, `LIM_REG_CLASSES',
-+ which is not a register class but rather tells how many classes there are.
-+
-+ Each register class has a number, which is the value of casting the class
-+ name to type `int'. The number serves as an index in many of the tables
-+ described below. */
-+
-+enum reg_class
-+{
-+ NO_REGS,
-+ DATA_REGS,
-+ FDPIC_REG,
-+ ADDRESS_REGS,
-+ ALL_ADDRESS_REGS,
-+ ACC_LO_REGS,
-+ ACC_REGS,
-+ CC_REG,
-+ DATA_ACC_REGS,
-+ SOURCE3_REG,
-+ SPECIAL_REGS,
-+ GENERAL_REGS,
-+ ALL_REGS,
-+ LIM_REG_CLASSES
-+};
-+
-+/* The number of distinct register classes. */
-+#define N_REG_CLASSES (int) LIM_REG_CLASSES
-+
-+/* An initializer containing the names of the register classes as C string
-+ constants. These names are used in writing some of the debugging dumps. */
-+
-+#define REG_CLASS_NAMES \
-+{ \
-+ "NO_REGS", \
-+ "DATA_REGS", \
-+ "FDPIC_REG", \
-+ "ADDRESS_REGS", \
-+ "ALL_ADDRESS_REGS", \
-+ "ACC_LO_REGS", \
-+ "ACC_REGS", \
-+ "CC_REG", \
-+ "DATA_ACC_REGS", \
-+ "SOURCE3_REG", \
-+ "SPECIAL_REGS", \
-+ "GENERAL_REGS", \
-+ "ALL_REGS", \
-+ "LIM_REGS" \
-+}
-+
-+/* An initializer containing the contents of the register classes, as integers
-+ which are bit masks. The Nth integer specifies the contents of class N.
-+ The way the integer MASK is interpreted is that register R is in the class
-+ if `MASK & (1 << R)' is 1.
-+
-+ When the machine has more than 32 registers, an integer does not suffice.
-+ Then the integers are replaced by sub-initializers, braced groupings
-+ containing several integers. Each sub-initializer must be suitable as an
-+ initializer for the type `HARD_REG_SET' which is defined in
-+ `hard-reg-set.h'. */
-+#define REG_CLASS_CONTENTS \
-+{ \
-+ {0x00000000, 0x00000000}, /* No regs */ \
-+ {0x0000ffff, 0x00000000}, /* DATA_REGS */ \
-+ {0x00010000, 0x00000000}, /* FDPIC_REG */ \
-+ {0x20fe0000, 0x00000000}, /* ADDRESS_REGS */ \
-+ {0x20ff0000, 0x00000000}, /* ALL_ADDRESS_REGS */ \
-+ {0x0a000000, 0x00000000}, /* ACC_LO_REGS */ \
-+ {0x0f000000, 0x00000000}, /* ACC_REGS */ \
-+ {0x40000000, 0x00000000}, /* CC_REG */ \
-+ {0x0f00ffff, 0x00000000}, /* DATA_ACC_REGS */ \
-+ {0x10000000, 0x00000000}, /* SOURGE3_REG */ \
-+ {0x80000000, 0x0000007f}, /* SPECIAL_REGS */ \
-+ {0xbfffffff, 0x0000007f}, /* GENERAL_REGS */ \
-+ {0xbfffffff, 0x0000007f} /* ALL_REGS */ \
-+}
-+
-+extern enum reg_class const ubicom32_regclass_map[FIRST_PSEUDO_REGISTER];
-+
-+/* A C expression whose value is a register class containing hard register
-+ REGNO. In general there is more than one such class; choose a class which
-+ is "minimal", meaning that no smaller class also contains the register. */
-+#define REGNO_REG_CLASS(REGNO) (ubicom32_regclass_map[REGNO])
-+
-+#define IRA_COVER_CLASSES \
-+{ \
-+ GENERAL_REGS, \
-+ LIM_REG_CLASSES \
-+}
-+
-+/* Ubicom32 base registers must be address registers since addresses can
-+ only be reached via address registers. */
-+#define BASE_REG_CLASS ALL_ADDRESS_REGS
-+
-+/* Ubicom32 index registers must be data registers since we cannot add
-+ two address registers together to form an address. */
-+#define INDEX_REG_CLASS DATA_REGS
-+
-+/* A C expression which is nonzero if register number NUM is suitable for use
-+ as a base register in operand addresses. It may be either a suitable hard
-+ register or a pseudo register that has been allocated such a hard register. */
-+
-+#ifndef REG_OK_STRICT
-+#define REGNO_OK_FOR_BASE_P(regno) \
-+ ubicom32_regno_ok_for_base_p (regno, 0)
-+#else
-+#define REGNO_OK_FOR_BASE_P(regno) \
-+ ubicom32_regno_ok_for_base_p (regno, 1)
-+#endif
-+
-+/* A C expression which is nonzero if register number NUM is suitable for use
-+ as an index register in operand addresses. It may be either a suitable hard
-+ register or a pseudo register that has been allocated such a hard register.
-+
-+ The difference between an index register and a base register is that the
-+ index register may be scaled. If an address involves the sum of two
-+ registers, neither one of them scaled, then either one may be labeled the
-+ "base" and the other the "index"; but whichever labeling is used must fit
-+ the machine's constraints of which registers may serve in each capacity.
-+ The compiler will try both labelings, looking for one that is valid, and
-+ will reload one or both registers only if neither labeling works. */
-+#ifndef REG_OK_STRICT
-+#define REGNO_OK_FOR_INDEX_P(regno) \
-+ ubicom32_regno_ok_for_index_p (regno, 0)
-+#else
-+#define REGNO_OK_FOR_INDEX_P(regno) \
-+ ubicom32_regno_ok_for_index_p (regno, 1)
-+#endif
-+
-+/* Attempt to restrict the register class we need to copy value X intoto the
-+ would-be register class CLASS. Most things are fine for Ubicom32 but we
-+ have to restrict certain types of address loads. */
-+#define PREFERRED_RELOAD_CLASS(X, CLASS) \
-+ ubicom32_preferred_reload_class (X, CLASS)
-+
-+/* A C expression for the maximum number of consecutive registers of
-+ class CLASS needed to hold a value of mode MODE. For Ubicom32 this
-+ is pretty much identical to HARD_REGNO_NREGS. */
-+#define CLASS_MAX_NREGS(CLASS, MODE) \
-+ ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
-+
-+/* For Ubicom32 the stack grows downwards when we push a word onto the stack
-+ - i.e. it moves to a smaller address. */
-+#define STACK_GROWS_DOWNWARD 1
-+
-+/* Offset from the frame pointer to the first local variable slot to
-+ be allocated. */
-+#define STARTING_FRAME_OFFSET 0
-+
-+/* Offset from the argument pointer register to the first argument's
-+ address. */
-+#define FIRST_PARM_OFFSET(FNDECL) 0
-+
-+/* A C expression whose value is RTL representing the value of the return
-+ address for the frame COUNT steps up from the current frame, after the
-+ prologue. FRAMEADDR is the frame pointer of the COUNT frame, or the frame
-+ pointer of the COUNT - 1 frame if `RETURN_ADDR_IN_PREVIOUS_FRAME' is
-+ defined.
-+
-+ The value of the expression must always be the correct address when COUNT is
-+ zero, but may be `NULL_RTX' if there is not way to determine the return
-+ address of other frames. */
-+#define RETURN_ADDR_RTX(COUNT, FRAME) \
-+ ubicom32_return_addr_rtx (COUNT, FRAME)
-+
-+/* Register That Address the Stack Frame. */
-+
-+/* We don't actually require a frame pointer in most functions with the
-+ Ubicom32 architecture so we allow it to be eliminated. */
-+#define FRAME_POINTER_REQUIRED 0
-+
-+/* Macro that defines a table of register pairs used to eliminate unecessary
-+ registers that point into the stack frame.
-+
-+ For Ubicom32 we don't generally need an arg pointer of a frame pointer
-+ so we allow the arg pointer to be replaced by either the frame pointer or
-+ the stack pointer. We also allow the frame pointer to be replaced by
-+ the stack pointer. */
-+#define ELIMINABLE_REGS \
-+{ \
-+ {ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
-+ {ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM}, \
-+ {FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM} \
-+}
-+
-+/* Let the compiler know that we want to use the ELIMINABLE_REGS macro
-+ above. */
-+#define CAN_ELIMINATE(FROM, TO) 1
-+
-+/* This macro is similar to `INITIAL_FRAME_POINTER_OFFSET'. It specifies the
-+ initial difference between the specified pair of registers. This macro must
-+ be defined if `ELIMINABLE_REGS' is defined. */
-+#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
-+ (OFFSET) = ubicom32_initial_elimination_offset (FROM, TO)
-+
-+/* If defined, the maximum amount of space required for outgoing arguments will
-+ be computed and placed into the variable
-+ `current_function_outgoing_args_size'. No space will be pushed onto the
-+ stack for each call; instead, the function prologue should increase the
-+ stack frame size by this amount.
-+
-+ Defining both `PUSH_ROUNDING' and `ACCUMULATE_OUTGOING_ARGS' is not
-+ proper. */
-+#define ACCUMULATE_OUTGOING_ARGS 1
-+
-+/* Define this macro if functions should assume that stack space has been
-+ allocated for arguments even when their values are passed in registers.
-+
-+ The value of this macro is the size, in bytes, of the area reserved for
-+ arguments passed in registers for the function represented by FNDECL.
-+
-+ This space can be allocated by the caller, or be a part of the
-+ machine-dependent stack frame: `OUTGOING_REG_PARM_STACK_SPACE' says
-+ which. */
-+#define REG_PARM_STACK_SPACE(FNDECL) ubicom32_reg_parm_stack_space(FNDECL)
-+
-+/* A C expression that should indicate the number of bytes of its own arguments
-+ that a function pops on returning, or 0 if the function pops no arguments
-+ and the caller must therefore pop them all after the function returns.
-+
-+ FUNDECL is a C variable whose value is a tree node that describes the
-+ function in question. Normally it is a node of type `FUNCTION_DECL' that
-+ describes the declaration of the function. From this it is possible to
-+ obtain the DECL_MACHINE_ATTRIBUTES of the function.
-+
-+ FUNTYPE is a C variable whose value is a tree node that describes the
-+ function in question. Normally it is a node of type `FUNCTION_TYPE' that
-+ describes the data type of the function. From this it is possible to obtain
-+ the data types of the value and arguments (if known).
-+
-+ When a call to a library function is being considered, FUNTYPE will contain
-+ an identifier node for the library function. Thus, if you need to
-+ distinguish among various library functions, you can do so by their names.
-+ Note that "library function" in this context means a function used to
-+ perform arithmetic, whose name is known specially in the compiler and was
-+ not mentioned in the C code being compiled.
-+
-+ STACK-SIZE is the number of bytes of arguments passed on the stack. If a
-+ variable number of bytes is passed, it is zero, and argument popping will
-+ always be the responsibility of the calling function.
-+
-+ On the Vax, all functions always pop their arguments, so the definition of
-+ this macro is STACK-SIZE. On the 68000, using the standard calling
-+ convention, no functions pop their arguments, so the value of the macro is
-+ always 0 in this case. But an alternative calling convention is available
-+ in which functions that take a fixed number of arguments pop them but other
-+ functions (such as `printf') pop nothing (the caller pops all). When this
-+ convention is in use, FUNTYPE is examined to determine whether a function
-+ takes a fixed number of arguments. */
-+#define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, STACK_SIZE) 0
-+
-+/* A C expression that controls whether a function argument is passed in a
-+ register, and which register.
-+
-+ The arguments are CUM, of type CUMULATIVE_ARGS, which summarizes (in a way
-+ defined by INIT_CUMULATIVE_ARGS and FUNCTION_ARG_ADVANCE) all of the previous
-+ arguments so far passed in registers; MODE, the machine mode of the argument;
-+ TYPE, the data type of the argument as a tree node or 0 if that is not known
-+ (which happens for C support library functions); and NAMED, which is 1 for an
-+ ordinary argument and 0 for nameless arguments that correspond to `...' in the
-+ called function's prototype.
-+
-+ The value of the expression should either be a `reg' RTX for the hard
-+ register in which to pass the argument, or zero to pass the argument on the
-+ stack.
-+
-+ For machines like the Vax and 68000, where normally all arguments are
-+ pushed, zero suffices as a definition.
-+
-+ The usual way to make the ANSI library `stdarg.h' work on a machine where
-+ some arguments are usually passed in registers, is to cause nameless
-+ arguments to be passed on the stack instead. This is done by making
-+ `FUNCTION_ARG' return 0 whenever NAMED is 0.
-+
-+ You may use the macro `MUST_PASS_IN_STACK (MODE, TYPE)' in the definition of
-+ this macro to determine if this argument is of a type that must be passed in
-+ the stack. If `REG_PARM_STACK_SPACE' is not defined and `FUNCTION_ARG'
-+ returns non-zero for such an argument, the compiler will abort. If
-+ `REG_PARM_STACK_SPACE' is defined, the argument will be computed in the
-+ stack and then loaded into a register. */
-+#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
-+ function_arg (&CUM, MODE, TYPE, NAMED)
-+
-+#define FUNCTION_INCOMING_ARG(CUM, MODE, TYPE, NAMED) \
-+ function_incoming_arg (&CUM, MODE, TYPE, NAMED)
-+
-+/* A C expression for the number of words, at the beginning of an argument,
-+ must be put in registers. The value must be zero for arguments that are
-+ passed entirely in registers or that are entirely pushed on the stack.
-+
-+ On some machines, certain arguments must be passed partially in registers
-+ and partially in memory. On these machines, typically the first N words of
-+ arguments are passed in registers, and the rest on the stack. If a
-+ multi-word argument (a `double' or a structure) crosses that boundary, its
-+ first few words must be passed in registers and the rest must be pushed.
-+ This macro tells the compiler when this occurs, and how many of the words
-+ should go in registers.
-+
-+ `FUNCTION_ARG' for these arguments should return the first register to be
-+ used by the caller for this argument; likewise `FUNCTION_INCOMING_ARG', for
-+ the called function. */
-+
-+/* A C expression that indicates when an argument must be passed by reference.
-+ If nonzero for an argument, a copy of that argument is made in memory and a
-+ pointer to the argument is passed instead of the argument itself. The
-+ pointer is passed in whatever way is appropriate for passing a pointer to
-+ that type.
-+
-+ On machines where `REG_PARM_STACK_SPACE' is not defined, a suitable
-+ definition of this macro might be
-+ #define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \
-+ MUST_PASS_IN_STACK (MODE, TYPE) */
-+
-+/* If defined, a C expression that indicates when it is the called function's
-+ responsibility to make a copy of arguments passed by invisible reference.
-+ Normally, the caller makes a copy and passes the address of the copy to the
-+ routine being called. When FUNCTION_ARG_CALLEE_COPIES is defined and is
-+ nonzero, the caller does not make a copy. Instead, it passes a pointer to
-+ the "live" value. The called function must not modify this value. If it
-+ can be determined that the value won't be modified, it need not make a copy;
-+ otherwise a copy must be made. */
-+
-+/* 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
-+ `int' suffices and can hold the number of bytes of argument so far.
-+
-+ There is no need to record in `CUMULATIVE_ARGS' anything about the arguments
-+ that have been passed on the stack. The compiler has other variables to
-+ keep track of that. For target machines on which all arguments are passed
-+ on the stack, there is no need to store anything in `CUMULATIVE_ARGS';
-+ however, the data structure must exist and should not be empty, so use
-+ `int'. */
-+struct cum_arg
-+{
-+ int nbytes;
-+ int reg;
-+ int stdarg;
-+};
-+#define CUMULATIVE_ARGS struct cum_arg
-+
-+/* A C statement (sans semicolon) for initializing the variable CUM for the
-+ state at the beginning of the argument list. The variable has type
-+ `CUMULATIVE_ARGS'. The value of FNTYPE is the tree node for the data type
-+ of the function which will receive the args, or 0 if the args are to a
-+ compiler support library function. The value of INDIRECT is nonzero when
-+ processing an indirect call, for example a call through a function pointer.
-+ The value of INDIRECT is zero for a call to an explicitly named function, a
-+ library function call, or when `INIT_CUMULATIVE_ARGS' is used to find
-+ arguments for the function being compiled.
-+
-+ When processing a call to a compiler support library function, LIBNAME
-+ identifies which one. It is a `symbol_ref' rtx which contains the name of
-+ the function, as a string. LIBNAME is 0 when an ordinary C function call is
-+ being processed. Thus, each time this macro is called, either LIBNAME or
-+ FNTYPE is nonzero, but never both of them at once. */
-+
-+#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT, NAMED_ARGS) \
-+ init_cumulative_args (&(CUM), FNTYPE, LIBNAME, INDIRECT);
-+
-+/* A C statement (sans semicolon) to update the summarizer variable CUM to
-+ advance past an argument in the argument list. The values MODE, TYPE and
-+ NAMED describe that argument. Once this is done, the variable CUM is
-+ suitable for analyzing the *following* argument with `FUNCTION_ARG', etc.
-+
-+ This macro need not do anything if the argument in question was passed on
-+ the stack. The compiler knows how to track the amount of stack space used
-+ for arguments without any special help. */
-+#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
-+ ((CUM).nbytes += ((MODE) != BLKmode \
-+ ? (GET_MODE_SIZE (MODE) + 3) & ~3 \
-+ : (int_size_in_bytes (TYPE) + 3) & ~3))
-+
-+/* For the Ubicom32 we define the upper function argument register here. */
-+#define UBICOM32_FUNCTION_ARG_REGS 10
-+
-+/* A C expression that is nonzero if REGNO is the number of a hard register in
-+ which function arguments are sometimes passed. This does *not* include
-+ implicit arguments such as the static chain and the structure-value address.
-+ On many machines, no registers can be used for this purpose since all
-+ function arguments are pushed on the stack. */
-+#define FUNCTION_ARG_REGNO_P(N) ((N) < UBICOM32_FUNCTION_ARG_REGS)
-+
-+\f
-+/* How Scalar Function Values are Returned. */
-+
-+/* The number of the hard register that is used to return a scalar value from a
-+ function call. */
-+#define RETURN_VALUE_REGNUM 0
-+
-+/* A C expression to create an RTX representing the place where a function
-+ returns a value of data type VALTYPE. VALTYPE is a tree node representing a
-+ data type. Write `TYPE_MODE (VALTYPE)' to get the machine mode used to
-+ represent that type. On many machines, only the mode is relevant.
-+ (Actually, on most machines, scalar values are returned in the same place
-+ regardless of mode).
-+
-+ If `PROMOTE_FUNCTION_RETURN' is defined, you must apply the same promotion
-+ rules specified in `PROMOTE_MODE' if VALTYPE is a scalar type.
-+
-+ If the precise function being called is known, FUNC is a tree node
-+ (`FUNCTION_DECL') for it; otherwise, FUNC is a null pointer. This makes it
-+ possible to use a different value-returning convention for specific
-+ functions when all their calls are known.
-+
-+ `FUNCTION_VALUE' is not used for return vales with aggregate data types,
-+ because these are returned in another way. See `STRUCT_VALUE_REGNUM' and
-+ related macros, below. */
-+#define FUNCTION_VALUE(VALTYPE, FUNC) \
-+ gen_rtx_REG (TYPE_MODE (VALTYPE), FIRST_DATA_REGNUM)
-+
-+/* A C expression to create an RTX representing the place where a library
-+ function returns a value of mode MODE.
-+
-+ Note that "library function" in this context means a compiler support
-+ routine, used to perform arithmetic, whose name is known specially by the
-+ compiler and was not mentioned in the C code being compiled.
-+
-+ The definition of `LIBRARY_VALUE' need not be concerned aggregate data
-+ types, because none of the library functions returns such types. */
-+#define LIBCALL_VALUE(MODE) gen_rtx_REG (MODE, FIRST_DATA_REGNUM)
-+
-+/* A C expression that is nonzero if REGNO is the number of a hard register in
-+ which the values of called function may come back.
-+
-+ A register whose use for returning values is limited to serving as the
-+ second of a pair (for a value of type `double', say) need not be recognized
-+ by this macro. So for most machines, this definition suffices:
-+
-+ #define FUNCTION_VALUE_REGNO_P(N) ((N) == RETURN)
-+
-+ If the machine has register windows, so that the caller and the called
-+ function use different registers for the return value, this macro should
-+ recognize only the caller's register numbers. */
-+#define FUNCTION_VALUE_REGNO_P(N) ((N) == FIRST_DATA_REGNUM)
-+
-+\f
-+/* How Large Values are Returned. */
-+
-+/* A C expression which can inhibit the returning of certain function values in
-+ registers, based on the type of value. A nonzero value says to return the
-+ function value in memory, just as large structures are always returned.
-+ Here TYPE will be a C expression of type `tree', representing the data type
-+ of the value.
-+
-+ Note that values of mode `BLKmode' must be explicitly handled by this macro.
-+ Also, the option `-fpcc-struct-return' takes effect regardless of this
-+ macro. On most systems, it is possible to leave the macro undefined; this
-+ causes a default definition to be used, whose value is the constant 1 for
-+ `BLKmode' values, and 0 otherwise.
-+
-+ Do not use this macro to indicate that structures and unions should always
-+ be returned in memory. You should instead use `DEFAULT_PCC_STRUCT_RETURN'
-+ to indicate this. */
-+#define RETURN_IN_MEMORY(TYPE) \
-+ (int_size_in_bytes (TYPE) > 8 || TYPE_MODE (TYPE) == BLKmode)
-+
-+/* Define this macro to be 1 if all structure and union return values must be
-+ in memory. Since this results in slower code, this should be defined only
-+ if needed for compatibility with other compilers or with an ABI. If you
-+ define this macro to be 0, then the conventions used for structure and union
-+ return values are decided by the `RETURN_IN_MEMORY' macro.
-+
-+ If not defined, this defaults to the value 1. */
-+#define DEFAULT_PCC_STRUCT_RETURN 0
-+
-+/* If the structure value address is not passed in a register, define
-+ `STRUCT_VALUE' as an expression returning an RTX for the place
-+ where the address is passed. If it returns 0, the address is
-+ passed as an "invisible" first argument. */
-+#define STRUCT_VALUE 0
-+
-+/* Define this macro as a C expression that is nonzero if the return
-+ instruction or the function epilogue ignores the value of the stack pointer;
-+ in other words, if it is safe to delete an instruction to adjust the stack
-+ pointer before a return from the function.
-+
-+ Note that this macro's value is relevant only for functions for which frame
-+ pointers are maintained. It is never safe to delete a final stack
-+ adjustment in a function that has no frame pointer, and the compiler knows
-+ this regardless of `EXIT_IGNORE_STACK'. */
-+#define EXIT_IGNORE_STACK 1
-+
-+/* A C statement or compound statement to output to FILE some assembler code to
-+ call the profiling subroutine `mcount'. Before calling, the assembler code
-+ must load the address of a counter variable into a register where `mcount'
-+ expects to find the address. The name of this variable is `LP' followed by
-+ the number LABELNO, so you would generate the name using `LP%d' in a
-+ `fprintf'.
-+
-+ The details of how the address should be passed to `mcount' are determined
-+ by your operating system environment, not by GNU CC. To figure them out,
-+ compile a small program for profiling using the system's installed C
-+ compiler and look at the assembler code that results.
-+
-+ This declaration must be present, but it can be an abort if profiling is
-+ not implemented. */
-+
-+#define FUNCTION_PROFILER(file, labelno) ubicom32_profiler(file, labelno)
-+
-+/* A C statement to output, on the stream FILE, assembler code for a block of
-+ data that contains the constant parts of a trampoline. This code should not
-+ include a label--the label is taken care of automatically. */
-+#if 0
-+#define TRAMPOLINE_TEMPLATE(FILE) \
-+ do { \
-+ fprintf (FILE, "\tadd -4,sp\n"); \
-+ fprintf (FILE, "\t.long 0x0004fffa\n"); \
-+ fprintf (FILE, "\tmov (0,sp),a0\n"); \
-+ fprintf (FILE, "\tadd 4,sp\n"); \
-+ fprintf (FILE, "\tmov (13,a0),a1\n"); \
-+ fprintf (FILE, "\tmov (17,a0),a0\n"); \
-+ fprintf (FILE, "\tjmp (a0)\n"); \
-+ fprintf (FILE, "\t.long 0\n"); \
-+ fprintf (FILE, "\t.long 0\n"); \
-+ } while (0)
-+#endif
-+
-+/* A C expression for the size in bytes of the trampoline, as an integer. */
-+#define TRAMPOLINE_SIZE 0x1b
-+
-+/* Alignment required for trampolines, in bits.
-+
-+ If you don't define this macro, the value of `BIGGEST_ALIGNMENT' is used for
-+ aligning trampolines. */
-+#define TRAMPOLINE_ALIGNMENT 32
-+
-+/* A C statement to initialize the variable parts of a trampoline. ADDR is an
-+ RTX for the address of the trampoline; FNADDR is an RTX for the address of
-+ the nested function; STATIC_CHAIN is an RTX for the static chain value that
-+ should be passed to the function when it is called. */
-+#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
-+{ \
-+ emit_move_insn (gen_rtx_MEM (SImode, plus_constant ((TRAMP), 0x14)), \
-+ (CXT)); \
-+ emit_move_insn (gen_rtx_MEM (SImode, plus_constant ((TRAMP), 0x18)), \
-+ (FNADDR)); \
-+}
-+
-+/* Ubicom32 supports pre and post increment/decrement addressing. */
-+#define HAVE_POST_INCREMENT 1
-+#define HAVE_PRE_INCREMENT 1
-+#define HAVE_POST_DECREMENT 1
-+#define HAVE_PRE_DECREMENT 1
-+
-+/* Ubicom32 supports pre and post address side-effects with constants
-+ other than the size of the memory operand. */
-+#define HAVE_PRE_MODIFY_DISP 1
-+#define HAVE_POST_MODIFY_DISP 1
-+
-+/* A C expression that is 1 if the RTX X is a constant which is a valid
-+ address. On most machines, this can be defined as `CONSTANT_P (X)',
-+ but a few machines are more restrictive in which constant addresses
-+ are supported.
-+
-+ `CONSTANT_P' accepts integer-values expressions whose values are not
-+ explicitly known, such as `symbol_ref', `label_ref', and `high'
-+ expressions and `const' arithmetic expressions, in addition to
-+ `const_int' and `const_double' expressions. */
-+#define CONSTANT_ADDRESS_P(X) \
-+ (GET_CODE (X) == LABEL_REF \
-+ || (GET_CODE (X) == CONST \
-+ && GET_CODE (XEXP (X, 0)) == PLUS \
-+ && GET_CODE (XEXP (XEXP (X, 0), 0)) == LABEL_REF))
-+
-+/* Ubicom32 supports a maximum of 2 registers in a valid memory address.
-+ One is always an address register while a second, optional, one may be a
-+ data register. */
-+#define MAX_REGS_PER_ADDRESS 2
-+
-+/* A C compound statement with a conditional `goto LABEL;' executed if X (an
-+ RTX) is a legitimate memory address on the target machine for a memory
-+ operand of mode MODE.
-+
-+ It usually pays to define several simpler macros to serve as subroutines for
-+ this one. Otherwise it may be too complicated to understand.
-+
-+ This macro must exist in two variants: a strict variant and a non-strict
-+ one. The strict variant is used in the reload pass. It must be defined so
-+ that any pseudo-register that has not been allocated a hard register is
-+ considered a memory reference. In contexts where some kind of register is
-+ required, a pseudo-register with no hard register must be rejected.
-+
-+ The non-strict variant is used in other passes. It must be defined to
-+ accept all pseudo-registers in every context where some kind of register is
-+ required.
-+
-+ Compiler source files that want to use the strict variant of this macro
-+ define the macro `REG_OK_STRICT'. You should use an `#ifdef REG_OK_STRICT'
-+ conditional to define the strict variant in that case and the non-strict
-+ variant otherwise.
-+
-+ Subroutines to check for acceptable registers for various purposes (one for
-+ base registers, one for index registers, and so on) are typically among the
-+ subroutines used to define `GO_IF_LEGITIMATE_ADDRESS'. Then only these
-+ subroutine macros need have two variants; the higher levels of macros may be
-+ the same whether strict or not.
-+
-+ Normally, constant addresses which are the sum of a `symbol_ref' and an
-+ integer are stored inside a `const' RTX to mark them as constant.
-+ Therefore, there is no need to recognize such sums specifically as
-+ legitimate addresses. Normally you would simply recognize any `const' as
-+ legitimate.
-+
-+ Usually `PRINT_OPERAND_ADDRESS' is not prepared to handle constant sums that
-+ are not marked with `const'. It assumes that a naked `plus' indicates
-+ indexing. If so, then you *must* reject such naked constant sums as
-+ illegitimate addresses, so that none of them will be given to
-+ `PRINT_OPERAND_ADDRESS'.
-+
-+ On some machines, whether a symbolic address is legitimate depends on the
-+ section that the address refers to. On these machines, define the macro
-+ `ENCODE_SECTION_INFO' to store the information into the `symbol_ref', and
-+ then check for it here. When you see a `const', you will have to look
-+ inside it to find the `symbol_ref' in order to determine the section.
-+
-+ The best way to modify the name string is by adding text to the beginning,
-+ with suitable punctuation to prevent any ambiguity. Allocate the new name
-+ in `saveable_obstack'. You will have to modify `ASM_OUTPUT_LABELREF' to
-+ remove and decode the added text and output the name accordingly, and define
-+ `STRIP_NAME_ENCODING' to access the original name string.
-+
-+ You can check the information stored here into the `symbol_ref' in the
-+ definitions of the macros `GO_IF_LEGITIMATE_ADDRESS' and
-+ `PRINT_OPERAND_ADDRESS'. */
-+/* On the ubicom32, the value in the address register must be
-+ in the same memory space/segment as the effective address.
-+
-+ This is problematical for reload since it does not understand
-+ that base+index != index+base in a memory reference. */
-+
-+#ifdef REG_OK_STRICT
-+#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
-+ if (ubicom32_legitimate_address_p (MODE, X, 1)) goto ADDR;
-+#else
-+#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
-+ if (ubicom32_legitimate_address_p (MODE, X, 0)) goto ADDR;
-+#endif
-+
-+/* Try machine-dependent ways of modifying an illegitimate address
-+ to be legitimate. If we find one, return the new, valid address.
-+ This macro is used in only one place: `memory_address' in explow.c.
-+
-+ OLDX is the address as it was before break_out_memory_refs was called.
-+ In some cases it is useful to look at this to decide what needs to be done.
-+
-+ MODE and WIN are passed so that this macro can use
-+ GO_IF_LEGITIMATE_ADDRESS.
-+
-+ It is always safe for this macro to do nothing. It exists to recognize
-+ opportunities to optimize the output.
-+
-+ On RS/6000, first check for the sum of a register with a constant
-+ integer that is out of range. If so, generate code to add the
-+ constant with the low-order 16 bits masked to the register and force
-+ this result into another register (this can be done with `cau').
-+ Then generate an address of REG+(CONST&0xffff), allowing for the
-+ possibility of bit 16 being a one.
-+
-+ Then check for the sum of a register and something not constant, try to
-+ load the other things into a register and return the sum. */
-+
-+#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \
-+{ \
-+ rtx result = ubicom32_legitimize_address ((X), (OLDX), (MODE)); \
-+ if (result != NULL_RTX) \
-+ { \
-+ (X) = result; \
-+ goto WIN; \
-+ } \
-+}
-+
-+/* Try a machine-dependent way of reloading an illegitimate address
-+ operand. If we find one, push the reload and jump to WIN. This
-+ macro is used in only one place: `find_reloads_address' in reload.c. */
-+#define LEGITIMIZE_RELOAD_ADDRESS(AD, MODE, OPNUM, TYPE, IND, WIN) \
-+{ \
-+ rtx new_rtx = ubicom32_legitimize_reload_address ((AD), (MODE), (OPNUM), (int)(TYPE)); \
-+ if (new_rtx) \
-+ { \
-+ (AD) = new_rtx; \
-+ goto WIN; \
-+ } \
-+}
-+
-+/* A C statement or compound statement with a conditional `goto LABEL;'
-+ executed if memory address X (an RTX) can have different meanings depending
-+ on the machine mode of the memory reference it is used for or if the address
-+ is valid for some modes but not others.
-+
-+ Autoincrement and autodecrement addresses typically have mode-dependent
-+ effects because the amount of the increment or decrement is the size of the
-+ operand being addressed. Some machines have other mode-dependent addresses.
-+ Many RISC machines have no mode-dependent addresses.
-+
-+ You may assume that ADDR is a valid address for the machine. */
-+#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL) \
-+ if (ubicom32_mode_dependent_address_p (ADDR)) \
-+ goto LABEL;
-+
-+/* A C expression that is nonzero if X is a legitimate constant for an
-+ immediate operand on the target machine. You can assume that X
-+ satisfies `CONSTANT_P', so you need not check this. In fact, `1' is
-+ a suitable definition for this macro on machines where anything
-+ `CONSTANT_P' is valid. */
-+#define LEGITIMATE_CONSTANT_P(X) \
-+ ubicom32_legitimate_constant_p ((X))
-+
-+/* Moves between registers are pretty-much single instructions for
-+ Ubicom32. We make this the default "2" that gcc likes. */
-+#define REGISTER_MOVE_COST(MODE, FROM, TO) 2
-+
-+/* This is a little bit of magic from the S390 port that wins 2% on code
-+ size when building the Linux kernel! Unfortunately while it wins on
-+ that size the user-space apps built using FD-PIC don't improve and the
-+ performance is lower because we put more pressure on the caches. We may
-+ want this back on some future CPU that has higher cache performance. */
-+/* #define IRA_HARD_REGNO_ADD_COST_MULTIPLIER(regno) 0.5 */
-+
-+/* Moves between registers and memory are more expensive than between
-+ registers because we have caches and write buffers that slow things
-+ down! */
-+#define MEMORY_MOVE_COST(MODE, CLASS, IN) 2
-+
-+/* A fall-through branch is very low cost but anything that changes the PC
-+ incurs a major pipeline hazard. We don't make the full extent of this
-+ hazard visible because we hope that multiple threads will absorb much
-+ of the cost and so we don't want a jump being replaced with, say, 7
-+ instructions. */
-+#define BRANCH_COST(SPEED_P, PREDICTABLE_P) \
-+ ((PREDICTABLE_P) ? 1 : 3)
-+
-+/* Define this macro as a C expression which is nonzero if accessing less than
-+ a word of memory (i.e. a `char' or a `short') is no faster than accessing a
-+ word of memory, i.e., if such access require more than one instruction or if
-+ there is no difference in cost between byte and (aligned) word loads.
-+
-+ When this macro is not defined, the compiler will access a field by finding
-+ the smallest containing object; when it is defined, a fullword load will be
-+ used if alignment permits. Unless bytes accesses are faster than word
-+ accesses, using word accesses is preferable since it may eliminate
-+ subsequent memory access if subsequent accesses occur to other fields in the
-+ same word of the structure, but to different bytes. */
-+#define SLOW_BYTE_ACCESS 0
-+
-+/* The number of scalar move insns which should be generated instead of a
-+ string move insn or a library call. Increasing the value will always make
-+ code faster, but eventually incurs high cost in increased code size.
-+
-+ If you don't define this, a reasonable default is used. */
-+/* According to expr.c, a value of around 6 should minimize code size. */
-+#define MOVE_RATIO(SPEED) 6
-+
-+/* We're much better off calling a constant function address with the
-+ Ubicom32 architecture because we have an opcode for doing so. Don't
-+ let the compiler extract function addresses as common subexpressions
-+ into an address register. */
-+#define NO_FUNCTION_CSE
-+
-+#define SELECT_CC_MODE(OP, X, Y) ubicom32_select_cc_mode (OP, X, Y)
-+
-+#define REVERSIBLE_CC_MODE(MODE) 1
-+
-+/* Canonicalize a comparison from one we don't have to one we do have. */
-+#define CANONICALIZE_COMPARISON(CODE, OP0, OP1) \
-+ ubicom32_canonicalize_comparison (&(CODE), &(OP0), &(OP1))
-+
-+/* Dividing the output into sections. */
-+
-+/* A C expression whose value is a string containing the assembler operation
-+ that should precede instructions and read-only data. Normally `".text"' is
-+ right. */
-+#define TEXT_SECTION_ASM_OP "\t.section .text"
-+
-+/* A C expression whose value is a string containing the assembler operation to
-+ identify the following data as writable initialized data. Normally
-+ `".data"' is right. */
-+#define DATA_SECTION_ASM_OP "\t.section .data"
-+
-+
-+/* If defined, a C expression whose value is a string containing the
-+ assembler operation to identify the following data as
-+ uninitialized global data. If not defined, and neither
-+ `ASM_OUTPUT_BSS' nor `ASM_OUTPUT_ALIGNED_BSS' are defined,
-+ uninitialized global data will be output in the data section if
-+ `-fno-common' is passed, otherwise `ASM_OUTPUT_COMMON' will be
-+ used. */
-+#define BSS_SECTION_ASM_OP "\t.section .bss"
-+
-+/* This is how we tell the assembler that a symbol is weak. */
-+
-+#define ASM_WEAKEN_LABEL(FILE, NAME) \
-+ do \
-+ { \
-+ fputs ("\t.weak\t", (FILE)); \
-+ assemble_name ((FILE), (NAME)); \
-+ fputc ('\n', (FILE)); \
-+ } \
-+ while (0)
-+
-+/* The Overall Framework of an Assembler File. */
-+
-+#undef SET_ASM_OP
-+#define SET_ASM_OP "\t.set\t"
-+
-+/* A C string constant describing how to begin a comment in the target
-+ assembler language. The compiler assumes that the comment will end at the
-+ end of the line. */
-+#define ASM_COMMENT_START ";"
-+
-+/* A C string constant for text to be output before each `asm' statement or
-+ group of consecutive ones. Normally this is `"#APP"', which is a comment
-+ that has no effect on most assemblers but tells the GNU assembler that it
-+ must check the lines that follow for all valid assembler constructs. */
-+#define ASM_APP_ON "#APP\n"
-+
-+/* A C string constant for text to be output after each `asm' statement or
-+ group of consecutive ones. Normally this is `"#NO_APP"', which tells the
-+ GNU assembler to resume making the time-saving assumptions that are valid
-+ for ordinary compiler output. */
-+#define ASM_APP_OFF "#NO_APP\n"
-+
-+/* Like `ASM_OUTPUT_BSS' except takes the required alignment as a separate,
-+ explicit argument. If you define this macro, it is used in place of
-+ `ASM_OUTPUT_BSS', and gives you more flexibility in handling the required
-+ alignment of the variable. The alignment is specified as the number of
-+ bits.
-+
-+ Try to use function `asm_output_aligned_bss' defined in file `varasm.c' when
-+ defining this macro. */
-+#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
-+ asm_output_aligned_bss ((FILE), (DECL), (NAME), (SIZE), (ALIGN))
-+
-+/* A C expression to assign to OUTVAR (which is a variable of type `char *') a
-+ newly allocated string made from the string NAME and the number NUMBER, with
-+ some suitable punctuation added. Use `alloca' to get space for the string.
-+
-+ The string will be used as an argument to `ASM_OUTPUT_LABELREF' to produce
-+ an assembler label for an internal static variable whose name is NAME.
-+ Therefore, the string must be such as to result in valid assembler code.
-+ The argument NUMBER is different each time this macro is executed; it
-+ prevents conflicts between similarly-named internal static variables in
-+ different scopes.
-+
-+ Ideally this string should not be a valid C identifier, to prevent any
-+ conflict with the user's own symbols. Most assemblers allow periods or
-+ percent signs in assembler symbols; putting at least one of these between
-+ the name and the number will suffice. */
-+#define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \
-+ ((OUTPUT) = (char *) alloca (strlen ((NAME)) + 10), \
-+ sprintf ((OUTPUT), "%s___%d", (NAME), (LABELNO)))
-+
-+#define ASM_GENERATE_INTERNAL_LABEL(STRING, PREFIX, NUM) \
-+ sprintf (STRING, "*.%s%ld", PREFIX, (long)(NUM))
-+/* A C statement to store into the string STRING a label whose name
-+ is made from the string PREFIX and the number NUM.
-+
-+ This string, when output subsequently by `assemble_name', should
-+ produce the output that `(*targetm.asm_out.internal_label)' would produce
-+ with the same PREFIX and NUM.
-+
-+ If the string begins with `*', then `assemble_name' will output
-+ the rest of the string unchanged. It is often convenient for
-+ `ASM_GENERATE_INTERNAL_LABEL' to use `*' in this way. If the
-+ string doesn't start with `*', then `ASM_OUTPUT_LABELREF' gets to
-+ output the string, and may change it. (Of course,
-+ `ASM_OUTPUT_LABELREF' is also part of your machine description, so
-+ you should know what it does on your machine.) */
-+
-+/* This says how to output assembler code to declare an
-+ uninitialized external linkage data object. Under SVR4,
-+ the linker seems to want the alignment of data objects
-+ to depend on their types. We do exactly that here. */
-+
-+#define COMMON_ASM_OP "\t.comm\t"
-+
-+#undef ASM_OUTPUT_COMMON
-+#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \
-+ do \
-+ { \
-+ fprintf ((FILE), "%s", COMMON_ASM_OP); \
-+ assemble_name ((FILE), (NAME)); \
-+ fprintf ((FILE), ", %u\n", (SIZE)); \
-+ } \
-+ while (0)
-+
-+/* This says how to output assembler code to declare an
-+ uninitialized internal linkage data object. Under SVR4,
-+ the linker seems to want the alignment of data objects
-+ to depend on their types. We do exactly that here. */
-+#define LOCAL_ASM_OP "\t.lcomm\t"
-+
-+#undef ASM_OUTPUT_LOCAL
-+#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \
-+ do \
-+ { \
-+ fprintf ((FILE), "%s", LOCAL_ASM_OP); \
-+ assemble_name ((FILE), (NAME)); \
-+ fprintf ((FILE), ", %u\n", (SIZE)); \
-+ } \
-+ while (0)
-+
-+/* Globalizing directive for a label. */
-+#define GLOBAL_ASM_OP ".global\t"
-+
-+/* Output the operand of an instruction. */
-+#define PRINT_OPERAND(FILE, X, CODE) \
-+ ubicom32_print_operand(FILE, X, CODE)
-+
-+/* Output the address of an operand. */
-+#define PRINT_OPERAND_ADDRESS(FILE, ADDR) \
-+ ubicom32_print_operand_address (FILE, ADDR)
-+
-+/* A C expression to output to STREAM some assembler code which will push hard
-+ register number REGNO onto the stack. The code need not be optimal, since
-+ this macro is used only when profiling. */
-+#define ASM_OUTPUT_REG_PUSH(FILE, REGNO)
-+
-+/* A C expression to output to STREAM some assembler code which will pop hard
-+ register number REGNO off of the stack. The code need not be optimal, since
-+ this macro is used only when profiling. */
-+#define ASM_OUTPUT_REG_POP(FILE, REGNO)
-+
-+/* This macro should be provided on machines where the addresses in a dispatch
-+ table are relative to the table's own address.
-+
-+ The definition should be a C statement to output to the stdio stream STREAM
-+ an assembler pseudo-instruction to generate a difference between two labels.
-+ VALUE and REL are the numbers of two internal labels. The definitions of
-+ these labels are output using `ASM_OUTPUT_INTERNAL_LABEL', and they must be
-+ printed in the same way here. For example,
-+
-+ fprintf (STREAM, "\t.word L%d-L%d\n", VALUE, REL) */
-+#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
-+ fprintf (FILE, "\t%s .L%d-.L%d\n", ".long", VALUE, REL)
-+
-+/* This macro should be provided on machines where the addresses in a dispatch
-+ table are absolute.
-+
-+ The definition should be a C statement to output to the stdio stream STREAM
-+ an assembler pseudo-instruction to generate a reference to a label. VALUE
-+ is the number of an internal label whose definition is output using
-+ `ASM_OUTPUT_INTERNAL_LABEL'. For example,
-+
-+ fprintf (STREAM, "\t.word L%d\n", VALUE) */
-+#define ASM_OUTPUT_ADDR_VEC_ELT(STREAM, VALUE) \
-+ fprintf (STREAM, "\t.word .L%d\n", VALUE)
-+
-+/* Switch into a generic section. */
-+#define TARGET_ASM_NAMED_SECTION default_elf_asm_named_section
-+
-+/* Assembler Commands for Alignment. */
-+
-+#define ASM_OUTPUT_SKIP(STREAM, N) fprintf (STREAM, "\t.skip %d,0\n", N)
-+/* A C statement to output to the stdio stream STREAM an assembler
-+ instruction to advance the location counter by NBYTES bytes.
-+ Those bytes should be zero when loaded. NBYTES will be a C
-+ expression of type `int'. */
-+
-+/* A C statement to output to the stdio stream STREAM an assembler command to
-+ advance the location counter to a multiple of 2 to the POWER bytes. POWER
-+ will be a C expression of type `int'. */
-+#define ASM_OUTPUT_ALIGN(FILE, LOG) \
-+ if ((LOG) != 0) \
-+ fprintf (FILE, "\t.align %d\n", (LOG))
-+
-+/* A C expression that returns the DBX register number for the compiler
-+ register number REGNO. In simple cases, the value of this expression may be
-+ REGNO itself. But sometimes there are some registers that the compiler
-+ knows about and DBX does not, or vice versa. In such cases, some register
-+ may need to have one number in the compiler and another for DBX.
-+
-+ If two registers have consecutive numbers inside GNU CC, and they can be
-+ used as a pair to hold a multiword value, then they *must* have consecutive
-+ numbers after renumbering with `DBX_REGISTER_NUMBER'. Otherwise, debuggers
-+ will be unable to access such a pair, because they expect register pairs to
-+ be consecutive in their own numbering scheme.
-+
-+ If you find yourself defining `DBX_REGISTER_NUMBER' in way that does not
-+ preserve register pairs, then what you must do instead is redefine the
-+ actual register numbering scheme.
-+
-+ This declaration is required. */
-+#define DBX_REGISTER_NUMBER(REGNO) REGNO
-+
-+/* A C expression that returns the integer offset value for an automatic
-+ variable having address X (an RTL expression). The default computation
-+ assumes that X is based on the frame-pointer and gives the offset from the
-+ frame-pointer. This is required for targets that produce debugging output
-+ for DBX or COFF-style debugging output for SDB and allow the frame-pointer
-+ to be eliminated when the `-g' options is used. */
-+#define DEBUGGER_AUTO_OFFSET(X) \
-+ ((GET_CODE (X) == PLUS ? INTVAL (XEXP (X, 1)) : 0) \
-+ + (frame_pointer_needed \
-+ ? 0 : -initial_elimination_offset (FRAME_POINTER_REGNUM, \
-+ STACK_POINTER_REGNUM)))
-+
-+/* A C expression that returns the integer offset value for an argument having
-+ address X (an RTL expression). The nominal offset is OFFSET. */
-+#define DEBUGGER_ARG_OFFSET(OFFSET, X) \
-+ ((GET_CODE (X) == PLUS ? OFFSET : 0) \
-+ + (frame_pointer_needed \
-+ ? 0 : -initial_elimination_offset (ARG_POINTER_REGNUM, \
-+ STACK_POINTER_REGNUM)))
-+
-+/* A C expression that returns the type of debugging output GNU CC produces
-+ when the user specifies `-g' or `-ggdb'. Define this if you have arranged
-+ for GNU CC to support more than one format of debugging output. Currently,
-+ the allowable values are `DBX_DEBUG', `SDB_DEBUG', `DWARF_DEBUG',
-+ `DWARF2_DEBUG', and `XCOFF_DEBUG'.
-+
-+ The value of this macro only affects the default debugging output; the user
-+ can always get a specific type of output by using `-gstabs', `-gcoff',
-+ `-gdwarf-1', `-gdwarf-2', or `-gxcoff'.
-+
-+ Defined in svr4.h.
-+*/
-+#undef PREFERRED_DEBUGGING_TYPE
-+#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
-+
-+/* Define this macro if GNU CC should produce dwarf version 2 format debugging
-+ output in response to the `-g' option.
-+
-+ To support optional call frame debugging information, you must also define
-+ `INCOMING_RETURN_ADDR_RTX' and either set `RTX_FRAME_RELATED_P' on the
-+ prologue insns if you use RTL for the prologue, or call `dwarf2out_def_cfa'
-+ and `dwarf2out_reg_save' as appropriate from `FUNCTION_PROLOGUE' if you
-+ don't.
-+
-+ Defined in svr4.h. */
-+
-+#define DWARF2_DEBUGGING_INFO 1
-+/*#define DWARF2_UNWIND_INFO 1*/
-+#define DWARF2_UNWIND_INFO 0
-+#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (Pmode, LINK_REGNO)
-+#define INCOMING_FRAME_SP_OFFSET 0
-+#define DWARF_FRAME_RETURN_COLUMN DWARF_FRAME_REGNUM (LINK_REGNO)
-+#define EH_RETURN_FIRST 9
-+#define EH_RETURN_DATA_REGNO(N) ((N) < 2 ? (N) + EH_RETURN_FIRST : INVALID_REGNUM)
-+
-+/* The EH_RETURN_STACKADJ_RTX macro returns RTL which describes the
-+ location used to store the amount to ajdust the stack. This is
-+ usually a registers that is available from end of the function's body
-+ to the end of the epilogue. Thus, this cannot be a register used as a
-+ temporary by the epilogue.
-+
-+ This must be an integer register. */
-+#define EH_RETURN_STACKADJ_REGNO 11
-+#define EH_RETURN_STACKADJ_RTX \
-+ gen_rtx_REG (Pmode, EH_RETURN_STACKADJ_REGNO)
-+
-+/* The EH_RETURN_HANDLER_RTX macro returns RTL which describes the
-+ location used to store the address the processor should jump to
-+ catch exception. This is usually a registers that is available from
-+ end of the function's body to the end of the epilogue. Thus, this
-+ cannot be a register used as a temporary by the epilogue.
-+
-+ This must be an address register. */
-+#define EH_RETURN_HANDLER_REGNO 18
-+#define EH_RETURN_HANDLER_RTX \
-+ gen_rtx_REG (Pmode, EH_RETURN_HANDLER_REGNO)
-+
-+/* #define DWARF2_DEBUGGING_INFO */
-+
-+/* Define this macro if GNU CC should produce dwarf version 2-style
-+ line numbers. This usually requires extending the assembler to
-+ support them, and #defining DWARF2_LINE_MIN_INSN_LENGTH in the
-+ assembler configuration header files. */
-+/* #define DWARF2_ASM_LINE_DEBUG_INFO 1 */
-+
-+
-+/* An alias for a machine mode name. This is the machine mode that elements
-+ of a jump-table have. */
-+#define CASE_VECTOR_MODE Pmode
-+
-+/* Smallest number of different values for which it is best to use a
-+ jump-table instead of a tree of conditional branches. For most Ubicom32
-+ targets this is quite small, but for the v1 architecture implementations
-+ we had very little data memory and so heavily prefer the tree approach
-+ rather than the jump tables. */
-+#define CASE_VALUES_THRESHOLD ubicom32_case_values_threshold
-+
-+/* Register operations within the Ubicom32 architecture always operate on
-+ the whole register word and not just the sub-bits required for the opcode
-+ mode size. */
-+#define WORD_REGISTER_OPERATIONS
-+
-+/* The maximum number of bytes that a single instruction can move quickly from
-+ memory to memory. */
-+#define MOVE_MAX 4
-+
-+/* A C expression that is nonzero if on this machine the number of bits
-+ actually used for the count of a shift operation is equal to the number of
-+ bits needed to represent the size of the object being shifted. When this
-+ macro is non-zero, the compiler will assume that it is safe to omit a
-+ sign-extend, zero-extend, and certain bitwise `and' instructions that
-+ truncates the count of a shift operation. On machines that have
-+ instructions that act on bitfields at variable positions, which may include
-+ `bit test' instructions, a nonzero `SHIFT_COUNT_TRUNCATED' also enables
-+ deletion of truncations of the values that serve as arguments to bitfield
-+ instructions.
-+
-+ If both types of instructions truncate the count (for shifts) and position
-+ (for bitfield operations), or if no variable-position bitfield instructions
-+ exist, you should define this macro.
-+
-+ However, on some machines, such as the 80386 and the 680x0, truncation only
-+ applies to shift operations and not the (real or pretended) bitfield
-+ operations. Define `SHIFT_COUNT_TRUNCATED' to be zero on such machines.
-+ Instead, add patterns to the `md' file that include the implied truncation
-+ of the shift instructions.
-+
-+ You need not define this macro if it would always have the value of zero. */
-+#define SHIFT_COUNT_TRUNCATED 1
-+
-+/* A C expression which is nonzero if on this machine it is safe to "convert"
-+ an integer of INPREC bits to one of OUTPREC bits (where OUTPREC is smaller
-+ than INPREC) by merely operating on it as if it had only OUTPREC bits.
-+
-+ On many machines, this expression can be 1.
-+
-+ When `TRULY_NOOP_TRUNCATION' returns 1 for a pair of sizes for modes for
-+ which `MODES_TIEABLE_P' is 0, suboptimal code can result. If this is the
-+ case, making `TRULY_NOOP_TRUNCATION' return 0 in such cases may improve
-+ things. */
-+#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
-+
-+/* A C string constant that tells the GNU CC driver program options to pass
-+ to the assembler. It can also specify how to translate options you give
-+ to GNU CC into options for GNU CC to pass to the assembler. See the
-+ file `sun3.h' for an example of this.
-+
-+ Defined in svr4.h. */
-+#undef ASM_SPEC
-+#define ASM_SPEC \
-+ "%{march=*:-m%*} %{!march=*:-mubicom32v4} %{mfdpic:-mfdpic}"
-+
-+#define LINK_SPEC "\
-+%{h*} %{v:-V} \
-+%{b} \
-+%{mfdpic:-melf32ubicom32fdpic -z text} \
-+%{static:-dn -Bstatic} \
-+%{shared:-G -Bdynamic} \
-+%{symbolic:-Bsymbolic} \
-+%{G*} \
-+%{YP,*} \
-+%{Qy:} %{!Qn:-Qy}"
-+
-+#undef STARTFILE_SPEC
-+#undef ENDFILE_SPEC
-+
-+/* The svr4.h LIB_SPEC with -leval and --*group tacked on */
-+
-+#undef LIB_SPEC
-+#define LIB_SPEC "%{!shared:%{!symbolic:--start-group -lc -leval -lgcc --end-group}}"
-+
-+#undef HAVE_GAS_SHF_MERGE
-+#define HAVE_GAS_SHF_MERGE 0
-+
-+#define HANDLE_SYSV_PRAGMA 1
-+#undef HANDLE_PRAGMA_PACK
-+
-+typedef void (*ubicom32_func_ptr) (void);
-+
-+/* Define builtins for selected special-purpose instructions. */
-+enum ubicom32_builtins
-+{
-+ UBICOM32_BUILTIN_UBICOM32_SWAPB_2,
-+ UBICOM32_BUILTIN_UBICOM32_SWAPB_4
-+};
-+
-+extern rtx ubicom32_compare_op0;
-+extern rtx ubicom32_compare_op1;
-+
-+#define TYPE_ASM_OP "\t.type\t"
-+#define TYPE_OPERAND_FMT "@%s"
-+
-+#ifndef ASM_DECLARE_RESULT
-+#define ASM_DECLARE_RESULT(FILE, RESULT)
-+#endif
-+
-+/* These macros generate the special .type and .size directives which
-+ are used to set the corresponding fields of the linker symbol table
-+ entries in an ELF object file under SVR4. These macros also output
-+ the starting labels for the relevant functions/objects. */
-+
-+/* Write the extra assembler code needed to declare a function properly.
-+ Some svr4 assemblers need to also have something extra said about the
-+ function's return value. We allow for that here. */
-+
-+#ifndef ASM_DECLARE_FUNCTION_NAME
-+#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \
-+ do \
-+ { \
-+ ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "function"); \
-+ ASM_DECLARE_RESULT (FILE, DECL_RESULT (DECL)); \
-+ ASM_OUTPUT_LABEL (FILE, NAME); \
-+ } \
-+ while (0)
-+#endif
---- /dev/null
-+++ b/gcc/config/ubicom32/ubicom32.md
-@@ -0,0 +1,3753 @@
-+; GCC machine description for Ubicom32
-+;
-+; Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Free Software
-+; Foundation, Inc.
-+; Contributed by Ubicom, Inc.
-+;
-+; This file is part of GCC.
-+;
-+; GCC is free software; you can redistribute it and/or modify
-+; it under the terms of the GNU General Public License as published by
-+; the Free Software Foundation; either version 3, or (at your option)
-+; any later version.
-+;
-+; GCC is distributed in the hope that it will be useful,
-+; but WITHOUT ANY WARRANTY; without even the implied warranty of
-+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+; GNU General Public License for more details.
-+;
-+; You should have received a copy of the GNU General Public License
-+; along with GCC; see the file COPYING3. If not see
-+; <http://www.gnu.org/licenses/>.
-+
-+(define_constants
-+ [(AUX_DATA_REGNO 15)
-+ (LINK_REGNO 21)
-+ (SP_REGNO 23)
-+ (ACC0_HI_REGNO 24)
-+ (ACC1_HI_REGNO 26)
-+ (CC_REGNO 30)])
-+
-+(define_constants
-+ [(UNSPEC_FDPIC_GOT 0)
-+ (UNSPEC_FDPIC_GOT_FUNCDESC 1)])
-+
-+(define_constants
-+ [(UNSPEC_VOLATILE_LOAD_FDPIC_FUNCDESC 0)])
-+
-+;; Types of instructions (for scheduling purposes).
-+
-+(define_attr "type" "mul,addr,other"
-+ (const_string "other"))
-+
-+; Define instruction scheduling characteristics. We can only issue
-+; one instruction per clock so we don't need to define CPU units.
-+;
-+(define_automaton "ubicom32")
-+
-+(define_cpu_unit "i_pipeline" "ubicom32");
-+
-+; We have a 4 cycle hazard associated with address calculations which
-+; seems rather tricky to avoid so we go with a defensive assumption
-+; that almost anything can be used to generate addresses.
-+;
-+;(define_insn_reservation "ubicom32_other" 4
-+; (eq_attr "type" "other")
-+; "i_pipeline")
-+
-+; Some moves don't generate hazards.
-+;
-+;(define_insn_reservation "ubicom32_addr" 1
-+; (eq_attr "type" "addr")
-+; "i_pipeline")
-+
-+; We need 3 cycles between a multiply instruction and any use of the
-+; matching accumulator register(s).
-+;
-+(define_insn_reservation "ubicom32_mul" 4
-+ (eq_attr "type" "mul")
-+ "i_pipeline")
-+
-+(define_attr "length" ""
-+ (const_int 4))
-+
-+(include "predicates.md")
-+(include "constraints.md")
-+
-+; 8-bit move with no change to the flags reg.
-+;
-+(define_insn "movqi"
-+ [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
-+ (match_operand:QI 1 "ubicom32_move_operand" "g"))]
-+ ""
-+ "move.1\\t%0, %1")
-+
-+; Combiner-generated 8-bit move with the zero flag set accordingly.
-+;
-+(define_insn "movqi_ccszn"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:QI 0 "nonimmediate_operand" "rm")
-+ (const_int 0)))
-+ (set (match_operand:QI 1 "nonimmediate_operand" "=rm")
-+ (match_dup 0))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "ext.1\\t%1, %0")
-+
-+; Combine isn't very good at merging some types of operations so we
-+; have to make do with a peephole. It's not as effective but it's better
-+; than doing nothing.
-+;
-+(define_peephole2
-+ [(set (match_operand:QI 0 "nonimmediate_operand" "")
-+ (match_operand:QI 1 "nonimmediate_operand" ""))
-+ (set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (match_operator 3 "ubicom32_compare_operator"
-+ [(match_dup 0)
-+ (const_int 0)]))]
-+ "(GET_MODE (operands[2]) == CCSZNmode
-+ || GET_MODE (operands[2]) == CCSZmode)"
-+ [(parallel
-+ [(set (match_dup 2)
-+ (match_op_dup 3
-+ [(match_dup 1)
-+ (const_int 0)]))
-+ (set (match_dup 0)
-+ (match_dup 1))])]
-+ "")
-+
-+; Combine isn't very good at merging some types of operations so we
-+; have to make do with a peephole. It's not as effective but it's better
-+; than doing nothing.
-+;
-+(define_peephole2
-+ [(set (match_operand:QI 0 "nonimmediate_operand" "")
-+ (match_operand:QI 1 "nonimmediate_operand" ""))
-+ (set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (match_operator 3 "ubicom32_compare_operator"
-+ [(match_dup 1)
-+ (const_int 0)]))]
-+ "(GET_MODE (operands[2]) == CCSZNmode
-+ || GET_MODE (operands[2]) == CCSZmode)"
-+ [(parallel
-+ [(set (match_dup 2)
-+ (match_op_dup 3
-+ [(match_dup 1)
-+ (const_int 0)]))
-+ (set (match_dup 0)
-+ (match_dup 1))])]
-+ "")
-+
-+; 16-bit move with no change to the flags reg.
-+;
-+(define_insn "movhi"
-+ [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
-+ (match_operand:HI 1 "ubicom32_move_operand" "g"))]
-+ ""
-+ "*
-+ {
-+ if (CONST_INT_P (operands[1]))
-+ return \"movei\\t%0, %1\";
-+
-+ return \"move.2\\t%0, %1\";
-+ }")
-+
-+; Combiner-generated 16-bit move with the zero flag set accordingly.
-+;
-+(define_insn "movhi_ccszn"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:HI 0 "nonimmediate_operand" "rm")
-+ (const_int 0)))
-+ (set (match_operand:HI 1 "nonimmediate_operand" "=rm")
-+ (match_dup 0))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "ext.2\\t%1, %0")
-+
-+; Combine isn't very good at merging some types of operations so we
-+; have to make do with a peephole. It's not as effective but it's better
-+; than doing nothing.
-+;
-+(define_peephole2
-+ [(set (match_operand:HI 0 "nonimmediate_operand" "")
-+ (match_operand:HI 1 "nonimmediate_operand" ""))
-+ (set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (match_operator 3 "ubicom32_compare_operator"
-+ [(match_dup 0)
-+ (const_int 0)]))]
-+ "(GET_MODE (operands[2]) == CCSZNmode
-+ || GET_MODE (operands[2]) == CCSZmode)"
-+ [(parallel
-+ [(set (match_dup 2)
-+ (match_op_dup 3
-+ [(match_dup 1)
-+ (const_int 0)]))
-+ (set (match_dup 0)
-+ (match_dup 1))])]
-+ "")
-+
-+; Combine isn't very good at merging some types of operations so we
-+; have to make do with a peephole. It's not as effective but it's better
-+; than doing nothing.
-+;
-+(define_peephole2
-+ [(set (match_operand:HI 0 "nonimmediate_operand" "")
-+ (match_operand:HI 1 "nonimmediate_operand" ""))
-+ (set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (match_operator 3 "ubicom32_compare_operator"
-+ [(match_dup 1)
-+ (const_int 0)]))]
-+ "(GET_MODE (operands[2]) == CCSZNmode
-+ || GET_MODE (operands[2]) == CCSZmode)"
-+ [(parallel
-+ [(set (match_dup 2)
-+ (match_op_dup 3
-+ [(match_dup 1)
-+ (const_int 0)]))
-+ (set (match_dup 0)
-+ (match_dup 1))])]
-+ "")
-+
-+; 32-bit move with no change to the flags reg.
-+;
-+(define_expand "movsi"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
-+ (match_operand:SI 1 "general_operand" ""))]
-+ ""
-+ "{
-+ /* Convert any complexities in operand 1 into something that can just
-+ fall into the default expander code. */
-+ ubicom32_expand_movsi (operands);
-+ }")
-+
-+(define_insn "movsi_high"
-+ [(set (match_operand:SI 0 "ubicom32_address_register_operand" "=a")
-+ (high:SI (match_operand:SI 1 "ubicom32_symbolic_address_operand" "s")))]
-+ ""
-+ "moveai\\t%0, #%%hi(%E1)")
-+
-+(define_insn "movsi_lo_sum"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (lo_sum:SI (match_operand:SI 1 "ubicom32_address_register_operand" "a")
-+ (match_operand:SI 2 "immediate_operand" "s")))]
-+ ""
-+ "lea.1\\t%0, %%lo(%E2)(%1)")
-+
-+(define_insn "movsi_internal"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (match_operand:SI 1 "ubicom32_move_operand" "rmnY"))]
-+ ""
-+ "*
-+ {
-+ if (CONST_INT_P (operands[1]))
-+ {
-+ ubicom32_emit_move_const_int (operands[0], operands[1]);
-+ return \"\";
-+ }
-+
-+ if (GET_CODE (operands[1]) == CONST_DOUBLE)
-+ {
-+ HOST_WIDE_INT i = CONST_DOUBLE_LOW (operands[1]);
-+
-+ ubicom32_emit_move_const_int (operands[0], GEN_INT (i));
-+ return \"\";
-+ }
-+
-+ if (ubicom32_address_register_operand (operands[0], VOIDmode)
-+ && register_operand (operands[1], VOIDmode))
-+ {
-+ if (ubicom32_address_register_operand (operands[1], VOIDmode))
-+ return \"lea.1\\t%0, 0(%1)\";
-+
-+ /* Use movea here to utilize the hazard bypass in the >= v4 ISA. */
-+ if (ubicom32_v4)
-+ return \"movea\\t%0, %1\";
-+
-+ return \"move.4\\t%0, %1\";
-+ }
-+
-+ return \"move.4\\t%0, %1\";
-+ }")
-+
-+; If we're not dependent on the state of the condition codes we can construct
-+; constants of value 2^n by using a bset.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(exact_log2 (INTVAL (operands[1])) > 14
-+ && peep2_regno_dead_p (0, CC_REGNO))"
-+ [(parallel
-+ [(set (match_dup 0)
-+ (ior:SI (const_int 0)
-+ (match_dup 1)))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "")
-+
-+; If we're not dependent on the state of the condition codes we can construct
-+; constants of value ~(2^n) by using a bclr.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(exact_log2 (~INTVAL (operands[1])) > 14
-+ && peep2_regno_dead_p (0, CC_REGNO))"
-+ [(parallel
-+ [(set (match_dup 0)
-+ (and:SI (const_int -1)
-+ (match_dup 1)))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "")
-+
-+; For 32-bit constants that have bits 0 through 24 and bit 31 set the same
-+; we can use swapb.4!
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(ubicom32_v4
-+ && (INTVAL (operands[1]) & 0xffffffff) != 0xffffffff
-+ && (INTVAL (operands[1]) & 0xffffffff) != 0
-+ && ((INTVAL (operands[1]) & 0x80ffffff) == 0
-+ || (INTVAL (operands[1]) & 0x80ffffff) == 0x80ffffff))"
-+ [(set (match_dup 0)
-+ (bswap:SI (match_dup 2)))]
-+ "{
-+ operands[2] = GEN_INT (INTVAL (operands[1]) >> 24);
-+ }")
-+
-+; If this is a write of a constant to memory look to see if we can usefully
-+; transform this into 2 smaller writes.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "memory_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "! satisfies_constraint_I (operands[1])
-+ && ubicom32_legitimate_address_p (HImode, plus_constant (XEXP (operands[0], 0), 2), 1)"
-+ [(set (match_dup 4) (match_dup 2))
-+ (set (match_dup 5) (match_dup 3))]
-+ "{
-+ rtx low_hword_addr;
-+
-+ operands[2] = gen_highpart_mode (HImode, SImode, operands[1]);
-+ operands[3] = gen_lowpart (HImode, operands[1]);
-+
-+ operands[4] = gen_rtx_MEM (HImode, XEXP (operands[0], 0));
-+ MEM_COPY_ATTRIBUTES (operands[4], operands[0]);
-+
-+ low_hword_addr = plus_constant (XEXP (operands[0], 0), 2);
-+ operands[5] = gen_rtx_MEM (HImode, low_hword_addr);
-+ MEM_COPY_ATTRIBUTES (operands[5], operands[0]);
-+ }")
-+
-+; If we're writing memory and we've not found a better way to do this then
-+; try loading into a D register and then copying to memory. This will
-+; perform the fewest possible memory read/writes.
-+;
-+(define_peephole2
-+ [(match_scratch:SI 2 "d")
-+ (set (match_operand:SI 0 "memory_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "! satisfies_constraint_I (operands[1])"
-+ [(set (match_dup 2) (match_dup 1))
-+ (set (match_dup 0) (match_dup 2))]
-+ "")
-+
-+; If we're not dependent on the state of the condition codes we can construct
-+; constants of value (2^n - 1) by using an lsr.4.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(exact_log2 (INTVAL (operands[1]) + 1) > 14
-+ && peep2_regno_dead_p (0, CC_REGNO))"
-+ [(parallel
-+ [(set (match_dup 0)
-+ (lshiftrt:SI (const_int -1)
-+ (match_dup 2)))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "{
-+ operands[2] = GEN_INT (32 - exact_log2 (INTVAL (operands[1]) + 1));
-+ }")
-+
-+; If we're not dependent on the state of the condition codes we can construct
-+; constants of value (2^n - 1) by using an lsr.4.
-+;
-+(define_peephole2
-+ [(match_scratch:SI 2 "d")
-+ (set (match_operand:SI 0 "nonimmediate_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(exact_log2 (INTVAL (operands[1]) + 1) > 14
-+ && peep2_regno_dead_p (0, CC_REGNO))"
-+ [(parallel
-+ [(set (match_dup 2)
-+ (lshiftrt:SI (const_int -1)
-+ (match_dup 3)))
-+ (clobber (reg:CC CC_REGNO))])
-+ (set (match_dup 0)
-+ (match_dup 2))]
-+ "{
-+ operands[3] = GEN_INT (32 - exact_log2 (INTVAL (operands[1]) + 1));
-+ }")
-+
-+; If we're not dependent on the state of the condition codes we can construct
-+; some other constants by using an lsl.4 to shift 7 bits left by some
-+; constant.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(ubicom32_shiftable_const_int (INTVAL (operands[1]))
-+ && peep2_regno_dead_p (0, CC_REGNO))"
-+ [(parallel
-+ [(set (match_dup 0)
-+ (ashift:SI (match_dup 2)
-+ (match_dup 3)))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "{
-+ int shift = ubicom32_shiftable_const_int (INTVAL (operands[1]));
-+ operands[2] = GEN_INT (INTVAL (operands[1]) >> shift);
-+ operands[3] = GEN_INT (shift);
-+ }")
-+
-+; If we're not dependent on the state of the condition codes we can construct
-+; some other constants by using an lsl.4 to shift 7 bits left by some
-+; constant.
-+;
-+(define_peephole2
-+ [(match_scratch:SI 2 "d")
-+ (set (match_operand:SI 0 "nonimmediate_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(ubicom32_shiftable_const_int (INTVAL (operands[1]))
-+ && peep2_regno_dead_p (0, CC_REGNO))"
-+ [(parallel
-+ [(set (match_dup 2)
-+ (ashift:SI (match_dup 3)
-+ (match_dup 4)))
-+ (clobber (reg:CC CC_REGNO))])
-+ (set (match_dup 0)
-+ (match_dup 2))]
-+ "{
-+ int shift = ubicom32_shiftable_const_int (INTVAL (operands[1]));
-+ operands[3] = GEN_INT (INTVAL (operands[1]) >> shift);
-+ operands[4] = GEN_INT (shift);
-+ }")
-+
-+; For some 16-bit unsigned constants that have bit 15 set we can use
-+; swapb.2!
-+;
-+; Note that the movsi code emits the same sequence but by using a peephole2
-+; we split the pattern early enough to allow instruction scheduling to
-+; occur.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(ubicom32_v4
-+ && (INTVAL (operands[1]) & 0xffff80ff) == 0x80ff)"
-+ [(set (match_dup 0)
-+ (zero_extend:SI (bswap:HI (match_dup 2))))]
-+ "{
-+ HOST_WIDE_INT i = INTVAL (operands[1]) >> 8;
-+ if (i >= 0x80)
-+ i -= 0x100;
-+ operands[2] = GEN_INT (i);
-+ }")
-+
-+; In general for a 16-bit unsigned constant that has bit 15 set
-+; then we need a movei/move.2 pair unless we can represent it
-+; via just a move.2.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(INTVAL (operands[1]) & 0xffff8000) == 0x8000
-+ && (INTVAL (operands[1]) & 0xffff) < 0xff80"
-+ [(set (match_dup 2)
-+ (match_dup 1))
-+ (set (match_dup 0)
-+ (zero_extend:SI (match_dup 2)))]
-+ "{
-+ operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));
-+ }")
-+
-+; If we're not dependent on the state of the condition codes we can construct
-+; 32-bit constants that have bits 16 through 31 set to arbitrary values
-+; and have bits 0 through 15 set to something representable as a default
-+; source-1 immediate - we use movei/shmrg.2
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(((INTVAL (operands[1]) >= 0x8000
-+ && INTVAL (operands[1]) < 0xff80)
-+ || INTVAL (operands[1]) >= 0x10000
-+ || INTVAL (operands[1]) < -0x8000)
-+ && ((INTVAL (operands[1]) & 0xffff) >= 0xff80
-+ || (INTVAL (operands[1]) & 0xffff) < 0x80)
-+ && peep2_regno_dead_p (0, CC_REGNO))"
-+ [(set (match_dup 0)
-+ (match_dup 2))
-+ (parallel
-+ [(set (match_dup 0)
-+ (ior:SI
-+ (ashift:SI (match_dup 0)
-+ (const_int 16))
-+ (zero_extend:SI
-+ (match_dup 3))))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "{
-+ operands[2] = gen_highpart_mode (HImode, SImode, operands[1]);
-+ operands[3] = gen_lowpart (HImode, operands[1]);
-+ }")
-+
-+; Exactly the same as the peephole2 preceding except that this targets a
-+; general register instead of D register. Hopefully the later optimization
-+; passes will notice that the value ended up in a D register first here
-+; and eliminate away the other register!
-+;
-+(define_peephole2
-+ [(match_scratch:SI 2 "d")
-+ (set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(((INTVAL (operands[1]) >= 0x8000
-+ && INTVAL (operands[1]) < 0xff80)
-+ || INTVAL (operands[1]) >= 0x10000
-+ || INTVAL (operands[1]) < -0x8000)
-+ && ((INTVAL (operands[1]) & 0xffff) >= 0xff80
-+ || (INTVAL (operands[1]) & 0xffff) < 0x80)
-+ && peep2_regno_dead_p (0, CC_REGNO))"
-+ [(set (match_dup 2)
-+ (match_dup 3))
-+ (parallel
-+ [(set (match_dup 2)
-+ (ior:SI
-+ (ashift:SI (match_dup 2)
-+ (const_int 16))
-+ (zero_extend:SI
-+ (match_dup 4))))
-+ (clobber (reg:CC CC_REGNO))])
-+ (set (match_dup 0)
-+ (match_dup 2))]
-+ "{
-+ operands[3] = gen_highpart_mode (HImode, SImode, operands[1]);
-+ operands[4] = gen_lowpart (HImode, operands[1]);
-+ }")
-+
-+; If we have a load of a large integer constant which does not have bit 31
-+; set and we have a spare A reg then construct it with a moveai/lea.1 pair
-+; instead. This avoids constructing it in 3 instructions on the stack.
-+;
-+; Note that we have to be careful not to match anything that matches
-+; something we can do in a single instruction! There aren't many such
-+; constants but there are some.
-+;
-+(define_peephole2
-+ [(match_scratch:SI 2 "a")
-+ (set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(! (INTVAL (operands[1]) & 0x80000000)
-+ && ((INTVAL (operands[1]) >= 0x8000
-+ && INTVAL (operands[1]) < 0xff80)
-+ || INTVAL (operands[1]) >= 0x10000))"
-+ [(set (match_dup 2)
-+ (match_dup 3))
-+ (set (match_dup 0)
-+ (plus:SI (match_dup 2)
-+ (match_dup 4)))]
-+ "{
-+ HOST_WIDE_INT i = INTVAL (operands[1]);
-+ operands[3] = GEN_INT (i & 0xffffff80);
-+ operands[4] = GEN_INT (i & 0x7f);
-+ }")
-+
-+; If we're not dependent on the state of the condition codes we can construct
-+; a 32-bit constant with a movei/movei/shmrg.2 sequence if possible.
-+;
-+(define_peephole2
-+ [(match_scratch:HI 2 "d")
-+ (set (match_operand:SI 0 "ubicom32_data_register_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))
-+ (match_dup 2)]
-+ "(INTVAL (operands[1]) & 0x80000000
-+ && INTVAL (operands[1]) < -0x8000
-+ && peep2_regno_dead_p (0, CC_REGNO))"
-+ [(set (match_dup 0)
-+ (match_dup 3))
-+ (set (match_dup 2)
-+ (match_dup 4))
-+ (parallel
-+ [(set (match_dup 0)
-+ (ior:SI
-+ (ashift:SI (match_dup 0)
-+ (const_int 16))
-+ (zero_extend:SI
-+ (match_dup 2))))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "{
-+ operands[3] = gen_highpart_mode (HImode, SImode, operands[1]);
-+ operands[4] = gen_lowpart (HImode, operands[1]);
-+ }")
-+
-+; Exactly the same as the peephole2 preceding except that this targets a
-+; general register instead of D register. Hopefully the later optimization
-+; passes will notice that the value ended up in a D register first here
-+; and eliminate away the other register!
-+;
-+(define_peephole2
-+ [(match_scratch:SI 2 "d")
-+ (match_scratch:HI 3 "d")
-+ (set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))
-+ (match_dup 3)]
-+ "(INTVAL (operands[1]) & 0x80000000
-+ && INTVAL (operands[1]) < -0x8000
-+ && peep2_regno_dead_p (0, CC_REGNO))"
-+ [(set (match_dup 2)
-+ (match_dup 4))
-+ (set (match_dup 3)
-+ (match_dup 5))
-+ (parallel
-+ [(set (match_dup 2)
-+ (ior:SI
-+ (ashift:SI (match_dup 2)
-+ (const_int 16))
-+ (zero_extend:SI
-+ (match_dup 3))))
-+ (clobber (reg:CC CC_REGNO))])
-+ (set (match_dup 0)
-+ (match_dup 2))]
-+ "{
-+ operands[4] = gen_highpart_mode (HImode, SImode, operands[1]);
-+ operands[5] = gen_lowpart (HImode, operands[1]);
-+ }")
-+
-+(define_insn "movsi_fdpic_got_offset"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (match_operand:SI 1 "ubicom32_fdpic_got_offset_operand" "Y"))]
-+ ""
-+ "movei\\t%0, %1")
-+
-+; The explicit MEM inside the UNSPEC prevents the compiler from moving
-+; the load before a branch after a NULL test, or before a store that
-+; initializes a function descriptor.
-+
-+(define_insn_and_split "load_fdpic_funcdesc"
-+ [(set (match_operand:SI 0 "ubicom32_address_register_operand" "=a")
-+ (unspec_volatile:SI [(mem:SI (match_operand:SI 1 "address_operand" "p"))]
-+ UNSPEC_VOLATILE_LOAD_FDPIC_FUNCDESC))]
-+ ""
-+ "#"
-+ "reload_completed"
-+ [(set (match_dup 0)
-+ (mem:SI (match_dup 1)))])
-+
-+; Combiner-generated 32-bit move with the zero flag set accordingly.
-+;
-+(define_insn "movsi_ccwzn"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:SI 0 "nonimmediate_operand" "rm, d")
-+ (const_int 0)))
-+ (set (match_operand:SI 1 "nonimmediate_operand" "=d,rm")
-+ (match_dup 0))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "@
-+ lsl.4\\t%1, %0, #0
-+ add.4\\t%1, #0, %0")
-+
-+; Combiner-generated 32-bit move with all flags set accordingly.
-+;
-+(define_insn "movsi_ccw"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:SI 0 "ubicom32_data_register_operand" "d")
-+ (const_int 0)))
-+ (set (match_operand:SI 1 "nonimmediate_operand" "=rm")
-+ (match_dup 0))]
-+ "ubicom32_match_cc_mode(insn, CCWmode)"
-+ "add.4\\t%1, #0, %0")
-+
-+; Combine isn't very good at merging some types of operations so we
-+; have to make do with a peephole. It's not as effective but it's better
-+; than doing nothing.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "")
-+ (match_operand:SI 1 "nonimmediate_operand" ""))
-+ (parallel
-+ [(set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (match_operator 3 "ubicom32_compare_operator"
-+ [(match_dup 0)
-+ (const_int 0)]))
-+ (clobber (match_operand:SI 4 "ubicom32_data_register_operand" ""))])]
-+ "(GET_MODE (operands[2]) == CCWZNmode
-+ || GET_MODE (operands[2]) == CCWZmode)"
-+ [(parallel
-+ [(set (match_dup 2)
-+ (match_op_dup 3
-+ [(match_dup 1)
-+ (const_int 0)]))
-+ (set (match_dup 0)
-+ (match_dup 1))])]
-+ "")
-+
-+; Combine isn't very good at merging some types of operations so we
-+; have to make do with a peephole. It's not as effective but it's better
-+; than doing nothing.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
-+ (match_operand:SI 1 "ubicom32_data_register_operand" ""))
-+ (parallel
-+ [(set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (match_operator 3 "ubicom32_compare_operator"
-+ [(match_dup 1)
-+ (const_int 0)]))
-+ (clobber (match_operand:SI 4 "ubicom32_data_register_operand" ""))])]
-+ "(GET_MODE (operands[2]) == CCWZNmode
-+ || GET_MODE (operands[2]) == CCWZmode)"
-+ [(parallel
-+ [(set (match_dup 2)
-+ (match_op_dup 3
-+ [(match_dup 1)
-+ (const_int 0)]))
-+ (set (match_dup 0)
-+ (match_dup 1))])]
-+ "")
-+
-+; Combine isn't very good at merging some types of operations so we
-+; have to make do with a peephole. It's not as effective but it's better
-+; than doing nothing.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "nonimmediate_operand" ""))
-+ (parallel
-+ [(set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (match_operator 3 "ubicom32_compare_operator"
-+ [(match_dup 0)
-+ (const_int 0)]))
-+ (set (match_operand:SI 4 "ubicom32_data_register_operand" "")
-+ (match_dup 0))])]
-+ "(peep2_reg_dead_p (2, operands[0])
-+ && (GET_MODE (operands[2]) == CCWZNmode
-+ || GET_MODE (operands[2]) == CCWZmode))"
-+ [(parallel
-+ [(set (match_dup 2)
-+ (match_op_dup 3
-+ [(match_dup 1)
-+ (const_int 0)]))
-+ (set (match_dup 4)
-+ (match_dup 1))])]
-+ "")
-+
-+; Register renaming may make a general reg into a D reg in which case
-+; we may be able to simplify a compare.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "nonimmediate_operand" ""))
-+ (parallel
-+ [(set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (match_operator 3 "ubicom32_compare_operator"
-+ [(match_dup 0)
-+ (const_int 0)]))
-+ (clobber (match_operand:SI 4 "ubicom32_data_register_operand" ""))])]
-+ "(peep2_reg_dead_p (2, operands[0])
-+ && (GET_MODE (operands[2]) == CCWZNmode
-+ || GET_MODE (operands[2]) == CCWZmode))"
-+ [(parallel
-+ [(set (match_dup 2)
-+ (match_op_dup 3
-+ [(match_dup 1)
-+ (const_int 0)]))
-+ (clobber (match_dup 4))])]
-+ "")
-+
-+(define_insn_and_split "movdi"
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
-+ (match_operand:DI 1 "general_operand" "rmi,ri"))]
-+ ""
-+ "#"
-+ "reload_completed"
-+ [(set (match_dup 2) (match_dup 3))
-+ (set (match_dup 4) (match_dup 5))]
-+ "{
-+ rtx dest_low;
-+ rtx src_low;
-+
-+ dest_low = gen_lowpart (SImode, operands[0]);
-+ src_low = gen_lowpart (SImode, operands[1]);
-+
-+ if (REG_P (operands[0])
-+ && REG_P (operands[1])
-+ && REGNO (operands[0]) < REGNO (operands[1]))
-+ {
-+ operands[2] = gen_highpart (SImode, operands[0]);
-+ operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
-+ operands[4] = dest_low;
-+ operands[5] = src_low;
-+ }
-+ else if (reg_mentioned_p (dest_low, src_low))
-+ {
-+ operands[2] = gen_highpart (SImode, operands[0]);
-+ operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
-+ operands[4] = dest_low;
-+ operands[5] = src_low;
-+ }
-+ else
-+ {
-+ operands[2] = dest_low;
-+ operands[3] = src_low;
-+ operands[4] = gen_highpart (SImode, operands[0]);
-+ operands[5] = gen_highpart_mode (SImode, DImode, operands[1]);
-+ }
-+ }"
-+ [(set_attr "length" "8")])
-+
-+; Combiner-generated 64-bit move with all flags set accordingly.
-+;
-+(define_insn "movdi_ccwzn"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:DI 0 "nonimmediate_operand" "d, m, r")
-+ (const_int 0)))
-+ (set (match_operand:DI 1 "nonimmediate_operand" "=&rm,rm,!&rm")
-+ (match_dup 0))
-+ (clobber (match_scratch:SI 2 "=X, d, d"))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "*
-+ {
-+ operands[3] = gen_lowpart (SImode, operands[0]);
-+ operands[4] = gen_lowpart (SImode, operands[1]);
-+ operands[5] = gen_highpart (SImode, operands[0]);
-+ operands[6] = gen_highpart (SImode, operands[1]);
-+
-+ if (ubicom32_data_register_operand (operands[0], VOIDmode))
-+ return \"add.4\\t%4, #0, %3\;addc\\t%6, #0, %5\";
-+
-+ return \"movei\\t%2, #0\;add.4\\t%4, %3, %2\;addc\\t%6, %5, %2\";
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_insn "movdi_ccw"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:DI 0 "nonimmediate_operand" "d, m, r")
-+ (const_int 0)))
-+ (set (match_operand:DI 1 "nonimmediate_operand" "=&rm,rm,!&rm")
-+ (match_dup 0))
-+ (clobber (match_scratch:SI 2 "=X, d, d"))]
-+ "ubicom32_match_cc_mode(insn, CCWmode)"
-+ "*
-+ {
-+ operands[3] = gen_lowpart (SImode, operands[0]);
-+ operands[4] = gen_lowpart (SImode, operands[1]);
-+ operands[5] = gen_highpart (SImode, operands[0]);
-+ operands[6] = gen_highpart (SImode, operands[1]);
-+
-+ if (ubicom32_data_register_operand (operands[0], VOIDmode))
-+ return \"add.4\\t%4, #0, %3\;addc\\t%6, #0, %5\";
-+
-+ return \"movei\\t%2, #0\;add.4\\t%4, %3, %2\;addc\\t%6, %5, %2\";
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_insn "movsf"
-+ [(set (match_operand:SF 0 "nonimmediate_operand" "=!d,*rm")
-+ (match_operand:SF 1 "ubicom32_move_operand" "rmF,rmF"))]
-+ ""
-+ "*
-+ {
-+ if (GET_CODE (operands[1]) == CONST_DOUBLE)
-+ {
-+ HOST_WIDE_INT val;
-+ REAL_VALUE_TYPE rv;
-+
-+ REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
-+ REAL_VALUE_TO_TARGET_SINGLE (rv, val);
-+
-+ ubicom32_emit_move_const_int (operands[0], GEN_INT (val));
-+ return \"\";
-+ }
-+
-+ return \"move.4\\t%0, %1\";
-+ }")
-+
-+(define_insn "zero_extendqihi2"
-+ [(set (match_operand:HI 0 "register_operand" "=r")
-+ (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
-+ ""
-+ "move.1\\t%0, %1")
-+
-+(define_insn "zero_extendqisi2"
-+ [(set (match_operand:SI 0 "register_operand" "=r")
-+ (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
-+ ""
-+ "move.1\\t%0, %1")
-+
-+(define_insn "zero_extendqisi2_ccwz_1"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "rm"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (zero_extend:SI (match_dup 1)))]
-+ "ubicom32_match_cc_mode(insn, CCWZmode)"
-+ "shmrg.1\\t%0, %1, #0")
-+
-+(define_insn "zero_extendhisi2"
-+ [(set (match_operand:SI 0 "register_operand" "=r")
-+ (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
-+ ""
-+ "move.2\\t%0, %1")
-+
-+(define_insn "zero_extendhisi2_ccwz_1"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (zero_extend:SI (match_dup 1)))]
-+ "ubicom32_match_cc_mode(insn, CCWZmode)"
-+ "shmrg.2\\t%0, %1, #0")
-+
-+(define_insn_and_split "zero_extendqidi2"
-+ [(set (match_operand:DI 0 "register_operand" "=r")
-+ (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
-+ ""
-+ "#"
-+ "reload_completed"
-+ [(set (match_dup 2)
-+ (zero_extend:SI (match_dup 1)))
-+ (set (match_dup 3)
-+ (const_int 0))]
-+ "{
-+ operands[2] = gen_lowpart (SImode, operands[0]);
-+ operands[3] = gen_highpart (SImode, operands[0]);
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_insn_and_split "zero_extendhidi2"
-+ [(set (match_operand:DI 0 "register_operand" "=r")
-+ (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
-+ ""
-+ "#"
-+ "reload_completed"
-+ [(set (match_dup 2)
-+ (zero_extend:SI (match_dup 1)))
-+ (set (match_dup 3)
-+ (const_int 0))]
-+ "{
-+ operands[2] = gen_lowpart (SImode, operands[0]);
-+ operands[3] = gen_highpart (SImode, operands[0]);
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_insn_and_split "zero_extendsidi2"
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
-+ (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
-+ ""
-+ "#"
-+ "reload_completed"
-+ [(set (match_dup 2)
-+ (match_dup 1))
-+ (set (match_dup 3)
-+ (const_int 0))]
-+ "{
-+ operands[2] = gen_lowpart (SImode, operands[0]);
-+ operands[3] = gen_highpart (SImode, operands[0]);
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_insn "extendqihi2"
-+ [(set (match_operand:HI 0 "register_operand" "=r")
-+ (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "rm")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "ext.1\\t%0, %1")
-+
-+(define_insn "extendqisi2"
-+ [(set (match_operand:SI 0 "register_operand" "=r")
-+ (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "rm")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "ext.1\\t%0, %1")
-+
-+(define_insn "extendhisi2"
-+ [(set (match_operand:SI 0 "register_operand" "=r")
-+ (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "ext.2\\t%0, %1")
-+
-+(define_insn_and_split "extendsidi2"
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "=d")
-+ (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "#"
-+ "reload_completed"
-+ [(set (match_dup 2)
-+ (match_dup 1))
-+ (parallel
-+ [(set (match_dup 3)
-+ (ashiftrt:SI (match_dup 2)
-+ (const_int 31)))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "{
-+ operands[2] = gen_lowpart (SImode, operands[0]);
-+ operands[3] = gen_highpart (SImode, operands[0]);
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_insn "bswaphi"
-+ [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
-+ (bswap:HI (match_operand:HI 1 "ubicom32_arith_operand" "rmI")))]
-+ "(ubicom32_v4)"
-+ "swapb.2\\t%0, %1");
-+
-+(define_insn "bswaphisi"
-+ [(set (match_operand:SI 0 "register_operand" "=r")
-+ (zero_extend:SI
-+ (bswap:HI (match_operand:HI 1 "ubicom32_arith_operand" "rmI"))))]
-+ "(ubicom32_v4)"
-+ "swapb.2\\t%0, %1");
-+
-+(define_insn "bswapsi"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (bswap:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")))]
-+ "(ubicom32_v4)"
-+ "swapb.4\\t%0, %1");
-+
-+(define_insn "tstqi_ext1"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:QI 0 "nonimmediate_operand" "rm")
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "ext.1\\t#0, %0")
-+
-+(define_expand "cmpqi"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:QI 0 "ubicom32_arith_operand" "")
-+ (match_operand:QI 1 "ubicom32_data_register_operand" "")))]
-+ "(ubicom32_v4)"
-+ "{
-+ ubicom32_compare_op0 = operands[0];
-+ ubicom32_compare_op1 = operands[1];
-+ DONE;
-+ }")
-+
-+(define_insn "sub1_ccs"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:QI 0 "ubicom32_arith_operand" "rmI")
-+ (match_operand:QI 1 "ubicom32_data_register_operand" "d")))]
-+ "(ubicom32_v4)"
-+ "sub.1\\t#0, %0, %1")
-+
-+; If we're testing for equality we don't have to worry about reversing conditions.
-+;
-+(define_insn "sub1_ccsz_1"
-+ [(set (reg:CCSZ CC_REGNO)
-+ (compare:CCSZ (match_operand:QI 0 "nonimmediate_operand" "rm")
-+ (match_operand:QI 1 "ubicom32_data_register_operand" "d")))]
-+ "(ubicom32_v4)"
-+ "sub.1\\t#0, %0, %1")
-+
-+(define_insn "sub1_ccsz_2"
-+ [(set (reg:CCSZ CC_REGNO)
-+ (compare:CCSZ (match_operand:QI 0 "ubicom32_data_register_operand" "d")
-+ (match_operand:QI 1 "ubicom32_arith_operand" "rmI")))]
-+ "(ubicom32_v4)"
-+ "sub.1\\t#0, %1, %0")
-+
-+; When the combiner runs it doesn't have any insight into whether or not an argument
-+; to a compare is spilled to the stack and therefore can't swap the comparison in
-+; an attempt to use sub.1 more effectively. We peephole this case here.
-+;
-+(define_peephole2
-+ [(set (match_operand:QI 0 "register_operand" "")
-+ (match_operand:QI 1 "ubicom32_arith_operand" ""))
-+ (set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (compare (match_operand:QI 3 "ubicom32_data_register_operand" "")
-+ (match_dup 0)))
-+ (set (pc)
-+ (if_then_else (match_operator 4 "comparison_operator"
-+ [(match_dup 2)
-+ (const_int 0)])
-+ (label_ref (match_operand 5 "" ""))
-+ (pc)))]
-+ "(peep2_reg_dead_p (2, operands[0])
-+ && peep2_regno_dead_p (3, CC_REGNO))"
-+ [(set (match_dup 2)
-+ (compare (match_dup 1)
-+ (match_dup 3)))
-+ (set (pc)
-+ (if_then_else (match_op_dup 6
-+ [(match_dup 2)
-+ (const_int 0)])
-+ (label_ref (match_dup 5))
-+ (pc)))]
-+ "{
-+ rtx cc_reg;
-+
-+ cc_reg = gen_rtx_REG (GET_MODE (operands[2]), CC_REGNO);
-+ operands[6] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[4])),
-+ GET_MODE (operands[4]),
-+ cc_reg,
-+ const0_rtx);
-+ }")
-+
-+(define_insn "tsthi_ext2"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:HI 0 "nonimmediate_operand" "rm")
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "ext.2\\t#0, %0")
-+
-+(define_expand "cmphi"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:HI 0 "ubicom32_arith_operand" "")
-+ (match_operand:HI 1 "ubicom32_compare_operand" "")))]
-+ ""
-+ "{
-+ do
-+ {
-+ /* Is this a cmpi? */
-+ if (CONST_INT_P (operands[1]))
-+ break;
-+
-+ /* Must be a sub.2 - if necessary copy an operand into a reg. */
-+ if (! ubicom32_data_register_operand (operands[1], HImode))
-+ operands[1] = copy_to_mode_reg (HImode, operands[1]);
-+ }
-+ while (0);
-+
-+ ubicom32_compare_op0 = operands[0];
-+ ubicom32_compare_op1 = operands[1];
-+ DONE;
-+ }")
-+
-+(define_insn "cmpi"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:HI 0 "nonimmediate_operand" "rm")
-+ (match_operand 1 "const_int_operand" "N")))]
-+ ""
-+ "cmpi\\t%0, %1")
-+
-+(define_insn "sub2_ccs"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:HI 0 "ubicom32_arith_operand" "rmI")
-+ (match_operand:HI 1 "ubicom32_data_register_operand" "d")))]
-+ ""
-+ "sub.2\\t#0, %0, %1")
-+
-+; If we're testing for equality we don't have to worry about reversing conditions.
-+;
-+(define_insn "sub2_ccsz_1"
-+ [(set (reg:CCSZ CC_REGNO)
-+ (compare:CCSZ (match_operand:HI 0 "nonimmediate_operand" "rm")
-+ (match_operand:HI 1 "ubicom32_data_register_operand" "d")))]
-+ ""
-+ "sub.2\\t#0, %0, %1")
-+
-+(define_insn "sub2_ccsz_2"
-+ [(set (reg:CCSZ CC_REGNO)
-+ (compare:CCSZ (match_operand:HI 0 "ubicom32_data_register_operand" "d")
-+ (match_operand:HI 1 "ubicom32_arith_operand" "rmI")))]
-+ ""
-+ "sub.2\\t#0, %1, %0")
-+
-+; When the combiner runs it doesn't have any insight into whether or not an argument
-+; to a compare is spilled to the stack and therefore can't swap the comparison in
-+; an attempt to use sub.2 more effectively. We peephole this case here.
-+;
-+(define_peephole2
-+ [(set (match_operand:HI 0 "register_operand" "")
-+ (match_operand:HI 1 "ubicom32_arith_operand" ""))
-+ (set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (compare (match_operand:HI 3 "ubicom32_data_register_operand" "")
-+ (match_dup 0)))
-+ (set (pc)
-+ (if_then_else (match_operator 4 "comparison_operator"
-+ [(match_dup 2)
-+ (const_int 0)])
-+ (label_ref (match_operand 5 "" ""))
-+ (pc)))]
-+ "(peep2_reg_dead_p (2, operands[0])
-+ && peep2_regno_dead_p (3, CC_REGNO))"
-+ [(set (match_dup 2)
-+ (compare (match_dup 1)
-+ (match_dup 3)))
-+ (set (pc)
-+ (if_then_else (match_op_dup 6
-+ [(match_dup 2)
-+ (const_int 0)])
-+ (label_ref (match_dup 5))
-+ (pc)))]
-+ "{
-+ rtx cc_reg;
-+
-+ cc_reg = gen_rtx_REG (GET_MODE (operands[2]), CC_REGNO);
-+ operands[6] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[4])),
-+ GET_MODE (operands[4]),
-+ cc_reg,
-+ const0_rtx);
-+ }")
-+
-+(define_insn_and_split "tstsi_lsl4"
-+ [(set (match_operand 0 "ubicom32_cc_register_operand" "=r")
-+ (match_operator 1 "ubicom32_compare_operator"
-+ [(match_operand:SI 2 "nonimmediate_operand" "rm")
-+ (const_int 0)]))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "#"
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ [(parallel
-+ [(set (match_dup 0)
-+ (match_op_dup 1
-+ [(match_dup 2)
-+ (const_int 0)]))
-+ (clobber (match_dup 3))])]
-+ "{
-+ operands[3] = gen_reg_rtx (SImode);
-+ }")
-+
-+(define_insn "tstsi_lsl4_d"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:SI 0 "nonimmediate_operand" "rm")
-+ (const_int 0)))
-+ (clobber (match_operand:SI 1 "ubicom32_data_register_operand" "=d"))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "lsl.4\\t%1, %0, #0")
-+
-+; Comparison for equality with -1.
-+;
-+(define_insn "cmpsi_not4_ccwz"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:SI 0 "nonimmediate_operand" "rm")
-+ (const_int -1)))]
-+ "ubicom32_match_cc_mode(insn, CCWZmode)"
-+ "not.4\\t#0, %0")
-+
-+(define_expand "cmpsi"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:SI 0 "ubicom32_arith_operand" "")
-+ (match_operand:SI 1 "ubicom32_compare_operand" "")))]
-+ ""
-+ "{
-+ do
-+ {
-+ /* Is this a cmpi? We can't take a memory address as cmpi takes
-+ 16-bit operands. */
-+ if (register_operand (operands[0], SImode)
-+ && CONST_INT_P (operands[1])
-+ && satisfies_constraint_N (operands[1]))
-+ break;
-+
-+ /* Must be a sub.4 - if necessary copy an operand into a reg. */
-+ if (! ubicom32_data_register_operand (operands[1], SImode))
-+ operands[1] = copy_to_mode_reg (SImode, operands[1]);
-+ }
-+ while (0);
-+
-+ ubicom32_compare_op0 = operands[0];
-+ ubicom32_compare_op1 = operands[1];
-+ DONE;
-+ }")
-+
-+(define_insn "cmpsi_cmpi"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:SI 0 "register_operand" "r")
-+ (match_operand 1 "const_int_operand" "N")))]
-+ "(satisfies_constraint_N (operands[1]))"
-+ "cmpi\\t%0, %1")
-+
-+(define_insn "cmpsi_sub4"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:SI 0 "ubicom32_arith_operand" "rmI")
-+ (match_operand:SI 1 "ubicom32_data_register_operand" "d")))]
-+ ""
-+ "sub.4\\t#0, %0, %1")
-+
-+; If we're testing for equality we don't have to worry about reversing conditions.
-+;
-+(define_insn "cmpsi_sub4_ccwz_1"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:SI 0 "nonimmediate_operand" "rm")
-+ (match_operand:SI 1 "ubicom32_data_register_operand" "d")))]
-+ "ubicom32_match_cc_mode(insn, CCWZmode)"
-+ "sub.4\\t#0, %0, %1")
-+
-+(define_insn "cmpsi_sub4_ccwz_2"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:SI 0 "ubicom32_data_register_operand" "d")
-+ (match_operand:SI 1 "nonimmediate_operand" "rm")))]
-+ "ubicom32_match_cc_mode(insn, CCWZmode)"
-+ "sub.4\\t#0, %1, %0")
-+
-+; When the combiner runs it doesn't have any insight into whether or not an argument
-+; to a compare is spilled to the stack and therefore can't swap the comparison in
-+; an attempt to use sub.4 more effectively. We peephole this case here.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "ubicom32_arith_operand" ""))
-+ (set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (compare (match_operand:SI 3 "ubicom32_data_register_operand" "")
-+ (match_dup 0)))
-+ (set (pc)
-+ (if_then_else (match_operator 4 "comparison_operator"
-+ [(match_dup 2)
-+ (const_int 0)])
-+ (label_ref (match_operand 5 "" ""))
-+ (pc)))]
-+ "(peep2_reg_dead_p (2, operands[0])
-+ && peep2_regno_dead_p (3, CC_REGNO))"
-+ [(set (match_dup 2)
-+ (compare (match_dup 1)
-+ (match_dup 3)))
-+ (set (pc)
-+ (if_then_else (match_op_dup 6
-+ [(match_dup 2)
-+ (const_int 0)])
-+ (label_ref (match_dup 5))
-+ (pc)))]
-+ "{
-+ rtx cc_reg;
-+
-+ cc_reg = gen_rtx_REG (GET_MODE (operands[2]), CC_REGNO);
-+ operands[6] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[4])),
-+ GET_MODE (operands[4]),
-+ cc_reg,
-+ const0_rtx);
-+ }")
-+
-+(define_insn_and_split "tstdi_or4"
-+ [(set (reg:CCWZ CC_REGNO)
-+ (compare:CCWZ (match_operand:DI 0 "nonimmediate_operand" "rm")
-+ (const_int 0)))]
-+ ""
-+ "#"
-+ ""
-+ [(parallel
-+ [(set (reg:CCWZ CC_REGNO)
-+ (compare:CCWZ (match_dup 0)
-+ (const_int 0)))
-+ (clobber (match_dup 1))])]
-+ "{
-+ operands[1] = gen_reg_rtx (SImode);
-+ }")
-+
-+(define_insn "tstdi_or4_d"
-+ [(set (reg:CCWZ CC_REGNO)
-+ (compare:CCWZ (match_operand:DI 0 "nonimmediate_operand" "rm")
-+ (const_int 0)))
-+ (clobber (match_operand:SI 1 "ubicom32_data_register_operand" "=d"))]
-+ ""
-+ "*
-+ {
-+ operands[2] = gen_lowpart (SImode, operands[0]);
-+ operands[3] = gen_highpart_mode (SImode, DImode, operands[0]);
-+
-+ if (ubicom32_data_register_operand (operands[0], GET_MODE (operands[0])))
-+ return \"or.4\\t#0, %2, %3\";
-+
-+ return \"move.4\\t%1, %2\;or.4\\t%1, %3, %1\";
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_expand "cmpdi"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:DI 0 "ubicom32_arith_operand" "")
-+ (match_operand:DI 1 "ubicom32_data_register_operand" "")))]
-+ ""
-+ "{
-+ ubicom32_compare_op0 = operands[0];
-+ ubicom32_compare_op1 = operands[1];
-+ DONE;
-+ }")
-+
-+(define_insn "cmpdi_sub4subc"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:DI 0 "ubicom32_arith_operand" "rmI")
-+ (match_operand:DI 1 "ubicom32_data_register_operand" "d")))]
-+ ""
-+ "*
-+ {
-+ operands[2] = gen_lowpart (SImode, operands[0]);
-+ operands[3] = gen_lowpart (SImode, operands[1]);
-+ operands[4] = gen_highpart_mode (SImode, DImode, operands[0]);
-+ operands[5] = gen_highpart_mode (SImode, DImode, operands[1]);
-+
-+ return \"sub.4\\t#0, %2, %3\;subc\\t#0, %4, %5\";
-+ }"
-+ [(set_attr "length" "8")])
-+
-+; When the combiner runs it doesn't have any insight into whether or not an argument
-+; to a compare is spilled to the stack and therefore can't swap the comparison in
-+; an attempt to use sub.4/subc more effectively. We peephole this case here.
-+;
-+(define_peephole2
-+ [(set (match_operand:DI 0 "register_operand" "")
-+ (match_operand:DI 1 "ubicom32_arith_operand" ""))
-+ (set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (compare (match_operand:DI 3 "ubicom32_data_register_operand" "")
-+ (match_dup 0)))
-+ (set (pc)
-+ (if_then_else (match_operator 4 "comparison_operator"
-+ [(match_dup 2)
-+ (const_int 0)])
-+ (label_ref (match_operand 5 "" ""))
-+ (pc)))]
-+ "(peep2_reg_dead_p (2, operands[0])
-+ && peep2_regno_dead_p (3, CC_REGNO))"
-+ [(set (match_dup 2)
-+ (compare (match_dup 1)
-+ (match_dup 3)))
-+ (set (pc)
-+ (if_then_else (match_op_dup 6
-+ [(match_dup 2)
-+ (const_int 0)])
-+ (label_ref (match_dup 5))
-+ (pc)))]
-+ "{
-+ rtx cc_reg;
-+
-+ cc_reg = gen_rtx_REG (GET_MODE (operands[2]), CC_REGNO);
-+ operands[6] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[4])),
-+ GET_MODE (operands[4]),
-+ cc_reg,
-+ const0_rtx);
-+ }")
-+
-+(define_insn "btst"
-+ [(set (reg:CCWZ CC_REGNO)
-+ (compare:CCWZ
-+ (zero_extract:SI
-+ (match_operand:SI 0 "nonimmediate_operand" "rm")
-+ (const_int 1)
-+ (match_operand:SI 1 "ubicom32_arith_operand" "dM"))
-+ (const_int 0)))]
-+ ""
-+ "btst\\t%0, %1")
-+
-+(define_insn "bfextu_ccwz_null"
-+ [(set (reg:CCWZ CC_REGNO)
-+ (compare:CCWZ
-+ (zero_extract:SI
-+ (match_operand:SI 0 "nonimmediate_operand" "rm")
-+ (match_operand 1 "const_int_operand" "M")
-+ (const_int 0))
-+ (const_int 0)))
-+ (clobber (match_scratch:SI 2 "=d"))]
-+ ""
-+ "bfextu\\t%2, %0, %1")
-+
-+(define_expand "addqi3"
-+ [(parallel
-+ [(set (match_operand:QI 0 "memory_operand" "")
-+ (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
-+ (match_operand:QI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "(ubicom32_v4)"
-+ "{
-+ if (!memory_operand (operands[0], QImode))
-+ FAIL;
-+
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (QImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (QImode, operands[2]);
-+ }")
-+
-+(define_insn "addqi3_add1"
-+ [(set (match_operand:QI 0 "memory_operand" "=m, m")
-+ (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:QI 2 "ubicom32_arith_operand" "rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4)"
-+ "@
-+ add.1\\t%0, %2, %1
-+ add.1\\t%0, %1, %2")
-+
-+(define_insn "addqi3_add1_ccszn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (neg:QI (match_operand:QI 0 "nonimmediate_operand" "%d,rm"))
-+ (match_operand:QI 1 "ubicom32_arith_operand" "rmI, d")))]
-+ "(ubicom32_v4
-+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
-+ "@
-+ add.1\\t#0, %1, %0
-+ add.1\\t#0, %0, %1")
-+
-+(define_expand "addhi3"
-+ [(parallel
-+ [(set (match_operand:HI 0 "memory_operand" "")
-+ (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
-+ (match_operand:HI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ ""
-+ "{
-+ if (!memory_operand (operands[0], HImode))
-+ FAIL;
-+
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (HImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (HImode, operands[2]);
-+ }")
-+
-+(define_insn "addhi3_add2"
-+ [(set (match_operand:HI 0 "memory_operand" "=m, m")
-+ (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:HI 2 "ubicom32_arith_operand" "rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "@
-+ add.2\\t%0, %2, %1
-+ add.2\\t%0, %1, %2")
-+
-+(define_insn "addhi3_add2_ccszn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (neg:HI (match_operand:HI 0 "nonimmediate_operand" "%d,rm"))
-+ (match_operand:HI 1 "ubicom32_arith_operand" "rmI, d")))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "@
-+ add.2\\t#0, %1, %0
-+ add.2\\t#0, %0, %1")
-+
-+(define_expand "addsi3"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
-+ (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
-+ (match_operand:SI 2 "ubicom32_move_operand" "")))]
-+ ""
-+ "{
-+ ubicom32_expand_addsi3 (operands);
-+ DONE;
-+ }")
-+
-+; We start with an instruction pattern that can do all sorts of interesting
-+; things but we split out any uses of lea or pdec instructions because
-+; those instructions don't clobber the condition codes.
-+;
-+(define_insn_and_split "addsi3_1"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm,rm,rm,rm, rm,rm")
-+ (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%a, a, a, a, a, d,rm")
-+ (match_operand:SI 2 "ubicom32_move_operand" "L, K, J, P, d,rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "@
-+ #
-+ #
-+ #
-+ #
-+ #
-+ add.4\\t%0, %2, %1
-+ add.4\\t%0, %1, %2"
-+ "(reload_completed
-+ && ubicom32_address_register_operand (operands[1], GET_MODE (operands[1])))"
-+ [(set (match_dup 0)
-+ (plus:SI (match_dup 1)
-+ (match_dup 2)))]
-+ ""
-+)
-+
-+(define_insn "addsi3_1_ccwzn"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
-+ (plus:SI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "@
-+ add.4\\t%0, %2, %1
-+ add.4\\t%0, %1, %2")
-+
-+(define_insn "addsi3_1_ccwzn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (neg:SI (match_operand:SI 0 "nonimmediate_operand" "%d,rm"))
-+ (match_operand:SI 1 "ubicom32_arith_operand" "rmI, d")))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "@
-+ add.4\\t#0, %1, %0
-+ add.4\\t#0, %0, %1")
-+
-+(define_insn_and_split "addsi3_2"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm,rm,rm,rm,rm")
-+ (plus:SI (match_operand:SI 1 "ubicom32_address_register_operand" "%a, a, a, a, a, a")
-+ (match_operand:SI 2 "ubicom32_move_operand" "L, K, J, P, d, n")))]
-+ ""
-+ "@
-+ lea.4\\t%0, %E2(%1)
-+ lea.2\\t%0, %E2(%1)
-+ lea.1\\t%0, %E2(%1)
-+ pdec\\t%0, %n2(%1)
-+ lea.1\\t%0, (%1,%2)
-+ #"
-+ "(reload_completed
-+ && ! satisfies_constraint_L (operands[2])
-+ && ! satisfies_constraint_K (operands[2])
-+ && ! satisfies_constraint_J (operands[2])
-+ && ! satisfies_constraint_P (operands[2])
-+ && ! ubicom32_data_register_operand (operands[2], GET_MODE (operands[2])))"
-+ [(set (reg:SI AUX_DATA_REGNO)
-+ (match_dup 2))
-+ (set (match_dup 0)
-+ (plus:SI (match_dup 1)
-+ (reg:SI AUX_DATA_REGNO)))]
-+ ""
-+)
-+
-+(define_insn "lea_2"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (plus:SI (mult:SI (match_operand:SI 1 "ubicom32_data_register_operand" "d")
-+ (const_int 2))
-+ (match_operand:SI 2 "ubicom32_address_register_operand" "a")))]
-+ ""
-+ "lea.2\\t%0, (%2,%1)")
-+
-+(define_insn "lea_4"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (plus:SI (mult:SI (match_operand:SI 1 "ubicom32_data_register_operand" "d")
-+ (const_int 4))
-+ (match_operand:SI 2 "ubicom32_address_register_operand" "a")))]
-+ ""
-+ "lea.4\\t%0, (%2,%1)")
-+
-+(define_expand "adddi3"
-+ [(parallel
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "")
-+ (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
-+ (match_operand:DI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ ""
-+ "{
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (DImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (DImode, operands[2]);
-+ }")
-+
-+; We construct a 64-bit add from 32-bit operations. Note that we use the
-+; & constraint to prevent overlapping registers being allocated. We do
-+; allow identical registers though as that won't break anything.
-+;
-+(define_insn "adddi3_add4addc"
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,&r,rm, d, m, m")
-+ (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%d,rm, 0, 0, d,rm")
-+ (match_operand:DI 2 "ubicom32_arith_operand" "rmI, d, d,rmI,rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "*
-+ {
-+ operands[3] = gen_lowpart (SImode, operands[0]);
-+ operands[4] = gen_lowpart (SImode, operands[1]);
-+ operands[5] = gen_lowpart (SImode, operands[2]);
-+ operands[6] = gen_highpart (SImode, operands[0]);
-+ operands[7] = gen_highpart (SImode, operands[1]);
-+ operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
-+
-+ if (ubicom32_data_register_operand (operands[2], GET_MODE (operands[2])))
-+ return \"add.4\\t%3, %4, %5\;addc\\t%6, %7, %8\";
-+
-+ return \"add.4\\t%3, %5, %4\;addc\\t%6, %8, %7\";
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_insn "adddi3_ccwz"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%d,rm, 0, 0, d,rm")
-+ (match_operand:DI 2 "ubicom32_arith_operand" "rmI, d, d,rmI,rmI, d"))
-+ (const_int 0)))
-+ (set (match_operand:DI 0 "nonimmediate_operand" "=&r,&r,rm, d, m, m")
-+ (plus:DI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "*
-+ {
-+ operands[3] = gen_lowpart (SImode, operands[0]);
-+ operands[6] = gen_highpart (SImode, operands[0]);
-+
-+ if (ubicom32_data_register_operand (operands[1], GET_MODE (operands[1])))
-+ {
-+ operands[4] = gen_lowpart (SImode, operands[1]);
-+ operands[5] = gen_lowpart (SImode, operands[2]);
-+ operands[7] = gen_highpart (SImode, operands[1]);
-+ operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
-+ }
-+ else
-+ {
-+ operands[4] = gen_lowpart (SImode, operands[2]);
-+ operands[5] = gen_lowpart (SImode, operands[1]);
-+ operands[7] = gen_highpart (SImode, operands[2]);
-+ operands[8] = gen_highpart (SImode, operands[1]);
-+ }
-+
-+ return \"add.4\\t%3, %5, %4\;addc\\t%6, %8, %7\";
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_insn "adddi3_ccwz_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (neg:DI (match_operand:DI 0 "nonimmediate_operand" "%d,rm"))
-+ (match_operand:DI 1 "ubicom32_arith_operand" "rmI, d")))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "*
-+ {
-+ if (ubicom32_data_register_operand (operands[0], GET_MODE (operands[0])))
-+ {
-+ operands[2] = gen_lowpart (SImode, operands[0]);
-+ operands[3] = gen_lowpart (SImode, operands[1]);
-+ operands[4] = gen_highpart (SImode, operands[0]);
-+ operands[5] = gen_highpart_mode (SImode, DImode, operands[1]);
-+ }
-+ else
-+ {
-+ operands[2] = gen_lowpart (SImode, operands[1]);
-+ operands[3] = gen_lowpart (SImode, operands[0]);
-+ operands[4] = gen_highpart (SImode, operands[1]);
-+ operands[5] = gen_highpart (SImode, operands[0]);
-+ }
-+
-+ return \"add.4\\t#0, %3, %2\;addc\\t#0, %5, %4\";
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_expand "subqi3"
-+ [(parallel
-+ [(set (match_operand:QI 0 "memory_operand" "")
-+ (minus:QI (match_operand:QI 1 "ubicom32_arith_operand" "")
-+ (match_operand:QI 2 "ubicom32_data_register_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "(ubicom32_v4)"
-+ "{
-+ if (!memory_operand (operands[0], QImode))
-+ FAIL;
-+ }")
-+
-+(define_insn "subqi3_sub1"
-+ [(set (match_operand:QI 0 "memory_operand" "=m")
-+ (minus:QI (match_operand:QI 1 "ubicom32_arith_operand" "rmI")
-+ (match_operand:QI 2 "ubicom32_data_register_operand" "d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4)"
-+ "sub.1\\t%0, %1, %2")
-+
-+(define_expand "subhi3"
-+ [(parallel
-+ [(set (match_operand:HI 0 "memory_operand" "")
-+ (minus:HI (match_operand:HI 1 "ubicom32_arith_operand" "")
-+ (match_operand:HI 2 "ubicom32_data_register_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "(ubicom32_v4)"
-+ "{
-+ if (!memory_operand (operands[0], HImode))
-+ FAIL;
-+ }")
-+
-+(define_insn "subhi3_sub2"
-+ [(set (match_operand:HI 0 "memory_operand" "=m")
-+ (minus:HI (match_operand:HI 1 "ubicom32_arith_operand" "rmI")
-+ (match_operand:HI 2 "ubicom32_data_register_operand" "d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "sub.2\\t%0, %1, %2")
-+
-+(define_insn "subsi3"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (minus:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")
-+ (match_operand:SI 2 "ubicom32_data_register_operand" "d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "sub.4\\t%0, %1, %2")
-+
-+(define_insn "subsi3_ccwz"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (minus:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")
-+ (match_operand:SI 2 "ubicom32_data_register_operand" "d"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (minus:SI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "sub.4\\t%0, %1, %2")
-+
-+; We construct a 64-bit add from 32-bit operations. Note that we use the
-+; & constraint to prevent overlapping registers being allocated. We do
-+; allow identical registers though as that won't break anything.
-+;
-+(define_insn "subdi3"
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,r, d, m")
-+ (minus:DI (match_operand:DI 1 "ubicom32_arith_operand" "rmI,0,rmI,rmI")
-+ (match_operand:DI 2 "ubicom32_data_register_operand" "d,d, 0, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "*
-+ {
-+ operands[3] = gen_lowpart (SImode, operands[0]);
-+ operands[4] = gen_lowpart (SImode, operands[1]);
-+ operands[5] = gen_lowpart (SImode, operands[2]);
-+ operands[6] = gen_highpart (SImode, operands[0]);
-+ operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
-+ operands[8] = gen_highpart (SImode, operands[2]);
-+
-+ return \"sub.4\\t%3, %4, %5\;subc\\t%6, %7, %8\";
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_insn "subdi3_ccwz"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (minus:DI (match_operand:DI 1 "ubicom32_arith_operand" "rmI,rmI")
-+ (match_operand:DI 2 "ubicom32_data_register_operand" "d, d"))
-+ (const_int 0)))
-+ (set (match_operand:DI 0 "nonimmediate_operand" "=&r, m")
-+ (minus:DI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "*
-+ {
-+ operands[3] = gen_lowpart (SImode, operands[0]);
-+ operands[4] = gen_lowpart (SImode, operands[1]);
-+ operands[5] = gen_lowpart (SImode, operands[2]);
-+ operands[6] = gen_highpart (SImode, operands[0]);
-+ operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
-+ operands[8] = gen_highpart (SImode, operands[2]);
-+
-+ return \"sub.4\\t%3, %4, %5\;subc\\t%6, %7, %8\";
-+ }"
-+ [(set_attr "length" "8")])
-+
-+;(define_insn "negqi2"
-+; [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
-+; (neg:QI (match_operand:QI 1 "ubicom32_data_register_operand" "d")))
-+; (clobber (reg:CC CC_REGNO))]
-+; "(ubicom32_v4)"
-+; "sub.1\\t%0, #0, %1")
-+
-+;(define_insn "neghi2"
-+; [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
-+; (neg:HI (match_operand:HI 1 "ubicom32_data_register_operand" "d")))
-+; (clobber (reg:CC CC_REGNO))]
-+; ""
-+; "sub.2\\t%0, #0, %1")
-+
-+(define_insn "negsi2"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (neg:SI (match_operand:SI 1 "ubicom32_data_register_operand" "d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "sub.4\\t%0, #0, %1")
-+
-+(define_insn_and_split "negdi2"
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "=&rm")
-+ (neg:DI (match_operand:DI 1 "ubicom32_data_register_operand" "d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "#"
-+ "reload_completed"
-+ [(parallel [(set (match_dup 0)
-+ (minus:DI (const_int 0)
-+ (match_dup 1)))
-+ (clobber (reg:CC CC_REGNO))])]
-+ ""
-+ [(set_attr "length" "8")])
-+
-+(define_insn "umulhisi3"
-+ [(set (match_operand:SI 0 "ubicom32_acc_lo_register_operand" "=l, l")
-+ (mult:SI
-+ (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "%d,rm"))
-+ (zero_extend:SI (match_operand:HI 2 "nonimmediate_operand" "rm, d"))))
-+ (clobber (reg:HI ACC0_HI_REGNO))
-+ (clobber (reg:HI ACC1_HI_REGNO))]
-+ ""
-+ "@
-+ mulu\\t%A0, %2, %1
-+ mulu\\t%A0, %1, %2"
-+ [(set_attr "type" "mul,mul")])
-+
-+(define_insn "mulhisi3"
-+ [(set (match_operand:SI 0 "ubicom32_acc_lo_register_operand" "=l, l")
-+ (mult:SI
-+ (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "%d,rm"))
-+ (sign_extend:SI (match_operand:HI 2 "nonimmediate_operand" "rm, d"))))
-+ (clobber (reg:HI ACC0_HI_REGNO))
-+ (clobber (reg:HI ACC1_HI_REGNO))]
-+ ""
-+ "@
-+ muls\\t%A0, %2, %1
-+ muls\\t%A0, %1, %2"
-+ [(set_attr "type" "mul,mul")])
-+
-+(define_expand "mulsi3"
-+ [(set (match_operand:SI 0 "ubicom32_acc_hi_register_operand" "")
-+ (mult:SI (match_operand:SI 1 "ubicom32_arith_operand" "")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "")))]
-+ ""
-+ "{
-+ if (ubicom32_emit_mult_sequence (operands))
-+ DONE;
-+ }")
-+
-+(define_insn "umulsidi3"
-+ [(set (match_operand:DI 0 "ubicom32_acc_hi_register_operand" "=h, h")
-+ (mult:DI
-+ (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%d,rm"))
-+ (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm, d"))))]
-+ "(ubicom32_v4)"
-+ "@
-+ mulu.4\\t%A0, %2, %1
-+ mulu.4\\t%A0, %1, %2"
-+ [(set_attr "type" "mul,mul")])
-+
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "nonimmediate_operand" ""))
-+ (set (match_operand:DI 2 "ubicom32_acc_hi_register_operand" "")
-+ (mult:DI
-+ (zero_extend:DI (match_dup 0))
-+ (zero_extend:DI (match_operand:SI 3 "ubicom32_data_register_operand" ""))))]
-+ "(peep2_reg_dead_p (2, operands[0])
-+ || REGNO (operands[0]) == REGNO (operands[2])
-+ || REGNO (operands[0]) == REGNO (operands[2]) + 1)
-+ && ! rtx_equal_p (operands[0], operands[3])"
-+ [(set (match_dup 2)
-+ (mult:DI
-+ (zero_extend:DI (match_dup 1))
-+ (zero_extend:DI (match_dup 3))))]
-+ "")
-+
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "nonimmediate_operand" ""))
-+ (set (match_operand:DI 2 "ubicom32_acc_hi_register_operand" "")
-+ (mult:DI
-+ (zero_extend:DI (match_operand:SI 3 "ubicom32_data_register_operand" ""))
-+ (zero_extend:DI (match_dup 0))))]
-+ "(peep2_reg_dead_p (2, operands[0])
-+ || REGNO (operands[0]) == REGNO (operands[2])
-+ || REGNO (operands[0]) == REGNO (operands[2]) + 1)
-+ && ! rtx_equal_p (operands[0], operands[3])"
-+ [(set (match_dup 2)
-+ (mult:DI
-+ (zero_extend:DI (match_dup 1))
-+ (zero_extend:DI (match_dup 3))))]
-+ "")
-+
-+(define_insn "umulsidi3_const"
-+ [(set (match_operand:DI 0 "ubicom32_acc_hi_register_operand" "=h")
-+ (mult:DI
-+ (zero_extend:DI (match_operand:SI 1 "ubicom32_data_register_operand" "%d"))
-+ (match_operand 2 "const_int_operand" "I")))]
-+ "(ubicom32_v4 && satisfies_constraint_I (operands[2]))"
-+ "mulu.4\\t%A0, %2, %1"
-+ [(set_attr "type" "mul")])
-+
-+(define_insn "mulsidi3"
-+ [(set (match_operand:DI 0 "ubicom32_acc_hi_register_operand" "=h, h")
-+ (mult:DI
-+ (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%d,rm"))
-+ (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm, d"))))]
-+ "(ubicom32_v4)"
-+ "@
-+ muls.4\\t%A0, %2, %1
-+ muls.4\\t%A0, %1, %2"
-+ [(set_attr "type" "mul,mul")])
-+
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "nonimmediate_operand" ""))
-+ (set (match_operand:DI 2 "ubicom32_acc_hi_register_operand" "")
-+ (mult:DI
-+ (sign_extend:DI (match_dup 0))
-+ (sign_extend:DI (match_operand:SI 3 "ubicom32_data_register_operand" ""))))]
-+ "(peep2_reg_dead_p (2, operands[0])
-+ || REGNO (operands[0]) == REGNO (operands[2])
-+ || REGNO (operands[0]) == REGNO (operands[2]) + 1)
-+ && ! rtx_equal_p (operands[0], operands[3])"
-+ [(set (match_dup 2)
-+ (mult:DI
-+ (sign_extend:DI (match_dup 1))
-+ (sign_extend:DI (match_dup 3))))]
-+ "")
-+
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "nonimmediate_operand" ""))
-+ (set (match_operand:DI 2 "ubicom32_acc_hi_register_operand" "")
-+ (mult:DI
-+ (sign_extend:DI (match_operand:SI 3 "ubicom32_data_register_operand" ""))
-+ (sign_extend:DI (match_dup 0))))]
-+ "(peep2_reg_dead_p (2, operands[0])
-+ || REGNO (operands[0]) == REGNO (operands[2])
-+ || REGNO (operands[0]) == REGNO (operands[2]) + 1)
-+ && ! rtx_equal_p (operands[0], operands[3])"
-+ [(set (match_dup 2)
-+ (mult:DI
-+ (sign_extend:DI (match_dup 1))
-+ (sign_extend:DI (match_dup 3))))]
-+ "")
-+
-+(define_insn "mulsidi3_const"
-+ [(set (match_operand:DI 0 "ubicom32_acc_hi_register_operand" "=h")
-+ (mult:DI
-+ (sign_extend:DI (match_operand:SI 1 "ubicom32_data_register_operand" "%d"))
-+ (match_operand 2 "const_int_operand" "I")))]
-+ "(ubicom32_v4 && satisfies_constraint_I (operands[2]))"
-+ "muls.4\\t%A0, %2, %1"
-+ [(set_attr "type" "mul")])
-+
-+(define_expand "andqi3"
-+ [(parallel
-+ [(set (match_operand:QI 0 "memory_operand" "")
-+ (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
-+ (match_operand:QI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "(ubicom32_v4)"
-+ "{
-+ if (!memory_operand (operands[0], QImode))
-+ FAIL;
-+
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (QImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (QImode, operands[2]);
-+ }")
-+
-+(define_insn "andqi3_and1"
-+ [(set (match_operand:QI 0 "memory_operand" "=m, m")
-+ (and:QI (match_operand:QI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:QI 2 "ubicom32_arith_operand" "rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4)"
-+ "@
-+ and.1\\t%0, %2, %1
-+ and.1\\t%0, %1, %2")
-+
-+(define_insn "andqi3_and1_ccszn"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (and:QI (match_operand:QI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:QI 2 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))
-+ (set (match_operand:QI 0 "memory_operand" "=m, m")
-+ (and:QI (match_dup 1)
-+ (match_dup 2)))]
-+ "(ubicom32_v4
-+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
-+ "@
-+ and.1\\t%0, %2, %1
-+ and.1\\t%0, %1, %2")
-+
-+(define_insn "andqi3_and1_ccszn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (and:QI (match_operand:QI 0 "nonimmediate_operand" "%d,rm")
-+ (match_operand:QI 1 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))]
-+ "(ubicom32_v4
-+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
-+ "@
-+ and.1\\t#0, %1, %0
-+ and.1\\t#0, %0, %1")
-+
-+(define_insn "and1_ccszn_null_1"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:QI
-+ (and:SI (match_operand:SI 0 "ubicom32_data_register_operand" "%d")
-+ (match_operand:SI 1 "ubicom32_arith_operand" "rI"))
-+ 3)
-+ (const_int 0)))]
-+ "(ubicom32_v4
-+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
-+ "and.1\\t#0, %1, %0")
-+
-+(define_insn "and1_ccszn_null_2"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:QI
-+ (and:SI (match_operand:SI 0 "ubicom32_data_register_operand" "d")
-+ (subreg:SI
-+ (match_operand:QI 1 "memory_operand" "m")
-+ 0))
-+ 3)
-+ (const_int 0)))]
-+ "(ubicom32_v4
-+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
-+ "and.1\\t#0, %1, %0")
-+
-+(define_insn "and1_ccszn_null_3"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:QI
-+ (and:SI (subreg:SI
-+ (match_operand:QI 0 "memory_operand" "m")
-+ 0)
-+ (match_operand:SI 1 "ubicom32_data_register_operand" "d"))
-+ 3)
-+ (const_int 0)))]
-+ "(ubicom32_v4
-+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
-+ "and.1\\t#0, %0, %1")
-+
-+(define_expand "andhi3"
-+ [(parallel
-+ [(set (match_operand:HI 0 "memory_operand" "")
-+ (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
-+ (match_operand:HI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ ""
-+ "{
-+ if (!memory_operand (operands[0], HImode))
-+ FAIL;
-+
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (HImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (HImode, operands[2]);
-+ }")
-+
-+(define_insn "andhi3_and2"
-+ [(set (match_operand:HI 0 "memory_operand" "=m, m")
-+ (and:HI (match_operand:HI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:HI 2 "ubicom32_arith_operand" "rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "@
-+ and.2\\t%0, %2, %1
-+ and.2\\t%0, %1, %2")
-+
-+(define_insn "andhi3_and2_ccszn"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (and:HI (match_operand:HI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:HI 2 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))
-+ (set (match_operand:HI 0 "memory_operand" "=m, m")
-+ (and:HI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "@
-+ and.2\\t%0, %2, %1
-+ and.2\\t%0, %1, %2")
-+
-+(define_insn "andhi3_and2_ccszn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (and:HI (match_operand:HI 0 "nonimmediate_operand" "%d,rm")
-+ (match_operand:HI 1 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "@
-+ and.2\\t#0, %1, %0
-+ and.2\\t#0, %0, %1")
-+
-+(define_insn "and2_ccszn_null_1"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:HI
-+ (and:SI (match_operand:SI 0 "ubicom32_data_register_operand" "%d")
-+ (match_operand:SI 1 "ubicom32_arith_operand" "rI"))
-+ 2)
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "and.2\\t#0, %1, %0")
-+
-+(define_insn "and2_ccszn_null_2"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:HI
-+ (and:SI (match_operand:SI 0 "ubicom32_data_register_operand" "d")
-+ (subreg:SI
-+ (match_operand:HI 1 "memory_operand" "m")
-+ 0))
-+ 2)
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "and.2\\t#0, %1, %0")
-+
-+(define_insn "and2_ccszn_null_3"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:HI
-+ (and:SI (subreg:SI
-+ (match_operand:HI 0 "memory_operand" "m")
-+ 0)
-+ (match_operand:SI 1 "ubicom32_data_register_operand" "d"))
-+ 2)
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "and.2\\t#0, %0, %1")
-+
-+(define_expand "andsi3"
-+ [(parallel
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
-+ (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
-+ (match_operand:SI 2 "ubicom32_and_or_si3_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ ""
-+ "{
-+ do
-+ {
-+ /* Is this a bfextu? */
-+ if (ubicom32_data_register_operand (operands[0], SImode)
-+ && CONST_INT_P (operands[2])
-+ && exact_log2 (INTVAL (operands[2]) + 1) != -1)
-+ break;
-+
-+ /* Is this a bclr? */
-+ if (CONST_INT_P (operands[2])
-+ && exact_log2 (~INTVAL (operands[2])) != -1)
-+ break;
-+
-+ /* Must be an and.4 */
-+ if (!ubicom32_data_register_operand (operands[1], SImode))
-+ operands[1] = copy_to_mode_reg (SImode, operands[1]);
-+
-+ if (!ubicom32_arith_operand (operands[2], SImode))
-+ operands[2] = copy_to_mode_reg (SImode, operands[2]);
-+ }
-+ while (0);
-+ }")
-+
-+(define_insn "andsi3_bfextu"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (and:SI (match_operand:SI 1 "nonimmediate_operand" "%rm")
-+ (match_operand:SI 2 "const_int_operand" "O")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(satisfies_constraint_O (operands[2]))"
-+ "*
-+ {
-+ operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2]) + 1));
-+
-+ return \"bfextu\\t%0, %1, %3\";
-+ }")
-+
-+(define_insn "andsi3_bfextu_ccwz"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (and:SI (match_operand:SI 1 "nonimmediate_operand" "%rm")
-+ (match_operand:SI 2 "const_int_operand" "O"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (and:SI (match_dup 1)
-+ (match_dup 2)))]
-+ "(satisfies_constraint_O (operands[2])
-+ && ubicom32_match_cc_mode(insn, CCWZmode))"
-+ "*
-+ {
-+ operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2]) + 1));
-+
-+ return \"bfextu\\t%0, %1, %3\";
-+ }")
-+
-+(define_insn "andsi3_bfextu_ccwz_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (and:SI (match_operand:SI 0 "nonimmediate_operand" "%rm")
-+ (match_operand:SI 1 "const_int_operand" "O"))
-+ (const_int 0)))
-+ (clobber (match_scratch:SI 2 "=d"))]
-+ "(satisfies_constraint_O (operands[1])
-+ && ubicom32_match_cc_mode(insn, CCWZmode))"
-+ "*
-+ {
-+ operands[3] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1));
-+
-+ return \"bfextu\\t%2, %0, %3\";
-+ }")
-+
-+(define_insn "andsi3_bclr"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (and:SI (match_operand:SI 1 "ubicom32_arith_operand" "%rmI")
-+ (match_operand:SI 2 "const_int_operand" "n")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(exact_log2 (~INTVAL (operands[2])) != -1)"
-+ "bclr\\t%0, %1, #%D2")
-+
-+(define_insn "andsi3_and4"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
-+ (and:SI (match_operand:SI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "@
-+ and.4\\t%0, %2, %1
-+ and.4\\t%0, %1, %2")
-+
-+(define_insn "andsi3_and4_ccwzn"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (and:SI (match_operand:SI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
-+ (and:SI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "@
-+ and.4\\t%0, %2, %1
-+ and.4\\t%0, %1, %2")
-+
-+(define_insn "andsi3_and4_ccwzn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (and:SI (match_operand:SI 0 "nonimmediate_operand" "%d,rm")
-+ (match_operand:SI 1 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "@
-+ and.4\\t#0, %1, %0
-+ and.4\\t#0, %0, %1")
-+
-+(define_insn "andsi3_lsr4_ccwz_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (and:SI (match_operand:SI 0 "nonimmediate_operand" "%rm")
-+ (match_operand:SI 1 "const_int_operand" "n"))
-+ (const_int 0)))
-+ (clobber (match_scratch:SI 2 "=d"))]
-+ "(exact_log2 ((~(INTVAL (operands[1]))) + 1) != -1
-+ && ubicom32_match_cc_mode(insn, CCWZmode))"
-+ "*
-+ {
-+ operands[3] = GEN_INT (exact_log2 ((~(INTVAL (operands[1]))) + 1));
-+
-+ return \"lsr.4\\t%2, %0, %3\";
-+ }")
-+
-+; We really would like the combiner to recognize this scenario and deal with
-+; it but unfortunately it tries to canonicalize zero_extract ops on MEMs
-+; into QImode operations and we can't match them in any useful way.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))
-+ (set (reg:CCWZ CC_REGNO)
-+ (compare:CCWZ
-+ (and:SI (match_operand:SI 2 "nonimmediate_operand" "")
-+ (match_dup 0))
-+ (const_int 0)))]
-+ "(exact_log2 (INTVAL (operands[1])) != -1
-+ && peep2_reg_dead_p (2, operands[0]))"
-+ [(set (reg:CCWZ CC_REGNO)
-+ (compare:CCWZ
-+ (zero_extract:SI
-+ (match_dup 2)
-+ (const_int 1)
-+ (match_dup 3))
-+ (const_int 0)))]
-+ "{
-+ operands[3] = GEN_INT (exact_log2 (INTVAL (operands[1])));
-+ }")
-+
-+(define_expand "anddi3"
-+ [(parallel
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "")
-+ (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
-+ (match_operand:DI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ ""
-+ "{
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (DImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (DImode, operands[2]);
-+ }")
-+
-+(define_insn_and_split "anddi3_and4"
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,&r, d,rm, m, m")
-+ (and:DI (match_operand:DI 1 "nonimmediate_operand" "%d,rm, 0, 0, d,rm")
-+ (match_operand:DI 2 "ubicom32_arith_operand" "rmI, d,rmI, d,rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "#"
-+ "reload_completed"
-+ [(parallel [(set (match_dup 3)
-+ (and:SI (match_dup 4)
-+ (match_dup 5)))
-+ (clobber (reg:CC CC_REGNO))])
-+ (parallel [(set (match_dup 6)
-+ (and:SI (match_dup 7)
-+ (match_dup 8)))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "{
-+ operands[3] = gen_lowpart (SImode, operands[0]);
-+ operands[4] = gen_lowpart (SImode, operands[1]);
-+ operands[5] = gen_lowpart (SImode, operands[2]);
-+ operands[6] = gen_highpart (SImode, operands[0]);
-+ operands[7] = gen_highpart (SImode, operands[1]);
-+ operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_expand "iorqi3"
-+ [(parallel
-+ [(set (match_operand:QI 0 "memory_operand" "")
-+ (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
-+ (match_operand:QI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "(ubicom32_v4)"
-+ "{
-+ if (!memory_operand (operands[0], QImode))
-+ FAIL;
-+
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (QImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (QImode, operands[2]);
-+ }")
-+
-+(define_insn "iorqi3_or1"
-+ [(set (match_operand:QI 0 "memory_operand" "=m, m")
-+ (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:QI 2 "ubicom32_arith_operand" "rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4)"
-+ "@
-+ or.1\\t%0, %2, %1
-+ or.1\\t%0, %1, %2")
-+
-+(define_expand "iorhi3"
-+ [(parallel
-+ [(set (match_operand:HI 0 "memory_operand" "")
-+ (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
-+ (match_operand:HI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ ""
-+ "{
-+ if (!memory_operand (operands[0], HImode))
-+ FAIL;
-+
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (HImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (HImode, operands[2]);
-+ }")
-+
-+(define_insn "iorhi3_or2"
-+ [(set (match_operand:HI 0 "memory_operand" "=m, m")
-+ (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:HI 2 "ubicom32_arith_operand" "rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "@
-+ or.2\\t%0, %2, %1
-+ or.2\\t%0, %1, %2")
-+
-+(define_expand "iorsi3"
-+ [(parallel
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
-+ (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
-+ (match_operand:SI 2 "ubicom32_and_or_si3_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ ""
-+ "{
-+ do
-+ {
-+ /* Is this a bset? */
-+ if (CONST_INT_P (operands[2])
-+ && exact_log2 (INTVAL (operands[2])) != -1)
-+ break;
-+
-+ /* Must be an or.4 */
-+ if (!ubicom32_data_register_operand (operands[1], SImode))
-+ operands[1] = copy_to_mode_reg (SImode, operands[1]);
-+
-+ if (!ubicom32_arith_operand (operands[2], SImode))
-+ operands[2] = copy_to_mode_reg (SImode, operands[2]);
-+ }
-+ while (0);
-+ }")
-+
-+(define_insn "iorsi3_bset"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (ior:SI (match_operand:SI 1 "ubicom32_arith_operand" "%rmI")
-+ (match_operand 2 "const_int_operand" "n")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(exact_log2 (INTVAL (operands[2])) != -1)"
-+ "bset\\t%0, %1, #%d2")
-+
-+(define_insn "iorsi3_or4"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
-+ (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "@
-+ or.4\\t%0, %2, %1
-+ or.4\\t%0, %1, %2")
-+
-+(define_insn "iorsi3_ccwzn"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
-+ (ior:SI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "@
-+ or.4\\t%0, %2, %1
-+ or.4\\t%0, %1, %2")
-+
-+(define_insn "iorsi3_ccwzn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (ior:SI (match_operand:SI 0 "nonimmediate_operand" "%d,rm")
-+ (match_operand:SI 1 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "@
-+ or.4\\t#0, %1, %0
-+ or.4\\t#0, %0, %1")
-+
-+(define_expand "iordi3"
-+ [(parallel
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "")
-+ (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
-+ (match_operand:DI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ ""
-+ "{
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (DImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (DImode, operands[2]);
-+ }")
-+
-+(define_insn_and_split "iordi3_or4"
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,&r, d,rm, m, m")
-+ (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%d,rm, 0, 0, d,rm")
-+ (match_operand:DI 2 "ubicom32_arith_operand" "rmI, d,rmI, d,rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "#"
-+ "reload_completed"
-+ [(parallel [(set (match_dup 3)
-+ (ior:SI (match_dup 4)
-+ (match_dup 5)))
-+ (clobber (reg:CC CC_REGNO))])
-+ (parallel [(set (match_dup 6)
-+ (ior:SI (match_dup 7)
-+ (match_dup 8)))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "{
-+ operands[3] = gen_lowpart (SImode, operands[0]);
-+ operands[4] = gen_lowpart (SImode, operands[1]);
-+ operands[5] = gen_lowpart (SImode, operands[2]);
-+ operands[6] = gen_highpart (SImode, operands[0]);
-+ operands[7] = gen_highpart (SImode, operands[1]);
-+ operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_expand "xorqi3"
-+ [(parallel
-+ [(set (match_operand:QI 0 "memory_operand" "")
-+ (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
-+ (match_operand:QI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "(ubicom32_v4)"
-+ "{
-+ if (!memory_operand (operands[0], QImode))
-+ FAIL;
-+
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (QImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (QImode, operands[2]);
-+ }")
-+
-+(define_insn "xorqi3_xor1"
-+ [(set (match_operand:QI 0 "memory_operand" "=m, m")
-+ (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:QI 2 "ubicom32_arith_operand" "rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4)"
-+ "@
-+ xor.1\\t%0, %2, %1
-+ xor.1\\t%0, %1, %2")
-+
-+(define_insn "xorqi3_xor1_ccszn"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:QI 2 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))
-+ (set (match_operand:QI 0 "memory_operand" "=m, m")
-+ (xor:QI (match_dup 1)
-+ (match_dup 2)))]
-+ "(ubicom32_v4
-+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
-+ "@
-+ xor.1\\t%0, %2, %1
-+ xor.1\\t%0, %1, %2")
-+
-+(define_insn "xorqi3_xor1_ccszn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (xor:QI (match_operand:QI 0 "nonimmediate_operand" "%d,rm")
-+ (match_operand:QI 1 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))]
-+ "(ubicom32_v4
-+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
-+ "@
-+ xor.1\\t#0, %1, %0
-+ xor.1\\t#0, %0, %1")
-+
-+(define_insn "xor1_ccszn_null_1"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:QI
-+ (xor:SI (match_operand:SI 0 "ubicom32_data_register_operand" "%d")
-+ (match_operand:SI 1 "ubicom32_arith_operand" "rI"))
-+ 3)
-+ (const_int 0)))]
-+ "(ubicom32_v4
-+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
-+ "xor.1\\t#0, %1, %0")
-+
-+(define_insn "xor1_ccszn_null_2"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:QI
-+ (xor:SI (match_operand:SI 0 "ubicom32_data_register_operand" "d")
-+ (subreg:SI
-+ (match_operand:QI 1 "memory_operand" "m")
-+ 0))
-+ 3)
-+ (const_int 0)))]
-+ "(ubicom32_v4
-+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
-+ "xor.1\\t#0, %1, %0")
-+
-+(define_insn "xor1_ccwzn_null_3"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:QI
-+ (xor:SI (subreg:SI
-+ (match_operand:QI 0 "memory_operand" "m")
-+ 0)
-+ (match_operand:SI 1 "ubicom32_data_register_operand" "d"))
-+ 3)
-+ (const_int 0)))]
-+ "(ubicom32_v4
-+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
-+ "xor.1\\t#0, %0, %1")
-+
-+(define_expand "xorhi3"
-+ [(parallel
-+ [(set (match_operand:HI 0 "memory_operand" "")
-+ (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
-+ (match_operand:HI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ ""
-+ "{
-+ if (!memory_operand (operands[0], HImode))
-+ FAIL;
-+
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (HImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (HImode, operands[2]);
-+ }")
-+
-+(define_insn "xorhi3_xor2"
-+ [(set (match_operand:HI 0 "memory_operand" "=m, m")
-+ (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:HI 2 "ubicom32_arith_operand" "rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "@
-+ xor.2\\t%0, %2, %1
-+ xor.2\\t%0, %1, %2")
-+
-+(define_insn "xorhi3_xor2_ccszn"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:HI 2 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))
-+ (set (match_operand:HI 0 "memory_operand" "=m, m")
-+ (xor:HI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "@
-+ xor.2\\t%0, %2, %1
-+ xor.2\\t%0, %1, %2")
-+
-+(define_insn "xorhi3_xor2_ccszn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (xor:HI (match_operand:HI 0 "nonimmediate_operand" "%d,rm")
-+ (match_operand:HI 1 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "@
-+ xor.2\\t#0, %1, %0
-+ xor.2\\t#0, %0, %1")
-+
-+(define_insn "xor2_ccszn_null_1"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:HI
-+ (xor:SI (match_operand:SI 0 "ubicom32_data_register_operand" "%d")
-+ (match_operand:SI 1 "ubicom32_arith_operand" "rI"))
-+ 2)
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "xor.2\\t#0, %1, %0")
-+
-+(define_insn "xor2_ccszn_null_2"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:HI
-+ (xor:SI (match_operand:SI 0 "ubicom32_data_register_operand" "d")
-+ (subreg:SI
-+ (match_operand:HI 1 "memory_operand" "m")
-+ 0))
-+ 2)
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "xor.2\\t#0, %1, %0")
-+
-+(define_insn "xor2_ccszn_null_3"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:HI
-+ (xor:SI (subreg:SI
-+ (match_operand:HI 0 "memory_operand" "m")
-+ 0)
-+ (match_operand:SI 1 "ubicom32_data_register_operand" "d"))
-+ 2)
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "xor.2\\t#0, %0, %1")
-+
-+(define_insn "xorsi3"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
-+ (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "@
-+ xor.4\\t%0, %2, %1
-+ xor.4\\t%0, %1, %2")
-+
-+(define_insn "xorsi3_ccwzn"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
-+ (xor:SI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "@
-+ xor.4\\t%0, %2, %1
-+ xor.4\\t%0, %1, %2")
-+
-+(define_insn "xorsi3_ccwzn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (xor:SI (match_operand:SI 0 "nonimmediate_operand" "%d,rm")
-+ (match_operand:SI 1 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "@
-+ xor.4\\t#0, %1, %0
-+ xor.4\\t#0, %0, %1")
-+
-+(define_expand "xordi3"
-+ [(parallel
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "")
-+ (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
-+ (match_operand:DI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ ""
-+ "{
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (DImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (DImode, operands[2]);
-+ }")
-+
-+(define_insn_and_split "xordi3_xor4"
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,&r, d,rm, m, m")
-+ (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%d,rm, 0, 0, d,rm")
-+ (match_operand:DI 2 "ubicom32_arith_operand" "rmI, d,rmI, d,rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "#"
-+ "reload_completed"
-+ [(parallel [(set (match_dup 3)
-+ (xor:SI (match_dup 4)
-+ (match_dup 5)))
-+ (clobber (reg:CC CC_REGNO))])
-+ (parallel [(set (match_dup 6)
-+ (xor:SI (match_dup 7)
-+ (match_dup 8)))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "{
-+ operands[3] = gen_lowpart (SImode, operands[0]);
-+ operands[4] = gen_lowpart (SImode, operands[1]);
-+ operands[5] = gen_lowpart (SImode, operands[2]);
-+ operands[6] = gen_highpart (SImode, operands[0]);
-+ operands[7] = gen_highpart (SImode, operands[1]);
-+ operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_insn "not2_2"
-+ [(set (match_operand:HI 0 "memory_operand" "=m")
-+ (subreg:HI
-+ (not:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI"))
-+ 2))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "not.2\\t%0, %1")
-+
-+(define_insn "one_cmplsi2"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (not:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "not.4\\t%0, %1")
-+
-+(define_insn "one_cmplsi2_ccwzn"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (not:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (not:SI (match_dup 1)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "not.4\\t%0, %1")
-+
-+(define_insn "one_cmplsi2_ccwzn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (not:SI (match_operand:SI 0 "ubicom32_arith_operand" "rmI"))
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "not.4\\t#0, %0")
-+
-+(define_insn_and_split "one_cmpldi2"
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "=&rm")
-+ (not:DI (match_operand:DI 1 "nonimmediate_operand" "rmI0")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "#"
-+ ""
-+ [(parallel [(set (match_dup 2)
-+ (not:SI (match_dup 3)))
-+ (clobber (reg:CC CC_REGNO))])
-+ (parallel [(set (match_dup 4)
-+ (not:SI (match_dup 5)))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "{
-+ operands[2] = gen_lowpart (SImode, operands[0]);
-+ operands[3] = gen_lowpart (SImode, operands[1]);
-+ operands[4] = gen_highpart (SImode, operands[0]);
-+ operands[5] = gen_highpart (SImode, operands[1]);
-+ }"
-+ [(set_attr "length" "8")])
-+
-+; Conditional jump instructions
-+
-+(define_expand "beq"
-+ [(set (pc)
-+ (if_then_else (eq (match_dup 1)
-+ (const_int 0))
-+ (label_ref (match_operand 0 "" ""))
-+ (pc)))]
-+ ""
-+ "{
-+ operands[1] = ubicom32_gen_compare_reg (EQ, ubicom32_compare_op0,
-+ ubicom32_compare_op1);
-+ }")
-+
-+(define_expand "bne"
-+ [(set (pc)
-+ (if_then_else (ne (match_dup 1)
-+ (const_int 0))
-+ (label_ref (match_operand 0 "" ""))
-+ (pc)))]
-+ ""
-+ "{
-+ operands[1] = ubicom32_gen_compare_reg (NE, ubicom32_compare_op0,
-+ ubicom32_compare_op1);
-+ }")
-+
-+(define_expand "bgt"
-+ [(set (pc)
-+ (if_then_else (gt (match_dup 1)
-+ (const_int 0))
-+ (label_ref (match_operand 0 "" ""))
-+ (pc)))]
-+ ""
-+ "{
-+ operands[1] = ubicom32_gen_compare_reg (GT, ubicom32_compare_op0,
-+ ubicom32_compare_op1);
-+ }")
-+
-+(define_expand "ble"
-+ [(set (pc)
-+ (if_then_else (le (match_dup 1)
-+ (const_int 0))
-+ (label_ref (match_operand 0 "" ""))
-+ (pc)))]
-+ ""
-+ "{
-+ operands[1] = ubicom32_gen_compare_reg (LE, ubicom32_compare_op0,
-+ ubicom32_compare_op1);
-+ }")
-+
-+(define_expand "bge"
-+ [(set (pc)
-+ (if_then_else (ge (match_dup 1)
-+ (const_int 0))
-+ (label_ref (match_operand 0 "" ""))
-+ (pc)))]
-+ ""
-+ "{
-+ operands[1] = ubicom32_gen_compare_reg (GE, ubicom32_compare_op0,
-+ ubicom32_compare_op1);
-+ }")
-+
-+(define_expand "blt"
-+ [(set (pc)
-+ (if_then_else (lt (match_dup 1)
-+ (const_int 0))
-+ (label_ref (match_operand 0 "" ""))
-+ (pc)))]
-+ ""
-+ "{
-+ operands[1] = ubicom32_gen_compare_reg (LT, ubicom32_compare_op0,
-+ ubicom32_compare_op1);
-+ }")
-+
-+(define_expand "bgtu"
-+ [(set (pc)
-+ (if_then_else (gtu (match_dup 1)
-+ (const_int 0))
-+ (label_ref (match_operand 0 "" ""))
-+ (pc)))]
-+ ""
-+ "{
-+ operands[1] = ubicom32_gen_compare_reg (GTU, ubicom32_compare_op0,
-+ ubicom32_compare_op1);
-+ }")
-+
-+(define_expand "bleu"
-+ [(set (pc)
-+ (if_then_else (leu (match_dup 1)
-+ (const_int 0))
-+ (label_ref (match_operand 0 "" ""))
-+ (pc)))]
-+ ""
-+ "{
-+ operands[1] = ubicom32_gen_compare_reg (LEU, ubicom32_compare_op0,
-+ ubicom32_compare_op1);
-+ }")
-+
-+(define_expand "bgeu"
-+ [(set (pc)
-+ (if_then_else (geu (match_dup 1)
-+ (const_int 0))
-+ (label_ref (match_operand 0 "" ""))
-+ (pc)))]
-+ ""
-+ "{
-+ operands[1] = ubicom32_gen_compare_reg (GEU, ubicom32_compare_op0,
-+ ubicom32_compare_op1);
-+ }")
-+
-+(define_expand "bltu"
-+ [(set (pc)
-+ (if_then_else (ltu (match_dup 1)
-+ (const_int 0))
-+ (label_ref (match_operand 0 "" ""))
-+ (pc)))]
-+ ""
-+ "{
-+ operands[1] = ubicom32_gen_compare_reg (LTU, ubicom32_compare_op0,
-+ ubicom32_compare_op1);
-+ }")
-+
-+(define_insn "jcc"
-+ [(set (pc)
-+ (if_then_else (match_operator 1 "comparison_operator"
-+ [(match_operand 2 "ubicom32_cc_register_operand" "")
-+ (const_int 0)])
-+ (label_ref (match_operand 0 "" ""))
-+ (pc)))]
-+ ""
-+ "*
-+ {
-+ ubicom32_output_cond_jump (insn, operands[1], operands[0]);
-+ return \"\";
-+ }")
-+
-+; Reverse branch - reverse our comparison condition so that we can
-+; branch in the opposite sense.
-+;
-+(define_insn_and_split "jcc_reverse"
-+ [(set (pc)
-+ (if_then_else (match_operator 1 "comparison_operator"
-+ [(match_operand 2 "ubicom32_cc_register_operand" "")
-+ (const_int 0)])
-+ (pc)
-+ (label_ref (match_operand 0 "" ""))))]
-+ ""
-+ "#"
-+ "reload_completed"
-+ [(set (pc)
-+ (if_then_else (match_dup 3)
-+ (label_ref (match_dup 0))
-+ (pc)))]
-+ "{
-+ rtx cc_reg;
-+
-+ cc_reg = gen_rtx_REG (GET_MODE (operands[2]), CC_REGNO);
-+ operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[1])),
-+ GET_MODE (operands[1]),
-+ cc_reg,
-+ const0_rtx);
-+ }")
-+
-+(define_insn "jump"
-+ [(set (pc)
-+ (label_ref (match_operand 0 "" "")))]
-+ ""
-+ "jmpt\\t%l0")
-+
-+(define_expand "indirect_jump"
-+ [(parallel [(set (pc)
-+ (match_operand:SI 0 "register_operand" ""))
-+ (clobber (match_dup 0))])]
-+ ""
-+ "")
-+
-+(define_insn "indirect_jump_internal"
-+ [(set (pc)
-+ (match_operand:SI 0 "register_operand" "a"))
-+ (clobber (match_dup 0))]
-+ ""
-+ "calli\\t%0,0(%0)")
-+
-+; Program Space: The table contains instructions, typically jumps.
-+; CALL An,TABLE_SIZE(PC) ;An = Jump Table Base Address.
-+; <Jump Table is Here> ;An -> Here.
-+; LEA Ak, (An,Dn) ;Ak -> Table Entry
-+; JMP/CALL (Ak)
-+
-+(define_expand "tablejump"
-+ [(parallel [(set (pc)
-+ (match_operand:SI 0 "nonimmediate_operand" ""))
-+ (use (label_ref (match_operand 1 "" "")))])]
-+ ""
-+ "")
-+
-+(define_insn "tablejump_internal"
-+ [(set (pc)
-+ (match_operand:SI 0 "nonimmediate_operand" "rm"))
-+ (use (label_ref (match_operand 1 "" "")))]
-+ ""
-+ "ret\\t%0")
-+
-+; Call subroutine with no return value.
-+;
-+(define_expand "call"
-+ [(call (match_operand:QI 0 "general_operand" "")
-+ (match_operand:SI 1 "general_operand" ""))]
-+ ""
-+ "{
-+ if (TARGET_FDPIC)
-+ {
-+ ubicom32_expand_call_fdpic (operands);
-+ DONE;
-+ }
-+
-+ if (! ubicom32_call_address_operand (XEXP (operands[0], 0), VOIDmode))
-+ XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
-+ }")
-+
-+; We expand to a simple form that doesn't clobber the link register and
-+; then split to a form that does. This allows the RTL optimizers that
-+; run before the splitter to have the opportunity to eliminate the call
-+; without marking A5 as being clobbered and this in turn avoids saves
-+; and returns in a number of cases.
-+;
-+(define_insn_and_split "call_1"
-+ [(call (mem:QI (match_operand:SI 0 "ubicom32_call_address_operand" "a,S"))
-+ (match_operand:SI 1 "general_operand" "g,g"))]
-+ "! TARGET_FDPIC"
-+ "#"
-+ ""
-+ [(parallel
-+ [(call (mem:QI (match_dup 0))
-+ (match_dup 1))
-+ (clobber (reg:SI LINK_REGNO))])]
-+ "")
-+
-+(define_insn "call_slow"
-+ [(call (mem:QI (match_operand:SI 0 "ubicom32_call_address_operand" "a,S"))
-+ (match_operand:SI 1 "general_operand" "g,g"))
-+ (clobber (reg:SI LINK_REGNO))]
-+ "(! TARGET_FDPIC && ! TARGET_FASTCALL)"
-+ "@
-+ calli\\ta5, 0(%0)
-+ moveai\\ta5, #%%hi(%C0)\;calli\\ta5, %%lo(%C0)(a5)")
-+
-+(define_insn "call_fast"
-+ [(call (mem:QI (match_operand:SI 0 "ubicom32_call_address_operand" "a,S"))
-+ (match_operand:SI 1 "general_operand" "g,g"))
-+ (clobber (reg:SI LINK_REGNO))]
-+ "(! TARGET_FDPIC && TARGET_FASTCALL)"
-+ "@
-+ calli\\ta5, 0(%0)
-+ call\\ta5, %C0")
-+
-+; We expand to a simple form that doesn't clobber the link register and
-+; then split to a form that does. This allows the RTL optimizers that
-+; run before the splitter to have the opportunity to eliminate the call
-+; without marking A5 as being clobbered and this in turn avoids saves
-+; and returns in a number of cases.
-+;
-+(define_insn_and_split "call_fdpic"
-+ [(call (mem:QI (match_operand:SI 0 "ubicom32_call_address_operand" "a,S"))
-+ (match_operand:SI 1 "general_operand" "g,g"))
-+ (use (match_operand:SI 2 "ubicom32_fdpic_operand" "Z,Z"))]
-+ "TARGET_FDPIC"
-+ "#"
-+ ""
-+ [(parallel
-+ [(call (mem:QI (match_dup 0))
-+ (match_dup 1))
-+ (use (match_dup 2))
-+ (clobber (reg:SI LINK_REGNO))])]
-+ "")
-+
-+(define_insn "call_fdpic_clobber"
-+ [(call (mem:QI (match_operand:SI 0 "ubicom32_call_address_operand" "a,S"))
-+ (match_operand:SI 1 "general_operand" "g,g"))
-+ (use (match_operand:SI 2 "ubicom32_fdpic_operand" "Z,Z"))
-+ (clobber (reg:SI LINK_REGNO))]
-+ "TARGET_FDPIC"
-+ "@
-+ move.4\\ta5, 0(%0)\;move.4\\t%2, 4(%0)\;calli\\ta5, 0(a5)
-+ call\\ta5, %C0")
-+
-+; Call subroutine, returning value in operand 0
-+; (which must be a hard register).
-+;
-+(define_expand "call_value"
-+ [(set (match_operand 0 "" "")
-+ (call (match_operand:QI 1 "general_operand" "")
-+ (match_operand:SI 2 "general_operand" "")))]
-+ ""
-+ "{
-+ if (TARGET_FDPIC)
-+ {
-+ ubicom32_expand_call_value_fdpic (operands);
-+ DONE;
-+ }
-+
-+ if (! ubicom32_call_address_operand (XEXP (operands[1], 0), VOIDmode))
-+ XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
-+ }")
-+
-+; We expand to a simple form that doesn't clobber the link register and
-+; then split to a form that does. This allows the RTL optimizers that
-+; run before the splitter to have the opportunity to eliminate the call
-+; without marking A5 as being clobbered and this in turn avoids saves
-+; and returns in a number of cases.
-+;
-+(define_insn_and_split "call_value_1"
-+ [(set (match_operand 0 "register_operand" "=r,r")
-+ (call (mem:QI (match_operand:SI 1 "ubicom32_call_address_operand" "a,S"))
-+ (match_operand:SI 2 "general_operand" "g,g")))]
-+ "! TARGET_FDPIC"
-+ "#"
-+ ""
-+ [(parallel
-+ [(set (match_dup 0)
-+ (call (mem:QI (match_dup 1))
-+ (match_dup 2)))
-+ (clobber (reg:SI LINK_REGNO))])]
-+ "")
-+
-+(define_insn "call_value_slow"
-+ [(set (match_operand 0 "register_operand" "=r,r")
-+ (call (mem:QI (match_operand:SI 1 "ubicom32_call_address_operand" "a,S"))
-+ (match_operand:SI 2 "general_operand" "g,g")))
-+ (clobber (reg:SI LINK_REGNO))]
-+ "(! TARGET_FDPIC && ! TARGET_FASTCALL)"
-+ "@
-+ calli\\ta5, 0(%1)
-+ moveai\\ta5, #%%hi(%C1)\;calli\\ta5, %%lo(%C1)(a5)")
-+
-+(define_insn "call_value_fast"
-+ [(set (match_operand 0 "register_operand" "=r,r")
-+ (call (mem:QI (match_operand:SI 1 "ubicom32_call_address_operand" "a,S"))
-+ (match_operand:SI 2 "general_operand" "g,g")))
-+ (clobber (reg:SI LINK_REGNO))]
-+ "(! TARGET_FDPIC && TARGET_FASTCALL)"
-+ "@
-+ calli\\ta5, 0(%1)
-+ call\\ta5, %C1")
-+
-+; We expand to a simple form that doesn't clobber the link register and
-+; then split to a form that does. This allows the RTL optimizers that
-+; run before the splitter to have the opportunity to eliminate the call
-+; without marking A5 as being clobbered and this in turn avoids saves
-+; and returns in a number of cases.
-+;
-+(define_insn_and_split "call_value_fdpic"
-+ [(set (match_operand 0 "register_operand" "=r,r")
-+ (call (mem:QI (match_operand:SI 1 "ubicom32_call_address_operand" "a,S"))
-+ (match_operand:SI 2 "general_operand" "g,g")))
-+ (use (match_operand:SI 3 "ubicom32_fdpic_operand" "Z,Z"))]
-+ "TARGET_FDPIC"
-+ "#"
-+ ""
-+ [(parallel
-+ [(set (match_dup 0)
-+ (call (mem:QI (match_dup 1))
-+ (match_dup 2)))
-+ (use (match_dup 3))
-+ (clobber (reg:SI LINK_REGNO))])]
-+ "")
-+
-+(define_insn "call_value_fdpic_clobber"
-+ [(set (match_operand 0 "register_operand" "=r,r")
-+ (call (mem:QI (match_operand:SI 1 "ubicom32_call_address_operand" "a,S"))
-+ (match_operand:SI 2 "general_operand" "g,g")))
-+ (use (match_operand:SI 3 "ubicom32_fdpic_operand" "Z,Z"))
-+ (clobber (reg:SI LINK_REGNO))]
-+ "TARGET_FDPIC"
-+ "@
-+ move.4\\ta5, 0(%1)\;move.4\\t%3, 4(%1)\;calli\\ta5, 0(a5)
-+ call\\ta5, %C1")
-+
-+(define_expand "untyped_call"
-+ [(parallel [(call (match_operand 0 "" "")
-+ (const_int 0))
-+ (match_operand 1 "" "")
-+ (match_operand 2 "" "")])]
-+ ""
-+ "{
-+ int i;
-+
-+ emit_call_insn (gen_call (operands[0], const0_rtx));
-+
-+ for (i = 0; i < XVECLEN (operands[2], 0); i++)
-+ {
-+ rtx set = XVECEXP (operands[2], 0, i);
-+ emit_move_insn (SET_DEST (set), SET_SRC (set));
-+ }
-+ DONE;
-+ }")
-+
-+(define_insn "lsl1_1"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (ashift:SI (subreg:SI
-+ (match_operand:QI 1 "memory_operand" "m")
-+ 0)
-+ (match_operand:SI 2 "ubicom32_arith_operand" "dM")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4)"
-+ "lsl.1\\t%0, %1, %2")
-+
-+; The combiner gets rather creative about left shifts of sub-word memory
-+; operands because it's uncertain about whether the memory is sign or
-+; zero extended. It only wants zero-extended behaviour and so throws
-+; in an extra and operation.
-+;
-+(define_insn "lsl1_2"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (and:SI
-+ (ashift:SI (subreg:SI
-+ (match_operand:QI 1 "memory_operand" "m")
-+ 0)
-+ (match_operand:SI 2 "const_int_operand" "M"))
-+ (match_operand:SI 3 "const_int_operand" "n")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4
-+ && INTVAL (operands[3]) == (0xff << INTVAL (operands[2])))"
-+ "lsl.1\\t%0, %1, %2")
-+
-+(define_insn "lsl2_1"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (ashift:SI (subreg:SI
-+ (match_operand:HI 1 "memory_operand" "m")
-+ 0)
-+ (match_operand:SI 2 "ubicom32_arith_operand" "dM")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4)"
-+ "lsl.2\\t%0, %1, %2")
-+
-+; The combiner gets rather creative about left shifts of sub-word memory
-+; operands because it's uncertain about whether the memory is sign or
-+; zero extended. It only wants zero-extended behaviour and so throws
-+; in an extra and operation.
-+;
-+(define_insn "lsl2_2"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (and:SI
-+ (ashift:SI (subreg:SI
-+ (match_operand:HI 1 "memory_operand" "m")
-+ 0)
-+ (match_operand:SI 2 "const_int_operand" "M"))
-+ (match_operand:SI 3 "const_int_operand" "n")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4
-+ && INTVAL (operands[3]) == (0xffff << INTVAL (operands[2])))"
-+ "lsl.2\\t%0, %1, %2")
-+
-+(define_insn "ashlsi3"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (ashift:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "dM")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "lsl.4\\t%0, %1, %2")
-+
-+(define_insn "lshlsi3_ccwz"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (ashift:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "dM"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (ashift:SI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCWZmode)"
-+ "lsl.4\\t%0, %1, %2")
-+
-+(define_insn "lshlsi3_ccwz_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (ashift:SI (match_operand:SI 0 "ubicom32_arith_operand" "rmI")
-+ (match_operand:SI 1 "ubicom32_arith_operand" "dM"))
-+ (const_int 0)))
-+ (clobber (match_scratch:SI 2 "=d"))]
-+ "ubicom32_match_cc_mode(insn, CCWZmode)"
-+ "lsl.4\\t%2, %0, %1")
-+
-+; The combiner finds this canonical form for what is in essence a right
-+; shift.
-+;
-+(define_insn "asr1_2"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (sign_extract:SI (match_operand:QI 1 "memory_operand" "m")
-+ (match_operand:SI 2 "const_int_operand" "M")
-+ (match_operand:SI 3 "const_int_operand" "M")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4
-+ && (INTVAL (operands[2]) + INTVAL (operands[3]) == 8))"
-+ "asr.1\\t%0, %1, %3")
-+
-+; The combiner finds this canonical form for what is in essence a right
-+; shift.
-+;
-+(define_insn "asr2_2"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (sign_extract:SI (match_operand:HI 1 "memory_operand" "m")
-+ (match_operand:SI 2 "const_int_operand" "M")
-+ (match_operand:SI 3 "const_int_operand" "M")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4
-+ && (INTVAL (operands[2]) + INTVAL (operands[3]) == 16))"
-+ "asr.2\\t%0, %1, %3")
-+
-+(define_insn "ashrsi3"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (ashiftrt:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmJ")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "dM")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "asr.4\\t%0, %1, %2")
-+
-+(define_insn "ashrsi3_ccwzn"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (ashiftrt:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmJ")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "dM"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (ashiftrt:SI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "asr.4\\t%0, %1, %2")
-+
-+(define_insn "ashrsi3_ccwzn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (ashiftrt:SI (match_operand:SI 0 "ubicom32_arith_operand" "rmJ")
-+ (match_operand:SI 1 "ubicom32_arith_operand" "dM"))
-+ (const_int 0)))
-+ (clobber (match_scratch:SI 2 "=d"))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "asr.4\\t%2, %0, %1")
-+
-+(define_insn "lsr1_1"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (lshiftrt:SI (subreg:SI
-+ (match_operand:QI 1 "memory_operand" "m")
-+ 0)
-+ (match_operand:SI 2 "ubicom32_arith_operand" "dM")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4)"
-+ "lsr.1\\t%0, %1, %2")
-+
-+; The combiner finds this canonical form for what is in essence a right
-+; shift.
-+;
-+(define_insn "lsr1_2"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (zero_extract:SI (match_operand:QI 1 "memory_operand" "m")
-+ (match_operand:SI 2 "const_int_operand" "M")
-+ (match_operand:SI 3 "const_int_operand" "M")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4
-+ && (INTVAL (operands[2]) + INTVAL (operands[3]) == 8))"
-+ "lsr.1\\t%0, %1, %3")
-+
-+(define_insn "lsr2_1"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (lshiftrt:SI (subreg:SI
-+ (match_operand:HI 1 "memory_operand" "m")
-+ 0)
-+ (match_operand:SI 2 "ubicom32_arith_operand" "dM")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4)"
-+ "lsr.2\\t%0, %1, %2")
-+
-+; The combiner finds this canonical form for what is in essence a right
-+; shift.
-+;
-+(define_insn "lsr2_2"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (zero_extract:SI (match_operand:HI 1 "memory_operand" "m")
-+ (match_operand:SI 2 "const_int_operand" "M")
-+ (match_operand:SI 3 "const_int_operand" "M")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4
-+ && (INTVAL (operands[2]) + INTVAL (operands[3]) == 16))"
-+ "lsr.2\\t%0, %1, %3")
-+
-+(define_insn "lshrsi3"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (lshiftrt:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "dM")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "lsr.4\\t%0, %1, %2")
-+
-+(define_insn "lshrsi3_ccwz"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (lshiftrt:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "dM"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (lshiftrt:SI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCWZmode)"
-+ "lsr.4\\t%0, %1, %2")
-+
-+(define_insn "lshrsi3_ccwz_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (lshiftrt:SI (match_operand:SI 0 "ubicom32_arith_operand" "rmI")
-+ (match_operand:SI 1 "ubicom32_arith_operand" "dM"))
-+ (const_int 0)))
-+ (clobber (match_scratch:SI 2 "=d"))]
-+ "ubicom32_match_cc_mode(insn, CCWZmode)"
-+ "lsr.4\\t%2, %0, %1")
-+
-+(define_expand "prologue"
-+ [(const_int 0)]
-+ ""
-+ "{
-+ ubicom32_expand_prologue ();
-+ DONE;
-+ }")
-+
-+(define_expand "epilogue"
-+ [(return)]
-+ ""
-+ "{
-+ ubicom32_expand_epilogue ();
-+ DONE;
-+ }")
-+
-+(define_expand "return"
-+ [(return)]
-+ ""
-+ "{
-+ ubicom32_expand_epilogue ();
-+ DONE;
-+ }")
-+
-+(define_expand "_eh_return"
-+ [(use (match_operand:SI 0 "register_operand" "r"))
-+ (use (match_operand:SI 1 "register_operand" "r"))]
-+ ""
-+ "{
-+ ubicom32_expand_eh_return (operands);
-+ DONE;
-+ }")
-+
-+; XXX - it looks almost certain that we could make return_internal use a Dn
-+; register too. In that instance we'd have to use a ret instruction
-+; rather than a calli but it might save cycles.
-+;
-+(define_insn "return_internal"
-+ [(const_int 2)
-+ (return)
-+ (use (match_operand:SI 0 "ubicom32_mem_or_address_register_operand" "rm"))]
-+ ""
-+ "*
-+ {
-+ if (REG_P (operands[0]) && REGNO (operands[0]) == LINK_REGNO
-+ && ubicom32_can_use_calli_to_ret)
-+ return \"calli\\t%0, 0(%0)\";
-+
-+ return \"ret\\t%0\";
-+ }")
-+
-+(define_insn "return_from_post_modify_sp"
-+ [(parallel
-+ [(const_int 2)
-+ (return)
-+ (use (mem:SI (post_modify:SI
-+ (reg:SI SP_REGNO)
-+ (plus:SI (reg:SI SP_REGNO)
-+ (match_operand:SI 0 "const_int_operand" "n")))))])]
-+ "INTVAL (operands[0]) >= 4 && INTVAL (operands[0]) <= 7 * 4"
-+ "ret\\t(sp)%E0++")
-+
-+;(define_insn "eh_return_internal"
-+; [(const_int 4)
-+; (return)
-+; (use (reg:SI 34))]
-+; ""
-+; "ret\\ta2")
-+
-+; No operation, needed in case the user uses -g but not -O.
-+(define_expand "nop"
-+ [(const_int 0)]
-+ ""
-+ "")
-+
-+(define_insn "nop_internal"
-+ [(const_int 0)]
-+ ""
-+ "nop")
-+
-+; The combiner will generate this pattern given shift and add operations.
-+; The canonical form that the combiner wants to use appears to be multiplies
-+; instead of shifts even if the compiled sources use shifts.
-+;
-+(define_insn "shmrg1_add"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (plus:SI
-+ (mult:SI (match_operand:SI 1 "ubicom32_data_register_operand" "d")
-+ (const_int 256))
-+ (zero_extend:SI
-+ (match_operand:QI 2 "ubicom32_arith_operand" "rmI"))))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "shmrg.1\\t%0, %2, %1")
-+
-+; The combiner will generate this pattern given shift and or operations.
-+;
-+(define_insn "shmrg1_ior"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (ior:SI
-+ (ashift:SI (match_operand:SI 1 "ubicom32_data_register_operand" "d")
-+ (const_int 8))
-+ (zero_extend:SI
-+ (match_operand:QI 2 "ubicom32_arith_operand" "rmI"))))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "shmrg.1\\t%0, %2, %1")
-+
-+; The combiner will generate this pattern given shift and add operations.
-+; The canonical form that the combiner wants to use appears to be multiplies
-+; instead of shifts even if the compiled sources use shifts.
-+;
-+(define_insn "shmrg2_add"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (plus:SI
-+ (mult:SI (match_operand:SI 1 "ubicom32_data_register_operand" "d")
-+ (const_int 65536))
-+ (zero_extend:SI
-+ (match_operand:HI 2 "ubicom32_arith_operand" "rmI"))))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "shmrg.2\\t%0, %2, %1")
-+
-+; The combiner will generate this pattern given shift and or operations.
-+;
-+(define_insn "shmrg2_ior"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (ior:SI
-+ (ashift:SI (match_operand:SI 1 "ubicom32_data_register_operand" "d")
-+ (const_int 16))
-+ (zero_extend:SI
-+ (match_operand:HI 2 "ubicom32_arith_operand" "rmI"))))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "shmrg.2\\t%0, %2, %1")
-+
-+; Match the case where we load a word from the stack but then discard the
-+; upper 16 bits. We turn this into a zero-extended load of that useful
-+; 16 bits direct from the stack where possible.
-+;
-+
-+; XXX - do these peephole2 ops actually work after the CCmode conversion?
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (mem:SI (plus:SI (reg:SI SP_REGNO)
-+ (match_operand:SI 1 "const_int_operand" ""))))
-+ (set (match_operand:SI 2 "nonimmediate_operand" "")
-+ (zero_extend:SI (match_operand:HI 3 "register_operand" "")))]
-+ "(INTVAL (operands[1]) <= 252
-+ && REGNO (operands[3]) == REGNO (operands[0])
-+ && ((peep2_reg_dead_p (2, operands[0])
-+ && ! reg_mentioned_p (operands[0], operands[2]))
-+ || rtx_equal_p (operands[0], operands[2])))"
-+ [(set (match_dup 2)
-+ (zero_extend:SI (mem:HI (plus:SI (reg:SI SP_REGNO)
-+ (match_dup 4)))))]
-+ "{
-+ operands[4] = GEN_INT (INTVAL (operands[1]) + 2);
-+ }")
-+
-+; Match the case where we load a word from the stack but then discard the
-+; upper 16 bits. We turn this into a 16-bit load of that useful
-+; 16 bits direct from the stack where possible.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (mem:SI (plus:SI (reg:SI SP_REGNO)
-+ (match_operand:SI 1 "const_int_operand" ""))))
-+ (set (match_operand:HI 2 "nonimmediate_operand" "")
-+ (match_operand:HI 3 "register_operand" ""))]
-+ "(INTVAL (operands[1]) <= 252
-+ && REGNO (operands[3]) == REGNO (operands[0])
-+ && ((peep2_reg_dead_p (2, operands[0])
-+ && ! reg_mentioned_p (operands[0], operands[2]))
-+ || rtx_equal_p (operands[0], operands[2])))"
-+ [(set (match_dup 2)
-+ (mem:HI (plus:SI (reg:SI SP_REGNO)
-+ (match_dup 4))))]
-+ "{
-+ operands[4] = GEN_INT (INTVAL (operands[1]) + 2);
-+ }")
-+
-+; Match the case where we load a word from the stack but then discard the
-+; upper 24 bits. We turn this into a zero-extended load of that useful
-+; 8 bits direct from the stack where possible.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (mem:SI (plus:SI (reg:SI SP_REGNO)
-+ (match_operand:SI 1 "const_int_operand" ""))))
-+ (set (match_operand:SI 2 "nonimmediate_operand" "")
-+ (zero_extend:SI (match_operand:QI 3 "register_operand" "")))]
-+ "(INTVAL (operands[1]) <= 124
-+ && REGNO (operands[3]) == REGNO (operands[0])
-+ && ((peep2_reg_dead_p (2, operands[0])
-+ && ! reg_mentioned_p (operands[0], operands[2]))
-+ || rtx_equal_p (operands[0], operands[2])))"
-+ [(set (match_dup 2)
-+ (zero_extend:SI (mem:QI (plus:SI (reg:SI SP_REGNO)
-+ (match_dup 4)))))]
-+ "{
-+ operands[4] = GEN_INT (INTVAL (operands[1]) + 3);
-+ }")
-+
-+; Match the case where we load a word from the stack but then discard the
-+; upper 24 bits. We turn this into an 8-bit load of that useful
-+; 8 bits direct from the stack where possible.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (mem:SI (plus:SI (reg:SI SP_REGNO)
-+ (match_operand:SI 1 "const_int_operand" ""))))
-+ (set (match_operand:QI 2 "nonimmediate_operand" "")
-+ (match_operand:QI 3 "register_operand" ""))]
-+ "(INTVAL (operands[1]) <= 124
-+ && REGNO (operands[3]) == REGNO (operands[0])
-+ && ((peep2_reg_dead_p (2, operands[0])
-+ && ! reg_mentioned_p (operands[0], operands[2]))
-+ || rtx_equal_p (operands[0], operands[2])))"
-+ [(set (match_dup 2)
-+ (mem:QI (plus:SI (reg:SI SP_REGNO)
-+ (match_dup 4))))]
-+ "{
-+ operands[4] = GEN_INT (INTVAL (operands[1]) + 3);
-+ }")
-+
---- /dev/null
-+++ b/gcc/config/ubicom32/ubicom32.opt
-@@ -0,0 +1,27 @@
-+mdebug-address
-+Target RejectNegative Report Undocumented Mask(DEBUG_ADDRESS)
-+Debug addresses
-+
-+mdebug-context
-+Target RejectNegative Report Undocumented Mask(DEBUG_CONTEXT)
-+Debug contexts
-+
-+march=
-+Target Report Var(ubicom32_arch_name) Init("ubicom32v4") Joined
-+Specify the name of the target architecture
-+
-+mfdpic
-+Target Report Mask(FDPIC)
-+Enable Function Descriptor PIC mode
-+
-+minline-plt
-+Target Report Mask(INLINE_PLT)
-+Enable inlining of PLT in function calls
-+
-+mfastcall
-+Target Report Mask(FASTCALL)
-+Enable default fast (call) calling sequence for smaller applications
-+
-+mipos-abi
-+Target Report Mask(IPOS_ABI)
-+Enable the ipOS ABI in which D10-D13 are caller-clobbered
---- /dev/null
-+++ b/gcc/config/ubicom32/uclinux.h
-@@ -0,0 +1,67 @@
-+/* Definitions of target machine for Ubicom32-uclinux
-+
-+ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
-+ 2009 Free Software Foundation, Inc.
-+ Contributed by Ubicom, Inc.
-+
-+ This file is part of GCC.
-+
-+ GCC is free software; you can redistribute it and/or modify it
-+ under the terms of the GNU General Public License as published
-+ by the Free Software Foundation; either version 3, or (at your
-+ option) any later version.
-+
-+ GCC is distributed in the hope that it will be useful, but WITHOUT
-+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
-+ License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with GCC; see the file COPYING3. If not see
-+ <http://www.gnu.org/licenses/>. */
-+
-+/* Don't assume anything about the header files. */
-+#define NO_IMPLICIT_EXTERN_C
-+
-+#undef LIB_SPEC
-+#define LIB_SPEC \
-+ "%{pthread:-lpthread} " \
-+ "%{!shared:%{!symbolic: -lc}} "
-+
-+
-+#undef LINK_GCC_C_SEQUENCE_SPEC
-+#define LINK_GCC_C_SEQUENCE_SPEC \
-+ "%{!shared:--start-group} %G %L %{!shared:--end-group}%{shared:%G} "
-+
-+#undef STARTFILE_SPEC
-+#define STARTFILE_SPEC \
-+ "%{!shared: crt1%O%s}" \
-+ " crti%O%s crtbegin%O%s"
-+
-+#undef ENDFILE_SPEC
-+#define ENDFILE_SPEC "crtend%O%s crtn%O%s"
-+
-+/* This macro applies on top of OBJECT_FORMAT_ELF and indicates that
-+ we want to support both flat and ELF output. */
-+#define OBJECT_FORMAT_FLAT
-+
-+#undef DRIVER_SELF_SPECS
-+#define DRIVER_SELF_SPECS \
-+ "%{!mno-fastcall:-mfastcall}"
-+
-+/* taken from linux.h */
-+/* The GNU C++ standard library requires that these macros be defined. */
-+#undef CPLUSPLUS_CPP_SPEC
-+#define CPLUSPLUS_CPP_SPEC "-D_GNU_SOURCE %(cpp)"
-+
-+#define TARGET_OS_CPP_BUILTINS() \
-+ do { \
-+ builtin_define_std ("__UBICOM32__"); \
-+ builtin_define_std ("__ubicom32__"); \
-+ builtin_define ("__gnu_linux__"); \
-+ builtin_define_std ("linux"); \
-+ builtin_define_std ("unix"); \
-+ builtin_assert ("system=linux"); \
-+ builtin_assert ("system=unix"); \
-+ builtin_assert ("system=posix"); \
-+ } while (0)
---- /dev/null
-+++ b/gcc/config/ubicom32/xm-ubicom32.h
-@@ -0,0 +1,36 @@
-+/* Configuration for Ubicom's Ubicom32 architecture.
-+ Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Free Software
-+ Foundation, Inc.
-+ Contributed by Ubicom Inc.
-+
-+This file is part of GNU CC.
-+
-+GNU CC is free software; you can redistribute it and/or modify
-+it under the terms of the GNU General Public License as published by
-+the Free Software Foundation; either version 2, or (at your option)
-+any later version.
-+
-+GNU CC is distributed in the hope that it will be useful,
-+but WITHOUT ANY WARRANTY; without even the implied warranty of
-+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+GNU General Public License for more details.
-+
-+You should have received a copy of the GNU General Public License
-+along with GNU CC; see the file COPYING. If not, write to
-+the Free Software Foundation, 59 Temple Place - Suite 330,
-+Boston, MA 02111-1307, USA. */
-+
-+/* #defines that need visibility everywhere. */
-+#define FALSE 0
-+#define TRUE 1
-+
-+/* This describes the machine the compiler is hosted on. */
-+#define HOST_BITS_PER_CHAR 8
-+#define HOST_BITS_PER_SHORT 16
-+#define HOST_BITS_PER_INT 32
-+#define HOST_BITS_PER_LONG 32
-+#define HOST_BITS_PER_LONGLONG 64
-+
-+/* Arguments to use with `exit'. */
-+#define SUCCESS_EXIT_CODE 0
-+#define FATAL_EXIT_CODE 33
---- a/gcc/config.gcc
-+++ b/gcc/config.gcc
-@@ -2314,6 +2314,34 @@ spu-*-elf*)
- c_target_objs="${c_target_objs} spu-c.o"
- cxx_target_objs="${cxx_target_objs} spu-c.o"
- ;;
-+ubicom32-*-elf)
-+ xm_file=ubicom32/xm-ubicom32.h
-+ tm_file="${tm_file} ubicom32/elf.h" # still need dbxelf.h elfos.h
-+ tmake_file=ubicom32/t-ubicom32
-+ ;;
-+ubicom32-*-uclinux*)
-+ xm_file=ubicom32/xm-ubicom32.h
-+ tm_file="${tm_file} ubicom32/elf.h ubicom32/uclinux.h" # still need dbxelf.h elfos.h linux.h
-+ tm_defines="${tm_defines} UCLIBC_DEFAULT=1"
-+ extra_options="${extra_options} linux.opt"
-+ tmake_file=ubicom32/t-ubicom32-uclinux
-+ use_collect2=no
-+ ;;
-+ubicom32-*-linux-uclibc)
-+ xm_file=ubicom32/xm-ubicom32.h
-+ tm_file="${tm_file} ubicom32/elf.h linux.h ubicom32/linux.h" # still need dbxelf.h elfos.h
-+ tmake_file="t-slibgcc-elf-ver ubicom32/t-ubicom32-linux"
-+ extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
-+ use_collect2=no
-+ ;;
-+ubicom32-*-linux*)
-+ xm_file=ubicom32/xm-ubicom32.h
-+ tm_file="${tm_file} ubicom32/elf.h linux.h ubicom32/linux.h" # still need dbxelf.h elfos.h
-+ tmake_file="t-slibgcc-elf-ver ubicom32/t-ubicom32-linux"
-+ tm_defines="${tm_defines} UCLIBC_DEFAULT=1"
-+ extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
-+ use_collect2=no
-+ ;;
- v850e1-*-*)
- target_cpu_default="TARGET_CPU_v850e1"
- tm_file="dbxelf.h elfos.h svr4.h v850/v850.h"
---- a/libgcc/config.host
-+++ b/libgcc/config.host
-@@ -551,6 +551,15 @@ sparc64-*-netbsd*)
- ;;
- spu-*-elf*)
- ;;
-+ubicom32*-*-elf*)
-+ ;;
-+ubicom32*-*-uclinux*)
-+ ;;
-+ubicom32*-*-linux*)
-+ # No need to build crtbeginT.o on uClibc systems. Should probably
-+ # be moved to the OS specific section above.
-+ extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
-+ ;;
- v850e1-*-*)
- ;;
- v850e-*-*)
+++ /dev/null
---- a/gcc/config/arm/linux-elf.h
-+++ b/gcc/config/arm/linux-elf.h
-@@ -60,7 +60,7 @@
- %{shared:-lc} \
- %{!shared:%{profile:-lc_p}%{!profile:-lc}}"
-
--#define LIBGCC_SPEC "%{msoft-float:-lfloat} %{mfloat-abi=soft*:-lfloat} -lgcc"
-+#define LIBGCC_SPEC "-lgcc"
-
- #define GLIBC_DYNAMIC_LINKER "/lib/ld-linux.so.2"
-
---- a/gcc/config/arm/t-linux
-+++ b/gcc/config/arm/t-linux
-@@ -4,7 +4,10 @@
-
- LIB1ASMSRC = arm/lib1funcs.asm
- LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_lnx _clzsi2 _clzdi2 \
-- _arm_addsubdf3 _arm_addsubsf3
-+ _arm_addsubdf3 _arm_addsubsf3 \
-+ _negdf2 _addsubdf3 _muldivdf3 _cmpdf2 _unorddf2 _fixdfsi _fixunsdfsi \
-+ _truncdfsf2 _negsf2 _addsubsf3 _muldivsf3 _cmpsf2 _unordsf2 \
-+ _fixsfsi _fixunssfsi _floatdidf _floatundidf _floatdisf _floatundisf
-
- # MULTILIB_OPTIONS = mhard-float/msoft-float
- # MULTILIB_DIRNAMES = hard-float soft-float
+++ /dev/null
---- a/libgcc/Makefile.in
-+++ b/libgcc/Makefile.in
-@@ -729,11 +729,12 @@ $(libgcov-objects): %$(objext): $(gcc_sr
-
- # Static libraries.
- libgcc.a: $(libgcc-objects)
-+libgcc_pic.a: $(libgcc-s-objects)
- libgcov.a: $(libgcov-objects)
- libunwind.a: $(libunwind-objects)
- libgcc_eh.a: $(libgcc-eh-objects)
-
--libgcc.a libgcov.a libunwind.a libgcc_eh.a:
-+libgcc.a libgcov.a libunwind.a libgcc_eh.a libgcc_pic.a:
- -rm -f $@
-
- objects="$(objects)"; \
-@@ -755,7 +756,7 @@ libgcc_s$(SHLIB_EXT): libunwind$(SHLIB_E
- endif
-
- ifeq ($(enable_shared),yes)
--all: libgcc_eh.a libgcc_s$(SHLIB_EXT)
-+all: libgcc_eh.a libgcc_pic.a libgcc_s$(SHLIB_EXT)
- ifneq ($(LIBUNWIND),)
- all: libunwind$(SHLIB_EXT)
- endif
-@@ -928,6 +929,10 @@ install-shared:
- chmod 644 $(DESTDIR)$(inst_libdir)/libgcc_eh.a
- $(RANLIB) $(DESTDIR)$(inst_libdir)/libgcc_eh.a
-
-+ $(INSTALL_DATA) libgcc_pic.a $(mapfile) $(DESTDIR)$(inst_libdir)/
-+ chmod 644 $(DESTDIR)$(inst_libdir)/libgcc_pic.a
-+ $(RANLIB) $(DESTDIR)$(inst_libdir)/libgcc_pic.a
-+
- $(subst @multilib_dir@,$(MULTIDIR),$(subst \
- @shlib_base_name@,libgcc_s,$(subst \
- @shlib_slibdir_qual@,$(MULTIOSSUBDIR),$(SHLIB_INSTALL))))
+++ /dev/null
-
- This patch brings over a few features from MirBSD:
- * -fhonour-copts
- If this option is not given, it's warned (depending
- on environment variables). This is to catch errors
- of misbuilt packages which override CFLAGS themselves.
- * -Werror-maybe-reset
- Has the effect of -Wno-error if GCC_NO_WERROR is
- set and not '0', a no-operation otherwise. This is
- to be able to use -Werror in "make" but prevent
- GNU autoconf generated configure scripts from
- freaking out.
- * Make -fno-strict-aliasing and -fno-delete-null-pointer-checks
- the default for -O2/-Os, because they trigger gcc bugs
- and can delete code with security implications.
-
- This patch was authored by Thorsten Glaser <tg at mirbsd.de>
- with copyright assignment to the FSF in effect.
-
---- a/gcc/c-opts.c
-+++ b/gcc/c-opts.c
-@@ -105,6 +105,9 @@
- /* Number of deferred options scanned for -include. */
- static size_t include_cursor;
-
-+/* Check if a port honours COPTS. */
-+static int honour_copts = 0;
-+
- static void set_Wimplicit (int);
- static void handle_OPT_d (const char *);
- static void set_std_cxx98 (int);
-@@ -454,6 +457,14 @@
- enable_warning_as_error ("implicit-function-declaration", value, CL_C | CL_ObjC);
- break;
-
-+ case OPT_Werror_maybe_reset:
-+ {
-+ char *ev = getenv ("GCC_NO_WERROR");
-+ if ((ev != NULL) && (*ev != '0'))
-+ cpp_opts->warnings_are_errors = 0;
-+ }
-+ break;
-+
- case OPT_Wformat:
- set_Wformat (value);
- break;
-@@ -690,6 +701,12 @@
- flag_exceptions = value;
- break;
-
-+ case OPT_fhonour_copts:
-+ if (c_language == clk_c) {
-+ honour_copts++;
-+ }
-+ break;
-+
- case OPT_fimplement_inlines:
- flag_implement_inlines = value;
- break;
-@@ -1209,6 +1226,47 @@
- return false;
- }
-
-+ if (c_language == clk_c) {
-+ char *ev = getenv ("GCC_HONOUR_COPTS");
-+ int evv;
-+ if (ev == NULL)
-+ evv = -1;
-+ else if ((*ev == '0') || (*ev == '\0'))
-+ evv = 0;
-+ else if (*ev == '1')
-+ evv = 1;
-+ else if (*ev == '2')
-+ evv = 2;
-+ else if (*ev == 's')
-+ evv = -1;
-+ else {
-+ warning (0, "unknown GCC_HONOUR_COPTS value, assuming 1");
-+ evv = 1; /* maybe depend this on something like MIRBSD_NATIVE? */
-+ }
-+ if (evv == 1) {
-+ if (honour_copts == 0) {
-+ error ("someone does not honour COPTS at all in lenient mode");
-+ return false;
-+ } else if (honour_copts != 1) {
-+ warning (0, "someone does not honour COPTS correctly, passed %d times",
-+ honour_copts);
-+ }
-+ } else if (evv == 2) {
-+ if (honour_copts == 0) {
-+ error ("someone does not honour COPTS at all in strict mode");
-+ return false;
-+ } else if (honour_copts != 1) {
-+ error ("someone does not honour COPTS correctly, passed %d times",
-+ honour_copts);
-+ return false;
-+ }
-+ } else if (evv == 0) {
-+ if (honour_copts != 1)
-+ inform (0, "someone does not honour COPTS correctly, passed %d times",
-+ honour_copts);
-+ }
-+ }
-+
- return true;
- }
-
---- a/gcc/c.opt
-+++ b/gcc/c.opt
-@@ -215,6 +215,10 @@
- C ObjC RejectNegative Warning
- This switch is deprecated; use -Werror=implicit-function-declaration instead
-
-+Werror-maybe-reset
-+C ObjC C++ ObjC++
-+; Documented in common.opt
-+
- Wfloat-equal
- C ObjC C++ ObjC++ Var(warn_float_equal) Warning
- Warn if testing floating point numbers for equality
-@@ -609,6 +613,9 @@
- fhonor-std
- C++ ObjC++
-
-+fhonour-copts
-+C ObjC C++ ObjC++ RejectNegative
-+
- fhosted
- C ObjC
- Assume normal C execution environment
---- a/gcc/common.opt
-+++ b/gcc/common.opt
-@@ -102,6 +102,10 @@
- Common Joined
- Treat specified warning as error
-
-+Werror-maybe-reset
-+Common
-+If environment variable GCC_NO_WERROR is set, act as -Wno-error
-+
- Wextra
- Common Warning
- Print extra (possibly unwanted) warnings
-@@ -573,6 +577,9 @@
- Common Report Var(flag_guess_branch_prob) Optimization
- Enable guessing of branch probabilities
-
-+fhonour-copts
-+Common RejectNegative
-+
- ; Nonzero means ignore `#ident' directives. 0 means handle them.
- ; Generate position-independent code for executables if possible
- ; On SVR4 targets, it also controls whether or not to emit a
---- a/gcc/opts.c
-+++ b/gcc/opts.c
-@@ -896,9 +896,6 @@
- flag_schedule_insns_after_reload = opt2;
- #endif
- flag_regmove = opt2;
-- flag_strict_aliasing = opt2;
-- flag_strict_overflow = opt2;
-- flag_delete_null_pointer_checks = opt2;
- flag_reorder_blocks = opt2;
- flag_reorder_functions = opt2;
- flag_tree_vrp = opt2;
-@@ -922,6 +919,9 @@
-
- /* -O3 optimizations. */
- opt3 = (optimize >= 3);
-+ flag_strict_aliasing = opt3;
-+ flag_strict_overflow = opt3;
-+ flag_delete_null_pointer_checks = opt3;
- flag_predictive_commoning = opt3;
- flag_inline_functions = opt3;
- flag_unswitch_loops = opt3;
-@@ -1601,6 +1601,17 @@
- enable_warning_as_error (arg, value, lang_mask);
- break;
-
-+ case OPT_Werror_maybe_reset:
-+ {
-+ char *ev = getenv ("GCC_NO_WERROR");
-+ if ((ev != NULL) && (*ev != '0'))
-+ warnings_are_errors = 0;
-+ }
-+ break;
-+
-+ case OPT_fhonour_copts:
-+ break;
-+
- case OPT_Wextra:
- set_Wextra (value);
- break;
---- a/gcc/doc/cppopts.texi
-+++ b/gcc/doc/cppopts.texi
-@@ -164,6 +164,11 @@
- Make all warnings into hard errors. Source code which triggers warnings
- will be rejected.
-
-+ at item -Werror-maybe-reset
-+ at opindex Werror-maybe-reset
-+Act like @samp{-Wno-error} if the @env{GCC_NO_WERROR} environment
-+variable is set to anything other than 0 or empty.
-+
- @item -Wsystem-headers
- @opindex Wsystem-headers
- Issue warnings for code in system headers. These are normally unhelpful
---- a/gcc/doc/invoke.texi
-+++ b/gcc/doc/invoke.texi
-@@ -234,7 +234,7 @@
- -Wconversion -Wcoverage-mismatch -Wno-deprecated @gol
- -Wno-deprecated-declarations -Wdisabled-optimization @gol
- -Wno-div-by-zero -Wempty-body -Wenum-compare -Wno-endif-labels @gol
---Werror -Werror=* @gol
-+-Werror -Werror=* -Werror-maybe-reset @gol
- -Wfatal-errors -Wfloat-equal -Wformat -Wformat=2 @gol
- -Wno-format-contains-nul -Wno-format-extra-args -Wformat-nonliteral @gol
- -Wformat-security -Wformat-y2k @gol
-@@ -4161,6 +4161,22 @@
- @option{-Wall} and by @option{-pedantic}, which can be disabled with
- @option{-Wno-pointer-sign}.
-
-+ at item -Werror-maybe-reset
-+ at opindex Werror-maybe-reset
-+Act like @samp{-Wno-error} if the @env{GCC_NO_WERROR} environment
-+variable is set to anything other than 0 or empty.
-+
-+ at item -fhonour-copts
-+ at opindex fhonour-copts
-+If @env{GCC_HONOUR_COPTS} is set to 1, abort if this option is not
-+given at least once, and warn if it is given more than once.
-+If @env{GCC_HONOUR_COPTS} is set to 2, abort if this option is not
-+given exactly once.
-+If @env{GCC_HONOUR_COPTS} is set to 0 or unset, warn if this option
-+is not given exactly once.
-+The warning is quelled if @env{GCC_HONOUR_COPTS} is set to @samp{s}.
-+This flag and environment variable only affect the C language.
-+
- @item -Wstack-protector
- @opindex Wstack-protector
- @opindex Wno-stack-protector
-@@ -5699,7 +5715,7 @@
- second branch or a point immediately following it, depending on whether
- the condition is known to be true or false.
-
--Enabled at levels @option{-O2}, @option{-O3}, @option{-Os}.
-+Enabled at levels @option{-O3}.
-
- @item -fsplit-wide-types
- @opindex fsplit-wide-types
-@@ -5844,7 +5860,7 @@
- @option{-fno-delete-null-pointer-checks} to disable this optimization
- for programs which depend on that behavior.
-
--Enabled at levels @option{-O2}, @option{-O3}, @option{-Os}.
-+Enabled at levels @option{-O3}.
-
- @item -fexpensive-optimizations
- @opindex fexpensive-optimizations
---- a/gcc/java/jvspec.c
-+++ b/gcc/java/jvspec.c
-@@ -670,6 +670,7 @@
- class name. Append dummy `.c' that can be stripped by set_input so %b
- is correct. */
- set_input (concat (main_class_name, "main.c", NULL));
-+ putenv ("GCC_HONOUR_COPTS=s"); /* XXX hack! */
- err = do_spec (jvgenmain_spec);
- if (err == 0)
- {
+++ /dev/null
---- gcc-4.4.0/gcc/config/arm/arm-protos.h 2009-02-20 16:20:38.000000000 +0100
-+++ gcc-4.4.0.new/gcc/config/arm/arm-protos.h 2009-04-22 16:00:58.000000000 +0200
-@@ -43,10 +43,10 @@
- extern void arm_output_fn_unwind (FILE *, bool);
-
-
--#ifdef RTX_CODE
- extern bool arm_vector_mode_supported_p (enum machine_mode);
- extern int arm_hard_regno_mode_ok (unsigned int, enum machine_mode);
- extern int const_ok_for_arm (HOST_WIDE_INT);
-+#ifdef RTX_CODE
- extern int arm_split_constant (RTX_CODE, enum machine_mode, rtx,
- HOST_WIDE_INT, rtx, rtx, int);
- extern RTX_CODE arm_canonicalize_comparison (RTX_CODE, enum machine_mode,
+++ /dev/null
-Index: gcc-4.4.2/gcc/config.gcc
-===================================================================
---- gcc-4.4.2.orig/gcc/config.gcc 2009-10-21 16:19:39.000000000 +0200
-+++ gcc-4.4.2/gcc/config.gcc 2009-10-21 16:19:40.000000000 +0200
-@@ -1506,6 +1506,7 @@
- if test x$sjlj != x1; then
- tmake_file="$tmake_file m68k/t-slibgcc-elf-ver"
- fi
-+ tmake_file="m68k/t-floatlib m68k/t-m68kbare m68k/t-m68kelf"
- ;;
- m68k-*-rtems*)
- default_m68k_cpu=68020
+++ /dev/null
---- a/config/mh-mingw
-+++ b/config/mh-mingw
-@@ -1,6 +1,8 @@
- # Add -D__USE_MINGW_ACCESS to enable the built compiler to work on Windows
- # Vista (see PR33281 for details).
--BOOT_CFLAGS += -D__USE_MINGW_ACCESS -Wno-pedantic-ms-format
--CFLAGS += -D__USE_MINGW_ACCESS
-+# Because we wrap access in libiberty/cygpath.c, we do not want to use
-+# the MinGW wrappers for access.
-+BOOT_CFLAGS += -Wno-pedantic-ms-format
-+# CFLAGS += -D__USE_MINGW_ACCESS
- # Increase stack limit to same as Linux default.
- LDFLAGS += -Wl,--stack,8388608
---- a/config/stdint.m4
-+++ b/config/stdint.m4
-@@ -115,19 +115,19 @@ AC_MSG_RESULT($acx_cv_header_stdint $acx
-
- # Lacking an uintptr_t? Test size of void *
- case "$acx_cv_header_stdint:$ac_cv_type_uintptr_t" in
-- stddef.h:* | *:no) AC_CHECK_SIZEOF(void *) ;;
-+ stddef.h:* | *:no) AC_CHECK_SIZEOF(void *,,/* no standard headers */) ;;
- esac
-
- # Lacking an uint64_t? Test size of long
- case "$acx_cv_header_stdint:$ac_cv_type_uint64_t:$ac_cv_type_u_int64_t" in
-- stddef.h:*:* | *:no:no) AC_CHECK_SIZEOF(long) ;;
-+ stddef.h:*:* | *:no:no) AC_CHECK_SIZEOF(long,,/* no standard headers */) ;;
- esac
-
- if test $acx_cv_header_stdint = stddef.h; then
- # Lacking a good header? Test size of everything and deduce all types.
-- AC_CHECK_SIZEOF(int)
-- AC_CHECK_SIZEOF(short)
-- AC_CHECK_SIZEOF(char)
-+ AC_CHECK_SIZEOF(int,,/* no standard headers */)
-+ AC_CHECK_SIZEOF(short,,/* no standard headers */)
-+ AC_CHECK_SIZEOF(char,,/* no standard headers */)
-
- AC_MSG_CHECKING(for type equivalent to int8_t)
- case "$ac_cv_sizeof_char" in
---- a/config/tls.m4
-+++ b/config/tls.m4
-@@ -1,5 +1,6 @@
- dnl Check whether the target supports TLS.
- AC_DEFUN([GCC_CHECK_TLS], [
-+ AC_REQUIRE([AC_CANONICAL_HOST])
- GCC_ENABLE(tls, yes, [], [Use thread-local storage])
- AC_CACHE_CHECK([whether the target supports thread-local storage],
- gcc_cv_have_tls, [
-@@ -66,7 +67,24 @@ AC_DEFUN([GCC_CHECK_TLS], [
- [dnl This is the cross-compiling case. Assume libc supports TLS if the
- dnl binutils and the compiler do.
- AC_LINK_IFELSE([__thread int a; int b; int main() { return a = b; }],
-- [gcc_cv_have_tls=yes], [gcc_cv_have_tls=no])
-+ [chktls_save_LDFLAGS="$LDFLAGS"
-+ dnl Shared library options may depend on the host; this check
-+ dnl is only known to be needed for GNU/Linux.
-+ case $host in
-+ *-*-linux*)
-+ LDFLAGS="-shared -Wl,--no-undefined $LDFLAGS"
-+ ;;
-+ esac
-+ chktls_save_CFLAGS="$CFLAGS"
-+ CFLAGS="-fPIC $CFLAGS"
-+ dnl If -shared works, test if TLS works in a shared library.
-+ AC_LINK_IFELSE([int f() { return 0; }],
-+ [AC_LINK_IFELSE([__thread int a; int b; int f() { return a = b; }],
-+ [gcc_cv_have_tls=yes],
-+ [gcc_cv_have_tls=no])],
-+ [gcc_cv_have_tls=yes])
-+ CFLAGS="$chktls_save_CFLAGS"
-+ LDFLAGS="$chktls_save_LDFLAGS"], [gcc_cv_have_tls=no])
- ]
- )])
- if test "$enable_tls $gcc_cv_have_tls" = "yes yes"; then
---- a/configure
-+++ b/configure
-@@ -2277,7 +2277,7 @@ case "${target}" in
- noconfigdirs="$noconfigdirs target-newlib target-libgloss target-rda ${libgcj}"
- ;;
- *-*-vxworks*)
-- noconfigdirs="$noconfigdirs target-newlib target-libgloss target-libiberty target-libstdc++-v3 ${libgcj}"
-+ noconfigdirs="$noconfigdirs target-newlib target-libgloss target-libiberty ${libgcj}"
- ;;
- alpha*-dec-osf*)
- # ld works, but does not support shared libraries.
---- a/configure.ac
-+++ b/configure.ac
-@@ -512,7 +512,7 @@ case "${target}" in
- noconfigdirs="$noconfigdirs target-newlib target-libgloss target-rda ${libgcj}"
- ;;
- *-*-vxworks*)
-- noconfigdirs="$noconfigdirs target-newlib target-libgloss target-libiberty target-libstdc++-v3 ${libgcj}"
-+ noconfigdirs="$noconfigdirs target-newlib target-libgloss target-libiberty ${libgcj}"
- ;;
- alpha*-dec-osf*)
- # ld works, but does not support shared libraries.
---- a/fixincludes/fixincl.tpl
-+++ b/fixincludes/fixincl.tpl
-@@ -38,7 +38,7 @@ x=fixincl.x =]
- #ifndef SED_PROGRAM
- #define SED_PROGRAM "/usr/bin/sed"
- #endif
--static char const sed_cmd_z[] = SED_PROGRAM;
-+static char const sed_cmd_z[] = "sed";
- [=
-
- FOR fix =]
---- a/fixincludes/fixincl.x
-+++ b/fixincludes/fixincl.x
-@@ -2,11 +2,11 @@
- *
- * DO NOT EDIT THIS FILE (fixincl.x)
- *
-- * It has been AutoGen-ed Saturday February 28, 2009 at 10:11:41 AM PST
-+ * It has been AutoGen-ed Monday July 20, 2009 at 01:53:53 PM PDT
- * From the definitions inclhack.def
- * and the template file fixincl
- */
--/* DO NOT SVN-MERGE THIS FILE, EITHER Sat Feb 28 10:11:41 PST 2009
-+/* DO NOT SVN-MERGE THIS FILE, EITHER Mon Jul 20 13:53:53 PDT 2009
- *
- * You must regenerate it. Use the ./genfixes script.
- *
-@@ -15,7 +15,7 @@
- * certain ANSI-incompatible system header files which are fixed to work
- * correctly with ANSI C and placed in a directory that GNU C will search.
- *
-- * This file contains 180 fixup descriptions.
-+ * This file contains 181 fixup descriptions.
- *
- * See README for more information.
- *
-@@ -39,7 +39,7 @@
- #ifndef SED_PROGRAM
- #define SED_PROGRAM "/usr/bin/sed"
- #endif
--static char const sed_cmd_z[] = SED_PROGRAM;
-+static char const sed_cmd_z[] = "sed";
-
- /* * * * * * * * * * * * * * * * * * * * * * * * * *
- *
-@@ -2300,6 +2300,42 @@ s/{ { 0, } }/{ { 0, 0, 0, 0, 0, 0 } }/\n
-
- /* * * * * * * * * * * * * * * * * * * * * * * * * *
- *
-+ * Description of Glibc_String2_Memset fix
-+ */
-+tSCC zGlibc_String2_MemsetName[] =
-+ "glibc_string2_memset";
-+
-+/*
-+ * File name selection pattern
-+ */
-+tSCC zGlibc_String2_MemsetList[] =
-+ "bits/string2.h\0";
-+/*
-+ * Machine/OS name selection pattern
-+ */
-+#define apzGlibc_String2_MemsetMachs (const char**)NULL
-+
-+/*
-+ * content selection pattern - do fix if pattern found
-+ */
-+tSCC zGlibc_String2_MemsetSelect0[] =
-+ "#ifndef _HAVE_STRING_ARCH_memset\n\
-+# if _STRING_ARCH_unaligned";
-+
-+#define GLIBC_STRING2_MEMSET_TEST_CT 1
-+static tTestDesc aGlibc_String2_MemsetTests[] = {
-+ { TT_EGREP, zGlibc_String2_MemsetSelect0, (regex_t*)NULL }, };
-+
-+/*
-+ * Fix Command Arguments for Glibc_String2_Memset
-+ */
-+static const char* apzGlibc_String2_MemsetPatch[] = {
-+ "format",
-+ "%0 && 0",
-+ (char*)NULL };
-+
-+/* * * * * * * * * * * * * * * * * * * * * * * * * *
-+ *
- * Description of Gnu_Types fix
- */
- tSCC zGnu_TypesName[] =
-@@ -5617,8 +5653,7 @@ tSCC zSolaris_Mutex_Init_2List[] =
- * Machine/OS name selection pattern
- */
- tSCC* apzSolaris_Mutex_Init_2Machs[] = {
-- "*-*-solaris2.[0-9]",
-- "*-*-solaris2.[0-9][!0-9]*",
-+ "*-*-solaris*",
- (const char*)NULL };
-
- /*
-@@ -5627,8 +5662,15 @@ tSCC* apzSolaris_Mutex_Init_2Machs[] = {
- tSCC zSolaris_Mutex_Init_2Select0[] =
- "@\\(#\\)pthread.h[ \t]+1.[0-9]+[ \t]+[0-9/]+ SMI";
-
--#define SOLARIS_MUTEX_INIT_2_TEST_CT 1
-+/*
-+ * perform the 'test' shell command - do fix on success
-+ */
-+tSCC zSolaris_Mutex_Init_2Test0[] =
-+ " -n \"`grep '#if __STDC__ - 0 == 0 && !defined(_NO_LONGLONG)' \\`dirname $file\\`/sys/types.h`\"";
-+
-+#define SOLARIS_MUTEX_INIT_2_TEST_CT 2
- static tTestDesc aSolaris_Mutex_Init_2Tests[] = {
-+ { TT_TEST, zSolaris_Mutex_Init_2Test0, 0 /* unused */ },
- { TT_EGREP, zSolaris_Mutex_Init_2Select0, (regex_t*)NULL }, };
-
- /*
-@@ -5670,8 +5712,15 @@ tSCC* apzSolaris_Rwlock_Init_1Machs[] =
- tSCC zSolaris_Rwlock_Init_1Select0[] =
- "@\\(#\\)pthread.h[ \t]+1.[0-9]+[ \t]+[0-9/]+ SMI";
-
--#define SOLARIS_RWLOCK_INIT_1_TEST_CT 1
-+/*
-+ * perform the 'test' shell command - do fix on success
-+ */
-+tSCC zSolaris_Rwlock_Init_1Test0[] =
-+ " -n \"`grep '#if __STDC__ - 0 == 0 && !defined(_NO_LONGLONG)' \\`dirname $file\\`/sys/types.h`\"";
-+
-+#define SOLARIS_RWLOCK_INIT_1_TEST_CT 2
- static tTestDesc aSolaris_Rwlock_Init_1Tests[] = {
-+ { TT_TEST, zSolaris_Rwlock_Init_1Test0, 0 /* unused */ },
- { TT_EGREP, zSolaris_Rwlock_Init_1Select0, (regex_t*)NULL }, };
-
- /*
-@@ -5741,8 +5790,7 @@ tSCC zSolaris_Once_Init_2List[] =
- * Machine/OS name selection pattern
- */
- tSCC* apzSolaris_Once_Init_2Machs[] = {
-- "*-*-solaris2.[0-9]",
-- "*-*-solaris2.[0-9][!0-9]*",
-+ "*-*-solaris*",
- (const char*)NULL };
-
- /*
-@@ -5751,8 +5799,15 @@ tSCC* apzSolaris_Once_Init_2Machs[] = {
- tSCC zSolaris_Once_Init_2Select0[] =
- "@\\(#\\)pthread.h[ \t]+1.[0-9]+[ \t]+[0-9/]+ SMI";
-
--#define SOLARIS_ONCE_INIT_2_TEST_CT 1
-+/*
-+ * perform the 'test' shell command - do fix on success
-+ */
-+tSCC zSolaris_Once_Init_2Test0[] =
-+ " -n \"`grep '#if __STDC__ - 0 == 0 && !defined(_NO_LONGLONG)' \\`dirname $file\\`/sys/types.h`\"";
-+
-+#define SOLARIS_ONCE_INIT_2_TEST_CT 2
- static tTestDesc aSolaris_Once_Init_2Tests[] = {
-+ { TT_TEST, zSolaris_Once_Init_2Test0, 0 /* unused */ },
- { TT_EGREP, zSolaris_Once_Init_2Select0, (regex_t*)NULL }, };
-
- /*
-@@ -7308,9 +7363,9 @@ static const char* apzX11_SprintfPatch[]
- *
- * List of all fixes
- */
--#define REGEX_COUNT 226
--#define MACH_LIST_SIZE_LIMIT 181
--#define FIX_COUNT 180
-+#define REGEX_COUNT 227
-+#define MACH_LIST_SIZE_LIMIT 169
-+#define FIX_COUNT 181
-
- /*
- * Enumerate the fixes
-@@ -7371,6 +7426,7 @@ typedef enum {
- GLIBC_C99_INLINE_3_FIXIDX,
- GLIBC_C99_INLINE_4_FIXIDX,
- GLIBC_MUTEX_INIT_FIXIDX,
-+ GLIBC_STRING2_MEMSET_FIXIDX,
- GNU_TYPES_FIXIDX,
- HP_INLINE_FIXIDX,
- HP_SYSFILE_FIXIDX,
-@@ -7774,6 +7830,11 @@ tFixDesc fixDescList[ FIX_COUNT ] = {
- GLIBC_MUTEX_INIT_TEST_CT, FD_MACH_ONLY,
- aGlibc_Mutex_InitTests, apzGlibc_Mutex_InitPatch, 0 },
-
-+ { zGlibc_String2_MemsetName, zGlibc_String2_MemsetList,
-+ apzGlibc_String2_MemsetMachs,
-+ GLIBC_STRING2_MEMSET_TEST_CT, FD_MACH_ONLY | FD_SUBROUTINE,
-+ aGlibc_String2_MemsetTests, apzGlibc_String2_MemsetPatch, 0 },
-+
- { zGnu_TypesName, zGnu_TypesList,
- apzGnu_TypesMachs,
- GNU_TYPES_TEST_CT, FD_MACH_IFNOT | FD_SUBROUTINE,
---- a/fixincludes/inclhack.def
-+++ b/fixincludes/inclhack.def
-@@ -1302,6 +1302,21 @@ fix = {
- };
-
-
-+/* glibc's bits/string2.h (before 2004-05-26) generates bogus
-+ -Wstrict-aliasing warnings from calls to memset. */
-+fix = {
-+ hackname = glibc_string2_memset;
-+ files = "bits/string2.h";
-+ select = "#ifndef _HAVE_STRING_ARCH_memset\n# if _STRING_ARCH_unaligned";
-+ c_fix = format;
-+ c_fix_arg = "%0 && 0";
-+ test_text = "#ifndef _HAVE_STRING_ARCH_memset\n"
-+ "# if _STRING_ARCH_unaligned\n"
-+ "# endif\n"
-+ "#endif\n";
-+};
-+
-+
- /*
- * Fix these files to use the types we think they should for
- * ptrdiff_t, size_t, and wchar_t.
-@@ -2939,24 +2954,32 @@ fix = {
- };
-
- /*
-- * Sun Solaris defines PTHREAD_MUTEX_INITIALIZER with a trailing
-- * "0" for the last field of the pthread_mutex_t structure, which is
-- * of type upad64_t, which itself is typedef'd to int64_t, but with
-- * __STDC__ defined (e.g. by -ansi) it is a union. So change the
-- * initializer to "{0}" instead
-+ * Sun Solaris defines the last field of the pthread_mutex_t structure
-+ * to have type upad64_t. Whether upad64_t is an integer type or a
-+ * union depends on whether or not the headers believe that a 64-bit
-+ * integer type is available. But, PTHREAD_MUTEX_INITIALIZER is not
-+ * appropriately conditionalized; it always uses "0", and never "{0}".
-+ * In order to avoid warnings/errors from the compiler, we must make
-+ * the initializer use braces where appropriate.
-+ *
-+ * Prior to Solaris 10, if __STDC__ is 1 (as when compiling with
-+ * -ansi), the definition would be a union. Beginning with Solaris
-+ * 10, the headers check for __GNUC__, and will never use a union with
-+ * GCC. We check /usr/include/sys/types.h to see if it checks for
-+ * __STDC__.
-+ *
-+ * A "mach" test for Solaris 10 is undesirable because we want to
-+ * allow a compiler built for Solaris <10 to be used on Solaris >=10,
-+ * but the installed version of fixincludes hard-wires the target
-+ * machine to the configure-time $target, rather than automatically
-+ * determining it at installation time.
- */
- fix = {
- hackname = solaris_mutex_init_2;
- select = '@\(#\)pthread.h' "[ \t]+1.[0-9]+[ \t]+[0-9/]+ SMI";
- files = pthread.h;
-- /*
-- * On Solaris 10, this fix is unnecessary because upad64_t is
-- * always defined correctly regardless of the definition of the
-- * __STDC__ macro. The first "mach" pattern matches up to
-- * solaris9. The second "mach" pattern will not match any two (or
-- * more) digit solaris version, but it will match e.g. 2.5.1.
-- */
-- mach = '*-*-solaris2.[0-9]', '*-*-solaris2.[0-9][!0-9]*';
-+ mach = '*-*-solaris*';
-+ test = " -n \"`grep '#if __STDC__ - 0 == 0 && !defined(_NO_LONGLONG)' \\`dirname $file\\`/sys/types.h`\"";
- c_fix = format;
- c_fix_arg = "#if __STDC__ - 0 == 0 && !defined(_NO_LONGLONG)\n"
- "%0\n"
-@@ -2967,6 +2990,7 @@ fix = {
- "(|/\*.*\*/[ \t]*\\\\\n[ \t]*)\\{.*)"
- ",[ \t]*0\\}" "(|[ \t].*)$";
- test_text =
-+ "`mkdir -p sys; echo '#if __STDC__ - 0 == 0 && !defined(_NO_LONGLONG)' >> sys/types.h`"
- '#ident "@(#)pthread.h 1.26 98/04/12 SMI"'"\n"
- "#define PTHREAD_MUTEX_INITIALIZER\t{{{0},0}, {{{0}}}, 0}\n"
- "#define PTHREAD_COND_INITIALIZER\t{{{0}, 0}, 0}\t/* DEFAULTCV */\n"
-@@ -2978,17 +3002,14 @@ fix = {
-
-
- /*
-- * Sun Solaris defines PTHREAD_RWLOCK_INITIALIZER with a "0" for some
-- * fields of the pthread_rwlock_t structure, which are of type
-- * upad64_t, which itself is typedef'd to int64_t, but with __STDC__
-- * defined (e.g. by -ansi) it is a union. So change the initializer
-- * to "{0}" instead.
-+ * See comments for solaris_mutex_init_2 re. upad64_t.
- */
- fix = {
- hackname = solaris_rwlock_init_1;
- select = '@\(#\)pthread.h' "[ \t]+1.[0-9]+[ \t]+[0-9/]+ SMI";
- files = pthread.h;
- mach = '*-*-solaris*';
-+ test = " -n \"`grep '#if __STDC__ - 0 == 0 && !defined(_NO_LONGLONG)' \\`dirname $file\\`/sys/types.h`\"";
- c_fix = format;
- c_fix_arg = "#if __STDC__ - 0 == 0 && !defined(_NO_LONGLONG)\n"
- "%0\n"
-@@ -3024,24 +3045,14 @@ fix = {
-
-
- /*
-- * Sun Solaris defines PTHREAD_ONCE_INIT with a "0" for some
-- * fields of the pthread_once_t structure, which are of type
-- * upad64_t, which itself is typedef'd to int64_t, but with __STDC__
-- * defined (e.g. by -ansi) it is a union. So change the initializer
-- * to "{0}" instead. This test relies on solaris_once_init_1.
-+ * See comments for solaris_mutex_init_2 re. upad64_t.
- */
- fix = {
- hackname = solaris_once_init_2;
- select = '@\(#\)pthread.h' "[ \t]+1.[0-9]+[ \t]+[0-9/]+ SMI";
- files = pthread.h;
-- /*
-- * On Solaris 10, this fix is unnecessary because upad64_t is
-- * always defined correctly regardless of the definition of the
-- * __STDC__ macro. The first "mach" pattern matches up to
-- * solaris9. The second "mach" pattern will not match any two (or
-- * more) digit solaris version, but it will match e.g. 2.5.1.
-- */
-- mach = '*-*-solaris2.[0-9]', '*-*-solaris2.[0-9][!0-9]*';
-+ mach = '*-*-solaris*';
-+ test = " -n \"`grep '#if __STDC__ - 0 == 0 && !defined(_NO_LONGLONG)' \\`dirname $file\\`/sys/types.h`\"";
- c_fix = format;
- c_fix_arg = "#if __STDC__ - 0 == 0 && !defined(_NO_LONGLONG)\n"
- "%0\n"
---- a/fixincludes/server.c
-+++ b/fixincludes/server.c
-@@ -266,7 +266,7 @@ run_shell (const char* pz_cmd)
- /* Make sure the process will pay attention to us, send the
- supplied command, and then have it output a special marker that
- we can find. */
-- fprintf (server_pair.pf_write, "cd %s\n%s\n\necho\necho %s\n",
-+ fprintf (server_pair.pf_write, "cd '%s'\n%s\n\necho\necho %s\n",
- p_cur_dir, pz_cmd, z_done);
- fflush (server_pair.pf_write);
-
---- a/fixincludes/tests/base/bits/string2.h
-+++ b/fixincludes/tests/base/bits/string2.h
-@@ -16,3 +16,12 @@
- # define __STRING_INLINE extern __inline
- # endif
- #endif /* GLIBC_C99_INLINE_3_CHECK */
-+
-+
-+#if defined( GLIBC_STRING2_MEMSET_CHECK )
-+#ifndef _HAVE_STRING_ARCH_memset
-+# if _STRING_ARCH_unaligned && 0
-+# endif
-+#endif
-+
-+#endif /* GLIBC_STRING2_MEMSET_CHECK */
---- a/fixincludes/tests/base/sys/types.h
-+++ b/fixincludes/tests/base/sys/types.h
-@@ -28,3 +28,4 @@ typedef __WCHAR_TYPE__ wchar_t;
-
- #endif /* ushort_t */
- #endif /* GNU_TYPES_CHECK */
-+#if !defined(__STRICT_ANSI__) && !defined(_NO_LONGLONG)
---- a/gcc/Makefile.in
-+++ b/gcc/Makefile.in
-@@ -327,6 +327,8 @@ GCC_FOR_TARGET = $(STAGE_CC_WRAPPER) ./x
- # It also specifies -isystem ./include to find, e.g., stddef.h.
- GCC_CFLAGS=$(CFLAGS_FOR_TARGET) $(INTERNAL_CFLAGS) $(T_CFLAGS) $(LOOSE_WARN) -Wold-style-definition $($@-warn) -isystem ./include $(TCFLAGS)
-
-+EGLIBC_CONFIGS = @EGLIBC_CONFIGS@
-+
- # ---------------------------------------------------
- # Programs which produce files for the target machine
- # ---------------------------------------------------
-@@ -408,6 +410,9 @@ TARGET_SYSTEM_ROOT = @TARGET_SYSTEM_ROOT
-
- xmake_file=@xmake_file@
- tmake_file=@tmake_file@
-+TM_ENDIAN_CONFIG=@TM_ENDIAN_CONFIG@
-+TM_MULTILIB_CONFIG=@TM_MULTILIB_CONFIG@
-+TM_MULTILIB_EXCEPTIONS_CONFIG=@TM_MULTILIB_EXCEPTIONS_CONFIG@
- out_file=$(srcdir)/config/@out_file@
- out_object_file=@out_object_file@
- md_file=$(srcdir)/config/@md_file@
-@@ -1249,6 +1254,7 @@ OBJS-common = \
- tree-ssa-loop-manip.o \
- tree-ssa-loop-niter.o \
- tree-ssa-loop-prefetch.o \
-+ tree-ssa-loop-promote.o \
- tree-ssa-loop-unswitch.o \
- tree-ssa-loop.o \
- tree-ssa-math-opts.o \
-@@ -1258,6 +1264,7 @@ OBJS-common = \
- tree-ssa-pre.o \
- tree-ssa-propagate.o \
- tree-ssa-reassoc.o \
-+ tree-ssa-remove-local-statics.o \
- tree-ssa-sccvn.o \
- tree-ssa-sink.o \
- tree-ssa-structalias.o \
-@@ -1674,7 +1681,7 @@ libgcc-support: libgcc.mvars stmp-int-hd
- $(MACHMODE_H) $(FPBIT) $(DPBIT) $(TPBIT) $(LIB2ADD) \
- $(LIB2ADD_ST) $(LIB2ADDEH) $(srcdir)/emutls.c gcov-iov.h $(SFP_MACHINE)
-
--libgcc.mvars: config.status Makefile $(LIB2ADD) $(LIB2ADD_ST) specs \
-+libgcc.mvars: config.status Makefile $(LIB2ADD) $(LIB2ADD_ST) specs $(tmake_file) \
- xgcc$(exeext)
- : > tmp-libgcc.mvars
- echo LIB1ASMFUNCS = '$(LIB1ASMFUNCS)' >> tmp-libgcc.mvars
-@@ -1728,7 +1735,7 @@ libgcc.mvars: config.status Makefile $(L
- # driver program needs to select the library directory based on the
- # switches.
- multilib.h: s-mlib; @true
--s-mlib: $(srcdir)/genmultilib Makefile
-+s-mlib: $(srcdir)/genmultilib Makefile $(tmakefile)
- if test @enable_multilib@ = yes \
- || test -n "$(MULTILIB_OSDIRNAMES)"; then \
- $(SHELL) $(srcdir)/genmultilib \
-@@ -1739,10 +1746,11 @@ s-mlib: $(srcdir)/genmultilib Makefile
- "$(MULTILIB_EXTRA_OPTS)" \
- "$(MULTILIB_EXCLUSIONS)" \
- "$(MULTILIB_OSDIRNAMES)" \
-+ "$(MULTILIB_ALIASES)" \
- "@enable_multilib@" \
- > tmp-mlib.h; \
- else \
-- $(SHELL) $(srcdir)/genmultilib '' '' '' '' '' '' '' no \
-+ $(SHELL) $(srcdir)/genmultilib '' '' '' '' '' '' '' '' no \
- > tmp-mlib.h; \
- fi
- $(SHELL) $(srcdir)/../move-if-change tmp-mlib.h multilib.h
-@@ -1816,7 +1824,7 @@ gcc.srcextra: gengtype-lex.c
-
- incpath.o: incpath.c incpath.h $(CONFIG_H) $(SYSTEM_H) $(CPPLIB_H) \
- intl.h prefix.h coretypes.h $(TM_H) cppdefault.h $(TARGET_H) \
-- $(MACHMODE_H)
-+ $(MACHMODE_H) $(FLAGS_H) toplev.h
-
- c-decl.o : c-decl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
- $(RTL_H) $(C_TREE_H) $(GGC_H) $(TARGET_H) $(FLAGS_H) $(FUNCTION_H) output.h \
-@@ -1900,7 +1908,7 @@ c-opts.o : c-opts.c $(CONFIG_H) $(SYSTEM
- $(TREE_H) $(C_PRAGMA_H) $(FLAGS_H) $(TOPLEV_H) langhooks.h \
- $(TREE_INLINE_H) $(DIAGNOSTIC_H) intl.h debug.h $(C_COMMON_H) \
- opts.h options.h $(MKDEPS_H) incpath.h cppdefault.h $(TARGET_H) \
-- $(TM_P_H) $(VARRAY_H)
-+ $(TM_P_H) $(VARRAY_H) $(C_TREE_H)
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) \
- $< $(OUTPUT_OPTION) @TARGET_SYSTEM_ROOT_DEFINE@
-
-@@ -1953,7 +1961,8 @@ DRIVER_DEFINES = \
- -DTOOLDIR_BASE_PREFIX=\"$(libsubdir_to_prefix)$(prefix_to_exec_prefix)\" \
- @TARGET_SYSTEM_ROOT_DEFINE@ \
- $(VALGRIND_DRIVER_DEFINES) \
-- `test "X$${SHLIB_LINK}" = "X" || test "@enable_shared@" != "yes" || echo "-DENABLE_SHARED_LIBGCC"`
-+ `test "X$${SHLIB_LINK}" = "X" || test "@enable_shared@" != "yes" || echo "-DENABLE_SHARED_LIBGCC"` \
-+ -DCONFIGURE_SPECS="\"@CONFIGURE_SPECS@\""
-
- gcc.o: gcc.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) intl.h multilib.h \
- Makefile $(lang_specs_files) specs.h prefix.h $(GCC_H) $(FLAGS_H) \
-@@ -2176,6 +2185,9 @@ tree-ssa-pre.o : tree-ssa-pre.c $(TREE_F
- alloc-pool.h $(BASIC_BLOCK_H) $(BITMAP_H) $(HASHTAB_H) $(GIMPLE_H) \
- $(TREE_INLINE_H) tree-iterator.h tree-ssa-sccvn.h $(PARAMS_H) \
- $(DBGCNT_H)
-+tree-ssa-remove-local-statics.o: tree-ssa-remove-local-statics.c \
-+ coretypes.h $(CONFIG_H) $(SYSTEM_H) $(BASIC_BLOCK_H) tree.h tree-pass.h \
-+ $(TM_H) $(HASHTAB_H) $(BASIC_BLOCK_H)
- tree-ssa-sccvn.o : tree-ssa-sccvn.c $(TREE_FLOW_H) $(CONFIG_H) \
- $(SYSTEM_H) $(TREE_H) $(GGC_H) $(DIAGNOSTIC_H) $(TIMEVAR_H) $(FIBHEAP_H) \
- $(TM_H) coretypes.h $(TREE_DUMP_H) tree-pass.h $(FLAGS_H) $(CFGLOOP_H) \
-@@ -2271,6 +2283,12 @@ tree-ssa-loop-prefetch.o: tree-ssa-loop-
- $(CFGLOOP_H) $(PARAMS_H) langhooks.h $(BASIC_BLOCK_H) hard-reg-set.h \
- tree-chrec.h $(TOPLEV_H) langhooks.h $(TREE_INLINE_H) $(TREE_DATA_REF_H) \
- $(OPTABS_H)
-+tree-ssa-loop-promote.o: tree-ssa-loop-promote.c \
-+ coretypes.h $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TOPLEV_H) \
-+ $(RTL_H) $(TM_P_H) hard-reg-set.h $(OBSTACK_H) $(BASIC_BLOCK_H) \
-+ pointer-set.h intl.h $(TREE_H) $(GIMPLE_H) $(HASHTAB_H) $(DIAGNOSTIC_H) \
-+ $(TREE_FLOW_H) $(TREE_DUMP_H) $(CFGLOOP_H) $(FLAGS_H) $(TIMEVAR_H) \
-+ tree-pass.h $(TM_H)
- tree-predcom.o: tree-predcom.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(TM_P_H) \
- $(CFGLOOP_H) $(TREE_FLOW_H) $(GGC_H) $(TREE_DATA_REF_H) $(SCEV_H) \
- $(PARAMS_H) $(DIAGNOSTIC_H) tree-pass.h $(TM_H) coretypes.h tree-affine.h \
-@@ -2865,7 +2883,7 @@ postreload.o : postreload.c $(CONFIG_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 $(TREE_H) $(MACHMODE_H) \
-- $(OBSTACK_H) $(TIMEVAR_H) tree-pass.h $(DF_H) $(DBGCNT_H)
-+ $(OBSTACK_H) $(TIMEVAR_H) tree-pass.h addresses.h $(DF_H) $(DBGCNT_H)
- postreload-gcse.o : postreload-gcse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
- $(TM_H) $(RTL_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h \
- $(RECOG_H) $(EXPR_H) $(BASIC_BLOCK_H) $(FUNCTION_H) output.h $(TOPLEV_H) \
-@@ -3582,7 +3600,7 @@ gcov-dump$(exeext): $(GCOV_DUMP_OBJS) $(
- # be rebuilt.
-
- # Build the include directories.
--stmp-int-hdrs: $(STMP_FIXINC) $(USER_H) $(UNWIND_H) fixinc_list
-+stmp-int-hdrs: $(STMP_FIXINC) $(USER_H) $(UNWIND_H)
- # Copy in the headers provided with gcc.
- # The sed command gets just the last file name component;
- # this is necessary because VPATH could add a dirname.
-@@ -3601,21 +3619,23 @@ stmp-int-hdrs: $(STMP_FIXINC) $(USER_H)
- done
- rm -f include/unwind.h
- cp $(UNWIND_H) include/unwind.h
-- set -e; for ml in `cat fixinc_list`; do \
-- sysroot_headers_suffix=`echo $${ml} | sed -e 's/;.*$$//'`; \
-- multi_dir=`echo $${ml} | sed -e 's/^[^;]*;//'`; \
-- fix_dir=include-fixed$${multi_dir}; \
-- if $(LIMITS_H_TEST) ; then \
-- cat $(srcdir)/limitx.h $(srcdir)/glimits.h $(srcdir)/limity.h > tmp-xlimits.h; \
-- else \
-- cat $(srcdir)/glimits.h > tmp-xlimits.h; \
-- fi; \
-- $(mkinstalldirs) $${fix_dir}; \
-- chmod a+rx $${fix_dir} || true; \
-- rm -f $${fix_dir}/limits.h; \
-- mv tmp-xlimits.h $${fix_dir}/limits.h; \
-- chmod a+r $${fix_dir}/limits.h; \
-- done
-+ set -e; if [ -f fixinc_list ] ; then \
-+ for ml in `cat fixinc_list`; do \
-+ sysroot_headers_suffix=`echo $${ml} | sed -e 's/;.*$$//'`; \
-+ multi_dir=`echo $${ml} | sed -e 's/^[^;]*;//'`; \
-+ fix_dir=include-fixed$${multi_dir}; \
-+ if $(LIMITS_H_TEST) ; then \
-+ cat $(srcdir)/limitx.h $(srcdir)/glimits.h $(srcdir)/limity.h > tmp-xlimits.h; \
-+ else \
-+ cat $(srcdir)/glimits.h > tmp-xlimits.h; \
-+ fi; \
-+ $(mkinstalldirs) $${fix_dir}; \
-+ chmod a+rx $${fix_dir} || true; \
-+ rm -f $${fix_dir}/limits.h; \
-+ mv tmp-xlimits.h $${fix_dir}/limits.h; \
-+ chmod a+r $${fix_dir}/limits.h; \
-+ done; \
-+ fi
- # Install the README
- rm -f include-fixed/README
- cp $(srcdir)/../fixincludes/README-fixinc include-fixed/README
-@@ -4340,16 +4360,18 @@ real-install-headers-cp:
-
- # Install supporting files for fixincludes to be run later.
- install-mkheaders: stmp-int-hdrs $(STMP_FIXPROTO) install-itoolsdirs \
-- macro_list fixinc_list
-+ macro_list
- $(INSTALL_DATA) $(srcdir)/gsyslimits.h \
- $(DESTDIR)$(itoolsdatadir)/gsyslimits.h
- $(INSTALL_DATA) macro_list $(DESTDIR)$(itoolsdatadir)/macro_list
-- $(INSTALL_DATA) fixinc_list $(DESTDIR)$(itoolsdatadir)/fixinc_list
-- set -e; for ml in `cat fixinc_list`; do \
-- multi_dir=`echo $${ml} | sed -e 's/^[^;]*;//'`; \
-- $(mkinstalldirs) $(DESTDIR)$(itoolsdatadir)/include$${multi_dir}; \
-- $(INSTALL_DATA) include-fixed$${multidir}/limits.h $(DESTDIR)$(itoolsdatadir)/include$${multi_dir}/limits.h; \
-- done
-+ set -e; if [ -f fixinc_list ] ; then \
-+ $(INSTALL_DATA) fixinc_list $(DESTDIR)$(itoolsdatadir)/fixinc_list; \
-+ for ml in `cat fixinc_list`; do \
-+ multi_dir=`echo $${ml} | sed -e 's/^[^;]*;//'`; \
-+ $(mkinstalldirs) $(DESTDIR)$(itoolsdatadir)/include$${multi_dir}; \
-+ $(INSTALL_DATA) include-fixed$${multidir}/limits.h $(DESTDIR)$(itoolsdatadir)/include$${multi_dir}/limits.h; \
-+ done; \
-+ fi
- $(INSTALL_SCRIPT) $(srcdir)/../mkinstalldirs \
- $(DESTDIR)$(itoolsdir)/mkinstalldirs ; \
- if [ x$(STMP_FIXPROTO) != x ] ; then \
---- a/gcc/addresses.h
-+++ b/gcc/addresses.h
-@@ -78,3 +78,42 @@ regno_ok_for_base_p (unsigned regno, enu
-
- return ok_for_base_p_1 (regno, mode, outer_code, index_code);
- }
-+
-+/* Wrapper function to unify target macros MODE_INDEX_REG_CLASS and
-+ INDEX_REG_CLASS. Arguments as for the MODE_INDEX_REG_CLASS macro. */
-+
-+static inline enum reg_class
-+index_reg_class (enum machine_mode mode ATTRIBUTE_UNUSED)
-+{
-+#ifdef MODE_INDEX_REG_CLASS
-+ return MODE_INDEX_REG_CLASS (mode);
-+#else
-+ return INDEX_REG_CLASS;
-+#endif
-+}
-+
-+/* Wrapper function to unify target macros REGNO_MODE_OK_FOR_INDEX_P
-+ and REGNO_OK_FOR_INDEX_P. Arguments as for the
-+ REGNO_MODE_OK_FOR_INDEX_P macro. */
-+
-+static inline bool
-+ok_for_index_p_1 (unsigned regno, enum machine_mode mode ATTRIBUTE_UNUSED)
-+{
-+#ifdef REGNO_MODE_OK_FOR_INDEX_P
-+ return REGNO_MODE_OK_FOR_INDEX_P (regno, mode);
-+#else
-+ return REGNO_OK_FOR_INDEX_P (regno);
-+#endif
-+}
-+
-+/* Wrapper around ok_for_index_p_1, for use after register allocation is
-+ complete. Arguments as for the called function. */
-+
-+static inline bool
-+regno_ok_for_index_p (unsigned regno, enum machine_mode mode)
-+{
-+ if (regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] >= 0)
-+ regno = reg_renumber[regno];
-+
-+ return ok_for_index_p_1 (regno, mode);
-+}
---- a/gcc/c-common.c
-+++ b/gcc/c-common.c
-@@ -33,7 +33,6 @@ along with GCC; see the file COPYING3.
- #include "varray.h"
- #include "expr.h"
- #include "c-common.h"
--#include "diagnostic.h"
- #include "tm_p.h"
- #include "obstack.h"
- #include "cpplib.h"
-@@ -42,6 +41,7 @@ along with GCC; see the file COPYING3.
- #include "tree-inline.h"
- #include "c-tree.h"
- #include "toplev.h"
-+#include "diagnostic.h"
- #include "tree-iterator.h"
- #include "hashtab.h"
- #include "tree-mudflap.h"
-@@ -497,6 +497,10 @@ tree (*make_fname_decl) (tree, int);
- This is a count, since unevaluated expressions can nest. */
- int skip_evaluation;
-
-+/* Whether lexing has been completed, so subsequent preprocessor
-+ errors should use the compiler's input_location. */
-+bool done_lexing = false;
-+
- /* Information about how a function name is generated. */
- struct fname_var_t
- {
-@@ -7522,6 +7526,68 @@ c_parse_error (const char *gmsgid, enum
- #undef catenate_messages
- }
-
-+/* Callback from cpp_error for PFILE to print diagnostics from the
-+ preprocessor. The diagnostic is of type LEVEL, at location
-+ LOCATION unless this is after lexing and the compiler's location
-+ should be used instead, with column number possibly overridden by
-+ COLUMN_OVERRIDE if not zero; MSG is the translated message and AP
-+ the arguments. Returns true if a diagnostic was emitted, false
-+ otherwise. */
-+
-+bool
-+c_cpp_error (cpp_reader *pfile ATTRIBUTE_UNUSED, int level,
-+ location_t location, unsigned int column_override,
-+ const char *msg, va_list *ap)
-+{
-+ diagnostic_info diagnostic;
-+ diagnostic_t dlevel;
-+ int save_warn_system_headers = warn_system_headers;
-+ bool ret;
-+
-+ switch (level)
-+ {
-+ case CPP_DL_WARNING_SYSHDR:
-+ if (flag_no_output)
-+ return false;
-+ warn_system_headers = 1;
-+ /* Fall through. */
-+ case CPP_DL_WARNING:
-+ if (flag_no_output)
-+ return false;
-+ dlevel = DK_WARNING;
-+ break;
-+ case CPP_DL_PEDWARN:
-+ if (flag_no_output && !flag_pedantic_errors)
-+ return false;
-+ dlevel = DK_PEDWARN;
-+ break;
-+ case CPP_DL_ERROR:
-+ dlevel = DK_ERROR;
-+ break;
-+ case CPP_DL_ICE:
-+ dlevel = DK_ICE;
-+ break;
-+ case CPP_DL_NOTE:
-+ dlevel = DK_NOTE;
-+ break;
-+ case CPP_DL_FATAL:
-+ dlevel = DK_FATAL;
-+ break;
-+ default:
-+ gcc_unreachable ();
-+ }
-+ if (done_lexing)
-+ location = input_location;
-+ diagnostic_set_info_translated (&diagnostic, msg, ap,
-+ location, dlevel);
-+ if (column_override)
-+ diagnostic_override_column (&diagnostic, column_override);
-+ ret = report_diagnostic (&diagnostic);
-+ if (level == CPP_DL_WARNING_SYSHDR)
-+ warn_system_headers = save_warn_system_headers;
-+ return ret;
-+}
-+
- /* Walk a gimplified function and warn for functions whose return value is
- ignored and attribute((warn_unused_result)) is set. This is done before
- inlining, so we don't have to worry about that. */
---- a/gcc/c-common.h
-+++ b/gcc/c-common.h
-@@ -658,6 +658,11 @@ extern int max_tinst_depth;
-
- extern int skip_evaluation;
-
-+/* Whether lexing has been completed, so subsequent preprocessor
-+ errors should use the compiler's input_location. */
-+
-+extern bool done_lexing;
-+
- /* C types are partitioned into three subsets: object, function, and
- incomplete types. */
- #define C_TYPE_OBJECT_P(type) \
---- a/gcc/c-convert.c
-+++ b/gcc/c-convert.c
-@@ -70,6 +70,7 @@ convert (tree type, tree expr)
- tree e = expr;
- enum tree_code code = TREE_CODE (type);
- const char *invalid_conv_diag;
-+ tree ret;
-
- if (type == error_mark_node
- || expr == error_mark_node
-@@ -85,6 +86,9 @@ convert (tree type, tree expr)
-
- if (type == TREE_TYPE (expr))
- return expr;
-+ ret = targetm.convert_to_type (type, expr);
-+ if (ret)
-+ return ret;
-
- if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (expr)))
- return fold_convert (type, expr);
---- a/gcc/c-decl.c
-+++ b/gcc/c-decl.c
-@@ -4001,6 +4001,7 @@ grokdeclarator (const struct c_declarato
- bool bitfield = width != NULL;
- tree element_type;
- struct c_arg_info *arg_info = 0;
-+ const char *errmsg;
-
- if (decl_context == FUNCDEF)
- funcdef_flag = true, decl_context = NORMAL;
-@@ -4538,6 +4539,12 @@ grokdeclarator (const struct c_declarato
- error ("%qs declared as function returning an array", name);
- type = integer_type_node;
- }
-+ errmsg = targetm.invalid_return_type (type);
-+ if (errmsg)
-+ {
-+ error (errmsg);
-+ type = integer_type_node;
-+ }
-
- /* Construct the function type and go to the next
- inner layer of declarator. */
-@@ -5051,6 +5058,7 @@ grokparms (struct c_arg_info *arg_info,
- {
- tree parm, type, typelt;
- unsigned int parmno;
-+ const char *errmsg;
-
- /* If there is a parameter of incomplete type in a definition,
- this is an error. In a declaration this is valid, and a
-@@ -5094,6 +5102,14 @@ grokparms (struct c_arg_info *arg_info,
- }
- }
-
-+ errmsg = targetm.invalid_parameter_type (type);
-+ if (errmsg)
-+ {
-+ error (errmsg);
-+ TREE_VALUE (typelt) = error_mark_node;
-+ TREE_TYPE (parm) = error_mark_node;
-+ }
-+
- if (DECL_NAME (parm) && TREE_USED (parm))
- warn_if_shadowing (parm);
- }
-@@ -8080,7 +8096,7 @@ c_write_global_declarations (void)
-
- /* Don't waste time on further processing if -fsyntax-only or we've
- encountered errors. */
-- if (flag_syntax_only || errorcount || sorrycount || cpp_errors (parse_in))
-+ if (flag_syntax_only || errorcount || sorrycount)
- return;
-
- /* Close the external scope. */
---- a/gcc/c-opts.c
-+++ b/gcc/c-opts.c
-@@ -40,6 +40,7 @@ along with GCC; see the file COPYING3.
- #include "mkdeps.h"
- #include "target.h"
- #include "tm_p.h"
-+#include "c-tree.h" /* For c_cpp_error. */
-
- #ifndef DOLLARS_IN_IDENTIFIERS
- # define DOLLARS_IN_IDENTIFIERS true
-@@ -201,6 +202,7 @@ c_common_init_options (unsigned int argc
- {
- static const unsigned int lang_flags[] = {CL_C, CL_ObjC, CL_CXX, CL_ObjCXX};
- unsigned int i, result;
-+ struct cpp_callbacks *cb;
-
- /* This is conditionalized only because that is the way the front
- ends used to do it. Maybe this should be unconditional? */
-@@ -216,6 +218,8 @@ c_common_init_options (unsigned int argc
-
- parse_in = cpp_create_reader (c_dialect_cxx () ? CLK_GNUCXX: CLK_GNUC89,
- ident_hash, line_table);
-+ cb = cpp_get_callbacks (parse_in);
-+ cb->error = c_cpp_error;
-
- cpp_opts = cpp_get_options (parse_in);
- cpp_opts->dollars_in_ident = DOLLARS_IN_IDENTIFIERS;
-@@ -333,12 +337,12 @@ c_common_handle_option (size_t scode, co
- or environment var dependency generation is used. */
- cpp_opts->deps.style = (code == OPT_M ? DEPS_SYSTEM: DEPS_USER);
- flag_no_output = 1;
-- cpp_opts->inhibit_warnings = 1;
- break;
-
- case OPT_MD:
- case OPT_MMD:
- cpp_opts->deps.style = (code == OPT_MD ? DEPS_SYSTEM: DEPS_USER);
-+ cpp_opts->deps.need_preprocessor_output = true;
- deps_file = arg;
- break;
-
-@@ -444,7 +448,6 @@ c_common_handle_option (size_t scode, co
- break;
-
- case OPT_Werror:
-- cpp_opts->warnings_are_errors = value;
- global_dc->warning_as_error_requested = value;
- break;
-
-@@ -503,10 +506,6 @@ c_common_handle_option (size_t scode, co
- warn_strict_null_sentinel = value;
- break;
-
-- case OPT_Wsystem_headers:
-- cpp_opts->warn_system_headers = value;
-- break;
--
- case OPT_Wtraditional:
- cpp_opts->warn_traditional = value;
- break;
-@@ -895,8 +894,6 @@ c_common_handle_option (size_t scode, co
- c_common_post_options, so that a subsequent -Wno-endif-labels
- is not overridden. */
- case OPT_pedantic_errors:
-- cpp_opts->pedantic_errors = 1;
-- /* Fall through. */
- case OPT_pedantic:
- cpp_opts->pedantic = 1;
- cpp_opts->warn_endif_labels = 1;
-@@ -971,10 +968,6 @@ c_common_handle_option (size_t scode, co
- flag_undef = 1;
- break;
-
-- case OPT_w:
-- cpp_opts->inhibit_warnings = 1;
-- break;
--
- case OPT_v:
- verbose = true;
- break;
-@@ -1159,10 +1152,6 @@ c_common_post_options (const char **pfil
-
- input_location = UNKNOWN_LOCATION;
-
-- /* If an error has occurred in cpplib, note it so we fail
-- immediately. */
-- errorcount += cpp_errors (parse_in);
--
- *pfilename = this_input_filename
- = cpp_read_main_file (parse_in, in_fnames[0]);
- /* Don't do any compilation or preprocessing if there is no input file. */
-@@ -1274,7 +1263,8 @@ c_common_finish (void)
- {
- FILE *deps_stream = NULL;
-
-- if (cpp_opts->deps.style != DEPS_NONE)
-+ /* Don't write the deps file if there are errors. */
-+ if (cpp_opts->deps.style != DEPS_NONE && errorcount == 0)
- {
- /* If -M or -MM was seen without -MF, default output to the
- output stream. */
-@@ -1290,7 +1280,7 @@ c_common_finish (void)
-
- /* For performance, avoid tearing down cpplib's internal structures
- with cpp_destroy (). */
-- errorcount += cpp_finish (parse_in, deps_stream);
-+ cpp_finish (parse_in, deps_stream);
-
- if (deps_stream && deps_stream != out_stream
- && (ferror (deps_stream) || fclose (deps_stream)))
---- a/gcc/c-ppoutput.c
-+++ b/gcc/c-ppoutput.c
-@@ -521,6 +521,7 @@ pp_file_change (const struct line_map *m
-
- if (map != NULL)
- {
-+ input_location = map->start_location;
- if (print.first_time)
- {
- /* Avoid printing foo.i when the main file is foo.c. */
---- a/gcc/c-tree.h
-+++ b/gcc/c-tree.h
-@@ -647,4 +647,8 @@ extern void c_write_global_declarations
- extern void pedwarn_c90 (location_t, int opt, const char *, ...) ATTRIBUTE_GCC_CDIAG(3,4);
- extern void pedwarn_c99 (location_t, int opt, const char *, ...) ATTRIBUTE_GCC_CDIAG(3,4);
-
-+extern bool c_cpp_error (cpp_reader *, int, location_t, unsigned int,
-+ const char *, va_list *)
-+ ATTRIBUTE_GCC_CDIAG(5,0);
-+
- #endif /* ! GCC_C_TREE_H */
---- a/gcc/c-typeck.c
-+++ b/gcc/c-typeck.c
-@@ -1765,6 +1765,7 @@ default_conversion (tree exp)
- tree orig_exp;
- tree type = TREE_TYPE (exp);
- enum tree_code code = TREE_CODE (type);
-+ tree promoted_type;
-
- /* Functions and arrays have been converted during parsing. */
- gcc_assert (code != FUNCTION_TYPE);
-@@ -1801,6 +1802,10 @@ default_conversion (tree exp)
- if (exp == error_mark_node)
- return error_mark_node;
-
-+ promoted_type = targetm.promoted_type (type);
-+ if (promoted_type)
-+ return convert (promoted_type, exp);
-+
- if (INTEGRAL_TYPE_P (type))
- return perform_integral_promotions (exp);
-
---- a/gcc/c.opt
-+++ b/gcc/c.opt
-@@ -720,6 +720,10 @@ fpreprocessed
- C ObjC C++ ObjC++
- Treat the input file as already preprocessed
-
-+fremove-local-statics
-+C C++ Var(flag_remove_local_statics) Optimization
-+Convert function-local static variables to automatic variables when it is safe to do so
-+
- freplace-objc-classes
- ObjC ObjC++
- Used in Fix-and-Continue mode to indicate that object files may be swapped in at runtime
---- a/gcc/calls.c
-+++ b/gcc/calls.c
-@@ -3806,7 +3806,7 @@ emit_library_call_value_1 (int retval, r
- cse'ing of library calls could delete a call and leave the pop. */
- NO_DEFER_POP;
- valreg = (mem_value == 0 && outmode != VOIDmode
-- ? hard_libcall_value (outmode) : NULL_RTX);
-+ ? hard_libcall_value (outmode, orgfun) : NULL_RTX);
-
- /* Stack must be properly aligned now. */
- gcc_assert (!(stack_pointer_delta
-@@ -4051,8 +4051,17 @@ store_one_arg (struct arg_data *arg, rtx
- /* We need to make a save area. */
- unsigned int size = arg->locate.size.constant * BITS_PER_UNIT;
- enum machine_mode save_mode = mode_for_size (size, MODE_INT, 1);
-- rtx adr = memory_address (save_mode, XEXP (arg->stack_slot, 0));
-- rtx stack_area = gen_rtx_MEM (save_mode, adr);
-+ rtx adr;
-+ rtx stack_area;
-+
-+ /* We can only use save_mode if the arg is sufficiently
-+ aligned. */
-+ if (STRICT_ALIGNMENT
-+ && GET_MODE_ALIGNMENT (save_mode) > arg->locate.boundary)
-+ save_mode = BLKmode;
-+
-+ adr = memory_address (save_mode, XEXP (arg->stack_slot, 0));
-+ stack_area = gen_rtx_MEM (save_mode, adr);
-
- if (save_mode == BLKmode)
- {
---- a/gcc/cfgexpand.c
-+++ b/gcc/cfgexpand.c
-@@ -488,7 +488,8 @@ get_decl_align_unit (tree decl)
- {
- unsigned int align;
-
-- align = LOCAL_DECL_ALIGNMENT (decl);
-+ align = alignment_for_aligned_arrays (TREE_TYPE (decl),
-+ LOCAL_DECL_ALIGNMENT (decl));
-
- if (align > MAX_SUPPORTED_STACK_ALIGNMENT)
- align = MAX_SUPPORTED_STACK_ALIGNMENT;
---- a/gcc/cgraph.c
-+++ b/gcc/cgraph.c
-@@ -475,9 +475,11 @@ cgraph_node (tree decl)
- if (DECL_CONTEXT (decl) && TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL)
- {
- node->origin = cgraph_node (DECL_CONTEXT (decl));
-+ node->origin->ever_was_nested = 1;
- node->next_nested = node->origin->nested;
- node->origin->nested = node;
- node->master_clone = node;
-+ node->ever_was_nested = 1;
- }
- if (assembler_name_hash)
- {
---- a/gcc/cgraph.h
-+++ b/gcc/cgraph.h
-@@ -185,6 +185,8 @@ struct cgraph_node GTY((chain_next ("%h.
- unsigned output : 1;
- /* Set for aliases once they got through assemble_alias. */
- unsigned alias : 1;
-+ /* Set if the function is a nested function or has nested functions. */
-+ unsigned ever_was_nested : 1;
-
- /* In non-unit-at-a-time mode the function body of inline candidates is saved
- into clone before compiling so the function in original form can be
---- a/gcc/common.opt
-+++ b/gcc/common.opt
-@@ -153,6 +153,10 @@ Wpadded
- Common Var(warn_padded) Warning
- Warn when padding is required to align structure members
-
-+Wpoison-system-directories
-+Common Var(flag_poison_system_directories) Init(1)
-+Warn for -I and -L options using system directories if cross compiling
-+
- Wshadow
- Common Var(warn_shadow) Warning
- Warn when one local variable shadows another
-@@ -270,6 +274,12 @@ Common Separate
- fabi-version=
- Common Joined UInteger Var(flag_abi_version) Init(2)
-
-+falign-arrays
-+Target Report Var(flag_align_arrays)
-+Set the minimum alignment for array variables to be the largest power
-+of two less than or equal to their total storage size, or the biggest
-+alignment used on the machine, whichever is smaller.
-+
- falign-functions
- Common Report Var(align_functions,0) Optimization UInteger
- Align the start of functions
-@@ -467,6 +477,10 @@ fearly-inlining
- Common Report Var(flag_early_inlining) Init(1) Optimization
- Perform early inlining
-
-+feglibc=
-+Common Report Joined Undocumented
-+EGLIBC configuration specifier, serves multilib purposes.
-+
- feliminate-dwarf2-dups
- Common Report Var(flag_eliminate_dwarf2_dups)
- Perform DWARF2 duplicate elimination
-@@ -895,6 +909,10 @@ fprofile-values
- Common Report Var(flag_profile_values)
- Insert code to profile values of expressions
-
-+fpromote-loop-indices
-+Common Report Var(flag_promote_loop_indices) Optimization
-+Promote loop indices to word-sized indices when safe
-+
- frandom-seed
- Common
-
-@@ -1227,6 +1245,15 @@ ftree-pre
- Common Report Var(flag_tree_pre) Optimization
- Enable SSA-PRE optimization on trees
-
-+ftree-pre-partial-partial
-+Common Report Var(flag_tree_pre_partial_partial) Optimization
-+In SSA-PRE optimization on trees, enable partial-partial redundancy elimination.
-+
-+ftree-pre-partial-partial-obliviously
-+Common Report Var(flag_tree_pre_partial_partial_obliviously) Optimization
-+In SSA-PRE optimization on trees, enable partial-partial redundancy
-+elimination without regard for the cost of the inserted phi nodes.
-+
- ftree-reassoc
- Common Report Var(flag_tree_reassoc) Init(1) Optimization
- Enable reassociation on tree level
---- a/gcc/config.gcc
-+++ b/gcc/config.gcc
-@@ -1088,7 +1088,7 @@ i[34567]86-*-linux* | i[34567]86-*-kfree
- tmake_file="${tmake_file} i386/t-linux64"
- need_64bit_hwint=yes
- case X"${with_cpu}" in
-- Xgeneric|Xcore2|Xnocona|Xx86-64|Xamdfam10|Xbarcelona|Xk8|Xopteron|Xathlon64|Xathlon-fx)
-+ Xgeneric|Xatom|Xcore2|Xnocona|Xx86-64|Xamdfam10|Xbarcelona|Xk8|Xopteron|Xathlon64|Xathlon-fx)
- ;;
- X)
- if test x$with_cpu_64 = x; then
-@@ -1097,7 +1097,7 @@ i[34567]86-*-linux* | i[34567]86-*-kfree
- ;;
- *)
- echo "Unsupported CPU used in --with-cpu=$with_cpu, supported values:" 1>&2
-- echo "generic core2 nocona x86-64 amdfam10 barcelona k8 opteron athlon64 athlon-fx" 1>&2
-+ echo "generic atom core2 nocona x86-64 amdfam10 barcelona k8 opteron athlon64 athlon-fx" 1>&2
- exit 1
- ;;
- esac
-@@ -1202,7 +1202,7 @@ i[34567]86-*-solaris2*)
- # libgcc/configure.ac instead.
- need_64bit_hwint=yes
- case X"${with_cpu}" in
-- Xgeneric|Xcore2|Xnocona|Xx86-64|Xamdfam10|Xbarcelona|Xk8|Xopteron|Xathlon64|Xathlon-fx)
-+ Xgeneric|Xatom|Xcore2|Xnocona|Xx86-64|Xamdfam10|Xbarcelona|Xk8|Xopteron|Xathlon64|Xathlon-fx)
- ;;
- X)
- if test x$with_cpu_64 = x; then
-@@ -1211,7 +1211,7 @@ i[34567]86-*-solaris2*)
- ;;
- *)
- echo "Unsupported CPU used in --with-cpu=$with_cpu, supported values:" 1>&2
-- echo "generic core2 nocona x86-64 amdfam10 barcelona k8 opteron athlon64 athlon-fx" 1>&2
-+ echo "generic atom core2 nocona x86-64 amdfam10 barcelona k8 opteron athlon64 athlon-fx" 1>&2
- exit 1
- ;;
- esac
-@@ -1573,6 +1573,7 @@ mips64*-*-linux* | mipsisa64*-*-linux*)
- tm_defines="${tm_defines} MIPS_ISA_DEFAULT=65"
- ;;
- esac
-+ tmake_file="$tmake_file mips/t-crtfm"
- gnu_ld=yes
- gas=yes
- test x$with_llsc != x || with_llsc=yes
-@@ -1803,6 +1804,10 @@ powerpc-*-elf*)
- tm_file="${tm_file} dbxelf.h elfos.h usegas.h svr4.h freebsd-spec.h rs6000/sysv4.h"
- extra_options="${extra_options} rs6000/sysv4.opt"
- tmake_file="rs6000/t-fprules rs6000/t-fprules-fpbit rs6000/t-ppcgas rs6000/t-ppccomm"
-+ if test x$enable_powerpc_e500mc_elf = xyes; then
-+ tm_file="${tm_file} rs6000/e500mc.h"
-+ tmake_file="${tmake_file} rs6000/t-ppc-e500mc"
-+ fi
- ;;
- powerpc-*-eabialtivec*)
- tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/eabi.h rs6000/e500.h rs6000/eabialtivec.h"
-@@ -2016,9 +2021,14 @@ sh-*-symbianelf* | sh[12346l]*-*-symbian
- *) with_endian=big,little ;;
- esac
- fi
-+ # TM_ENDIAN_CONFIG is used by t-sh to determine multilibs.
-+ # First word : the default endian.
-+ # Second word: the secondary endian (optional).
- case ${with_endian} in
-- big|little) tmake_file="${tmake_file} sh/t-1e" ;;
-- big,little|little,big) ;;
-+ big) TM_ENDIAN_CONFIG=mb ;;
-+ little) TM_ENDIAN_CONFIG=ml ;;
-+ big,little) TM_ENDIAN_CONFIG="mb ml" ;;
-+ little,big) TM_ENDIAN_CONFIG="ml mb" ;;
- *) echo "with_endian=${with_endian} not supported."; exit 1 ;;
- esac
- case ${with_endian} in
-@@ -2125,7 +2135,7 @@ sh-*-symbianelf* | sh[12346l]*-*-symbian
- *) echo "with_cpu=$with_cpu not supported"; exit 1 ;;
- esac
- sh_multilibs=${with_multilib_list}
-- if test x${sh_multilibs} = x ; then
-+ if test "$sh_multilibs" = "default" ; then
- case ${target} in
- sh64-superh-linux* | \
- sh[1234]*) sh_multilibs=${sh_cpu_target} ;;
-@@ -2141,25 +2151,32 @@ sh-*-symbianelf* | sh[12346l]*-*-symbian
- fi
- target_cpu_default=SELECT_`echo ${sh_cpu_default}|tr abcdefghijklmnopqrstuvwxyz- ABCDEFGHIJKLMNOPQRSTUVWXYZ_`
- tm_defines=${tm_defines}' SH_MULTILIB_CPU_DEFAULT=\"'`echo $sh_cpu_default|sed s/sh/m/`'\"'
-- sh_multilibs=`echo $sh_multilibs,$sh_cpu_default | sed -e 's/[ ,/][ ,]*/ /g' -e 's/ $//' -e 's/^m/sh/' -e 's/ m/ sh/g' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ_ abcdefghijklmnopqrstuvwxyz-`
-+ tm_defines="$tm_defines SUPPORT_`echo $sh_cpu_default | sed 's/^m/sh/' | tr abcdefghijklmnopqrstuvwxyz- ABCDEFGHIJKLMNOPQRSTUVWXYZ_`=1"
-+ sh_multilibs=`echo $sh_multilibs | sed -e 's/,/ /g' -e 's/^sh/m/i' -e 's/ sh/ m/gi' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ_ abcdefghijklmnopqrstuvwxyz-`
- for sh_multilib in ${sh_multilibs}; do
- case ${sh_multilib} in
-- sh1 | sh2 | sh2e | sh3 | sh3e | \
-- sh4 | sh4-single | sh4-single-only | sh4-nofpu | sh4-300 |\
-- sh4a | sh4a-single | sh4a-single-only | sh4a-nofpu | sh4al | \
-- sh2a | sh2a-single | sh2a-single-only | sh2a-nofpu | \
-- sh5-64media | sh5-64media-nofpu | \
-- sh5-32media | sh5-32media-nofpu | \
-- sh5-compact | sh5-compact-nofpu)
-- tmake_file="${tmake_file} sh/t-mlib-${sh_multilib}"
-- tm_defines="$tm_defines SUPPORT_`echo $sh_multilib|tr abcdefghijklmnopqrstuvwxyz- ABCDEFGHIJKLMNOPQRSTUVWXYZ_`=1"
-- ;;
-+ m1 | m2 | m2e | m3 | m3e | \
-+ m4 | m4-single | m4-single-only | m4-nofpu | m4-300 |\
-+ m4a | m4a-single | m4a-single-only | m4a-nofpu | m4al | \
-+ m2a | m2a-single | m2a-single-only | m2a-nofpu | \
-+ m5-64media | m5-64media-nofpu | \
-+ m5-32media | m5-32media-nofpu | \
-+ m5-compact | m5-compact-nofpu)
-+ # TM_MULTILIB_CONFIG is used by t-sh for the non-endian multilib definition
-+ # It is passed to MULTIILIB_OPTIONS verbatim.
-+ TM_MULTILIB_CONFIG="${TM_MULTILIB_CONFIG}/${sh_multilib}"
-+ tm_defines="$tm_defines SUPPORT_`echo $sh_multilib | sed 's/^m/sh/' | tr abcdefghijklmnopqrstuvwxyz- ABCDEFGHIJKLMNOPQRSTUVWXYZ_`=1"
-+ ;;
-+ \!*) # TM_MULTILIB_EXCEPTIONS_CONFIG is used by t-sh
-+ # It is passed the MULTILIB_EXCEPTIONS verbatim.
-+ TM_MULTILIB_EXCEPTIONS_CONFIG="${TM_MULTILIB_EXCEPTIONS_CONFIG} `echo $sh_multilib | sed 's/^!//'`" ;;
- *)
- echo "with_multilib_list=${sh_multilib} not supported."
- exit 1
- ;;
- esac
- done
-+ TM_MULTILIB_CONFIG=`echo $TM_MULTILIB_CONFIG | sed 's:^/::'`
- if test x${enable_incomplete_targets} = xyes ; then
- tm_defines="$tm_defines SUPPORT_SH1=1 SUPPORT_SH2E=1 SUPPORT_SH4=1 SUPPORT_SH4_SINGLE=1 SUPPORT_SH2A=1 SUPPORT_SH2A_SINGLE=1 SUPPORT_SH5_32MEDIA=1 SUPPORT_SH5_32MEDIA_NOFPU=1 SUPPORT_SH5_64MEDIA=1 SUPPORT_SH5_64MEDIA_NOFPU=1"
- fi
-@@ -2427,6 +2444,8 @@ i[34567]86-*-linux* | x86_64-*-linux*)
- i[34567]86-*-* | x86_64-*-*)
- tmake_file="${tmake_file} i386/t-gmm_malloc i386/t-i386"
- ;;
-+powerpc*-*-* | rs6000-*-*)
-+ tm_file="${tm_file} rs6000/option-defaults.h"
- esac
-
- # Support for --with-cpu and related options (and a few unrelated options,
-@@ -2653,8 +2672,8 @@ case "${target}" in
- | armv[23456] | armv2a | armv3m | armv4t | armv5t \
- | armv5te | armv6j |armv6k | armv6z | armv6zk | armv6-m \
- | armv7 | armv7-a | armv7-r | armv7-m \
-- | iwmmxt | ep9312)
-- # OK
-+ | iwmmxt | ep9312 | marvell-f )
-+ # OK
- ;;
- *)
- echo "Unknown arch used in --with-arch=$with_arch" 1>&2
-@@ -2675,7 +2694,10 @@ case "${target}" in
-
- case "$with_fpu" in
- "" \
-- | fpa | fpe2 | fpe3 | maverick | vfp | vfp3 | vfpv3 | vfpv3-d16 | neon )
-+ | fpa | fpe2 | fpe3 | maverick \
-+ | vfp | vfp3 | vfpv3 | vfpv3-fp16 | vfpv3-d16 \
-+ | vfpv3-d16-fp16 | vfpv4 | vfpv4-d16 | fpv4-sp-d16 \
-+ | neon | neon-fp16 | neon-vfpv4 )
- # OK
- ;;
- *)
-@@ -2812,7 +2834,7 @@ case "${target}" in
- esac
- # OK
- ;;
-- "" | amdfam10 | barcelona | k8 | opteron | athlon64 | athlon-fx | nocona | core2 | generic)
-+ "" | amdfam10 | barcelona | k8 | opteron | athlon64 | athlon-fx | nocona | core2 | atom | generic)
- # OK
- ;;
- *)
-@@ -2824,7 +2846,7 @@ case "${target}" in
- ;;
-
- mips*-*-*)
-- supported_defaults="abi arch float tune divide llsc mips-plt"
-+ supported_defaults="abi arch arch_32 arch_64 float tune tune_32 tune_64 divide llsc mips-plt"
-
- case ${with_float} in
- "" | soft | hard)
-@@ -2889,12 +2911,20 @@ case "${target}" in
- ;;
-
- powerpc*-*-* | rs6000-*-*)
-- supported_defaults="cpu float tune"
-+ supported_defaults="cpu cpu_32 cpu_64 float tune tune_32 tune_64"
-
-- for which in cpu tune; do
-+ for which in cpu cpu_32 cpu_64 tune tune_32 tune_64; do
- eval "val=\$with_$which"
- case ${val} in
- default32 | default64)
-+ case $which in
-+ cpu | tune)
-+ ;;
-+ *)
-+ echo "$val only valid for --with-cpu and --with-tune." 1>&2
-+ exit 1
-+ ;;
-+ esac
- with_which="with_$which"
- eval $with_which=
- ;;
---- a/gcc/config.in
-+++ b/gcc/config.in
-@@ -108,6 +108,12 @@
- #endif
-
-
-+/* Define to warn for use of native system header directories */
-+#ifndef USED_FOR_TARGET
-+#undef ENABLE_POISON_SYSTEM_DIRECTORIES
-+#endif
-+
-+
- /* Define if you want all operations on RTL (the basic data structure of the
- optimizer and back end) to be checked for dynamic type safety at runtime.
- This is quite expensive. */
-@@ -821,6 +827,13 @@
- #endif
-
-
-+/* Define if your assembler supports specifying the alignment of objects
-+ allocated using the GAS .comm command. */
-+#ifndef USED_FOR_TARGET
-+#undef HAVE_GAS_ALIGNED_COMM
-+#endif
-+
-+
- /* Define if your assembler supports .balign and .p2align. */
- #ifndef USED_FOR_TARGET
- #undef HAVE_GAS_BALIGN_AND_P2ALIGN
---- a/gcc/config/arm/arm-cores.def
-+++ b/gcc/config/arm/arm-cores.def
-@@ -104,6 +104,7 @@ ARM_CORE("arm1022e", arm1022e, 5TE,
- ARM_CORE("xscale", xscale, 5TE, FL_LDSCHED | FL_STRONG | FL_XSCALE, xscale)
- ARM_CORE("iwmmxt", iwmmxt, 5TE, FL_LDSCHED | FL_STRONG | FL_XSCALE | FL_IWMMXT, xscale)
- ARM_CORE("iwmmxt2", iwmmxt2, 5TE, FL_LDSCHED | FL_STRONG | FL_XSCALE | FL_IWMMXT, xscale)
-+ARM_CORE("marvell-f", marvell_f, 5TE, FL_LDSCHED | FL_VFPV2 | FL_MARVELL_F, 9e)
-
- /* V5TEJ Architecture Processors */
- ARM_CORE("arm926ej-s", arm926ejs, 5TEJ, FL_LDSCHED, 9e)
-@@ -117,9 +118,13 @@ ARM_CORE("arm1176jzf-s", arm1176jzfs, 6
- ARM_CORE("mpcorenovfp", mpcorenovfp, 6K, FL_LDSCHED, 9e)
- ARM_CORE("mpcore", mpcore, 6K, FL_LDSCHED | FL_VFPV2, 9e)
- ARM_CORE("arm1156t2-s", arm1156t2s, 6T2, FL_LDSCHED, 9e)
-+
-+/* V7 Architecture Processors */
-+ARM_CORE("cortex-a5", cortexa5, 7A, FL_LDSCHED, 9e)
- ARM_CORE("cortex-a8", cortexa8, 7A, FL_LDSCHED, 9e)
- ARM_CORE("cortex-a9", cortexa9, 7A, FL_LDSCHED, 9e)
- ARM_CORE("cortex-r4", cortexr4, 7R, FL_LDSCHED, 9e)
- ARM_CORE("cortex-r4f", cortexr4f, 7R, FL_LDSCHED, 9e)
- ARM_CORE("cortex-m3", cortexm3, 7M, FL_LDSCHED, 9e)
- ARM_CORE("cortex-m1", cortexm1, 6M, FL_LDSCHED, 9e)
-+ARM_CORE("cortex-m0", cortexm0, 6M, FL_LDSCHED, 9e)
---- a/gcc/config/arm/arm-modes.def
-+++ b/gcc/config/arm/arm-modes.def
-@@ -25,6 +25,11 @@
- FIXME What format is this? */
- FLOAT_MODE (XF, 12, 0);
-
-+/* Half-precision floating point */
-+FLOAT_MODE (HF, 2, 0);
-+ADJUST_FLOAT_FORMAT (HF, ((arm_fp16_format == ARM_FP16_FORMAT_ALTERNATIVE)
-+ ? &arm_half_format : &ieee_half_format));
-+
- /* CCFPEmode should be used with floating inequalities,
- CCFPmode should be used with floating equalities.
- CC_NOOVmode should be used with SImode integer equalities.
-@@ -62,6 +67,4 @@ VECTOR_MODES (FLOAT, 16); /* V
- INT_MODE (EI, 24);
- INT_MODE (OI, 32);
- INT_MODE (CI, 48);
--/* ??? This should actually have 512 bits but the precision only has 9
-- bits. */
--FRACTIONAL_INT_MODE (XI, 511, 64);
-+INT_MODE (XI, 64);
---- a/gcc/config/arm/arm-protos.h
-+++ b/gcc/config/arm/arm-protos.h
-@@ -88,7 +88,7 @@ extern bool arm_cannot_force_const_mem (
-
- extern int cirrus_memory_offset (rtx);
- extern int arm_coproc_mem_operand (rtx, bool);
--extern int neon_vector_mem_operand (rtx, bool);
-+extern int neon_vector_mem_operand (rtx, int);
- extern int neon_struct_mem_operand (rtx);
- extern int arm_no_early_store_addr_dep (rtx, rtx);
- extern int arm_no_early_alu_shift_dep (rtx, rtx);
-@@ -144,6 +144,7 @@ extern void arm_final_prescan_insn (rtx)
- extern int arm_debugger_arg_offset (int, rtx);
- extern bool arm_is_long_call_p (tree);
- extern int arm_emit_vector_const (FILE *, rtx);
-+extern void arm_emit_fp16_const (rtx c);
- extern const char * arm_output_load_gr (rtx *);
- extern const char *vfp_output_fstmd (rtx *);
- extern void arm_set_return_address (rtx, rtx);
-@@ -154,13 +155,15 @@ extern bool arm_output_addr_const_extra
-
- #if defined TREE_CODE
- extern rtx arm_function_arg (CUMULATIVE_ARGS *, enum machine_mode, tree, int);
-+extern void arm_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode,
-+ tree, bool);
- extern void arm_init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree);
- extern bool arm_pad_arg_upward (enum machine_mode, const_tree);
- extern bool arm_pad_reg_upward (enum machine_mode, tree, int);
- extern bool arm_needs_doubleword_align (enum machine_mode, tree);
--extern rtx arm_function_value(const_tree, const_tree);
- #endif
- extern int arm_apply_result_size (void);
-+extern rtx aapcs_libcall_value (enum machine_mode);
-
- #endif /* RTX_CODE */
-
---- a/gcc/config/arm/arm-tune.md
-+++ b/gcc/config/arm/arm-tune.md
-@@ -1,5 +1,5 @@
- ;; -*- buffer-read-only: t -*-
- ;; Generated automatically by gentune.sh from arm-cores.def
- (define_attr "tune"
-- "arm2,arm250,arm3,arm6,arm60,arm600,arm610,arm620,arm7,arm7d,arm7di,arm70,arm700,arm700i,arm710,arm720,arm710c,arm7100,arm7500,arm7500fe,arm7m,arm7dm,arm7dmi,arm8,arm810,strongarm,strongarm110,strongarm1100,strongarm1110,arm7tdmi,arm7tdmis,arm710t,arm720t,arm740t,arm9,arm9tdmi,arm920,arm920t,arm922t,arm940t,ep9312,arm10tdmi,arm1020t,arm9e,arm946es,arm966es,arm968es,arm10e,arm1020e,arm1022e,xscale,iwmmxt,iwmmxt2,arm926ejs,arm1026ejs,arm1136js,arm1136jfs,arm1176jzs,arm1176jzfs,mpcorenovfp,mpcore,arm1156t2s,cortexa8,cortexa9,cortexr4,cortexr4f,cortexm3,cortexm1"
-+ "arm2,arm250,arm3,arm6,arm60,arm600,arm610,arm620,arm7,arm7d,arm7di,arm70,arm700,arm700i,arm710,arm720,arm710c,arm7100,arm7500,arm7500fe,arm7m,arm7dm,arm7dmi,arm8,arm810,strongarm,strongarm110,strongarm1100,strongarm1110,arm7tdmi,arm7tdmis,arm710t,arm720t,arm740t,arm9,arm9tdmi,arm920,arm920t,arm922t,arm940t,ep9312,arm10tdmi,arm1020t,arm9e,arm946es,arm966es,arm968es,arm10e,arm1020e,arm1022e,xscale,iwmmxt,iwmmxt2,marvell_f,arm926ejs,arm1026ejs,arm1136js,arm1136jfs,arm1176jzs,arm1176jzfs,mpcorenovfp,mpcore,arm1156t2s,cortexa5,cortexa8,cortexa9,cortexr4,cortexr4f,cortexm3,cortexm1,cortexm0"
- (const (symbol_ref "arm_tune")))
---- a/gcc/config/arm/arm.c
-+++ b/gcc/config/arm/arm.c
-@@ -43,6 +43,7 @@
- #include "optabs.h"
- #include "toplev.h"
- #include "recog.h"
-+#include "cgraph.h"
- #include "ggc.h"
- #include "except.h"
- #include "c-pragma.h"
-@@ -54,6 +55,8 @@
- #include "langhooks.h"
- #include "df.h"
- #include "libfuncs.h"
-+#include "intl.h"
-+#include "params.h"
-
- /* Forward definitions of types. */
- typedef struct minipool_node Mnode;
-@@ -111,6 +114,7 @@ static unsigned long arm_compute_save_re
- static unsigned long arm_isr_value (tree);
- static unsigned long arm_compute_func_type (void);
- static tree arm_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
-+static tree arm_handle_pcs_attribute (tree *, tree, tree, int, bool *);
- static tree arm_handle_isr_attribute (tree *, tree, tree, int, bool *);
- #if TARGET_DLLIMPORT_DECL_ATTRIBUTES
- static tree arm_handle_notshared_attribute (tree *, tree, tree, int, bool *);
-@@ -124,6 +128,10 @@ static int arm_adjust_cost (rtx, rtx, rt
- static int count_insns_for_constant (HOST_WIDE_INT, int);
- static int arm_get_strip_length (int);
- static bool arm_function_ok_for_sibcall (tree, tree);
-+static bool arm_return_in_memory (const_tree, const_tree);
-+static rtx arm_function_value (const_tree, const_tree, bool);
-+static rtx arm_libcall_value (enum machine_mode, rtx);
-+
- static void arm_internal_label (FILE *, const char *, unsigned long);
- static void arm_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT,
- tree);
-@@ -149,6 +157,9 @@ static void emit_constant_insn (rtx cond
- static rtx emit_set_insn (rtx, rtx);
- static int arm_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
- tree, bool);
-+static rtx aapcs_allocate_return_reg (enum machine_mode, const_tree,
-+ const_tree);
-+static int aapcs_select_return_coproc (const_tree, const_tree);
-
- #ifdef OBJECT_FORMAT_ELF
- static void arm_elf_asm_constructor (rtx, int) ATTRIBUTE_UNUSED;
-@@ -176,6 +187,7 @@ static void arm_unwind_emit (FILE *, rtx
- static bool arm_output_ttype (rtx);
- #endif
- static void arm_dwarf_handle_frame_unspec (const char *, rtx, int);
-+static rtx arm_dwarf_register_span(rtx);
-
- static tree arm_cxx_guard_type (void);
- static bool arm_cxx_guard_mask_bit (void);
-@@ -198,6 +210,15 @@ static bool arm_tls_symbol_p (rtx x);
- static int arm_issue_rate (void);
- static void arm_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
- static bool arm_allocate_stack_slots_for_args (void);
-+static bool arm_warn_func_result (void);
-+static int arm_multipass_dfa_lookahead (void);
-+static const char *arm_invalid_parameter_type (const_tree t);
-+static const char *arm_invalid_return_type (const_tree t);
-+static tree arm_promoted_type (const_tree t);
-+static tree arm_convert_to_type (tree type, tree expr);
-+static bool arm_scalar_mode_supported_p (enum machine_mode);
-+static int arm_vector_min_alignment (const_tree type);
-+static bool arm_vector_always_misalign(const_tree);
-
- \f
- /* Initialize the GCC target structure. */
-@@ -257,6 +278,12 @@ static bool arm_allocate_stack_slots_for
- #undef TARGET_FUNCTION_OK_FOR_SIBCALL
- #define TARGET_FUNCTION_OK_FOR_SIBCALL arm_function_ok_for_sibcall
-
-+#undef TARGET_FUNCTION_VALUE
-+#define TARGET_FUNCTION_VALUE arm_function_value
-+
-+#undef TARGET_LIBCALL_VALUE
-+#define TARGET_LIBCALL_VALUE arm_libcall_value
-+
- #undef TARGET_ASM_OUTPUT_MI_THUNK
- #define TARGET_ASM_OUTPUT_MI_THUNK arm_output_mi_thunk
- #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
-@@ -300,6 +327,9 @@ static bool arm_allocate_stack_slots_for
- #undef TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS
- #define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS arm_allocate_stack_slots_for_args
-
-+#undef TARGET_WARN_FUNC_RESULT
-+#define TARGET_WARN_FUNC_RESULT arm_warn_func_result
-+
- #undef TARGET_DEFAULT_SHORT_ENUMS
- #define TARGET_DEFAULT_SHORT_ENUMS arm_default_short_enums
-
-@@ -354,6 +384,9 @@ static bool arm_allocate_stack_slots_for
- #undef TARGET_ASM_TTYPE
- #define TARGET_ASM_TTYPE arm_output_ttype
-
-+#undef TARGET_CXX_TTYPE_REF_ENCODE
-+#define TARGET_CXX_TTYPE_REF_ENCODE hook_cxx_ttype_ref_in_bit0
-+
- #undef TARGET_ARM_EABI_UNWINDER
- #define TARGET_ARM_EABI_UNWINDER true
- #endif /* TARGET_UNWIND_INFO */
-@@ -361,6 +394,9 @@ static bool arm_allocate_stack_slots_for
- #undef TARGET_DWARF_HANDLE_FRAME_UNSPEC
- #define TARGET_DWARF_HANDLE_FRAME_UNSPEC arm_dwarf_handle_frame_unspec
-
-+#undef TARGET_DWARF_REGISTER_SPAN
-+#define TARGET_DWARF_REGISTER_SPAN arm_dwarf_register_span
-+
- #undef TARGET_CANNOT_COPY_INSN_P
- #define TARGET_CANNOT_COPY_INSN_P arm_cannot_copy_insn_p
-
-@@ -399,6 +435,30 @@ static bool arm_allocate_stack_slots_for
- #define TARGET_ASM_OUTPUT_DWARF_DTPREL arm_output_dwarf_dtprel
- #endif
-
-+#undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
-+#define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD arm_multipass_dfa_lookahead
-+
-+#undef TARGET_INVALID_PARAMETER_TYPE
-+#define TARGET_INVALID_PARAMETER_TYPE arm_invalid_parameter_type
-+
-+#undef TARGET_INVALID_RETURN_TYPE
-+#define TARGET_INVALID_RETURN_TYPE arm_invalid_return_type
-+
-+#undef TARGET_PROMOTED_TYPE
-+#define TARGET_PROMOTED_TYPE arm_promoted_type
-+
-+#undef TARGET_CONVERT_TO_TYPE
-+#define TARGET_CONVERT_TO_TYPE arm_convert_to_type
-+
-+#undef TARGET_SCALAR_MODE_SUPPORTED_P
-+#define TARGET_SCALAR_MODE_SUPPORTED_P arm_scalar_mode_supported_p
-+
-+#undef TARGET_VECTOR_MIN_ALIGNMENT
-+#define TARGET_VECTOR_MIN_ALIGNMENT arm_vector_min_alignment
-+
-+#undef TARGET_VECTOR_ALWAYS_MISALIGN
-+#define TARGET_VECTOR_ALWAYS_MISALIGN arm_vector_always_misalign
-+
- struct gcc_target targetm = TARGET_INITIALIZER;
- \f
- /* Obstack for minipool constant handling. */
-@@ -424,18 +484,18 @@ enum processor_type arm_tune = arm_none;
- /* The default processor used if not overridden by commandline. */
- static enum processor_type arm_default_cpu = arm_none;
-
--/* Which floating point model to use. */
--enum arm_fp_model arm_fp_model;
--
--/* Which floating point hardware is available. */
--enum fputype arm_fpu_arch;
--
- /* Which floating point hardware to schedule for. */
--enum fputype arm_fpu_tune;
-+int arm_fpu_attr;
-+
-+/* Which floating popint hardware to use. */
-+const struct arm_fpu_desc *arm_fpu_desc;
-
- /* Whether to use floating point hardware. */
- enum float_abi_type arm_float_abi;
-
-+/* Which __fp16 format to use. */
-+enum arm_fp16_format_type arm_fp16_format;
-+
- /* Which ABI to use. */
- enum arm_abi_type arm_abi;
-
-@@ -474,9 +534,19 @@ static int thumb_call_reg_needed;
- #define FL_DIV (1 << 18) /* Hardware divide. */
- #define FL_VFPV3 (1 << 19) /* Vector Floating Point V3. */
- #define FL_NEON (1 << 20) /* Neon instructions. */
-+#define FL_MARVELL_F (1 << 21) /* Marvell Feroceon. */
-+#define FL_ARCH7EM (1 << 22) /* Instructions present in ARMv7E-M. */
-
- #define FL_IWMMXT (1 << 29) /* XScale v2 or "Intel Wireless MMX technology". */
-
-+/* Some flags are ignored when comparing -mcpu and -march:
-+ FL_MARVELL_F so that -mcpu=marvell-f -march=v5te works.
-+ FL_LDSCHED and FL_WBUF only effect tuning,
-+ FL_CO_PROC, FL_VFPV2, FL_VFPV3 and FL_NEON because FP
-+ coprocessors are handled separately. */
-+#define FL_COMPAT (FL_MARVELL_F | FL_LDSCHED | FL_WBUF | FL_CO_PROC | \
-+ FL_VFPV2 | FL_VFPV3 | FL_NEON)
-+
- #define FL_FOR_ARCH2 FL_NOTM
- #define FL_FOR_ARCH3 (FL_FOR_ARCH2 | FL_MODE32)
- #define FL_FOR_ARCH3M (FL_FOR_ARCH3 | FL_ARCH3M)
-@@ -498,6 +568,7 @@ static int thumb_call_reg_needed;
- #define FL_FOR_ARCH7A (FL_FOR_ARCH7 | FL_NOTM)
- #define FL_FOR_ARCH7R (FL_FOR_ARCH7A | FL_DIV)
- #define FL_FOR_ARCH7M (FL_FOR_ARCH7 | FL_DIV)
-+#define FL_FOR_ARCH7EM (FL_FOR_ARCH7M | FL_ARCH7EM)
-
- /* The bits in this mask specify which
- instructions we are allowed to generate. */
-@@ -534,6 +605,9 @@ int arm_arch6k = 0;
- /* Nonzero if instructions not present in the 'M' profile can be used. */
- int arm_arch_notm = 0;
-
-+/* Nonzero if instructions present in ARMv7E-M can be used. */
-+int arm_arch7em = 0;
-+
- /* Nonzero if this chip can benefit from load scheduling. */
- int arm_ld_sched = 0;
-
-@@ -552,6 +626,9 @@ int arm_arch_xscale = 0;
- /* Nonzero if tuning for XScale */
- int arm_tune_xscale = 0;
-
-+/* Nonzero if tuning for Marvell Feroceon. */
-+int arm_tune_marvell_f = 0;
-+
- /* Nonzero if we want to tune for stores that access the write-buffer.
- This typically means an ARM6 or ARM7 with MMU or MPU. */
- int arm_tune_wbuf = 0;
-@@ -562,6 +639,9 @@ int arm_tune_cortex_a9 = 0;
- /* Nonzero if generating Thumb instructions. */
- int thumb_code = 0;
-
-+/* Nonzero if generating code for Janus2. */
-+int janus2_code = 0;
-+
- /* Nonzero if we should define __THUMB_INTERWORK__ in the
- preprocessor.
- XXX This is a bit of a hack, it's intended to help work around
-@@ -594,6 +674,8 @@ static int after_arm_reorg = 0;
- /* The maximum number of insns to be used when loading a constant. */
- static int arm_constant_limit = 3;
-
-+static enum arm_pcs arm_pcs_default;
-+
- /* For an explanation of these variables, see final_prescan_insn below. */
- int arm_ccfsm_state;
- /* arm_current_cc is also used for Thumb-2 cond_exec blocks. */
-@@ -674,9 +756,11 @@ static const struct processors all_archi
- {"armv7-a", cortexa8, "7A", FL_CO_PROC | FL_FOR_ARCH7A, NULL},
- {"armv7-r", cortexr4, "7R", FL_CO_PROC | FL_FOR_ARCH7R, NULL},
- {"armv7-m", cortexm3, "7M", FL_CO_PROC | FL_FOR_ARCH7M, NULL},
-+ {"armv7e-m", cortexm3, "7EM", FL_CO_PROC | FL_FOR_ARCH7EM, NULL},
- {"ep9312", ep9312, "4T", FL_LDSCHED | FL_CIRRUS | FL_FOR_ARCH4, NULL},
- {"iwmmxt", iwmmxt, "5TE", FL_LDSCHED | FL_STRONG | FL_FOR_ARCH5TE | FL_XSCALE | FL_IWMMXT , NULL},
- {"iwmmxt2", iwmmxt2, "5TE", FL_LDSCHED | FL_STRONG | FL_FOR_ARCH5TE | FL_XSCALE | FL_IWMMXT , NULL},
-+ {"marvell-f", marvell_f, "5TE", FL_CO_PROC | FL_FOR_ARCH5TE | FL_MARVELL_F, NULL},
- {NULL, arm_none, NULL, 0 , NULL}
- };
-
-@@ -706,49 +790,34 @@ static struct arm_cpu_select arm_select[
-
- /* The name of the preprocessor macro to define for this architecture. */
-
--char arm_arch_name[] = "__ARM_ARCH_0UNK__";
--
--struct fpu_desc
--{
-- const char * name;
-- enum fputype fpu;
--};
--
-+#define ARM_ARCH_NAME_SIZE 25
-+char arm_arch_name[ARM_ARCH_NAME_SIZE] = "__ARM_ARCH_0UNK__";
-
- /* Available values for -mfpu=. */
-
--static const struct fpu_desc all_fpus[] =
-+static const struct arm_fpu_desc all_fpus[] =
- {
-- {"fpa", FPUTYPE_FPA},
-- {"fpe2", FPUTYPE_FPA_EMU2},
-- {"fpe3", FPUTYPE_FPA_EMU2},
-- {"maverick", FPUTYPE_MAVERICK},
-- {"vfp", FPUTYPE_VFP},
-- {"vfp3", FPUTYPE_VFP3},
-- {"vfpv3", FPUTYPE_VFP3},
-- {"vfpv3-d16", FPUTYPE_VFP3D16},
-- {"neon", FPUTYPE_NEON}
-+ {"fpa", ARM_FP_MODEL_FPA, 0, 0, false, false},
-+ {"fpe2", ARM_FP_MODEL_FPA, 2, 0, false, false},
-+ {"fpe3", ARM_FP_MODEL_FPA, 3, 0, false, false},
-+ {"maverick", ARM_FP_MODEL_MAVERICK, 0, 0, false, false},
-+ {"vfp", ARM_FP_MODEL_VFP, 2, VFP_REG_D16, false, false},
-+ {"vfpv3", ARM_FP_MODEL_VFP, 3, VFP_REG_D32, false, false},
-+ {"vfpv3-fp16", ARM_FP_MODEL_VFP, 3, VFP_REG_D32, false, true },
-+ {"vfpv3-d16", ARM_FP_MODEL_VFP, 3, VFP_REG_D16, false, false},
-+ {"vfpv3xd", ARM_FP_MODEL_VFP, 3, VFP_REG_SINGLE, false, false},
-+ {"vfpv3xd-fp16", ARM_FP_MODEL_VFP, 3, VFP_REG_SINGLE, false, true },
-+ {"vfpv3-d16-fp16", ARM_FP_MODEL_VFP, 3, VFP_REG_D16, false, true },
-+ {"neon", ARM_FP_MODEL_VFP, 3, VFP_REG_D32, true , false},
-+ {"neon-fp16", ARM_FP_MODEL_VFP, 3, VFP_REG_D32, true , true },
-+ {"vfpv4", ARM_FP_MODEL_VFP, 4, VFP_REG_D32, false, true },
-+ {"vfpv4-d16", ARM_FP_MODEL_VFP, 4, VFP_REG_D16, false, true },
-+ {"fpv4-sp-d16", ARM_FP_MODEL_VFP, 4, VFP_REG_SINGLE, false, true },
-+ {"neon-vfpv4", ARM_FP_MODEL_VFP, 4, VFP_REG_D32, true , true },
-+ /* Compatibility aliases. */
-+ {"vfp3", ARM_FP_MODEL_VFP, 3, VFP_REG_D32, false, false},
- };
-
--
--/* Floating point models used by the different hardware.
-- See fputype in arm.h. */
--
--static const enum fputype fp_model_for_fpu[] =
--{
-- /* No FP hardware. */
-- ARM_FP_MODEL_UNKNOWN, /* FPUTYPE_NONE */
-- ARM_FP_MODEL_FPA, /* FPUTYPE_FPA */
-- ARM_FP_MODEL_FPA, /* FPUTYPE_FPA_EMU2 */
-- ARM_FP_MODEL_FPA, /* FPUTYPE_FPA_EMU3 */
-- ARM_FP_MODEL_MAVERICK, /* FPUTYPE_MAVERICK */
-- ARM_FP_MODEL_VFP, /* FPUTYPE_VFP */
-- ARM_FP_MODEL_VFP, /* FPUTYPE_VFP3D16 */
-- ARM_FP_MODEL_VFP, /* FPUTYPE_VFP3 */
-- ARM_FP_MODEL_VFP /* FPUTYPE_NEON */
--};
--
--
- struct float_abi
- {
- const char * name;
-@@ -766,6 +835,23 @@ static const struct float_abi all_float_
- };
-
-
-+struct fp16_format
-+{
-+ const char *name;
-+ enum arm_fp16_format_type fp16_format_type;
-+};
-+
-+
-+/* Available values for -mfp16-format=. */
-+
-+static const struct fp16_format all_fp16_formats[] =
-+{
-+ {"none", ARM_FP16_FORMAT_NONE},
-+ {"ieee", ARM_FP16_FORMAT_IEEE},
-+ {"alternative", ARM_FP16_FORMAT_ALTERNATIVE}
-+};
-+
-+
- struct abi_name
- {
- const char *name;
-@@ -924,6 +1010,45 @@ arm_init_libfuncs (void)
- set_optab_libfunc (smod_optab, SImode, NULL);
- set_optab_libfunc (umod_optab, SImode, NULL);
-
-+
-+ /* Half-precision float operations. The compiler handles all operations
-+ with NULL libfuncs by converting the SFmode. */
-+ switch (arm_fp16_format)
-+ {
-+ case ARM_FP16_FORMAT_IEEE:
-+ case ARM_FP16_FORMAT_ALTERNATIVE:
-+
-+ /* Conversions. */
-+ set_conv_libfunc (trunc_optab, HFmode, SFmode,
-+ (arm_fp16_format == ARM_FP16_FORMAT_IEEE
-+ ? "__gnu_f2h_ieee"
-+ : "__gnu_f2h_alternative"));
-+ set_conv_libfunc (sext_optab, SFmode, HFmode,
-+ (arm_fp16_format == ARM_FP16_FORMAT_IEEE
-+ ? "__gnu_h2f_ieee"
-+ : "__gnu_h2f_alternative"));
-+
-+ /* Arithmetic. */
-+ set_optab_libfunc (add_optab, HFmode, NULL);
-+ set_optab_libfunc (sdiv_optab, HFmode, NULL);
-+ set_optab_libfunc (smul_optab, HFmode, NULL);
-+ set_optab_libfunc (neg_optab, HFmode, NULL);
-+ set_optab_libfunc (sub_optab, HFmode, NULL);
-+
-+ /* Comparisons. */
-+ set_optab_libfunc (eq_optab, HFmode, NULL);
-+ set_optab_libfunc (ne_optab, HFmode, NULL);
-+ set_optab_libfunc (lt_optab, HFmode, NULL);
-+ set_optab_libfunc (le_optab, HFmode, NULL);
-+ set_optab_libfunc (ge_optab, HFmode, NULL);
-+ set_optab_libfunc (gt_optab, HFmode, NULL);
-+ set_optab_libfunc (unord_optab, HFmode, NULL);
-+ break;
-+
-+ default:
-+ break;
-+ }
-+
- if (TARGET_AAPCS_BASED)
- synchronize_libfunc = init_one_libfunc ("__sync_synchronize");
- }
-@@ -1139,6 +1264,7 @@ void
- arm_override_options (void)
- {
- unsigned i;
-+ int len;
- enum processor_type target_arch_cpu = arm_none;
- enum processor_type selected_cpu = arm_none;
-
-@@ -1156,7 +1282,11 @@ arm_override_options (void)
- {
- /* Set the architecture define. */
- if (i != ARM_OPT_SET_TUNE)
-- sprintf (arm_arch_name, "__ARM_ARCH_%s__", sel->arch);
-+ {
-+ len = snprintf (arm_arch_name, ARM_ARCH_NAME_SIZE,
-+ "__ARM_ARCH_%s__", sel->arch);
-+ gcc_assert (len < ARM_ARCH_NAME_SIZE);
-+ }
-
- /* Determine the processor core for which we should
- tune code-generation. */
-@@ -1182,8 +1312,8 @@ arm_override_options (void)
- make sure that they are compatible. We only generate
- a warning though, and we prefer the CPU over the
- architecture. */
-- if (insn_flags != 0 && (insn_flags ^ sel->flags))
-- warning (0, "switch -mcpu=%s conflicts with -march= switch",
-+ if (insn_flags != 0 && ((insn_flags ^ sel->flags) & ~FL_COMPAT))
-+ warning (0, "switch -mcpu=%s conflicts with -march= switch, assuming CPU feature set",
- ptr->string);
-
- insn_flags = sel->flags;
-@@ -1283,7 +1413,11 @@ arm_override_options (void)
-
- insn_flags = sel->flags;
- }
-- sprintf (arm_arch_name, "__ARM_ARCH_%s__", sel->arch);
-+
-+ len = snprintf (arm_arch_name, ARM_ARCH_NAME_SIZE,
-+ "__ARM_ARCH_%s__", sel->arch);
-+ gcc_assert (len < ARM_ARCH_NAME_SIZE);
-+
- arm_default_cpu = (enum processor_type) (sel - all_cores);
- if (arm_tune == arm_none)
- arm_tune = arm_default_cpu;
-@@ -1293,8 +1427,35 @@ arm_override_options (void)
- chosen. */
- gcc_assert (arm_tune != arm_none);
-
-+ if (arm_tune == cortexa8 && optimize >= 3)
-+ {
-+ /* These alignments were experimentally determined to improve SPECint
-+ performance on SPECCPU 2000. */
-+ if (align_functions <= 0)
-+ align_functions = 16;
-+ if (align_jumps <= 0)
-+ align_jumps = 16;
-+ }
-+
- tune_flags = all_cores[(int)arm_tune].flags;
-
-+ if (target_fp16_format_name)
-+ {
-+ for (i = 0; i < ARRAY_SIZE (all_fp16_formats); i++)
-+ {
-+ if (streq (all_fp16_formats[i].name, target_fp16_format_name))
-+ {
-+ arm_fp16_format = all_fp16_formats[i].fp16_format_type;
-+ break;
-+ }
-+ }
-+ if (i == ARRAY_SIZE (all_fp16_formats))
-+ error ("invalid __fp16 format option: -mfp16-format=%s",
-+ target_fp16_format_name);
-+ }
-+ else
-+ arm_fp16_format = ARM_FP16_FORMAT_NONE;
-+
- if (target_abi_name)
- {
- for (i = 0; i < ARRAY_SIZE (arm_all_abis); i++)
-@@ -1387,6 +1548,7 @@ arm_override_options (void)
- arm_arch6 = (insn_flags & FL_ARCH6) != 0;
- arm_arch6k = (insn_flags & FL_ARCH6K) != 0;
- arm_arch_notm = (insn_flags & FL_NOTM) != 0;
-+ arm_arch7em = (insn_flags & FL_ARCH7EM) != 0;
- arm_arch_thumb2 = (insn_flags & FL_THUMB2) != 0;
- arm_arch_xscale = (insn_flags & FL_XSCALE) != 0;
- arm_arch_cirrus = (insn_flags & FL_CIRRUS) != 0;
-@@ -1394,12 +1556,25 @@ arm_override_options (void)
- arm_ld_sched = (tune_flags & FL_LDSCHED) != 0;
- arm_tune_strongarm = (tune_flags & FL_STRONG) != 0;
- thumb_code = (TARGET_ARM == 0);
-+ janus2_code = (TARGET_FIX_JANUS != 0);
-+ if (janus2_code && TARGET_THUMB2)
-+ error ("janus2 fix is not applicable when targeting a thumb2 core");
- arm_tune_wbuf = (tune_flags & FL_WBUF) != 0;
- arm_tune_xscale = (tune_flags & FL_XSCALE) != 0;
-+ arm_tune_marvell_f = (tune_flags & FL_MARVELL_F) != 0;
- arm_arch_iwmmxt = (insn_flags & FL_IWMMXT) != 0;
-- arm_arch_hwdiv = (insn_flags & FL_DIV) != 0;
- arm_tune_cortex_a9 = (arm_tune == cortexa9) != 0;
-
-+ /* Hardware integer division is supported by some variants of the ARM
-+ architecture in Thumb-2 mode. In addition some (but not all) Marvell
-+ CPUs support their own hardware integer division instructions.
-+ The assembler will pick the correct encoding. */
-+ if (TARGET_MARVELL_DIV && (insn_flags & FL_MARVELL_F) == 0)
-+ error ("-mmarvell-div is only supported when targeting a Marvell core");
-+
-+ arm_arch_hwdiv = (TARGET_ARM && TARGET_MARVELL_DIV)
-+ || (TARGET_THUMB2 && (insn_flags & FL_DIV) != 0);
-+
- /* If we are not using the default (ARM mode) section anchor offset
- ranges, then set the correct ranges now. */
- if (TARGET_THUMB1)
-@@ -1438,7 +1613,6 @@ arm_override_options (void)
- if (TARGET_IWMMXT_ABI && !TARGET_IWMMXT)
- error ("iwmmxt abi requires an iwmmxt capable cpu");
-
-- arm_fp_model = ARM_FP_MODEL_UNKNOWN;
- if (target_fpu_name == NULL && target_fpe_name != NULL)
- {
- if (streq (target_fpe_name, "2"))
-@@ -1449,46 +1623,52 @@ arm_override_options (void)
- error ("invalid floating point emulation option: -mfpe=%s",
- target_fpe_name);
- }
-- if (target_fpu_name != NULL)
-- {
-- /* The user specified a FPU. */
-- for (i = 0; i < ARRAY_SIZE (all_fpus); i++)
-- {
-- if (streq (all_fpus[i].name, target_fpu_name))
-- {
-- arm_fpu_arch = all_fpus[i].fpu;
-- arm_fpu_tune = arm_fpu_arch;
-- arm_fp_model = fp_model_for_fpu[arm_fpu_arch];
-- break;
-- }
-- }
-- if (arm_fp_model == ARM_FP_MODEL_UNKNOWN)
-- error ("invalid floating point option: -mfpu=%s", target_fpu_name);
-- }
-- else
-+
-+ if (target_fpu_name == NULL)
- {
- #ifdef FPUTYPE_DEFAULT
-- /* Use the default if it is specified for this platform. */
-- arm_fpu_arch = FPUTYPE_DEFAULT;
-- arm_fpu_tune = FPUTYPE_DEFAULT;
-+ target_fpu_name = FPUTYPE_DEFAULT;
- #else
-- /* Pick one based on CPU type. */
-- /* ??? Some targets assume FPA is the default.
-- if ((insn_flags & FL_VFP) != 0)
-- arm_fpu_arch = FPUTYPE_VFP;
-- else
-- */
- if (arm_arch_cirrus)
-- arm_fpu_arch = FPUTYPE_MAVERICK;
-+ target_fpu_name = "maverick";
- else
-- arm_fpu_arch = FPUTYPE_FPA_EMU2;
-+ target_fpu_name = "fpe2";
- #endif
-- if (tune_flags & FL_CO_PROC && arm_fpu_arch == FPUTYPE_FPA_EMU2)
-- arm_fpu_tune = FPUTYPE_FPA;
-+ }
-+
-+ arm_fpu_desc = NULL;
-+ for (i = 0; i < ARRAY_SIZE (all_fpus); i++)
-+ {
-+ if (streq (all_fpus[i].name, target_fpu_name))
-+ {
-+ arm_fpu_desc = &all_fpus[i];
-+ break;
-+ }
-+ }
-+ if (!arm_fpu_desc)
-+ error ("invalid floating point option: -mfpu=%s", target_fpu_name);
-+
-+ switch (arm_fpu_desc->model)
-+ {
-+ case ARM_FP_MODEL_FPA:
-+ if (arm_fpu_desc->rev == 2)
-+ arm_fpu_attr = FPU_FPE2;
-+ else if (arm_fpu_desc->rev == 3)
-+ arm_fpu_attr = FPU_FPE3;
- else
-- arm_fpu_tune = arm_fpu_arch;
-- arm_fp_model = fp_model_for_fpu[arm_fpu_arch];
-- gcc_assert (arm_fp_model != ARM_FP_MODEL_UNKNOWN);
-+ arm_fpu_attr = FPU_FPA;
-+ break;
-+
-+ case ARM_FP_MODEL_MAVERICK:
-+ arm_fpu_attr = FPU_MAVERICK;
-+ break;
-+
-+ case ARM_FP_MODEL_VFP:
-+ arm_fpu_attr = FPU_VFP;
-+ break;
-+
-+ default:
-+ gcc_unreachable();
- }
-
- if (target_float_abi_name != NULL)
-@@ -1509,9 +1689,6 @@ arm_override_options (void)
- else
- arm_float_abi = TARGET_DEFAULT_FLOAT_ABI;
-
-- if (arm_float_abi == ARM_FLOAT_ABI_HARD && TARGET_VFP)
-- sorry ("-mfloat-abi=hard and VFP");
--
- /* FPA and iWMMXt are incompatible because the insn encodings overlap.
- VFP and iWMMXt can theoretically coexist, but it's unlikely such silicon
- will ever exist. GCC makes no attempt to support this combination. */
-@@ -1522,15 +1699,40 @@ arm_override_options (void)
- if (TARGET_THUMB2 && TARGET_IWMMXT)
- sorry ("Thumb-2 iWMMXt");
-
-+ /* __fp16 support currently assumes the core has ldrh. */
-+ if (!arm_arch4 && arm_fp16_format != ARM_FP16_FORMAT_NONE)
-+ sorry ("__fp16 and no ldrh");
-+
- /* If soft-float is specified then don't use FPU. */
- if (TARGET_SOFT_FLOAT)
-- arm_fpu_arch = FPUTYPE_NONE;
-+ arm_fpu_attr = FPU_NONE;
-+
-+ if (TARGET_AAPCS_BASED)
-+ {
-+ if (arm_abi == ARM_ABI_IWMMXT)
-+ arm_pcs_default = ARM_PCS_AAPCS_IWMMXT;
-+ else if (arm_float_abi == ARM_FLOAT_ABI_HARD
-+ && TARGET_HARD_FLOAT
-+ && TARGET_VFP)
-+ arm_pcs_default = ARM_PCS_AAPCS_VFP;
-+ else
-+ arm_pcs_default = ARM_PCS_AAPCS;
-+ }
-+ else
-+ {
-+ if (arm_float_abi == ARM_FLOAT_ABI_HARD && TARGET_VFP)
-+ sorry ("-mfloat-abi=hard and VFP");
-+
-+ if (arm_abi == ARM_ABI_APCS)
-+ arm_pcs_default = ARM_PCS_APCS;
-+ else
-+ arm_pcs_default = ARM_PCS_ATPCS;
-+ }
-
- /* For arm2/3 there is no need to do any scheduling if there is only
- a floating point emulator, or we are doing software floating-point. */
- if ((TARGET_SOFT_FLOAT
-- || arm_fpu_tune == FPUTYPE_FPA_EMU2
-- || arm_fpu_tune == FPUTYPE_FPA_EMU3)
-+ || (TARGET_FPA && arm_fpu_desc->rev))
- && (tune_flags & FL_MODE32) == 0)
- flag_schedule_insns = flag_schedule_insns_after_reload = 0;
-
-@@ -1620,8 +1822,7 @@ arm_override_options (void)
- fix_cm3_ldrd = 0;
- }
-
-- /* ??? We might want scheduling for thumb2. */
-- if (TARGET_THUMB && flag_schedule_insns)
-+ if (TARGET_THUMB1 && flag_schedule_insns)
- {
- /* Don't warn since it's on by default in -O2. */
- flag_schedule_insns = 0;
-@@ -1664,6 +1865,36 @@ arm_override_options (void)
-
- /* Register global variables with the garbage collector. */
- arm_add_gc_roots ();
-+
-+ if (low_irq_latency && TARGET_THUMB)
-+ {
-+ warning (0,
-+ "-low-irq-latency has no effect when compiling for the Thumb");
-+ low_irq_latency = 0;
-+ }
-+
-+ /* CSL LOCAL */
-+ /* Loop unrolling can be a substantial win. At -O2, limit to 2x
-+ unrolling by default to prevent excessive code growth; at -O3,
-+ limit to 4x unrolling by default. We know we are not optimizing
-+ for size if this is set (see arm_optimization_options). */
-+ if (flag_unroll_loops == 2)
-+ {
-+ if (optimize == 2)
-+ {
-+ flag_unroll_loops = 1;
-+ if (!PARAM_SET_P (PARAM_MAX_UNROLL_TIMES))
-+ set_param_value ("max-unroll-times", 2);
-+ }
-+ else if (optimize > 2)
-+ {
-+ flag_unroll_loops = 1;
-+ if (!PARAM_SET_P (PARAM_MAX_UNROLL_TIMES))
-+ set_param_value ("max-unroll-times", 4);
-+ }
-+ else
-+ flag_unroll_loops = 0;
-+ }
- }
-
- static void
-@@ -1793,6 +2024,14 @@ arm_allocate_stack_slots_for_args (void)
- return !IS_NAKED (arm_current_func_type ());
- }
-
-+static bool
-+arm_warn_func_result (void)
-+{
-+ /* Naked functions are implemented entirely in assembly, including the
-+ return sequence, so suppress warnings about this. */
-+ return !IS_NAKED (arm_current_func_type ());
-+}
-+
- \f
- /* Return 1 if it is possible to return using a single instruction.
- If SIBLING is non-null, this is a test for a return before a sibling
-@@ -2884,14 +3123,19 @@ arm_canonicalize_comparison (enum rtx_co
-
- /* Define how to find the value returned by a function. */
-
--rtx
--arm_function_value(const_tree type, const_tree func ATTRIBUTE_UNUSED)
-+static rtx
-+arm_function_value(const_tree type, const_tree func,
-+ bool outgoing ATTRIBUTE_UNUSED)
- {
- enum machine_mode mode;
- int unsignedp ATTRIBUTE_UNUSED;
- rtx r ATTRIBUTE_UNUSED;
-
- mode = TYPE_MODE (type);
-+
-+ if (TARGET_AAPCS_BASED)
-+ return aapcs_allocate_return_reg (mode, type, func);
-+
- /* Promote integer types. */
- if (INTEGRAL_TYPE_P (type))
- PROMOTE_FUNCTION_MODE (mode, unsignedp, type);
-@@ -2908,7 +3152,36 @@ arm_function_value(const_tree type, cons
- }
- }
-
-- return LIBCALL_VALUE(mode);
-+ return LIBCALL_VALUE (mode);
-+}
-+
-+rtx
-+arm_libcall_value (enum machine_mode mode, rtx libcall)
-+{
-+ if (TARGET_AAPCS_BASED && arm_pcs_default != ARM_PCS_AAPCS
-+ && GET_MODE_CLASS (mode) == MODE_FLOAT)
-+ {
-+ /* The following libcalls return their result in integer registers,
-+ even though they return a floating point value. */
-+ if (rtx_equal_p (libcall,
-+ convert_optab_libfunc (sfloat_optab, mode, SImode))
-+ || rtx_equal_p (libcall,
-+ convert_optab_libfunc (ufloat_optab, mode, SImode))
-+ || rtx_equal_p (libcall,
-+ convert_optab_libfunc (sfloat_optab, mode, DImode))
-+ || rtx_equal_p (libcall,
-+ convert_optab_libfunc (ufloat_optab, mode, DImode))
-+ || rtx_equal_p (libcall,
-+ convert_optab_libfunc (trunc_optab, HFmode, SFmode))
-+ || rtx_equal_p (libcall,
-+ convert_optab_libfunc (sext_optab, SFmode, HFmode)))
-+ return gen_rtx_REG (mode, ARG_REGISTER(1));
-+
-+ /* XXX There are other libcalls that return in integer registers,
-+ but I think they are all handled by hard insns. */
-+ }
-+
-+ return LIBCALL_VALUE (mode);
- }
-
- /* Determine the amount of memory needed to store the possible return
-@@ -2918,10 +3191,12 @@ arm_apply_result_size (void)
- {
- int size = 16;
-
-- if (TARGET_ARM)
-+ if (TARGET_32BIT)
- {
- if (TARGET_HARD_FLOAT_ABI)
- {
-+ if (TARGET_VFP)
-+ size += 32;
- if (TARGET_FPA)
- size += 12;
- if (TARGET_MAVERICK)
-@@ -2934,27 +3209,56 @@ arm_apply_result_size (void)
- return size;
- }
-
--/* Decide whether a type should be returned in memory (true)
-- or in a register (false). This is called as the target hook
-- TARGET_RETURN_IN_MEMORY. */
-+/* Decide whether TYPE should be returned in memory (true)
-+ or in a register (false). FNTYPE is the type of the function making
-+ the call. */
- static bool
--arm_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
-+arm_return_in_memory (const_tree type, const_tree fntype)
- {
- HOST_WIDE_INT size;
-
-- size = int_size_in_bytes (type);
-+ size = int_size_in_bytes (type); /* Negative if not fixed size. */
-+
-+ if (TARGET_AAPCS_BASED)
-+ {
-+ /* Simple, non-aggregate types (ie not including vectors and
-+ complex) are always returned in a register (or registers).
-+ We don't care about which register here, so we can short-cut
-+ some of the detail. */
-+ if (!AGGREGATE_TYPE_P (type)
-+ && TREE_CODE (type) != VECTOR_TYPE
-+ && TREE_CODE (type) != COMPLEX_TYPE)
-+ return false;
-+
-+ /* Any return value that is no larger than one word can be
-+ returned in r0. */
-+ if (((unsigned HOST_WIDE_INT) size) <= UNITS_PER_WORD)
-+ return false;
-+
-+ /* Check any available co-processors to see if they accept the
-+ type as a register candidate (VFP, for example, can return
-+ some aggregates in consecutive registers). These aren't
-+ available if the call is variadic. */
-+ if (aapcs_select_return_coproc (type, fntype) >= 0)
-+ return false;
-+
-+ /* Vector values should be returned using ARM registers, not
-+ memory (unless they're over 16 bytes, which will break since
-+ we only have four call-clobbered registers to play with). */
-+ if (TREE_CODE (type) == VECTOR_TYPE)
-+ return (size < 0 || size > (4 * UNITS_PER_WORD));
-+
-+ /* The rest go in memory. */
-+ return true;
-+ }
-
-- /* Vector values should be returned using ARM registers, not memory (unless
-- they're over 16 bytes, which will break since we only have four
-- call-clobbered registers to play with). */
- if (TREE_CODE (type) == VECTOR_TYPE)
- return (size < 0 || size > (4 * UNITS_PER_WORD));
-
- if (!AGGREGATE_TYPE_P (type) &&
-- !(TARGET_AAPCS_BASED && TREE_CODE (type) == COMPLEX_TYPE))
-- /* All simple types are returned in registers.
-- For AAPCS, complex types are treated the same as aggregates. */
-- return 0;
-+ (TREE_CODE (type) != VECTOR_TYPE))
-+ /* All simple types are returned in registers. */
-+ return false;
-
- if (arm_abi != ARM_ABI_APCS)
- {
-@@ -2971,7 +3275,7 @@ arm_return_in_memory (const_tree type, c
- the aggregate is either huge or of variable size, and in either case
- we will want to return it via memory and not in a register. */
- if (size < 0 || size > UNITS_PER_WORD)
-- return 1;
-+ return true;
-
- if (TREE_CODE (type) == RECORD_TYPE)
- {
-@@ -2991,18 +3295,18 @@ arm_return_in_memory (const_tree type, c
- continue;
-
- if (field == NULL)
-- return 0; /* An empty structure. Allowed by an extension to ANSI C. */
-+ return false; /* An empty structure. Allowed by an extension to ANSI C. */
-
- /* Check that the first field is valid for returning in a register. */
-
- /* ... Floats are not allowed */
- if (FLOAT_TYPE_P (TREE_TYPE (field)))
-- return 1;
-+ return true;
-
- /* ... Aggregates that are not themselves valid for returning in
- a register are not allowed. */
- if (arm_return_in_memory (TREE_TYPE (field), NULL_TREE))
-- return 1;
-+ return true;
-
- /* Now check the remaining fields, if any. Only bitfields are allowed,
- since they are not addressable. */
-@@ -3014,10 +3318,10 @@ arm_return_in_memory (const_tree type, c
- continue;
-
- if (!DECL_BIT_FIELD_TYPE (field))
-- return 1;
-+ return true;
- }
-
-- return 0;
-+ return false;
- }
-
- if (TREE_CODE (type) == UNION_TYPE)
-@@ -3034,18 +3338,18 @@ arm_return_in_memory (const_tree type, c
- continue;
-
- if (FLOAT_TYPE_P (TREE_TYPE (field)))
-- return 1;
-+ return true;
-
- if (arm_return_in_memory (TREE_TYPE (field), NULL_TREE))
-- return 1;
-+ return true;
- }
-
-- return 0;
-+ return false;
- }
- #endif /* not ARM_WINCE */
-
- /* Return all other types in memory. */
-- return 1;
-+ return true;
- }
-
- /* Indicate whether or not words of a double are in big-endian order. */
-@@ -3070,14 +3374,780 @@ arm_float_words_big_endian (void)
- return 1;
- }
-
-+const struct pcs_attribute_arg
-+{
-+ const char *arg;
-+ enum arm_pcs value;
-+} pcs_attribute_args[] =
-+ {
-+ {"aapcs", ARM_PCS_AAPCS},
-+ {"aapcs-vfp", ARM_PCS_AAPCS_VFP},
-+ {"aapcs-iwmmxt", ARM_PCS_AAPCS_IWMMXT},
-+ {"atpcs", ARM_PCS_ATPCS},
-+ {"apcs", ARM_PCS_APCS},
-+ {NULL, ARM_PCS_UNKNOWN}
-+ };
-+
-+static enum arm_pcs
-+arm_pcs_from_attribute (tree attr)
-+{
-+ const struct pcs_attribute_arg *ptr;
-+ const char *arg;
-+
-+ /* Get the value of the argument. */
-+ if (TREE_VALUE (attr) == NULL_TREE
-+ || TREE_CODE (TREE_VALUE (attr)) != STRING_CST)
-+ return ARM_PCS_UNKNOWN;
-+
-+ arg = TREE_STRING_POINTER (TREE_VALUE (attr));
-+
-+ /* Check it against the list of known arguments. */
-+ for (ptr = pcs_attribute_args; ptr->arg != NULL; ptr++)
-+ if (streq (arg, ptr->arg))
-+ return ptr->value;
-+
-+ /* An unrecognized interrupt type. */
-+ return ARM_PCS_UNKNOWN;
-+}
-+
-+/* Get the PCS variant to use for this call. TYPE is the function's type
-+ specification, DECL is the specific declartion. DECL may be null if
-+ the call could be indirect or if this is a library call. */
-+static enum arm_pcs
-+arm_get_pcs_model (const_tree type, const_tree decl)
-+{
-+ bool user_convention = false;
-+ enum arm_pcs user_pcs = arm_pcs_default;
-+ tree attr;
-+
-+ gcc_assert (type);
-+
-+ attr = lookup_attribute ("pcs", TYPE_ATTRIBUTES (type));
-+ if (attr)
-+ {
-+ user_pcs = arm_pcs_from_attribute (TREE_VALUE (attr));
-+ user_convention = true;
-+ }
-+
-+ if (TARGET_AAPCS_BASED)
-+ {
-+ /* Detect varargs functions. These always use the base rules
-+ (no argument is ever a candidate for a co-processor
-+ register). */
-+ bool base_rules = (TYPE_ARG_TYPES (type) != 0
-+ && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (type)))
-+ != void_type_node));
-+
-+ if (user_convention)
-+ {
-+ if (user_pcs > ARM_PCS_AAPCS_LOCAL)
-+ sorry ("Non-AAPCS derived PCS variant");
-+ else if (base_rules && user_pcs != ARM_PCS_AAPCS)
-+ error ("Variadic functions must use the base AAPCS variant");
-+ }
-+
-+ if (base_rules)
-+ return ARM_PCS_AAPCS;
-+ else if (user_convention)
-+ return user_pcs;
-+ else if (decl && flag_unit_at_a_time)
-+ {
-+ /* Local functions never leak outside this compilation unit,
-+ so we are free to use whatever conventions are
-+ appropriate. */
-+ /* FIXME: remove CONST_CAST_TREE when cgraph is constified. */
-+ struct cgraph_local_info *i = cgraph_local_info (CONST_CAST_TREE(decl));
-+ if (i && i->local)
-+ return ARM_PCS_AAPCS_LOCAL;
-+ }
-+ }
-+ else if (user_convention && user_pcs != arm_pcs_default)
-+ sorry ("PCS variant");
-+
-+ /* For everything else we use the target's default. */
-+ return arm_pcs_default;
-+}
-+
-+
-+static void
-+aapcs_vfp_cum_init (CUMULATIVE_ARGS *pcum ATTRIBUTE_UNUSED,
-+ const_tree fntype ATTRIBUTE_UNUSED,
-+ rtx libcall ATTRIBUTE_UNUSED,
-+ const_tree fndecl ATTRIBUTE_UNUSED)
-+{
-+ /* Record the unallocated VFP registers. */
-+ pcum->aapcs_vfp_regs_free = (1 << NUM_VFP_ARG_REGS) - 1;
-+ pcum->aapcs_vfp_reg_alloc = 0;
-+}
-+
-+/* Walk down the type tree of TYPE counting consecutive base elements.
-+ If *MODEP is VOIDmode, then set it to the first valid floating point
-+ type. If a non-floating point type is found, or if a floating point
-+ type that doesn't match a non-VOIDmode *MODEP is found, then return -1,
-+ otherwise return the count in the sub-tree. */
-+static int
-+aapcs_vfp_sub_candidate (const_tree type, enum machine_mode *modep)
-+{
-+ enum machine_mode mode;
-+ HOST_WIDE_INT size;
-+
-+ switch (TREE_CODE (type))
-+ {
-+ case REAL_TYPE:
-+ mode = TYPE_MODE (type);
-+ if (mode != DFmode && mode != SFmode)
-+ return -1;
-+
-+ if (*modep == VOIDmode)
-+ *modep = mode;
-+
-+ if (*modep == mode)
-+ return 1;
-+
-+ break;
-+
-+ case COMPLEX_TYPE:
-+ mode = TYPE_MODE (TREE_TYPE (type));
-+ if (mode != DFmode && mode != SFmode)
-+ return -1;
-+
-+ if (*modep == VOIDmode)
-+ *modep = mode;
-+
-+ if (*modep == mode)
-+ return 2;
-+
-+ break;
-+
-+ case VECTOR_TYPE:
-+ /* Use V2SImode and V4SImode as representatives of all 64-bit
-+ and 128-bit vector types, whether or not those modes are
-+ supported with the present options. */
-+ size = int_size_in_bytes (type);
-+ switch (size)
-+ {
-+ case 8:
-+ mode = V2SImode;
-+ break;
-+ case 16:
-+ mode = V4SImode;
-+ break;
-+ default:
-+ return -1;
-+ }
-+
-+ if (*modep == VOIDmode)
-+ *modep = mode;
-+
-+ /* Vector modes are considered to be opaque: two vectors are
-+ equivalent for the purposes of being homogeneous aggregates
-+ if they are the same size. */
-+ if (*modep == mode)
-+ return 1;
-+
-+ break;
-+
-+ case ARRAY_TYPE:
-+ {
-+ int count;
-+ tree index = TYPE_DOMAIN (type);
-+
-+ /* Can't handle incomplete types. */
-+ if (!COMPLETE_TYPE_P(type))
-+ return -1;
-+
-+ count = aapcs_vfp_sub_candidate (TREE_TYPE (type), modep);
-+ if (count == -1
-+ || !index
-+ || !TYPE_MAX_VALUE (index)
-+ || !host_integerp (TYPE_MAX_VALUE (index), 1)
-+ || !TYPE_MIN_VALUE (index)
-+ || !host_integerp (TYPE_MIN_VALUE (index), 1)
-+ || count < 0)
-+ return -1;
-+
-+ count *= (1 + tree_low_cst (TYPE_MAX_VALUE (index), 1)
-+ - tree_low_cst (TYPE_MIN_VALUE (index), 1));
-+
-+ /* There must be no padding. */
-+ if (!host_integerp (TYPE_SIZE (type), 1)
-+ || (tree_low_cst (TYPE_SIZE (type), 1)
-+ != count * GET_MODE_BITSIZE (*modep)))
-+ return -1;
-+
-+ return count;
-+ }
-+
-+ case RECORD_TYPE:
-+ {
-+ int count = 0;
-+ int sub_count;
-+ tree field;
-+
-+ /* Can't handle incomplete types. */
-+ if (!COMPLETE_TYPE_P(type))
-+ return -1;
-+
-+ for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
-+ {
-+ if (TREE_CODE (field) != FIELD_DECL)
-+ continue;
-+
-+ sub_count = aapcs_vfp_sub_candidate (TREE_TYPE (field), modep);
-+ if (sub_count < 0)
-+ return -1;
-+ count += sub_count;
-+ }
-+
-+ /* There must be no padding. */
-+ if (!host_integerp (TYPE_SIZE (type), 1)
-+ || (tree_low_cst (TYPE_SIZE (type), 1)
-+ != count * GET_MODE_BITSIZE (*modep)))
-+ return -1;
-+
-+ return count;
-+ }
-+
-+ case UNION_TYPE:
-+ case QUAL_UNION_TYPE:
-+ {
-+ /* These aren't very interesting except in a degenerate case. */
-+ int count = 0;
-+ int sub_count;
-+ tree field;
-+
-+ /* Can't handle incomplete types. */
-+ if (!COMPLETE_TYPE_P(type))
-+ return -1;
-+
-+ for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
-+ {
-+ if (TREE_CODE (field) != FIELD_DECL)
-+ continue;
-+
-+ sub_count = aapcs_vfp_sub_candidate (TREE_TYPE (field), modep);
-+ if (sub_count < 0)
-+ return -1;
-+ count = count > sub_count ? count : sub_count;
-+ }
-+
-+ /* There must be no padding. */
-+ if (!host_integerp (TYPE_SIZE (type), 1)
-+ || (tree_low_cst (TYPE_SIZE (type), 1)
-+ != count * GET_MODE_BITSIZE (*modep)))
-+ return -1;
-+
-+ return count;
-+ }
-+
-+ default:
-+ break;
-+ }
-+
-+ return -1;
-+}
-+
-+/* Return true if PCS_VARIANT should use VFP registers. */
-+static bool
-+use_vfp_abi (enum arm_pcs pcs_variant, bool is_double)
-+{
-+ if (pcs_variant == ARM_PCS_AAPCS_VFP)
-+ return true;
-+
-+ if (pcs_variant != ARM_PCS_AAPCS_LOCAL)
-+ return false;
-+
-+ return (TARGET_32BIT && TARGET_VFP && TARGET_HARD_FLOAT &&
-+ (TARGET_VFP_DOUBLE || !is_double));
-+}
-+
-+static bool
-+aapcs_vfp_is_call_or_return_candidate (enum arm_pcs pcs_variant,
-+ enum machine_mode mode, const_tree type,
-+ int *base_mode, int *count)
-+{
-+ enum machine_mode new_mode = VOIDmode;
-+
-+ if (GET_MODE_CLASS (mode) == MODE_FLOAT
-+ || GET_MODE_CLASS (mode) == MODE_VECTOR_INT
-+ || GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT)
-+ {
-+ *count = 1;
-+ new_mode = mode;
-+ }
-+ else if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT)
-+ {
-+ *count = 2;
-+ new_mode = (mode == DCmode ? DFmode : SFmode);
-+ }
-+ else if (type && (mode == BLKmode || TREE_CODE (type) == VECTOR_TYPE))
-+ {
-+ int ag_count = aapcs_vfp_sub_candidate (type, &new_mode);
-+
-+ if (ag_count > 0 && ag_count <= 4)
-+ *count = ag_count;
-+ else
-+ return false;
-+ }
-+ else
-+ return false;
-+
-+
-+ if (!use_vfp_abi (pcs_variant, ARM_NUM_REGS (new_mode) > 1))
-+ return false;
-+
-+ *base_mode = new_mode;
-+ return true;
-+}
-+
-+static bool
-+aapcs_vfp_is_return_candidate (enum arm_pcs pcs_variant,
-+ enum machine_mode mode, const_tree type)
-+{
-+ int count ATTRIBUTE_UNUSED;
-+ int ag_mode ATTRIBUTE_UNUSED;
-+
-+ if (!use_vfp_abi (pcs_variant, false))
-+ return false;
-+ return aapcs_vfp_is_call_or_return_candidate (pcs_variant, mode, type,
-+ &ag_mode, &count);
-+}
-+
-+static bool
-+aapcs_vfp_is_call_candidate (CUMULATIVE_ARGS *pcum, enum machine_mode mode,
-+ const_tree type)
-+{
-+ if (!use_vfp_abi (pcum->pcs_variant, false))
-+ return false;
-+
-+ return aapcs_vfp_is_call_or_return_candidate (pcum->pcs_variant, mode, type,
-+ &pcum->aapcs_vfp_rmode,
-+ &pcum->aapcs_vfp_rcount);
-+}
-+
-+static bool
-+aapcs_vfp_allocate (CUMULATIVE_ARGS *pcum, enum machine_mode mode,
-+ const_tree type ATTRIBUTE_UNUSED)
-+{
-+ int shift = GET_MODE_SIZE (pcum->aapcs_vfp_rmode) / GET_MODE_SIZE (SFmode);
-+ unsigned mask = (1 << (shift * pcum->aapcs_vfp_rcount)) - 1;
-+ int regno;
-+
-+ for (regno = 0; regno < NUM_VFP_ARG_REGS; regno += shift)
-+ if (((pcum->aapcs_vfp_regs_free >> regno) & mask) == mask)
-+ {
-+ pcum->aapcs_vfp_reg_alloc = mask << regno;
-+ if (mode == BLKmode || (mode == TImode && !TARGET_NEON))
-+ {
-+ int i;
-+ int rcount = pcum->aapcs_vfp_rcount;
-+ int rshift = shift;
-+ enum machine_mode rmode = pcum->aapcs_vfp_rmode;
-+ rtx par;
-+ if (!TARGET_NEON)
-+ {
-+ /* Avoid using unsupported vector modes. */
-+ if (rmode == V2SImode)
-+ rmode = DImode;
-+ else if (rmode == V4SImode)
-+ {
-+ rmode = DImode;
-+ rcount *= 2;
-+ rshift /= 2;
-+ }
-+ }
-+ par = gen_rtx_PARALLEL (mode, rtvec_alloc (rcount));
-+ for (i = 0; i < rcount; i++)
-+ {
-+ rtx tmp = gen_rtx_REG (rmode,
-+ FIRST_VFP_REGNUM + regno + i * rshift);
-+ tmp = gen_rtx_EXPR_LIST
-+ (VOIDmode, tmp,
-+ GEN_INT (i * GET_MODE_SIZE (rmode)));
-+ XVECEXP (par, 0, i) = tmp;
-+ }
-+
-+ pcum->aapcs_reg = par;
-+ }
-+ else
-+ pcum->aapcs_reg = gen_rtx_REG (mode, FIRST_VFP_REGNUM + regno);
-+ return true;
-+ }
-+ return false;
-+}
-+
-+static rtx
-+aapcs_vfp_allocate_return_reg (enum arm_pcs pcs_variant ATTRIBUTE_UNUSED,
-+ enum machine_mode mode,
-+ const_tree type ATTRIBUTE_UNUSED)
-+{
-+ if (!use_vfp_abi (pcs_variant, false))
-+ return false;
-+
-+ if (mode == BLKmode || (mode == TImode && !TARGET_NEON))
-+ {
-+ int count;
-+ int ag_mode;
-+ int i;
-+ rtx par;
-+ int shift;
-+
-+ aapcs_vfp_is_call_or_return_candidate (pcs_variant, mode, type,
-+ &ag_mode, &count);
-+
-+ if (!TARGET_NEON)
-+ {
-+ if (ag_mode == V2SImode)
-+ ag_mode = DImode;
-+ else if (ag_mode == V4SImode)
-+ {
-+ ag_mode = DImode;
-+ count *= 2;
-+ }
-+ }
-+ shift = GET_MODE_SIZE(ag_mode) / GET_MODE_SIZE(SFmode);
-+ par = gen_rtx_PARALLEL (mode, rtvec_alloc (count));
-+ for (i = 0; i < count; i++)
-+ {
-+ rtx tmp = gen_rtx_REG (ag_mode, FIRST_VFP_REGNUM + i * shift);
-+ tmp = gen_rtx_EXPR_LIST (VOIDmode, tmp,
-+ GEN_INT (i * GET_MODE_SIZE (ag_mode)));
-+ XVECEXP (par, 0, i) = tmp;
-+ }
-+
-+ return par;
-+ }
-+
-+ return gen_rtx_REG (mode, FIRST_VFP_REGNUM);
-+}
-+
-+static void
-+aapcs_vfp_advance (CUMULATIVE_ARGS *pcum ATTRIBUTE_UNUSED,
-+ enum machine_mode mode ATTRIBUTE_UNUSED,
-+ const_tree type ATTRIBUTE_UNUSED)
-+{
-+ pcum->aapcs_vfp_regs_free &= ~pcum->aapcs_vfp_reg_alloc;
-+ pcum->aapcs_vfp_reg_alloc = 0;
-+ return;
-+}
-+
-+#define AAPCS_CP(X) \
-+ { \
-+ aapcs_ ## X ## _cum_init, \
-+ aapcs_ ## X ## _is_call_candidate, \
-+ aapcs_ ## X ## _allocate, \
-+ aapcs_ ## X ## _is_return_candidate, \
-+ aapcs_ ## X ## _allocate_return_reg, \
-+ aapcs_ ## X ## _advance \
-+ }
-+
-+/* Table of co-processors that can be used to pass arguments in
-+ registers. Idealy no arugment should be a candidate for more than
-+ one co-processor table entry, but the table is processed in order
-+ and stops after the first match. If that entry then fails to put
-+ the argument into a co-processor register, the argument will go on
-+ the stack. */
-+static struct
-+{
-+ /* Initialize co-processor related state in CUMULATIVE_ARGS structure. */
-+ void (*cum_init) (CUMULATIVE_ARGS *, const_tree, rtx, const_tree);
-+
-+ /* Return true if an argument of mode MODE (or type TYPE if MODE is
-+ BLKmode) is a candidate for this co-processor's registers; this
-+ function should ignore any position-dependent state in
-+ CUMULATIVE_ARGS and only use call-type dependent information. */
-+ bool (*is_call_candidate) (CUMULATIVE_ARGS *, enum machine_mode, const_tree);
-+
-+ /* Return true if the argument does get a co-processor register; it
-+ should set aapcs_reg to an RTX of the register allocated as is
-+ required for a return from FUNCTION_ARG. */
-+ bool (*allocate) (CUMULATIVE_ARGS *, enum machine_mode, const_tree);
-+
-+ /* Return true if a result of mode MODE (or type TYPE if MODE is
-+ BLKmode) is can be returned in this co-processor's registers. */
-+ bool (*is_return_candidate) (enum arm_pcs, enum machine_mode, const_tree);
-+
-+ /* Allocate and return an RTX element to hold the return type of a
-+ call, this routine must not fail and will only be called if
-+ is_return_candidate returned true with the same parameters. */
-+ rtx (*allocate_return_reg) (enum arm_pcs, enum machine_mode, const_tree);
-+
-+ /* Finish processing this argument and prepare to start processing
-+ the next one. */
-+ void (*advance) (CUMULATIVE_ARGS *, enum machine_mode, const_tree);
-+} aapcs_cp_arg_layout[ARM_NUM_COPROC_SLOTS] =
-+ {
-+ AAPCS_CP(vfp)
-+ };
-+
-+#undef AAPCS_CP
-+
-+static int
-+aapcs_select_call_coproc (CUMULATIVE_ARGS *pcum, enum machine_mode mode,
-+ tree type)
-+{
-+ int i;
-+
-+ for (i = 0; i < ARM_NUM_COPROC_SLOTS; i++)
-+ if (aapcs_cp_arg_layout[i].is_call_candidate (pcum, mode, type))
-+ return i;
-+
-+ return -1;
-+}
-+
-+static int
-+aapcs_select_return_coproc (const_tree type, const_tree fntype)
-+{
-+ /* We aren't passed a decl, so we can't check that a call is local.
-+ However, it isn't clear that that would be a win anyway, since it
-+ might limit some tail-calling opportunities. */
-+ enum arm_pcs pcs_variant;
-+
-+ if (fntype)
-+ {
-+ const_tree fndecl = NULL_TREE;
-+
-+ if (TREE_CODE (fntype) == FUNCTION_DECL)
-+ {
-+ fndecl = fntype;
-+ fntype = TREE_TYPE (fntype);
-+ }
-+
-+ pcs_variant = arm_get_pcs_model (fntype, fndecl);
-+ }
-+ else
-+ pcs_variant = arm_pcs_default;
-+
-+ if (pcs_variant != ARM_PCS_AAPCS)
-+ {
-+ int i;
-+
-+ for (i = 0; i < ARM_NUM_COPROC_SLOTS; i++)
-+ if (aapcs_cp_arg_layout[i].is_return_candidate (pcs_variant,
-+ TYPE_MODE (type),
-+ type))
-+ return i;
-+ }
-+ return -1;
-+}
-+
-+static rtx
-+aapcs_allocate_return_reg (enum machine_mode mode, const_tree type,
-+ const_tree fntype)
-+{
-+ /* We aren't passed a decl, so we can't check that a call is local.
-+ However, it isn't clear that that would be a win anyway, since it
-+ might limit some tail-calling opportunities. */
-+ enum arm_pcs pcs_variant;
-+
-+ if (fntype)
-+ {
-+ const_tree fndecl = NULL_TREE;
-+
-+ if (TREE_CODE (fntype) == FUNCTION_DECL)
-+ {
-+ fndecl = fntype;
-+ fntype = TREE_TYPE (fntype);
-+ }
-+
-+ pcs_variant = arm_get_pcs_model (fntype, fndecl);
-+ }
-+ else
-+ pcs_variant = arm_pcs_default;
-+
-+ /* Promote integer types. */
-+ if (type && INTEGRAL_TYPE_P (type))
-+ PROMOTE_FUNCTION_MODE (mode, unsignedp, type);
-+
-+ if (pcs_variant != ARM_PCS_AAPCS)
-+ {
-+ int i;
-+
-+ for (i = 0; i < ARM_NUM_COPROC_SLOTS; i++)
-+ if (aapcs_cp_arg_layout[i].is_return_candidate (pcs_variant, mode,
-+ type))
-+ return aapcs_cp_arg_layout[i].allocate_return_reg (pcs_variant,
-+ mode, type);
-+ }
-+
-+ /* Promotes small structs returned in a register to full-word size
-+ for big-endian AAPCS. */
-+ if (type && arm_return_in_msb (type))
-+ {
-+ HOST_WIDE_INT size = int_size_in_bytes (type);
-+ if (size % UNITS_PER_WORD != 0)
-+ {
-+ size += UNITS_PER_WORD - size % UNITS_PER_WORD;
-+ mode = mode_for_size (size * BITS_PER_UNIT, MODE_INT, 0);
-+ }
-+ }
-+
-+ return gen_rtx_REG (mode, R0_REGNUM);
-+}
-+
-+rtx
-+aapcs_libcall_value (enum machine_mode mode)
-+{
-+ return aapcs_allocate_return_reg (mode, NULL_TREE, NULL_TREE);
-+}
-+
-+/* Lay out a function argument using the AAPCS rules. The rule
-+ numbers referred to here are those in the AAPCS. */
-+static void
-+aapcs_layout_arg (CUMULATIVE_ARGS *pcum, enum machine_mode mode,
-+ tree type, int named)
-+{
-+ int nregs, nregs2;
-+ int ncrn;
-+
-+ /* We only need to do this once per argument. */
-+ if (pcum->aapcs_arg_processed)
-+ return;
-+
-+ pcum->aapcs_arg_processed = true;
-+
-+ /* Special case: if named is false then we are handling an incoming
-+ anonymous argument which is on the stack. */
-+ if (!named)
-+ return;
-+
-+ /* Is this a potential co-processor register candidate? */
-+ if (pcum->pcs_variant != ARM_PCS_AAPCS)
-+ {
-+ int slot = aapcs_select_call_coproc (pcum, mode, type);
-+ pcum->aapcs_cprc_slot = slot;
-+
-+ /* We don't have to apply any of the rules from part B of the
-+ preparation phase, these are handled elsewhere in the
-+ compiler. */
-+
-+ if (slot >= 0)
-+ {
-+ /* A Co-processor register candidate goes either in its own
-+ class of registers or on the stack. */
-+ if (!pcum->aapcs_cprc_failed[slot])
-+ {
-+ /* C1.cp - Try to allocate the argument to co-processor
-+ registers. */
-+ if (aapcs_cp_arg_layout[slot].allocate (pcum, mode, type))
-+ return;
-+
-+ /* C2.cp - Put the argument on the stack and note that we
-+ can't assign any more candidates in this slot. We also
-+ need to note that we have allocated stack space, so that
-+ we won't later try to split a non-cprc candidate between
-+ core registers and the stack. */
-+ pcum->aapcs_cprc_failed[slot] = true;
-+ pcum->can_split = false;
-+ }
-+
-+ /* We didn't get a register, so this argument goes on the
-+ stack. */
-+ gcc_assert (pcum->can_split == false);
-+ return;
-+ }
-+ }
-+
-+ /* C3 - For double-word aligned arguments, round the NCRN up to the
-+ next even number. */
-+ ncrn = pcum->aapcs_ncrn;
-+ if ((ncrn & 1) && arm_needs_doubleword_align (mode, type))
-+ ncrn++;
-+
-+ nregs = ARM_NUM_REGS2(mode, type);
-+
-+ /* Sigh, this test should really assert that nregs > 0, but a GCC
-+ extension allows empty structs and then gives them empty size; it
-+ then allows such a structure to be passed by value. For some of
-+ the code below we have to pretend that such an argument has
-+ non-zero size so that we 'locate' it correctly either in
-+ registers or on the stack. */
-+ gcc_assert (nregs >= 0);
-+
-+ nregs2 = nregs ? nregs : 1;
-+
-+ /* C4 - Argument fits entirely in core registers. */
-+ if (ncrn + nregs2 <= NUM_ARG_REGS)
-+ {
-+ pcum->aapcs_reg = gen_rtx_REG (mode, ncrn);
-+ pcum->aapcs_next_ncrn = ncrn + nregs;
-+ return;
-+ }
-+
-+ /* C5 - Some core registers left and there are no arguments already
-+ on the stack: split this argument between the remaining core
-+ registers and the stack. */
-+ if (ncrn < NUM_ARG_REGS && pcum->can_split)
-+ {
-+ pcum->aapcs_reg = gen_rtx_REG (mode, ncrn);
-+ pcum->aapcs_next_ncrn = NUM_ARG_REGS;
-+ pcum->aapcs_partial = (NUM_ARG_REGS - ncrn) * UNITS_PER_WORD;
-+ return;
-+ }
-+
-+ /* C6 - NCRN is set to 4. */
-+ pcum->aapcs_next_ncrn = NUM_ARG_REGS;
-+
-+ /* C7,C8 - arugment goes on the stack. We have nothing to do here. */
-+ return;
-+}
-+
- /* Initialize a variable CUM of type CUMULATIVE_ARGS
- for a call to a function whose data type is FNTYPE.
- For a library call, FNTYPE is NULL. */
- void
- arm_init_cumulative_args (CUMULATIVE_ARGS *pcum, tree fntype,
-- rtx libname ATTRIBUTE_UNUSED,
-+ rtx libname,
- tree fndecl ATTRIBUTE_UNUSED)
- {
-+ /* Long call handling. */
-+ if (fntype)
-+ pcum->pcs_variant = arm_get_pcs_model (fntype, fndecl);
-+ else
-+ pcum->pcs_variant = arm_pcs_default;
-+
-+ if (pcum->pcs_variant <= ARM_PCS_AAPCS_LOCAL)
-+ {
-+ /* XXX We should also detect some library calls here and handle
-+ them using the base rules too; for example the floating point
-+ support functions always work this way. */
-+
-+ if (rtx_equal_p (libname,
-+ convert_optab_libfunc (sfix_optab, DImode, DFmode))
-+ || rtx_equal_p (libname,
-+ convert_optab_libfunc (ufix_optab, DImode, DFmode))
-+ || rtx_equal_p (libname,
-+ convert_optab_libfunc (sfix_optab, DImode, SFmode))
-+ || rtx_equal_p (libname,
-+ convert_optab_libfunc (ufix_optab, DImode, SFmode))
-+ || rtx_equal_p (libname,
-+ convert_optab_libfunc (trunc_optab, HFmode, SFmode))
-+ || rtx_equal_p (libname,
-+ convert_optab_libfunc (sext_optab, SFmode, HFmode)))
-+ pcum->pcs_variant = ARM_PCS_AAPCS;
-+
-+ pcum->aapcs_ncrn = pcum->aapcs_next_ncrn = 0;
-+ pcum->aapcs_reg = NULL_RTX;
-+ pcum->aapcs_partial = 0;
-+ pcum->aapcs_arg_processed = false;
-+ pcum->aapcs_cprc_slot = -1;
-+ pcum->can_split = true;
-+
-+ if (pcum->pcs_variant != ARM_PCS_AAPCS)
-+ {
-+ int i;
-+
-+ for (i = 0; i < ARM_NUM_COPROC_SLOTS; i++)
-+ {
-+ pcum->aapcs_cprc_failed[i] = false;
-+ aapcs_cp_arg_layout[i].cum_init (pcum, fntype, libname, fndecl);
-+ }
-+ }
-+ return;
-+ }
-+
-+ /* Legacy ABIs */
-+
- /* On the ARM, the offset starts at 0. */
- pcum->nregs = 0;
- pcum->iwmmxt_nregs = 0;
-@@ -3131,6 +4201,17 @@ arm_function_arg (CUMULATIVE_ARGS *pcum,
- {
- int nregs;
-
-+ /* Handle the special case quickly. Pick an arbitrary value for op2 of
-+ a call insn (op3 of a call_value insn). */
-+ if (mode == VOIDmode)
-+ return const0_rtx;
-+
-+ if (pcum->pcs_variant <= ARM_PCS_AAPCS_LOCAL)
-+ {
-+ aapcs_layout_arg (pcum, mode, type, named);
-+ return pcum->aapcs_reg;
-+ }
-+
- /* Varargs vectors are treated the same as long long.
- named_count avoids having to change the way arm handles 'named' */
- if (TARGET_IWMMXT_ABI
-@@ -3172,10 +4253,16 @@ arm_function_arg (CUMULATIVE_ARGS *pcum,
-
- static int
- arm_arg_partial_bytes (CUMULATIVE_ARGS *pcum, enum machine_mode mode,
-- tree type, bool named ATTRIBUTE_UNUSED)
-+ tree type, bool named)
- {
- int nregs = pcum->nregs;
-
-+ if (pcum->pcs_variant <= ARM_PCS_AAPCS_LOCAL)
-+ {
-+ aapcs_layout_arg (pcum, mode, type, named);
-+ return pcum->aapcs_partial;
-+ }
-+
- if (TARGET_IWMMXT_ABI && arm_vector_mode_supported_p (mode))
- return 0;
-
-@@ -3184,7 +4271,40 @@ arm_arg_partial_bytes (CUMULATIVE_ARGS *
- && pcum->can_split)
- return (NUM_ARG_REGS - nregs) * UNITS_PER_WORD;
-
-- return 0;
-+ return 0;
-+}
-+
-+void
-+arm_function_arg_advance (CUMULATIVE_ARGS *pcum, enum machine_mode mode,
-+ tree type, bool named)
-+{
-+ if (pcum->pcs_variant <= ARM_PCS_AAPCS_LOCAL)
-+ {
-+ aapcs_layout_arg (pcum, mode, type, named);
-+
-+ if (pcum->aapcs_cprc_slot >= 0)
-+ {
-+ aapcs_cp_arg_layout[pcum->aapcs_cprc_slot].advance (pcum, mode,
-+ type);
-+ pcum->aapcs_cprc_slot = -1;
-+ }
-+
-+ /* Generic stuff. */
-+ pcum->aapcs_arg_processed = false;
-+ pcum->aapcs_ncrn = pcum->aapcs_next_ncrn;
-+ pcum->aapcs_reg = NULL_RTX;
-+ pcum->aapcs_partial = 0;
-+ }
-+ else
-+ {
-+ pcum->nargs += 1;
-+ if (arm_vector_mode_supported_p (mode)
-+ && pcum->named_count > pcum->nargs
-+ && TARGET_IWMMXT_ABI)
-+ pcum->iwmmxt_nregs += 1;
-+ else
-+ pcum->nregs += ARM_NUM_REGS2 (mode, type);
-+ }
- }
-
- /* Variable sized types are passed by reference. This is a GCC
-@@ -3237,6 +4357,8 @@ const struct attribute_spec arm_attribut
- /* Whereas these functions are always known to reside within the 26 bit
- addressing range. */
- { "short_call", 0, 0, false, true, true, NULL },
-+ /* Specify the procedure call conventions for a function. */
-+ { "pcs", 1, 1, false, true, true, arm_handle_pcs_attribute },
- /* Interrupt Service Routines have special prologue and epilogue requirements. */
- { "isr", 0, 1, false, false, false, arm_handle_isr_attribute },
- { "interrupt", 0, 1, false, false, false, arm_handle_isr_attribute },
-@@ -3339,6 +4461,21 @@ arm_handle_isr_attribute (tree *node, tr
- return NULL_TREE;
- }
-
-+/* Handle a "pcs" attribute; arguments as in struct
-+ attribute_spec.handler. */
-+static tree
-+arm_handle_pcs_attribute (tree *node ATTRIBUTE_UNUSED, tree name, tree args,
-+ int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
-+{
-+ if (arm_pcs_from_attribute (args) == ARM_PCS_UNKNOWN)
-+ {
-+ warning (OPT_Wattributes, "%qs attribute ignored",
-+ IDENTIFIER_POINTER (name));
-+ *no_add_attrs = true;
-+ }
-+ return NULL_TREE;
-+}
-+
- #if TARGET_DLLIMPORT_DECL_ATTRIBUTES
- /* Handle the "notshared" attribute. This attribute is another way of
- requesting hidden visibility. ARM's compiler supports
-@@ -3500,7 +4637,7 @@ arm_is_long_call_p (tree decl)
-
- /* Return nonzero if it is ok to make a tail-call to DECL. */
- static bool
--arm_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
-+arm_function_ok_for_sibcall (tree decl, tree exp)
- {
- unsigned long func_type;
-
-@@ -3533,6 +4670,21 @@ arm_function_ok_for_sibcall (tree decl,
- if (IS_INTERRUPT (func_type))
- return false;
-
-+ if (!VOID_TYPE_P (TREE_TYPE (DECL_RESULT (cfun->decl))))
-+ {
-+ /* Check that the return value locations are the same. For
-+ example that we aren't returning a value from the sibling in
-+ a VFP register but then need to transfer it to a core
-+ register. */
-+ rtx a, b;
-+
-+ a = arm_function_value (TREE_TYPE (exp), decl, false);
-+ b = arm_function_value (TREE_TYPE (DECL_RESULT (cfun->decl)),
-+ cfun->decl, false);
-+ if (!rtx_equal_p (a, b))
-+ return false;
-+ }
-+
- /* Never tailcall if function may be called with a misaligned SP. */
- if (IS_STACKALIGN (func_type))
- return false;
-@@ -4131,6 +5283,7 @@ arm_legitimate_index_p (enum machine_mod
- if (GET_MODE_SIZE (mode) <= 4
- && ! (arm_arch4
- && (mode == HImode
-+ || mode == HFmode
- || (mode == QImode && outer == SIGN_EXTEND))))
- {
- if (code == MULT)
-@@ -4159,13 +5312,15 @@ arm_legitimate_index_p (enum machine_mod
- load. */
- if (arm_arch4)
- {
-- if (mode == HImode || (outer == SIGN_EXTEND && mode == QImode))
-+ if (mode == HImode
-+ || mode == HFmode
-+ || (outer == SIGN_EXTEND && mode == QImode))
- range = 256;
- else
- range = 4096;
- }
- else
-- range = (mode == HImode) ? 4095 : 4096;
-+ range = (mode == HImode || mode == HFmode) ? 4095 : 4096;
-
- return (code == CONST_INT
- && INTVAL (index) < range
-@@ -4336,7 +5491,8 @@ thumb1_legitimate_address_p (enum machin
- return 1;
-
- /* This is PC relative data after arm_reorg runs. */
-- else if (GET_MODE_SIZE (mode) >= 4 && reload_completed
-+ else if ((GET_MODE_SIZE (mode) >= 4 || mode == HFmode)
-+ && reload_completed
- && (GET_CODE (x) == LABEL_REF
- || (GET_CODE (x) == CONST
- && GET_CODE (XEXP (x, 0)) == PLUS
-@@ -5035,7 +6191,7 @@ arm_rtx_costs_1 (rtx x, enum rtx_code ou
- case UMOD:
- if (TARGET_HARD_FLOAT && mode == SFmode)
- *total = COSTS_N_INSNS (2);
-- else if (TARGET_HARD_FLOAT && mode == DFmode)
-+ else if (TARGET_HARD_FLOAT && mode == DFmode && !TARGET_VFP_SINGLE)
- *total = COSTS_N_INSNS (4);
- else
- *total = COSTS_N_INSNS (20);
-@@ -5074,23 +6230,6 @@ arm_rtx_costs_1 (rtx x, enum rtx_code ou
- return true;
-
- case MINUS:
-- if (TARGET_THUMB2)
-- {
-- if (GET_MODE_CLASS (mode) == MODE_FLOAT)
-- {
-- if (TARGET_HARD_FLOAT && (mode == SFmode || mode == DFmode))
-- *total = COSTS_N_INSNS (1);
-- else
-- *total = COSTS_N_INSNS (20);
-- }
-- else
-- *total = COSTS_N_INSNS (ARM_NUM_REGS (mode));
-- /* Thumb2 does not have RSB, so all arguments must be
-- registers (subtracting a constant is canonicalized as
-- addition of the negated constant). */
-- return false;
-- }
--
- if (mode == DImode)
- {
- *total = COSTS_N_INSNS (ARM_NUM_REGS (mode));
-@@ -5113,7 +6252,9 @@ arm_rtx_costs_1 (rtx x, enum rtx_code ou
-
- if (GET_MODE_CLASS (mode) == MODE_FLOAT)
- {
-- if (TARGET_HARD_FLOAT && (mode == SFmode || mode == DFmode))
-+ if (TARGET_HARD_FLOAT
-+ && (mode == SFmode
-+ || (mode == DFmode && !TARGET_VFP_SINGLE)))
- {
- *total = COSTS_N_INSNS (1);
- if (GET_CODE (XEXP (x, 0)) == CONST_DOUBLE
-@@ -5154,6 +6295,17 @@ arm_rtx_costs_1 (rtx x, enum rtx_code ou
- return true;
- }
-
-+ /* A shift as a part of RSB costs no more than RSB itself. */
-+ if (GET_CODE (XEXP (x, 0)) == MULT
-+ && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
-+ && ((INTVAL (XEXP (XEXP (x, 0), 1))
-+ & (INTVAL (XEXP (XEXP (x, 0), 1)) - 1)) == 0))
-+ {
-+ *total += rtx_cost (XEXP (XEXP (x, 0), 0), code, speed);
-+ *total += rtx_cost (XEXP (x, 1), code, speed);
-+ return true;
-+ }
-+
- if (subcode == MULT
- && GET_CODE (XEXP (XEXP (x, 1), 1)) == CONST_INT
- && ((INTVAL (XEXP (XEXP (x, 1), 1)) &
-@@ -5175,6 +6327,19 @@ arm_rtx_costs_1 (rtx x, enum rtx_code ou
- return true;
- }
-
-+ /* MLS is just as expensive as its underlying multiplication.
-+ Exclude a shift by a constant, which is expressed as a
-+ multiplication. */
-+ if (TARGET_32BIT && arm_arch_thumb2
-+ && GET_CODE (XEXP (x, 1)) == MULT
-+ && ! (GET_CODE (XEXP (XEXP (x, 1), 1)) == CONST_INT
-+ && ((INTVAL (XEXP (XEXP (x, 1), 1)) &
-+ (INTVAL (XEXP (XEXP (x, 1), 1)) - 1)) == 0)))
-+ {
-+ /* The cost comes from the cost of the multiply. */
-+ return false;
-+ }
-+
- /* Fall through */
-
- case PLUS:
-@@ -5203,7 +6368,9 @@ arm_rtx_costs_1 (rtx x, enum rtx_code ou
-
- if (GET_MODE_CLASS (mode) == MODE_FLOAT)
- {
-- if (TARGET_HARD_FLOAT && (mode == SFmode || mode == DFmode))
-+ if (TARGET_HARD_FLOAT
-+ && (mode == SFmode
-+ || (mode == DFmode && !TARGET_VFP_SINGLE)))
- {
- *total = COSTS_N_INSNS (1);
- if (GET_CODE (XEXP (x, 1)) == CONST_DOUBLE
-@@ -5318,7 +6485,9 @@ arm_rtx_costs_1 (rtx x, enum rtx_code ou
- case NEG:
- if (GET_MODE_CLASS (mode) == MODE_FLOAT)
- {
-- if (TARGET_HARD_FLOAT && (mode == SFmode || mode == DFmode))
-+ if (TARGET_HARD_FLOAT
-+ && (mode == SFmode
-+ || (mode == DFmode && !TARGET_VFP_SINGLE)))
- {
- *total = COSTS_N_INSNS (1);
- return false;
-@@ -5471,7 +6640,9 @@ arm_rtx_costs_1 (rtx x, enum rtx_code ou
- case ABS:
- if (GET_MODE_CLASS (mode == MODE_FLOAT))
- {
-- if (TARGET_HARD_FLOAT && (mode == SFmode || mode == DFmode))
-+ if (TARGET_HARD_FLOAT
-+ && (mode == SFmode
-+ || (mode == DFmode && !TARGET_VFP_SINGLE)))
- {
- *total = COSTS_N_INSNS (1);
- return false;
-@@ -5574,7 +6745,8 @@ arm_rtx_costs_1 (rtx x, enum rtx_code ou
- return true;
-
- case CONST_DOUBLE:
-- if (TARGET_HARD_FLOAT && vfp3_const_double_rtx (x))
-+ if (TARGET_HARD_FLOAT && vfp3_const_double_rtx (x)
-+ && (mode == SFmode || !TARGET_VFP_SINGLE))
- *total = COSTS_N_INSNS (1);
- else
- *total = COSTS_N_INSNS (4);
-@@ -5649,7 +6821,8 @@ arm_size_rtx_costs (rtx x, enum rtx_code
- return false;
-
- case MINUS:
-- if (TARGET_HARD_FLOAT && GET_MODE_CLASS (mode) == MODE_FLOAT)
-+ if (TARGET_HARD_FLOAT && GET_MODE_CLASS (mode) == MODE_FLOAT
-+ && (mode == SFmode || !TARGET_VFP_SINGLE))
- {
- *total = COSTS_N_INSNS (1);
- return false;
-@@ -5679,7 +6852,8 @@ arm_size_rtx_costs (rtx x, enum rtx_code
- return false;
-
- case PLUS:
-- if (TARGET_HARD_FLOAT && GET_MODE_CLASS (mode) == MODE_FLOAT)
-+ if (TARGET_HARD_FLOAT && GET_MODE_CLASS (mode) == MODE_FLOAT
-+ && (mode == SFmode || !TARGET_VFP_SINGLE))
- {
- *total = COSTS_N_INSNS (1);
- return false;
-@@ -5709,7 +6883,8 @@ arm_size_rtx_costs (rtx x, enum rtx_code
- return false;
-
- case NEG:
-- if (TARGET_HARD_FLOAT && GET_MODE_CLASS (mode) == MODE_FLOAT)
-+ if (TARGET_HARD_FLOAT && GET_MODE_CLASS (mode) == MODE_FLOAT
-+ && (mode == SFmode || !TARGET_VFP_SINGLE))
- {
- *total = COSTS_N_INSNS (1);
- return false;
-@@ -5733,7 +6908,8 @@ arm_size_rtx_costs (rtx x, enum rtx_code
- return false;
-
- case ABS:
-- if (TARGET_HARD_FLOAT && GET_MODE_CLASS (mode) == MODE_FLOAT)
-+ if (TARGET_HARD_FLOAT && GET_MODE_CLASS (mode) == MODE_FLOAT
-+ && (mode == SFmode || !TARGET_VFP_SINGLE))
- *total = COSTS_N_INSNS (1);
- else
- *total = COSTS_N_INSNS (1 + ARM_NUM_REGS (mode));
-@@ -5950,7 +7126,9 @@ arm_fastmul_rtx_costs (rtx x, enum rtx_c
-
- if (GET_MODE_CLASS (mode) == MODE_FLOAT)
- {
-- if (TARGET_HARD_FLOAT && (mode == SFmode || mode == DFmode))
-+ if (TARGET_HARD_FLOAT
-+ && (mode == SFmode
-+ || (mode == DFmode && !TARGET_VFP_SINGLE)))
- {
- *total = COSTS_N_INSNS (1);
- return false;
-@@ -6107,7 +7285,9 @@ arm_9e_rtx_costs (rtx x, enum rtx_code c
-
- if (GET_MODE_CLASS (mode) == MODE_FLOAT)
- {
-- if (TARGET_HARD_FLOAT && (mode == SFmode || mode == DFmode))
-+ if (TARGET_HARD_FLOAT
-+ && (mode == SFmode
-+ || (mode == DFmode && !TARGET_VFP_SINGLE)))
- {
- *total = COSTS_N_INSNS (1);
- return false;
-@@ -6930,10 +8110,13 @@ arm_coproc_mem_operand (rtx op, bool wb)
- }
-
- /* Return TRUE if OP is a memory operand which we can load or store a vector
-- to/from. If CORE is true, we're moving from ARM registers not Neon
-- registers. */
-+ to/from. TYPE is one of the following values:
-+ 0 - Vector load/stor (vldr)
-+ 1 - Core registers (ldm)
-+ 2 - Element/structure loads (vld1)
-+ */
- int
--neon_vector_mem_operand (rtx op, bool core)
-+neon_vector_mem_operand (rtx op, int type)
- {
- rtx ind;
-
-@@ -6966,23 +8149,16 @@ neon_vector_mem_operand (rtx op, bool co
- return arm_address_register_rtx_p (ind, 0);
-
- /* Allow post-increment with Neon registers. */
-- if (!core && GET_CODE (ind) == POST_INC)
-+ if ((type != 1 && GET_CODE (ind) == POST_INC)
-+ || (type == 0 && GET_CODE (ind) == PRE_DEC))
- return arm_address_register_rtx_p (XEXP (ind, 0), 0);
-
--#if 0
-- /* FIXME: We can support this too if we use VLD1/VST1. */
-- if (!core
-- && GET_CODE (ind) == POST_MODIFY
-- && arm_address_register_rtx_p (XEXP (ind, 0), 0)
-- && GET_CODE (XEXP (ind, 1)) == PLUS
-- && rtx_equal_p (XEXP (XEXP (ind, 1), 0), XEXP (ind, 0)))
-- ind = XEXP (ind, 1);
--#endif
-+ /* FIXME: vld1 allows register post-modify. */
-
- /* Match:
- (plus (reg)
- (const)). */
-- if (!core
-+ if (type == 0
- && GET_CODE (ind) == PLUS
- && GET_CODE (XEXP (ind, 0)) == REG
- && REG_MODE_OK_FOR_BASE_P (XEXP (ind, 0), VOIDmode)
-@@ -7049,10 +8225,19 @@ arm_eliminable_register (rtx x)
- enum reg_class
- coproc_secondary_reload_class (enum machine_mode mode, rtx x, bool wb)
- {
-+ if (mode == HFmode)
-+ {
-+ if (!TARGET_NEON_FP16)
-+ return GENERAL_REGS;
-+ if (s_register_operand (x, mode) || neon_vector_mem_operand (x, 2))
-+ return NO_REGS;
-+ return GENERAL_REGS;
-+ }
-+
- if (TARGET_NEON
- && (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
- || GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT)
-- && neon_vector_mem_operand (x, FALSE))
-+ && neon_vector_mem_operand (x, 0))
- return NO_REGS;
-
- if (arm_coproc_mem_operand (x, wb) || s_register_operand (x, mode))
-@@ -7449,6 +8634,9 @@ load_multiple_sequence (rtx *operands, i
- int base_reg = -1;
- int i;
-
-+ if (low_irq_latency)
-+ return 0;
-+
- /* Can only handle 2, 3, or 4 insns at present,
- though could be easily extended if required. */
- gcc_assert (nops >= 2 && nops <= 4);
-@@ -7678,6 +8866,9 @@ store_multiple_sequence (rtx *operands,
- int base_reg = -1;
- int i;
-
-+ if (low_irq_latency)
-+ return 0;
-+
- /* Can only handle 2, 3, or 4 insns at present, though could be easily
- extended if required. */
- gcc_assert (nops >= 2 && nops <= 4);
-@@ -7885,7 +9076,7 @@ arm_gen_load_multiple (int base_regno, i
-
- As a compromise, we use ldr for counts of 1 or 2 regs, and ldm
- for counts of 3 or 4 regs. */
-- if (arm_tune_xscale && count <= 2 && ! optimize_size)
-+ if (low_irq_latency || (arm_tune_xscale && count <= 2 && ! optimize_size))
- {
- rtx seq;
-
-@@ -7948,7 +9139,7 @@ arm_gen_store_multiple (int base_regno,
-
- /* See arm_gen_load_multiple for discussion of
- the pros/cons of ldm/stm usage for XScale. */
-- if (arm_tune_xscale && count <= 2 && ! optimize_size)
-+ if (low_irq_latency || (arm_tune_xscale && count <= 2 && ! optimize_size))
- {
- rtx seq;
-
-@@ -9566,7 +10757,10 @@ create_fix_barrier (Mfix *fix, HOST_WIDE
- gcc_assert (GET_CODE (from) != BARRIER);
-
- /* Count the length of this insn. */
-- count += get_attr_length (from);
-+ if (LABEL_P (from) && (align_jumps > 0 || align_loops > 0))
-+ count += MAX (align_jumps, align_loops);
-+ else
-+ count += get_attr_length (from);
-
- /* If there is a jump table, add its length. */
- tmp = is_jump_table (from);
-@@ -9878,6 +11072,8 @@ arm_reorg (void)
- insn = table;
- }
- }
-+ else if (LABEL_P (insn) && (align_jumps > 0 || align_loops > 0))
-+ address += MAX (align_jumps, align_loops);
- }
-
- fix = minipool_fix_head;
-@@ -10083,6 +11279,21 @@ static void
- vfp_output_fldmd (FILE * stream, unsigned int base, int reg, int count)
- {
- int i;
-+ int offset;
-+
-+ if (low_irq_latency)
-+ {
-+ /* Output a sequence of FLDD instructions. */
-+ offset = 0;
-+ for (i = reg; i < reg + count; ++i, offset += 8)
-+ {
-+ fputc ('\t', stream);
-+ asm_fprintf (stream, "fldd\td%d, [%r,#%d]\n", i, base, offset);
-+ }
-+ asm_fprintf (stream, "\tadd\tsp, sp, #%d\n", count * 8);
-+ return;
-+ }
-+
-
- /* Workaround ARM10 VFPr1 bug. */
- if (count == 2 && !arm_arch6)
-@@ -10153,6 +11364,56 @@ vfp_emit_fstmd (int base_reg, int count)
- rtx tmp, reg;
- int i;
-
-+ if (low_irq_latency)
-+ {
-+ int saved_size;
-+ rtx sp_insn;
-+
-+ if (!count)
-+ return 0;
-+
-+ saved_size = count * GET_MODE_SIZE (DFmode);
-+
-+ /* Since fstd does not have postdecrement addressing mode,
-+ we first decrement stack pointer and then use base+offset
-+ stores for VFP registers. The ARM EABI unwind information
-+ can't easily describe base+offset loads, so we attach
-+ a note for the effects of the whole block in the first insn,
-+ and avoid marking the subsequent instructions
-+ with RTX_FRAME_RELATED_P. */
-+ sp_insn = gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
-+ GEN_INT (-saved_size));
-+ sp_insn = emit_insn (sp_insn);
-+ RTX_FRAME_RELATED_P (sp_insn) = 1;
-+
-+ dwarf = gen_rtx_SEQUENCE (VOIDmode, rtvec_alloc (count + 1));
-+ XVECEXP (dwarf, 0, 0) =
-+ gen_rtx_SET (VOIDmode, stack_pointer_rtx,
-+ plus_constant (stack_pointer_rtx, -saved_size));
-+
-+ /* push double VFP registers to stack */
-+ for (i = 0; i < count; ++i )
-+ {
-+ rtx reg;
-+ rtx mem;
-+ rtx addr;
-+ rtx insn;
-+ reg = gen_rtx_REG (DFmode, base_reg + 2*i);
-+ addr = (i == 0) ? stack_pointer_rtx
-+ : gen_rtx_PLUS (SImode, stack_pointer_rtx,
-+ GEN_INT (i * GET_MODE_SIZE (DFmode)));
-+ mem = gen_frame_mem (DFmode, addr);
-+ insn = emit_move_insn (mem, reg);
-+ XVECEXP (dwarf, 0, i+1) =
-+ gen_rtx_SET (VOIDmode, mem, reg);
-+ }
-+
-+ REG_NOTES (sp_insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, dwarf,
-+ REG_NOTES (sp_insn));
-+
-+ return saved_size;
-+ }
-+
- /* Workaround ARM10 VFPr1 bug. Data corruption can occur when exactly two
- register pairs are stored by a store multiple insn. We avoid this
- by pushing an extra pair. */
-@@ -10769,7 +12030,7 @@ output_move_double (rtx *operands)
- }
-
- /* Output a move, load or store for quad-word vectors in ARM registers. Only
-- handles MEMs accepted by neon_vector_mem_operand with CORE=true. */
-+ handles MEMs accepted by neon_vector_mem_operand with TYPE=1. */
-
- const char *
- output_move_quad (rtx *operands)
-@@ -10965,6 +12226,12 @@ output_move_neon (rtx *operands)
- ops[1] = reg;
- break;
-
-+ case PRE_DEC:
-+ templ = "v%smdb%%?\t%%0!, %%h1";
-+ ops[0] = XEXP (addr, 0);
-+ ops[1] = reg;
-+ break;
-+
- case POST_MODIFY:
- /* FIXME: Not currently enabled in neon_vector_mem_operand. */
- gcc_unreachable ();
-@@ -11568,7 +12835,7 @@ arm_get_vfp_saved_size (void)
- if (count > 0)
- {
- /* Workaround ARM10 VFPr1 bug. */
-- if (count == 2 && !arm_arch6)
-+ if (count == 2 && !arm_arch6 && !low_irq_latency)
- count++;
- saved += count * 8;
- }
-@@ -11897,6 +13164,41 @@ arm_output_function_prologue (FILE *f, H
- return_used_this_function = 0;
- }
-
-+/* Generate to STREAM a code sequence that pops registers identified
-+ in REGS_MASK from SP. SP is incremented as the result.
-+*/
-+static void
-+print_pop_reg_by_ldr (FILE *stream, int regs_mask, int rfe)
-+{
-+ int reg;
-+
-+ gcc_assert (! (regs_mask & (1 << SP_REGNUM)));
-+
-+ for (reg = 0; reg < PC_REGNUM; ++reg)
-+ if (regs_mask & (1 << reg))
-+ asm_fprintf (stream, "\tldr\t%r, [%r], #4\n",
-+ reg, SP_REGNUM);
-+
-+ if (regs_mask & (1 << PC_REGNUM))
-+ {
-+ if (rfe)
-+ /* When returning from exception, we need to
-+ copy SPSR to CPSR. There are two ways to do
-+ that: the ldm instruction with "^" suffix,
-+ and movs instruction. The latter would
-+ require that we load from stack to some
-+ scratch register, and then move to PC.
-+ Therefore, we'd need extra instruction and
-+ have to make sure we actually have a spare
-+ register. Using ldm with a single register
-+ is simler. */
-+ asm_fprintf (stream, "\tldm\tsp!, {pc}^\n");
-+ else
-+ asm_fprintf (stream, "\tldr\t%r, [%r], #4\n",
-+ PC_REGNUM, SP_REGNUM);
-+ }
-+}
-+
- const char *
- arm_output_epilogue (rtx sibling)
- {
-@@ -11957,7 +13259,7 @@ arm_output_epilogue (rtx sibling)
- /* This variable is for the Virtual Frame Pointer, not VFP regs. */
- int vfp_offset = offsets->frame;
-
-- if (arm_fpu_arch == FPUTYPE_FPA_EMU2)
-+ if (TARGET_FPA_EMU2)
- {
- for (reg = LAST_FPA_REGNUM; reg >= FIRST_FPA_REGNUM; reg--)
- if (df_regs_ever_live_p (reg) && !call_used_regs[reg])
-@@ -12180,7 +13482,7 @@ arm_output_epilogue (rtx sibling)
- SP_REGNUM, HARD_FRAME_POINTER_REGNUM);
- }
-
-- if (arm_fpu_arch == FPUTYPE_FPA_EMU2)
-+ if (TARGET_FPA_EMU2)
- {
- for (reg = FIRST_FPA_REGNUM; reg <= LAST_FPA_REGNUM; reg++)
- if (df_regs_ever_live_p (reg) && !call_used_regs[reg])
-@@ -12264,22 +13566,19 @@ arm_output_epilogue (rtx sibling)
- to load use the LDR instruction - it is faster. For Thumb-2
- always use pop and the assembler will pick the best instruction.*/
- if (TARGET_ARM && saved_regs_mask == (1 << LR_REGNUM)
-- && !IS_INTERRUPT(func_type))
-+ && !IS_INTERRUPT (func_type))
- {
- asm_fprintf (f, "\tldr\t%r, [%r], #4\n", LR_REGNUM, SP_REGNUM);
- }
- else if (saved_regs_mask)
- {
-- if (saved_regs_mask & (1 << SP_REGNUM))
-- /* Note - write back to the stack register is not enabled
-- (i.e. "ldmfd sp!..."). We know that the stack pointer is
-- in the list of registers and if we add writeback the
-- instruction becomes UNPREDICTABLE. */
-- print_multi_reg (f, "ldmfd\t%r, ", SP_REGNUM, saved_regs_mask,
-- rfe);
-- else if (TARGET_ARM)
-- print_multi_reg (f, "ldmfd\t%r!, ", SP_REGNUM, saved_regs_mask,
-- rfe);
-+ gcc_assert ( ! (saved_regs_mask & (1 << SP_REGNUM)));
-+ if (TARGET_ARM)
-+ if (low_irq_latency)
-+ print_pop_reg_by_ldr (f, saved_regs_mask, rfe);
-+ else
-+ print_multi_reg (f, "ldmfd\t%r!, ", SP_REGNUM, saved_regs_mask,
-+ rfe);
- else
- print_multi_reg (f, "pop\t", SP_REGNUM, saved_regs_mask, 0);
- }
-@@ -12400,6 +13699,32 @@ emit_multi_reg_push (unsigned long mask)
-
- gcc_assert (num_regs && num_regs <= 16);
-
-+ if (low_irq_latency)
-+ {
-+ rtx insn = 0;
-+
-+ /* Emit a series of ldr instructions rather rather than a single ldm. */
-+ /* TODO: Use ldrd where possible. */
-+ gcc_assert (! (mask & (1 << SP_REGNUM)));
-+
-+ for (i = LAST_ARM_REGNUM; i >= 0; --i)
-+ {
-+ if (mask & (1 << i))
-+
-+ {
-+ rtx reg, where, mem;
-+
-+ reg = gen_rtx_REG (SImode, i);
-+ where = gen_rtx_PRE_DEC (SImode, stack_pointer_rtx);
-+ mem = gen_rtx_MEM (SImode, where);
-+ insn = emit_move_insn (mem, reg);
-+ RTX_FRAME_RELATED_P (insn) = 1;
-+ }
-+ }
-+
-+ return insn;
-+ }
-+
- /* We don't record the PC in the dwarf frame information. */
- num_dwarf_regs = num_regs;
- if (mask & (1 << PC_REGNUM))
-@@ -12748,22 +14073,23 @@ arm_get_frame_offsets (void)
- {
- int reg = -1;
-
-- for (i = 4; i <= (TARGET_THUMB1 ? LAST_LO_REGNUM : 11); i++)
-- {
-- if ((offsets->saved_regs_mask & (1 << i)) == 0)
-- {
-- reg = i;
-- break;
-- }
-- }
--
-- if (reg == -1 && arm_size_return_regs () <= 12
-- && !crtl->tail_call_emit)
-+ /* If it is safe to use r3, then do so. This sometimes
-+ generates better code on Thumb-2 by avoiding the need to
-+ use 32-bit push/pop instructions. */
-+ if (!crtl->tail_call_emit
-+ && arm_size_return_regs () <= 12)
- {
-- /* Push/pop an argument register (r3) if all callee saved
-- registers are already being pushed. */
- reg = 3;
- }
-+ else
-+ for (i = 4; i <= (TARGET_THUMB1 ? LAST_LO_REGNUM : 11); i++)
-+ {
-+ if ((offsets->saved_regs_mask & (1 << i)) == 0)
-+ {
-+ reg = i;
-+ break;
-+ }
-+ }
-
- if (reg != -1)
- {
-@@ -12887,7 +14213,7 @@ arm_save_coproc_regs(void)
-
- /* Save any floating point call-saved registers used by this
- function. */
-- if (arm_fpu_arch == FPUTYPE_FPA_EMU2)
-+ if (TARGET_FPA_EMU2)
- {
- for (reg = LAST_FPA_REGNUM; reg >= FIRST_FPA_REGNUM; reg--)
- if (df_regs_ever_live_p (reg) && !call_used_regs[reg])
-@@ -13494,7 +14820,11 @@ arm_print_operand (FILE *stream, rtx x,
- {
- fprintf (stream, ", %s ", shift);
- if (val == -1)
-- arm_print_operand (stream, XEXP (x, 1), 0);
-+ {
-+ arm_print_operand (stream, XEXP (x, 1), 0);
-+ if (janus2_code)
-+ fprintf(stream, "\n\tnop");
-+ }
- else
- fprintf (stream, "#" HOST_WIDE_INT_PRINT_DEC, val);
- }
-@@ -13715,6 +15045,30 @@ arm_print_operand (FILE *stream, rtx x,
- }
- return;
-
-+ /* Print the high single-precision register of a VFP double-precision
-+ register. */
-+ case 'p':
-+ {
-+ int mode = GET_MODE (x);
-+ int regno;
-+
-+ if (GET_MODE_SIZE (mode) != 8 || GET_CODE (x) != REG)
-+ {
-+ output_operand_lossage ("invalid operand for code '%c'", code);
-+ return;
-+ }
-+
-+ regno = REGNO (x);
-+ if (!VFP_REGNO_OK_FOR_DOUBLE (regno))
-+ {
-+ output_operand_lossage ("invalid operand for code '%c'", code);
-+ return;
-+ }
-+
-+ fprintf (stream, "s%d", regno - FIRST_VFP_REGNUM + 1);
-+ }
-+ return;
-+
- /* Print a VFP/Neon double precision or quad precision register name. */
- case 'P':
- case 'q':
-@@ -13832,6 +15186,57 @@ arm_print_operand (FILE *stream, rtx x,
- }
- return;
-
-+ /* Memory operand for vld1/vst1 instruction. */
-+ case 'A':
-+ {
-+ rtx addr;
-+ bool postinc = FALSE;
-+ unsigned align;
-+
-+ gcc_assert (GET_CODE (x) == MEM);
-+ addr = XEXP (x, 0);
-+ if (GET_CODE (addr) == POST_INC)
-+ {
-+ postinc = 1;
-+ addr = XEXP (addr, 0);
-+ }
-+ align = MEM_ALIGN (x) >> 3;
-+ asm_fprintf (stream, "[%r", REGNO (addr));
-+ if (align > GET_MODE_SIZE (GET_MODE (x)))
-+ align = GET_MODE_SIZE (GET_MODE (x));
-+ if (align >= 8)
-+ asm_fprintf (stream, ", :%d", align << 3);
-+ asm_fprintf (stream, "]");
-+ if (postinc)
-+ fputs("!", stream);
-+ }
-+ return;
-+
-+ /* Register specifier for vld1.16/vst1.16. Translate the S register
-+ number into a D register number and element index. */
-+ case 'z':
-+ {
-+ int mode = GET_MODE (x);
-+ int regno;
-+
-+ if (GET_MODE_SIZE (mode) != 2 || GET_CODE (x) != REG)
-+ {
-+ output_operand_lossage ("invalid operand for code '%c'", code);
-+ return;
-+ }
-+
-+ regno = REGNO (x);
-+ if (!VFP_REGNO_OK_FOR_SINGLE (regno))
-+ {
-+ output_operand_lossage ("invalid operand for code '%c'", code);
-+ return;
-+ }
-+
-+ regno = regno - FIRST_VFP_REGNUM;
-+ fprintf (stream, "d%d[%d]", regno/2, ((regno % 2) ? 2 : 0));
-+ }
-+ return;
-+
- default:
- if (x == 0)
- {
-@@ -13865,6 +15270,12 @@ arm_print_operand (FILE *stream, rtx x,
- default:
- gcc_assert (GET_CODE (x) != NEG);
- fputc ('#', stream);
-+ if (GET_CODE (x) == HIGH)
-+ {
-+ fputs (":lower16:", stream);
-+ x = XEXP (x, 0);
-+ }
-+
- output_addr_const (stream, x);
- break;
- }
-@@ -14256,6 +15667,10 @@ arm_final_prescan_insn (rtx insn)
- first insn after the following code_label if REVERSE is true. */
- rtx start_insn = insn;
-
-+ /* Don't do this if we're not considering conditional execution. */
-+ if (TARGET_NO_SINGLE_COND_EXEC)
-+ return;
-+
- /* If in state 4, check if the target branch is reached, in order to
- change back to state 0. */
- if (arm_ccfsm_state == 4)
-@@ -14629,6 +16044,11 @@ arm_hard_regno_mode_ok (unsigned int reg
- if (mode == DFmode)
- return VFP_REGNO_OK_FOR_DOUBLE (regno);
-
-+ /* VFP registers can hold HFmode values, but there is no point in
-+ putting them there unless we have hardware conversion insns. */
-+ if (mode == HFmode)
-+ return TARGET_FP16 && VFP_REGNO_OK_FOR_SINGLE (regno);
-+
- if (TARGET_NEON)
- return (VALID_NEON_DREG_MODE (mode) && VFP_REGNO_OK_FOR_DOUBLE (regno))
- || (VALID_NEON_QREG_MODE (mode)
-@@ -14648,16 +16068,16 @@ arm_hard_regno_mode_ok (unsigned int reg
- return mode == SImode;
-
- if (IS_IWMMXT_REGNUM (regno))
-- return VALID_IWMMXT_REG_MODE (mode);
-+ return VALID_IWMMXT_REG_MODE (mode) && mode != SImode;
- }
-
-- /* We allow any value to be stored in the general registers.
-+ /* We allow almost any value to be stored in the general registers.
- Restrict doubleword quantities to even register pairs so that we can
-- use ldrd. Do not allow Neon structure opaque modes in general registers;
-- they would use too many. */
-+ use ldrd. Do not allow very large Neon structure opaque modes in
-+ general registers; they would use too many. */
- if (regno <= LAST_ARM_REGNUM)
- return !(TARGET_LDRD && GET_MODE_SIZE (mode) > 4 && (regno & 1) != 0)
-- && !VALID_NEON_STRUCT_MODE (mode);
-+ && ARM_NUM_REGS (mode) <= 4;
-
- if (regno == FRAME_POINTER_REGNUM
- || regno == ARG_POINTER_REGNUM)
-@@ -16114,6 +17534,15 @@ arm_init_neon_builtins (void)
- }
-
- static void
-+arm_init_fp16_builtins (void)
-+{
-+ tree fp16_type = make_node (REAL_TYPE);
-+ TYPE_PRECISION (fp16_type) = 16;
-+ layout_type (fp16_type);
-+ (*lang_hooks.types.register_builtin_type) (fp16_type, "__fp16");
-+}
-+
-+static void
- arm_init_builtins (void)
- {
- arm_init_tls_builtins ();
-@@ -16123,6 +17552,71 @@ arm_init_builtins (void)
-
- if (TARGET_NEON)
- arm_init_neon_builtins ();
-+
-+ if (arm_fp16_format)
-+ arm_init_fp16_builtins ();
-+}
-+
-+/* Implement TARGET_INVALID_PARAMETER_TYPE. */
-+
-+static const char *
-+arm_invalid_parameter_type (const_tree t)
-+{
-+ if (SCALAR_FLOAT_TYPE_P (t) && TYPE_PRECISION (t) == 16)
-+ return N_("function parameters cannot have __fp16 type");
-+ return NULL;
-+}
-+
-+/* Implement TARGET_INVALID_PARAMETER_TYPE. */
-+
-+static const char *
-+arm_invalid_return_type (const_tree t)
-+{
-+ if (SCALAR_FLOAT_TYPE_P (t) && TYPE_PRECISION (t) == 16)
-+ return N_("functions cannot return __fp16 type");
-+ return NULL;
-+}
-+
-+/* Implement TARGET_PROMOTED_TYPE. */
-+
-+static tree
-+arm_promoted_type (const_tree t)
-+{
-+ if (SCALAR_FLOAT_TYPE_P (t) && TYPE_PRECISION (t) == 16)
-+ return float_type_node;
-+ return NULL_TREE;
-+}
-+
-+/* Implement TARGET_CONVERT_TO_TYPE.
-+ Specifically, this hook implements the peculiarity of the ARM
-+ half-precision floating-point C semantics that requires conversions between
-+ __fp16 to or from double to do an intermediate conversion to float. */
-+
-+static tree
-+arm_convert_to_type (tree type, tree expr)
-+{
-+ tree fromtype = TREE_TYPE (expr);
-+ if (!SCALAR_FLOAT_TYPE_P (fromtype) || !SCALAR_FLOAT_TYPE_P (type))
-+ return NULL_TREE;
-+ if ((TYPE_PRECISION (fromtype) == 16 && TYPE_PRECISION (type) > 32)
-+ || (TYPE_PRECISION (type) == 16 && TYPE_PRECISION (fromtype) > 32))
-+ return convert (type, convert (float_type_node, expr));
-+ return NULL_TREE;
-+}
-+
-+/* Implement TARGET_SCALAR_MODE_SUPPORTED_P.
-+ This simply adds HFmode as a supported mode; even though we don't
-+ implement arithmetic on this type directly, it's supported by
-+ optabs conversions, much the way the double-word arithmetic is
-+ special-cased in the default hook. */
-+
-+static bool
-+arm_scalar_mode_supported_p (enum machine_mode mode)
-+{
-+ if (mode == HFmode)
-+ return (arm_fp16_format != ARM_FP16_FORMAT_NONE);
-+ else
-+ return default_scalar_mode_supported_p (mode);
- }
-
- /* Errors in the source file can cause expand_expr to return const0_rtx
-@@ -17202,6 +18696,7 @@ thumb_shiftable_const (unsigned HOST_WID
- unsigned HOST_WIDE_INT mask = 0xff;
- int i;
-
-+ val = val & (unsigned HOST_WIDE_INT)0xffffffffu;
- if (val == 0) /* XXX */
- return 0;
-
-@@ -18290,40 +19785,8 @@ arm_file_start (void)
- else
- {
- int set_float_abi_attributes = 0;
-- switch (arm_fpu_arch)
-- {
-- case FPUTYPE_FPA:
-- fpu_name = "fpa";
-- break;
-- case FPUTYPE_FPA_EMU2:
-- fpu_name = "fpe2";
-- break;
-- case FPUTYPE_FPA_EMU3:
-- fpu_name = "fpe3";
-- break;
-- case FPUTYPE_MAVERICK:
-- fpu_name = "maverick";
-- break;
-- case FPUTYPE_VFP:
-- fpu_name = "vfp";
-- set_float_abi_attributes = 1;
-- break;
-- case FPUTYPE_VFP3D16:
-- fpu_name = "vfpv3-d16";
-- set_float_abi_attributes = 1;
-- break;
-- case FPUTYPE_VFP3:
-- fpu_name = "vfpv3";
-- set_float_abi_attributes = 1;
-- break;
-- case FPUTYPE_NEON:
-- fpu_name = "neon";
-- set_float_abi_attributes = 1;
-- break;
-- default:
-- abort();
-- }
-- if (set_float_abi_attributes)
-+ fpu_name = arm_fpu_desc->name;
-+ if (arm_fp_model == ARM_FP_MODEL_VFP)
- {
- if (TARGET_HARD_FLOAT)
- asm_fprintf (asm_out_file, "\t.eabi_attribute 27, 3\n");
-@@ -18373,6 +19836,11 @@ arm_file_start (void)
- val = 6;
- asm_fprintf (asm_out_file, "\t.eabi_attribute 30, %d\n", val);
-
-+ /* Tag_ABI_FP_16bit_format. */
-+ if (arm_fp16_format)
-+ asm_fprintf (asm_out_file, "\t.eabi_attribute 38, %d\n",
-+ (int)arm_fp16_format);
-+
- if (arm_lang_output_object_attributes_hook)
- arm_lang_output_object_attributes_hook();
- }
-@@ -18602,6 +20070,23 @@ arm_emit_vector_const (FILE *file, rtx x
- return 1;
- }
-
-+/* Emit a fp16 constant appropriately padded to occupy a 4-byte word.
-+ HFmode constant pool entries are actually loaded with ldr. */
-+void
-+arm_emit_fp16_const (rtx c)
-+{
-+ REAL_VALUE_TYPE r;
-+ long bits;
-+
-+ REAL_VALUE_FROM_CONST_DOUBLE (r, c);
-+ bits = real_to_target (NULL, &r, HFmode);
-+ if (WORDS_BIG_ENDIAN)
-+ assemble_zeros (2);
-+ assemble_integer (GEN_INT (bits), 2, BITS_PER_WORD, 1);
-+ if (!WORDS_BIG_ENDIAN)
-+ assemble_zeros (2);
-+}
-+
- const char *
- arm_output_load_gr (rtx *operands)
- {
-@@ -18639,19 +20124,24 @@ arm_output_load_gr (rtx *operands)
- that way. */
-
- static void
--arm_setup_incoming_varargs (CUMULATIVE_ARGS *cum,
-+arm_setup_incoming_varargs (CUMULATIVE_ARGS *pcum,
- enum machine_mode mode,
- tree type,
- int *pretend_size,
- int second_time ATTRIBUTE_UNUSED)
- {
-- int nregs = cum->nregs;
-- if (nregs & 1
-- && ARM_DOUBLEWORD_ALIGN
-- && arm_needs_doubleword_align (mode, type))
-- nregs++;
--
-+ int nregs;
-+
- cfun->machine->uses_anonymous_args = 1;
-+ if (pcum->pcs_variant <= ARM_PCS_AAPCS_LOCAL)
-+ {
-+ nregs = pcum->aapcs_ncrn;
-+ if ((nregs & 1) && arm_needs_doubleword_align (mode, type))
-+ nregs++;
-+ }
-+ else
-+ nregs = pcum->nregs;
-+
- if (nregs < NUM_ARG_REGS)
- *pretend_size = (NUM_ARG_REGS - nregs) * UNITS_PER_WORD;
- }
-@@ -19035,9 +20525,10 @@ arm_vector_mode_supported_p (enum machin
- || mode == V16QImode || mode == V4SFmode || mode == V2DImode))
- return true;
-
-- if ((mode == V2SImode)
-- || (mode == V4HImode)
-- || (mode == V8QImode))
-+ if ((TARGET_NEON || TARGET_IWMMXT)
-+ && ((mode == V2SImode)
-+ || (mode == V4HImode)
-+ || (mode == V8QImode)))
- return true;
-
- return false;
-@@ -19068,9 +20559,14 @@ arm_dbx_register_number (unsigned int re
- if (IS_FPA_REGNUM (regno))
- return (TARGET_AAPCS_BASED ? 96 : 16) + regno - FIRST_FPA_REGNUM;
-
-- /* FIXME: VFPv3 register numbering. */
- if (IS_VFP_REGNUM (regno))
-- return 64 + regno - FIRST_VFP_REGNUM;
-+ {
-+ /* See comment in arm_dwarf_register_span. */
-+ if (VFP_REGNO_OK_FOR_SINGLE (regno))
-+ return 64 + regno - FIRST_VFP_REGNUM;
-+ else
-+ return 256 + (regno - FIRST_VFP_REGNUM) / 2;
-+ }
-
- if (IS_IWMMXT_GR_REGNUM (regno))
- return 104 + regno - FIRST_IWMMXT_GR_REGNUM;
-@@ -19081,6 +20577,39 @@ arm_dbx_register_number (unsigned int re
- gcc_unreachable ();
- }
-
-+/* Dwarf models VFPv3 registers as 32 64-bit registers.
-+ GCC models tham as 64 32-bit registers, so we need to describe this to
-+ the DWARF generation code. Other registers can use the default. */
-+static rtx
-+arm_dwarf_register_span(rtx rtl)
-+{
-+ unsigned regno;
-+ int nregs;
-+ int i;
-+ rtx p;
-+
-+ regno = REGNO (rtl);
-+ if (!IS_VFP_REGNUM (regno))
-+ return NULL_RTX;
-+
-+ /* The EABI defines two VFP register ranges:
-+ 64-95: Legacy VFPv2 numbering for S0-S31 (obsolescent)
-+ 256-287: D0-D31
-+ The recommended encodings for s0-s31 is a DW_OP_bit_piece of the
-+ corresponding D register. However gdb6.6 does not support this, so
-+ we use the legacy encodings. We also use these encodings for D0-D15
-+ for compatibility with older debuggers. */
-+ if (VFP_REGNO_OK_FOR_SINGLE (regno))
-+ return NULL_RTX;
-+
-+ nregs = GET_MODE_SIZE (GET_MODE (rtl)) / 8;
-+ p = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc(nregs));
-+ regno = (regno - FIRST_VFP_REGNUM) / 2;
-+ for (i = 0; i < nregs; i++)
-+ XVECEXP (p, 0, i) = gen_rtx_REG (DImode, 256 + regno + i);
-+
-+ return p;
-+}
-
- #ifdef TARGET_UNWIND_INFO
- /* Emit unwind directives for a store-multiple instruction or stack pointer
-@@ -19567,6 +21096,7 @@ arm_issue_rate (void)
- case cortexr4f:
- case cortexa8:
- case cortexa9:
-+ case marvell_f:
- return 2;
-
- default:
-@@ -19631,6 +21161,10 @@ arm_mangle_type (const_tree type)
- return "St9__va_list";
- }
-
-+ /* Half-precision float. */
-+ if (TREE_CODE (type) == REAL_TYPE && TYPE_PRECISION (type) == 16)
-+ return "Dh";
-+
- if (TREE_CODE (type) != VECTOR_TYPE)
- return NULL;
-
-@@ -19687,6 +21221,86 @@ arm_optimization_options (int level, int
- given on the command line. */
- if (level > 0)
- flag_section_anchors = 2;
-+
-+ if (size)
-+ {
-+ /* Select optimizations that are a win for code size.
-+
-+ The inlining options set below have two important
-+ consequences for functions not explicitly marked
-+ inline:
-+ - Static functions used once are inlined if
-+ sufficiently small. Static functions used twice
-+ are not inlined.
-+ - Non-static functions are never inlined.
-+ So in effect, inlining will never cause two copies
-+ of function bodies to be created. */
-+ /* Empirical results show that these options benefit code
-+ size on arm. */
-+ /* FIXME: -fsee seems to be broken for Thumb-2. */
-+ /* flag_see = 1; */
-+ flag_move_loop_invariants = 0;
-+ /* In Thumb mode the function call code size overhead is typically very
-+ small, and narrow branch instructions have very limited range.
-+ Inlining even medium sized functions tends to bloat the caller and
-+ require the use of long branch instructions. On average the long
-+ branches cost more than eliminating the function call overhead saves,
-+ so we use extremely restrictive automatic inlining heuristics. In ARM
-+ mode the results are fairly neutral, probably due to better constant
-+ pool placement. */
-+ set_param_value ("max-inline-insns-single", 1);
-+ set_param_value ("max-inline-insns-auto", 1);
-+ }
-+ else
-+ {
-+ /* CSL LOCAL */
-+ /* Set flag_unroll_loops to a default value, so that we can tell
-+ if it was specified on the command line; see
-+ arm_override_options. */
-+ flag_unroll_loops = 2;
-+ /* Promote loop indices to int where possible. Consider moving this
-+ to -Os, also. */
-+ flag_promote_loop_indices = 1;
-+ }
-+}
-+
-+/* Return how many instructions to look ahead for better insn
-+ scheduling. */
-+static int
-+arm_multipass_dfa_lookahead (void)
-+{
-+ return (arm_tune == marvell_f) ? 4 : 0;
-+}
-+
-+/* Return the minimum alignment required to load or store a
-+ vector of the given type, which may be less than the
-+ natural alignment of the type. */
-+
-+static int
-+arm_vector_min_alignment (const_tree type)
-+{
-+ if (TARGET_NEON)
-+ {
-+ /* The NEON element load and store instructions only require the
-+ alignment of the element type. They can benefit from higher
-+ statically reported alignment, but we do not take advantage
-+ of that yet. */
-+ gcc_assert (TREE_CODE (type) == VECTOR_TYPE);
-+ return TYPE_ALIGN_UNIT (TREE_TYPE (type));
-+ }
-+
-+ return default_vector_min_alignment (type);
-+}
-+
-+static bool
-+arm_vector_always_misalign(const_tree type ATTRIBUTE_UNUSED)
-+{
-+ /* On big-endian targets array loads (vld1) and vector loads (vldm)
-+ use a different format. Always use the "misaligned" array variant.
-+ FIXME: this still doesn't work for big-endian because of constant
-+ loads and other operations using vldm ordering. See
-+ issue 6722. */
-+ return TARGET_NEON && !BYTES_BIG_ENDIAN;
- }
-
- #include "gt-arm.h"
---- a/gcc/config/arm/arm.h
-+++ b/gcc/config/arm/arm.h
-@@ -85,6 +85,10 @@ extern char arm_arch_name[];
- builtin_define ("__IWMMXT__"); \
- if (TARGET_AAPCS_BASED) \
- builtin_define ("__ARM_EABI__"); \
-+ if (arm_tune_marvell_f) \
-+ builtin_define ("__ARM_TUNE_MARVELL_F__"); \
-+ if (low_irq_latency) \
-+ builtin_define ("__low_irq_latency__"); \
- } while (0)
-
- /* The various ARM cores. */
-@@ -199,6 +203,13 @@ extern void (*arm_lang_output_object_att
- #define TARGET_AAPCS_BASED \
- (arm_abi != ARM_ABI_APCS && arm_abi != ARM_ABI_ATPCS)
-
-+/* True if we should avoid generating conditional execution instructions. */
-+#define TARGET_NO_COND_EXEC (arm_tune_marvell_f && !optimize_size)
-+/* Avoid most conditional instructions, but allow pairs with opposite
-+ conditions and the same destination. */
-+#define TARGET_NO_SINGLE_COND_EXEC \
-+ ((arm_tune_cortex_a9 || arm_tune_marvell_f) && !optimize_size)
-+
- #define TARGET_HARD_TP (target_thread_pointer == TP_CP15)
- #define TARGET_SOFT_TP (target_thread_pointer == TP_SOFT)
-
-@@ -211,35 +222,43 @@ extern void (*arm_lang_output_object_att
- /* Thumb-1 only. */
- #define TARGET_THUMB1_ONLY (TARGET_THUMB1 && !arm_arch_notm)
-
-+#define TARGET_FPA_EMU2 (TARGET_FPA && arm_fpu_desc->rev == 2)
- /* The following two macros concern the ability to execute coprocessor
- instructions for VFPv3 or NEON. TARGET_VFP3/TARGET_VFPD32 are currently
- only ever tested when we know we are generating for VFP hardware; we need
- to be more careful with TARGET_NEON as noted below. */
-
- /* FPU is has the full VFPv3/NEON register file of 32 D registers. */
--#define TARGET_VFPD32 (arm_fp_model == ARM_FP_MODEL_VFP \
-- && (arm_fpu_arch == FPUTYPE_VFP3 \
-- || arm_fpu_arch == FPUTYPE_NEON))
-+#define TARGET_VFPD32 (TARGET_VFP && arm_arch_vfp_regs == VFP_REG_D32)
-
- /* FPU supports VFPv3 instructions. */
--#define TARGET_VFP3 (arm_fp_model == ARM_FP_MODEL_VFP \
-- && (arm_fpu_arch == FPUTYPE_VFP3D16 \
-- || TARGET_VFPD32))
-+#define TARGET_VFP3 (TARGET_VFP && arm_arch_vfp_rev >= 3)
-+
-+/* FPU only supports VFP single-precision instructions. */
-+#define TARGET_VFP_SINGLE (TARGET_VFP && arm_arch_vfp_regs == VFP_REG_SINGLE)
-+
-+/* FPU supports VFP double-precision instructions. */
-+#define TARGET_VFP_DOUBLE (TARGET_VFP && arm_arch_vfp_regs != VFP_REG_SINGLE)
-+
-+/* FPU supports half-precision floating-point with NEON element load/store. */
-+#define TARGET_NEON_FP16 (TARGET_VFP && arm_arch_vfp_neon && arm_arch_vfp_fp16)
-+
-+/* FPU supports VFP half-precision floating-point. */
-+#define TARGET_FP16 (TARGET_VFP && arm_arch_vfp_fp16)
-
- /* FPU supports Neon instructions. The setting of this macro gets
- revealed via __ARM_NEON__ so we add extra guards upon TARGET_32BIT
- and TARGET_HARD_FLOAT to ensure that NEON instructions are
- available. */
- #define TARGET_NEON (TARGET_32BIT && TARGET_HARD_FLOAT \
-- && arm_fp_model == ARM_FP_MODEL_VFP \
-- && arm_fpu_arch == FPUTYPE_NEON)
-+ && TARGET_VFP && arm_arch_vfp_neon)
-
- /* "DSP" multiply instructions, eg. SMULxy. */
- #define TARGET_DSP_MULTIPLY \
-- (TARGET_32BIT && arm_arch5e && arm_arch_notm)
-+ (TARGET_32BIT && arm_arch5e && (arm_arch_notm || arm_arch7em))
- /* Integer SIMD instructions, and extend-accumulate instructions. */
- #define TARGET_INT_SIMD \
-- (TARGET_32BIT && arm_arch6 && arm_arch_notm)
-+ (TARGET_32BIT && arm_arch6 && (arm_arch_notm || arm_arch7em))
-
- /* Should MOVW/MOVT be used in preference to a constant pool. */
- #define TARGET_USE_MOVT (arm_arch_thumb2 && !optimize_size)
-@@ -289,40 +308,30 @@ enum arm_fp_model
- ARM_FP_MODEL_VFP
- };
-
--extern enum arm_fp_model arm_fp_model;
--
--/* Which floating point hardware is available. Also update
-- fp_model_for_fpu in arm.c when adding entries to this list. */
--enum fputype
--{
-- /* No FP hardware. */
-- FPUTYPE_NONE,
-- /* Full FPA support. */
-- FPUTYPE_FPA,
-- /* Emulated FPA hardware, Issue 2 emulator (no LFM/SFM). */
-- FPUTYPE_FPA_EMU2,
-- /* Emulated FPA hardware, Issue 3 emulator. */
-- FPUTYPE_FPA_EMU3,
-- /* Cirrus Maverick floating point co-processor. */
-- FPUTYPE_MAVERICK,
-- /* VFP. */
-- FPUTYPE_VFP,
-- /* VFPv3-D16. */
-- FPUTYPE_VFP3D16,
-- /* VFPv3. */
-- FPUTYPE_VFP3,
-- /* Neon. */
-- FPUTYPE_NEON
-+enum vfp_reg_type {
-+ VFP_REG_D16,
-+ VFP_REG_D32,
-+ VFP_REG_SINGLE
- };
-
--/* Recast the floating point class to be the floating point attribute. */
--#define arm_fpu_attr ((enum attr_fpu) arm_fpu_tune)
--
--/* What type of floating point to tune for */
--extern enum fputype arm_fpu_tune;
-+extern const struct arm_fpu_desc
-+{
-+ const char *name;
-+ enum arm_fp_model model;
-+ int rev;
-+ enum vfp_reg_type myregs;
-+ int neon;
-+ int fp16;
-+} *arm_fpu_desc;
-+
-+#define arm_fp_model arm_fpu_desc->model
-+#define arm_arch_vfp_rev arm_fpu_desc->rev
-+#define arm_arch_vfp_regs arm_fpu_desc->myregs
-+#define arm_arch_vfp_neon arm_fpu_desc->neon
-+#define arm_arch_vfp_fp16 arm_fpu_desc->fp16
-
--/* What type of floating point instructions are available */
--extern enum fputype arm_fpu_arch;
-+/* Which floating point hardware to schedule for. */
-+extern int arm_fpu_attr;
-
- enum float_abi_type
- {
-@@ -337,6 +346,21 @@ extern enum float_abi_type arm_float_abi
- #define TARGET_DEFAULT_FLOAT_ABI ARM_FLOAT_ABI_SOFT
- #endif
-
-+/* Which __fp16 format to use.
-+ The enumeration values correspond to the numbering for the
-+ Tag_ABI_FP_16bit_format attribute.
-+ */
-+enum arm_fp16_format_type
-+{
-+ ARM_FP16_FORMAT_NONE = 0,
-+ ARM_FP16_FORMAT_IEEE = 1,
-+ ARM_FP16_FORMAT_ALTERNATIVE = 2
-+};
-+
-+extern enum arm_fp16_format_type arm_fp16_format;
-+#define LARGEST_EXPONENT_IS_NORMAL(bits) \
-+ ((bits) == 16 && arm_fp16_format == ARM_FP16_FORMAT_ALTERNATIVE)
-+
- /* Which ABI to use. */
- enum arm_abi_type
- {
-@@ -383,12 +407,18 @@ extern int arm_arch6;
- /* Nonzero if instructions not present in the 'M' profile can be used. */
- extern int arm_arch_notm;
-
-+/* Nonzero if instructions present in ARMv7E-M can be used. */
-+extern int arm_arch7em;
-+
- /* Nonzero if this chip can benefit from load scheduling. */
- extern int arm_ld_sched;
-
- /* Nonzero if generating thumb code. */
- extern int thumb_code;
-
-+/* Nonzero if generating Janus2 code. */
-+extern int janus2_code;
-+
- /* Nonzero if this chip is a StrongARM. */
- extern int arm_tune_strongarm;
-
-@@ -404,6 +434,9 @@ extern int arm_arch_xscale;
- /* Nonzero if tuning for XScale. */
- extern int arm_tune_xscale;
-
-+/* Nonzero if tuning for Marvell Feroceon. */
-+extern int arm_tune_marvell_f;
-+
- /* Nonzero if tuning for stores via the write buffer. */
- extern int arm_tune_wbuf;
-
-@@ -423,6 +456,10 @@ extern int arm_arch_thumb2;
- /* Nonzero if chip supports integer division instruction. */
- extern int arm_arch_hwdiv;
-
-+/* Nonzero if we should minimize interrupt latency of the
-+ generated code. */
-+extern int low_irq_latency;
-+
- #ifndef TARGET_DEFAULT
- #define TARGET_DEFAULT (MASK_APCS_FRAME)
- #endif
-@@ -757,12 +794,11 @@ extern int arm_structure_size_boundary;
- fixed_regs[regno] = call_used_regs[regno] = 1; \
- } \
- \
-- if (TARGET_THUMB && optimize_size) \
-- { \
-- /* When optimizing for size, it's better not to use \
-- the HI regs, because of the overhead of stacking \
-- them. */ \
-- /* ??? Is this still true for thumb2? */ \
-+ if (TARGET_THUMB1 && optimize_size) \
-+ { \
-+ /* When optimizing for size on Thumb-1, it's better not \
-+ to use the HI regs, because of the overhead of \
-+ stacking them. */ \
- for (regno = FIRST_HI_REGNUM; \
- regno <= LAST_HI_REGNUM; ++regno) \
- fixed_regs[regno] = call_used_regs[regno] = 1; \
-@@ -881,6 +917,9 @@ extern int arm_structure_size_boundary;
- /* The number of (integer) argument register available. */
- #define NUM_ARG_REGS 4
-
-+/* And similarly for the VFP. */
-+#define NUM_VFP_ARG_REGS 16
-+
- /* Return the register number of the N'th (integer) argument. */
- #define ARG_REGISTER(N) (N - 1)
-
-@@ -1059,7 +1098,7 @@ extern int arm_structure_size_boundary;
- (GET_MODE_CLASS (MODE1) == GET_MODE_CLASS (MODE2))
-
- #define VALID_IWMMXT_REG_MODE(MODE) \
-- (arm_vector_mode_supported_p (MODE) || (MODE) == DImode)
-+ (arm_vector_mode_supported_p (MODE) || (MODE) == DImode || (MODE) == SImode)
-
- /* Modes valid for Neon D registers. */
- #define VALID_NEON_DREG_MODE(MODE) \
-@@ -1230,11 +1269,14 @@ enum reg_class
- || reg_classes_intersect_p (VFP_REGS, (CLASS)) \
- : 0)
-
--/* We need to define this for LO_REGS on thumb. Otherwise we can end up
-- using r0-r4 for function arguments, r7 for the stack frame and don't
-- have enough left over to do doubleword arithmetic. */
-+/* We need to define this for LO_REGS on Thumb-1. Otherwise we can end up
-+ using r0-r4 for function arguments, r7 for the stack frame and don't have
-+ enough left over to do doubleword arithmetic. For Thumb-2 all the
-+ potentially problematic instructions accept high registers so this is not
-+ necessary. Care needs to be taken to avoid adding new Thumb-2 patterns
-+ that require many low registers. */
- #define CLASS_LIKELY_SPILLED_P(CLASS) \
-- ((TARGET_THUMB && (CLASS) == LO_REGS) \
-+ ((TARGET_THUMB1 && (CLASS) == LO_REGS) \
- || (CLASS) == CC_REG)
-
- /* The class value for index registers, and the one for base regs. */
-@@ -1245,7 +1287,7 @@ enum reg_class
- when addressing quantities in QI or HI mode; if we don't know the
- mode, then we must be conservative. */
- #define MODE_BASE_REG_CLASS(MODE) \
-- (TARGET_32BIT ? CORE_REGS : \
-+ (TARGET_32BIT ? (TARGET_THUMB2 ? LO_REGS : CORE_REGS) : \
- (((MODE) == SImode) ? BASE_REGS : LO_REGS))
-
- /* For Thumb we can not support SP+reg addressing, so we return LO_REGS
-@@ -1346,6 +1388,9 @@ enum reg_class
- else if (TARGET_MAVERICK && TARGET_HARD_FLOAT) \
- /* Need to be careful, -256 is not a valid offset. */ \
- low = val >= 0 ? (val & 0xff) : -((-val) & 0xff); \
-+ else if (TARGET_REALLY_IWMMXT && MODE == SImode) \
-+ /* Need to be careful, -1024 is not a valid offset. */ \
-+ low = val >= 0 ? (val & 0x3ff) : -((-val) & 0x3ff); \
- else if (MODE == SImode \
- || (MODE == SFmode && TARGET_SOFT_FLOAT) \
- || ((MODE == HImode || MODE == QImode) && ! arm_arch4)) \
-@@ -1416,13 +1461,17 @@ do { \
- /* If defined, gives a class of registers that cannot be used as the
- operand of a SUBREG that changes the mode of the object illegally. */
-
--/* Moves between FPA_REGS and GENERAL_REGS are two memory insns. */
-+/* Moves between FPA_REGS and GENERAL_REGS are two memory insns.
-+ Moves between VFP_REGS and GENERAL_REGS are a single insn, but
-+ it is typically more expensive than a single memory access. We set
-+ the cost to less than two memory accesses so that floating
-+ point to integer conversion does not go through memory. */
- #define REGISTER_MOVE_COST(MODE, FROM, TO) \
- (TARGET_32BIT ? \
- ((FROM) == FPA_REGS && (TO) != FPA_REGS ? 20 : \
- (FROM) != FPA_REGS && (TO) == FPA_REGS ? 20 : \
-- IS_VFP_CLASS (FROM) && !IS_VFP_CLASS (TO) ? 10 : \
-- !IS_VFP_CLASS (FROM) && IS_VFP_CLASS (TO) ? 10 : \
-+ IS_VFP_CLASS (FROM) && !IS_VFP_CLASS (TO) ? 15 : \
-+ !IS_VFP_CLASS (FROM) && IS_VFP_CLASS (TO) ? 15 : \
- (FROM) == IWMMXT_REGS && (TO) != IWMMXT_REGS ? 4 : \
- (FROM) != IWMMXT_REGS && (TO) == IWMMXT_REGS ? 4 : \
- (FROM) == IWMMXT_GR_REGS || (TO) == IWMMXT_GR_REGS ? 20 : \
-@@ -1491,9 +1540,10 @@ do { \
-
- /* Define how to find the value returned by a library function
- assuming the value has mode MODE. */
--#define LIBCALL_VALUE(MODE) \
-- (TARGET_32BIT && TARGET_HARD_FLOAT_ABI && TARGET_FPA \
-- && GET_MODE_CLASS (MODE) == MODE_FLOAT \
-+#define LIBCALL_VALUE(MODE) \
-+ (TARGET_AAPCS_BASED ? aapcs_libcall_value (MODE) \
-+ : (TARGET_32BIT && TARGET_HARD_FLOAT_ABI && TARGET_FPA \
-+ && GET_MODE_CLASS (MODE) == MODE_FLOAT) \
- ? gen_rtx_REG (MODE, FIRST_FPA_REGNUM) \
- : TARGET_32BIT && TARGET_HARD_FLOAT_ABI && TARGET_MAVERICK \
- && GET_MODE_CLASS (MODE) == MODE_FLOAT \
-@@ -1502,22 +1552,16 @@ do { \
- ? gen_rtx_REG (MODE, FIRST_IWMMXT_REGNUM) \
- : gen_rtx_REG (MODE, ARG_REGISTER (1)))
-
--/* Define how to find the value returned by a function.
-- VALTYPE is the data type of the value (as a tree).
-- If the precise function being called is known, FUNC is its FUNCTION_DECL;
-- otherwise, FUNC is 0. */
--#define FUNCTION_VALUE(VALTYPE, FUNC) \
-- arm_function_value (VALTYPE, FUNC);
--
--/* 1 if N is a possible register number for a function value.
-- On the ARM, only r0 and f0 can return results. */
--/* On a Cirrus chip, mvf0 can return results. */
--#define FUNCTION_VALUE_REGNO_P(REGNO) \
-- ((REGNO) == ARG_REGISTER (1) \
-- || (TARGET_32BIT && ((REGNO) == FIRST_CIRRUS_FP_REGNUM) \
-- && TARGET_HARD_FLOAT_ABI && TARGET_MAVERICK) \
-- || ((REGNO) == FIRST_IWMMXT_REGNUM && TARGET_IWMMXT_ABI) \
-- || (TARGET_32BIT && ((REGNO) == FIRST_FPA_REGNUM) \
-+/* 1 if REGNO is a possible register number for a function value. */
-+#define FUNCTION_VALUE_REGNO_P(REGNO) \
-+ ((REGNO) == ARG_REGISTER (1) \
-+ || (TARGET_AAPCS_BASED && TARGET_32BIT \
-+ && TARGET_VFP && TARGET_HARD_FLOAT \
-+ && (REGNO) == FIRST_VFP_REGNUM) \
-+ || (TARGET_32BIT && ((REGNO) == FIRST_CIRRUS_FP_REGNUM) \
-+ && TARGET_HARD_FLOAT_ABI && TARGET_MAVERICK) \
-+ || ((REGNO) == FIRST_IWMMXT_REGNUM && TARGET_IWMMXT_ABI) \
-+ || (TARGET_32BIT && ((REGNO) == FIRST_FPA_REGNUM) \
- && TARGET_HARD_FLOAT_ABI && TARGET_FPA))
-
- /* Amount of memory needed for an untyped call to save all possible return
-@@ -1617,9 +1661,27 @@ machine_function;
- that is in text_section. */
- extern GTY(()) rtx thumb_call_via_label[14];
-
-+/* The number of potential ways of assigning to a co-processor. */
-+#define ARM_NUM_COPROC_SLOTS 1
-+
-+/* Enumeration of procedure calling standard variants. We don't really
-+ support all of these yet. */
-+enum arm_pcs
-+{
-+ ARM_PCS_AAPCS, /* Base standard AAPCS. */
-+ ARM_PCS_AAPCS_VFP, /* Use VFP registers for floating point values. */
-+ ARM_PCS_AAPCS_IWMMXT, /* Use iWMMXT registers for vectors. */
-+ /* This must be the last AAPCS variant. */
-+ ARM_PCS_AAPCS_LOCAL, /* Private call within this compilation unit. */
-+ ARM_PCS_ATPCS, /* ATPCS. */
-+ ARM_PCS_APCS, /* APCS (legacy Linux etc). */
-+ ARM_PCS_UNKNOWN
-+};
-+
-+/* We can't define this inside a generator file because it needs enum
-+ machine_mode. */
- /* 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 `int' suffices and can hold the number of bytes of argument so far. */
-+ `FUNCTION_ARG' and other related values. */
- typedef struct
- {
- /* This is the number of registers of arguments scanned so far. */
-@@ -1628,9 +1690,33 @@ typedef struct
- int iwmmxt_nregs;
- int named_count;
- int nargs;
-- int can_split;
-+ /* Which procedure call variant to use for this call. */
-+ enum arm_pcs pcs_variant;
-+
-+ /* AAPCS related state tracking. */
-+ int aapcs_arg_processed; /* No need to lay out this argument again. */
-+ int aapcs_cprc_slot; /* Index of co-processor rules to handle
-+ this argument, or -1 if using core
-+ registers. */
-+ int aapcs_ncrn;
-+ int aapcs_next_ncrn;
-+ rtx aapcs_reg; /* Register assigned to this argument. */
-+ int aapcs_partial; /* How many bytes are passed in regs (if
-+ split between core regs and stack.
-+ Zero otherwise. */
-+ int aapcs_cprc_failed[ARM_NUM_COPROC_SLOTS];
-+ int can_split; /* Argument can be split between core regs
-+ and the stack. */
-+ /* Private data for tracking VFP register allocation */
-+ unsigned aapcs_vfp_regs_free;
-+ unsigned aapcs_vfp_reg_alloc;
-+ int aapcs_vfp_rcount;
-+ /* Can't include insn-modes.h because this header is needed before we
-+ generate it. */
-+ int /* enum machine_mode */ aapcs_vfp_rmode;
- } CUMULATIVE_ARGS;
-
-+
- /* Define where to put the arguments to a function.
- Value is zero to push the argument on the stack,
- or a hard register in which to store the argument.
-@@ -1674,13 +1760,7 @@ typedef struct
- of mode MODE and data type TYPE.
- (TYPE is null for libcalls where that information may not be available.) */
- #define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
-- (CUM).nargs += 1; \
-- if (arm_vector_mode_supported_p (MODE) \
-- && (CUM).named_count > (CUM).nargs \
-- && TARGET_IWMMXT_ABI) \
-- (CUM).iwmmxt_nregs += 1; \
-- else \
-- (CUM).nregs += ARM_NUM_REGS2 (MODE, TYPE)
-+ arm_function_arg_advance (&(CUM), (MODE), (TYPE), (NAMED))
-
- /* If defined, a C expression that gives the alignment boundary, in bits, of an
- argument with the specified mode and type. If it is not defined,
-@@ -1692,9 +1772,11 @@ typedef struct
-
- /* 1 if N is a possible register number for function argument passing.
- On the ARM, r0-r3 are used to pass args. */
--#define FUNCTION_ARG_REGNO_P(REGNO) \
-- (IN_RANGE ((REGNO), 0, 3) \
-- || (TARGET_IWMMXT_ABI \
-+#define FUNCTION_ARG_REGNO_P(REGNO) \
-+ (IN_RANGE ((REGNO), 0, 3) \
-+ || (TARGET_AAPCS_BASED && TARGET_VFP && TARGET_HARD_FLOAT \
-+ && IN_RANGE ((REGNO), FIRST_VFP_REGNUM, FIRST_VFP_REGNUM + 15)) \
-+ || (TARGET_IWMMXT_ABI \
- && IN_RANGE ((REGNO), FIRST_IWMMXT_REGNUM, FIRST_IWMMXT_REGNUM + 9)))
-
- \f
-@@ -2324,7 +2406,8 @@ do { \
- /* Try to generate sequences that don't involve branches, we can then use
- conditional instructions */
- #define BRANCH_COST(speed_p, predictable_p) \
-- (TARGET_32BIT ? 4 : (optimize > 0 ? 2 : 0))
-+ (TARGET_32BIT ? (TARGET_THUMB2 && optimize_size ? 1 : 4) \
-+ : (optimize > 0 ? 2 : 0))
- \f
- /* Position Independent Code. */
- /* We decide which register to use based on the compilation options and
-@@ -2392,6 +2475,7 @@ extern int making_const_table;
-
- /* The arm5 clz instruction returns 32. */
- #define CLZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = 32, 1)
-+#define CTZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = 32, 1)
- \f
- #undef ASM_APP_OFF
- #define ASM_APP_OFF (TARGET_THUMB1 ? "\t.code\t16\n" : \
-@@ -2404,6 +2488,19 @@ extern int making_const_table;
- if (TARGET_ARM) \
- asm_fprintf (STREAM,"\tstmfd\t%r!,{%r}\n", \
- STACK_POINTER_REGNUM, REGNO); \
-+ else if (TARGET_THUMB1 \
-+ && (REGNO) == STATIC_CHAIN_REGNUM) \
-+ { \
-+ /* We can't push STATIC_CHAIN_REGNUM (r12) directly with Thumb-1.
-+ We know that ASM_OUTPUT_REG_PUSH will be matched with
-+ ASM_OUTPUT_REG_POP, and that r7 isn't used by the function
-+ profiler, so we can use it as a scratch reg. WARNING: This isn't
-+ safe in the general case! It may be sensitive to future changes
-+ in final.c:profile_function. */ \
-+ asm_fprintf (STREAM, "\tpush\t{r7}\n"); \
-+ asm_fprintf (STREAM, "\tmov\tr7, %r\n", REGNO);\
-+ asm_fprintf (STREAM, "\tpush\t{r7}\n"); \
-+ } \
- else \
- asm_fprintf (STREAM, "\tpush {%r}\n", REGNO); \
- } while (0)
-@@ -2415,6 +2512,14 @@ extern int making_const_table;
- if (TARGET_ARM) \
- asm_fprintf (STREAM, "\tldmfd\t%r!,{%r}\n", \
- STACK_POINTER_REGNUM, REGNO); \
-+ else if (TARGET_THUMB1 \
-+ && (REGNO) == STATIC_CHAIN_REGNUM) \
-+ { \
-+ /* See comment in ASM_OUTPUT_REG_PUSH. */ \
-+ asm_fprintf (STREAM, "\tpop\t{r7}\n"); \
-+ asm_fprintf (STREAM, "\tmov\t%r, r7\n", REGNO);\
-+ asm_fprintf (STREAM, "\tpop\t{r7}\n"); \
-+ } \
- else \
- asm_fprintf (STREAM, "\tpop {%r}\n", REGNO); \
- } while (0)
---- a/gcc/config/arm/arm.md
-+++ b/gcc/config/arm/arm.md
-@@ -99,6 +99,7 @@
- ; correctly for PIC usage.
- (UNSPEC_GOTSYM_OFF 24) ; The offset of the start of the the GOT from a
- ; a given symbolic address.
-+ (UNSPEC_RBIT 25) ; rbit operation.
- ]
- )
-
-@@ -131,6 +132,8 @@
- (VUNSPEC_WCMP_EQ 12) ; Used by the iWMMXt WCMPEQ instructions
- (VUNSPEC_WCMP_GTU 13) ; Used by the iWMMXt WCMPGTU instructions
- (VUNSPEC_WCMP_GT 14) ; Used by the iwMMXT WCMPGT instructions
-+ (VUNSPEC_ALIGN16 15) ; Used to force 16-byte alignment.
-+ (VUNSPEC_ALIGN32 16) ; Used to force 32-byte alignment.
- (VUNSPEC_EH_RETURN 20); Use to override the return address for exception
- ; handling.
- ]
-@@ -144,6 +147,10 @@
- ; patterns that share the same RTL in both ARM and Thumb code.
- (define_attr "is_thumb" "no,yes" (const (symbol_ref "thumb_code")))
-
-+; FIX_JANUS is set to 'yes' when compiling for Janus2, it causes to
-+; add a nop after shifts, in order to work around a Janus2 bug
-+(define_attr "fix_janus" "no,yes" (const (symbol_ref "janus2_code")))
-+
- ; IS_STRONGARM is set to 'yes' when compiling for StrongARM, it affects
- ; scheduling decisions for the load unit and the multiplier.
- (define_attr "is_strongarm" "no,yes" (const (symbol_ref "arm_tune_strongarm")))
-@@ -158,7 +165,7 @@
- ; Floating Point Unit. If we only have floating point emulation, then there
- ; is no point in scheduling the floating point insns. (Well, for best
- ; performance we should try and group them together).
--(define_attr "fpu" "none,fpa,fpe2,fpe3,maverick,vfp,vfpv3d16,vfpv3,neon"
-+(define_attr "fpu" "none,fpa,fpe2,fpe3,maverick,vfp"
- (const (symbol_ref "arm_fpu_attr")))
-
- ; LENGTH of an instruction (in bytes)
-@@ -185,7 +192,7 @@
- ;; scheduling information.
-
- (define_attr "insn"
-- "mov,mvn,smulxy,smlaxy,smlalxy,smulwy,smlawx,mul,muls,mla,mlas,umull,umulls,umlal,umlals,smull,smulls,smlal,smlals,smlawy,smuad,smuadx,smlad,smladx,smusd,smusdx,smlsd,smlsdx,smmul,smmulr,smmla,umaal,smlald,smlsld,clz,mrs,msr,xtab,sdiv,udiv,other"
-+ "mov,mvn,and,orr,eor,smulxy,smlaxy,smlalxy,smulwy,smlawx,mul,muls,mla,mlas,umull,umulls,umlal,umlals,smull,smulls,smlal,smlals,smlawy,smuad,smuadx,smlad,smladx,smusd,smusdx,smlsd,smlsdx,smmul,smmulr,smmla,umaal,smlald,smlsld,clz,mrs,msr,xtab,sdiv,udiv,other"
- (const_string "other"))
-
- ; TYPE attribute is used to detect floating point instructions which, if
-@@ -251,8 +258,6 @@
- (define_attr "ldsched" "no,yes" (const (symbol_ref "arm_ld_sched")))
-
- ;; Classification of NEON instructions for scheduling purposes.
--;; Do not set this attribute and the "type" attribute together in
--;; any one instruction pattern.
- (define_attr "neon_type"
- "neon_int_1,\
- neon_int_2,\
-@@ -415,7 +420,7 @@
-
- (define_attr "generic_sched" "yes,no"
- (const (if_then_else
-- (ior (eq_attr "tune" "arm926ejs,arm1020e,arm1026ejs,arm1136js,arm1136jfs,cortexa8,cortexa9")
-+ (ior (eq_attr "tune" "arm926ejs,arm1020e,arm1026ejs,arm1136js,arm1136jfs,cortexa8,cortexa9,marvell_f")
- (eq_attr "tune_cortexr4" "yes"))
- (const_string "no")
- (const_string "yes"))))
-@@ -423,7 +428,7 @@
- (define_attr "generic_vfp" "yes,no"
- (const (if_then_else
- (and (eq_attr "fpu" "vfp")
-- (eq_attr "tune" "!arm1020e,arm1022e,cortexa8,cortexa9")
-+ (eq_attr "tune" "!arm1020e,arm1022e,cortexa8,cortexa9,marvell_f")
- (eq_attr "tune_cortexr4" "no"))
- (const_string "yes")
- (const_string "no"))))
-@@ -437,6 +442,8 @@
- (include "cortex-a9.md")
- (include "cortex-r4.md")
- (include "cortex-r4f.md")
-+(include "marvell-f.md")
-+(include "marvell-f-vfp.md")
- (include "vfp11.md")
-
- \f
-@@ -620,10 +627,11 @@
- sub%?\\t%0, %1, #%n2
- sub%?\\t%0, %1, #%n2
- #"
-- "TARGET_32BIT &&
-- GET_CODE (operands[2]) == CONST_INT
-+ "TARGET_32BIT
-+ && GET_CODE (operands[2]) == CONST_INT
- && !(const_ok_for_arm (INTVAL (operands[2]))
-- || const_ok_for_arm (-INTVAL (operands[2])))"
-+ || const_ok_for_arm (-INTVAL (operands[2])))
-+ && (reload_completed || !arm_eliminable_register (operands[1]))"
- [(clobber (const_int 0))]
- "
- arm_split_constant (PLUS, SImode, curr_insn,
-@@ -639,10 +647,10 @@
- ;; register. Trying to reload it will always fail catastrophically,
- ;; so never allow those alternatives to match if reloading is needed.
-
--(define_insn "*thumb1_addsi3"
-- [(set (match_operand:SI 0 "register_operand" "=l,l,l,*rk,*hk,l,!k")
-- (plus:SI (match_operand:SI 1 "register_operand" "%0,0,l,*0,*0,!k,!k")
-- (match_operand:SI 2 "nonmemory_operand" "I,J,lL,*hk,*rk,!M,!O")))]
-+(define_insn_and_split "*thumb1_addsi3"
-+ [(set (match_operand:SI 0 "register_operand" "=l,l,l,*rk,*hk,l,!k,l,l")
-+ (plus:SI (match_operand:SI 1 "register_operand" "%0,0,l,*0,*0,!k,!k,0,l")
-+ (match_operand:SI 2 "nonmemory_operand" "I,J,lL,*hk,*rk,!M,!O,Pa,Pb")))]
- "TARGET_THUMB1"
- "*
- static const char * const asms[] =
-@@ -653,7 +661,9 @@
- \"add\\t%0, %0, %2\",
- \"add\\t%0, %0, %2\",
- \"add\\t%0, %1, %2\",
-- \"add\\t%0, %1, %2\"
-+ \"add\\t%0, %1, %2\",
-+ \"#\",
-+ \"#\"
- };
- if ((which_alternative == 2 || which_alternative == 6)
- && GET_CODE (operands[2]) == CONST_INT
-@@ -661,7 +671,22 @@
- return \"sub\\t%0, %1, #%n2\";
- return asms[which_alternative];
- "
-- [(set_attr "length" "2")]
-+ "&& reload_completed && CONST_INT_P (operands[2])
-+ && operands[1] != stack_pointer_rtx
-+ && (INTVAL (operands[2]) > 255 || INTVAL (operands[2]) < -255)"
-+ [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
-+ (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
-+ {
-+ HOST_WIDE_INT offset = INTVAL (operands[2]);
-+ if (offset > 255)
-+ offset = 255;
-+ else if (offset < -255)
-+ offset = -255;
-+
-+ operands[3] = GEN_INT (offset);
-+ operands[2] = GEN_INT (INTVAL (operands[2]) - offset);
-+ }
-+ [(set_attr "length" "2,2,2,2,2,2,2,4,4")]
- )
-
- ;; Reloading and elimination of the frame pointer can
-@@ -854,7 +879,11 @@
- [(set_attr "conds" "use")
- (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
- (const_string "alu_shift")
-- (const_string "alu_shift_reg")))]
-+ (const_string "alu_shift_reg")))
-+ (set (attr "length") (if_then_else (and (eq_attr "type" "alu_shift_reg")
-+ (eq_attr "fix_janus" "yes"))
-+ (const_int 8)
-+ (const_int 4)))]
- )
-
- (define_insn "*addsi3_carryin_alt1"
-@@ -938,7 +967,7 @@
- [(set (match_operand:DF 0 "s_register_operand" "")
- (plus:DF (match_operand:DF 1 "s_register_operand" "")
- (match_operand:DF 2 "arm_float_add_operand" "")))]
-- "TARGET_32BIT && TARGET_HARD_FLOAT"
-+ "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
- "
- if (TARGET_MAVERICK
- && !cirrus_fp_register (operands[2], DFmode))
-@@ -1176,7 +1205,7 @@
- [(set (match_operand:DF 0 "s_register_operand" "")
- (minus:DF (match_operand:DF 1 "arm_float_rhs_operand" "")
- (match_operand:DF 2 "arm_float_rhs_operand" "")))]
-- "TARGET_32BIT && TARGET_HARD_FLOAT"
-+ "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
- "
- if (TARGET_MAVERICK)
- {
-@@ -1332,6 +1361,49 @@
- (set_attr "predicable" "yes")]
- )
-
-+; The combiner cannot combine the first and last insns in the
-+; following sequence because of the intervening insn, so help the
-+; combiner with this splitter. The combiner does attempt to split
-+; this particular combination but does not know this exact split.
-+; Note that the combiner puts the constant at the outermost operation
-+; as a part of canonicalization.
-+;
-+; mul r3, r2, r1
-+; <add/sub> r3, r3, <constant>
-+; add r3, r3, r4
-+
-+(define_split
-+ [(set (match_operand:SI 0 "s_register_operand" "")
-+ (match_operator:SI 1 "plusminus_operator"
-+ [(plus:SI (mult:SI (match_operand:SI 2 "s_register_operand" "")
-+ (match_operand:SI 3 "s_register_operand" ""))
-+ (match_operand:SI 4 "s_register_operand" ""))
-+ (match_operand:SI 5 "arm_immediate_operand" "")]))]
-+ "TARGET_32BIT"
-+ [(set (match_dup 0)
-+ (plus:SI (mult:SI (match_dup 2) (match_dup 3))
-+ (match_dup 4)))
-+ (set (match_dup 0)
-+ (match_op_dup:SI 1 [(match_dup 0) (match_dup 5)]))]
-+ "")
-+
-+; Likewise for MLS. MLS is available only on select architectures.
-+
-+(define_split
-+ [(set (match_operand:SI 0 "s_register_operand" "")
-+ (match_operator:SI 1 "plusminus_operator"
-+ [(minus:SI (match_operand:SI 2 "s_register_operand" "")
-+ (mult:SI (match_operand:SI 3 "s_register_operand" "")
-+ (match_operand:SI 4 "s_register_operand" "")))
-+ (match_operand:SI 5 "arm_immediate_operand" "")]))]
-+ "TARGET_32BIT && arm_arch_thumb2"
-+ [(set (match_dup 0)
-+ (minus:SI (match_dup 2)
-+ (mult:SI (match_dup 3) (match_dup 4))))
-+ (set (match_dup 0)
-+ (match_op_dup:SI 1 [(match_dup 0) (match_dup 5)]))]
-+ "")
-+
- (define_insn "*mulsi3addsi_compare0"
- [(set (reg:CC_NOOV CC_REGNUM)
- (compare:CC_NOOV
-@@ -1713,7 +1785,7 @@
- [(set (match_operand:DF 0 "s_register_operand" "")
- (mult:DF (match_operand:DF 1 "s_register_operand" "")
- (match_operand:DF 2 "arm_float_rhs_operand" "")))]
-- "TARGET_32BIT && TARGET_HARD_FLOAT"
-+ "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
- "
- if (TARGET_MAVERICK
- && !cirrus_fp_register (operands[2], DFmode))
-@@ -1733,7 +1805,7 @@
- [(set (match_operand:DF 0 "s_register_operand" "")
- (div:DF (match_operand:DF 1 "arm_float_rhs_operand" "")
- (match_operand:DF 2 "arm_float_rhs_operand" "")))]
-- "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
-+ "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP_DOUBLE)"
- "")
- \f
- ;; Modulo insns
-@@ -1960,6 +2032,7 @@
- DONE;
- "
- [(set_attr "length" "4,4,16")
-+ (set_attr "insn" "and")
- (set_attr "predicable" "yes")]
- )
-
-@@ -1969,7 +2042,8 @@
- (match_operand:SI 2 "register_operand" "l")))]
- "TARGET_THUMB1"
- "and\\t%0, %0, %2"
-- [(set_attr "length" "2")]
-+ [(set_attr "length" "2")
-+ (set_attr "insn" "and")]
- )
-
- (define_insn "*andsi3_compare0"
-@@ -1984,7 +2058,8 @@
- "@
- and%.\\t%0, %1, %2
- bic%.\\t%0, %1, #%B2"
-- [(set_attr "conds" "set")]
-+ [(set_attr "conds" "set")
-+ (set_attr "insn" "and,*")]
- )
-
- (define_insn "*andsi3_compare0_scratch"
-@@ -2280,7 +2355,7 @@
- }
- }
-
-- target = operands[0];
-+ target = copy_rtx (operands[0]);
- /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical
- subreg as the final target. */
- if (GET_CODE (target) == SUBREG)
-@@ -2528,7 +2603,11 @@
- (set_attr "shift" "2")
- (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
- (const_string "alu_shift")
-- (const_string "alu_shift_reg")))]
-+ (const_string "alu_shift_reg")))
-+ (set (attr "length") (if_then_else (and (eq_attr "type" "alu_shift_reg")
-+ (eq_attr "fix_janus" "yes"))
-+ (const_int 8)
-+ (const_int 4)))]
- )
-
- (define_insn "*andsi_notsi_si_compare0"
-@@ -2576,6 +2655,7 @@
- orr%?\\t%Q0, %Q1, %2
- #"
- [(set_attr "length" "4,8")
-+ (set_attr "insn" "orr")
- (set_attr "predicable" "yes")]
- )
-
-@@ -2638,7 +2718,8 @@
- (match_operand:SI 2 "register_operand" "l")))]
- "TARGET_THUMB1"
- "orr\\t%0, %0, %2"
-- [(set_attr "length" "2")]
-+ [(set_attr "length" "2")
-+ (set_attr "insn" "orr")]
- )
-
- (define_peephole2
-@@ -2663,7 +2744,8 @@
- (ior:SI (match_dup 1) (match_dup 2)))]
- "TARGET_32BIT"
- "orr%.\\t%0, %1, %2"
-- [(set_attr "conds" "set")]
-+ [(set_attr "conds" "set")
-+ (set_attr "insn" "orr")]
- )
-
- (define_insn "*iorsi3_compare0_scratch"
-@@ -2674,7 +2756,8 @@
- (clobber (match_scratch:SI 0 "=r"))]
- "TARGET_32BIT"
- "orr%.\\t%0, %1, %2"
-- [(set_attr "conds" "set")]
-+ [(set_attr "conds" "set")
-+ (set_attr "insn" "orr")]
- )
-
- (define_insn "xordi3"
-@@ -2697,7 +2780,8 @@
- eor%?\\t%Q0, %Q1, %2
- #"
- [(set_attr "length" "4,8")
-- (set_attr "predicable" "yes")]
-+ (set_attr "predicable" "yes")
-+ (set_attr "insn" "eor")]
- )
-
- (define_insn "*xordi_sesidi_di"
-@@ -2728,7 +2812,8 @@
- (match_operand:SI 2 "arm_rhs_operand" "rI")))]
- "TARGET_32BIT"
- "eor%?\\t%0, %1, %2"
-- [(set_attr "predicable" "yes")]
-+ [(set_attr "predicable" "yes")
-+ (set_attr "insn" "eor")]
- )
-
- (define_insn "*thumb1_xorsi3"
-@@ -2737,7 +2822,8 @@
- (match_operand:SI 2 "register_operand" "l")))]
- "TARGET_THUMB1"
- "eor\\t%0, %0, %2"
-- [(set_attr "length" "2")]
-+ [(set_attr "length" "2")
-+ (set_attr "insn" "eor")]
- )
-
- (define_insn "*xorsi3_compare0"
-@@ -2749,7 +2835,8 @@
- (xor:SI (match_dup 1) (match_dup 2)))]
- "TARGET_32BIT"
- "eor%.\\t%0, %1, %2"
-- [(set_attr "conds" "set")]
-+ [(set_attr "conds" "set")
-+ (set_attr "insn" "eor")]
- )
-
- (define_insn "*xorsi3_compare0_scratch"
-@@ -2906,7 +2993,7 @@
- (smax:SI (match_operand:SI 1 "s_register_operand" "")
- (match_operand:SI 2 "arm_rhs_operand" "")))
- (clobber (reg:CC CC_REGNUM))])]
-- "TARGET_32BIT"
-+ "TARGET_32BIT && !TARGET_NO_COND_EXEC"
- "
- if (operands[2] == const0_rtx || operands[2] == constm1_rtx)
- {
-@@ -2933,7 +3020,8 @@
- (const_int -1)))]
- "TARGET_32BIT"
- "orr%?\\t%0, %1, %1, asr #31"
-- [(set_attr "predicable" "yes")]
-+ [(set_attr "predicable" "yes")
-+ (set_attr "insn" "orr")]
- )
-
- (define_insn "*arm_smax_insn"
-@@ -2941,7 +3029,7 @@
- (smax:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
- (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
- (clobber (reg:CC CC_REGNUM))]
-- "TARGET_ARM"
-+ "TARGET_ARM && !TARGET_NO_COND_EXEC"
- "@
- cmp\\t%1, %2\;movlt\\t%0, %2
- cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
-@@ -2955,7 +3043,7 @@
- (smin:SI (match_operand:SI 1 "s_register_operand" "")
- (match_operand:SI 2 "arm_rhs_operand" "")))
- (clobber (reg:CC CC_REGNUM))])]
-- "TARGET_32BIT"
-+ "TARGET_32BIT && !TARGET_NO_COND_EXEC"
- "
- if (operands[2] == const0_rtx)
- {
-@@ -2973,7 +3061,8 @@
- (const_int 0)))]
- "TARGET_32BIT"
- "and%?\\t%0, %1, %1, asr #31"
-- [(set_attr "predicable" "yes")]
-+ [(set_attr "predicable" "yes")
-+ (set_attr "insn" "and")]
- )
-
- (define_insn "*arm_smin_insn"
-@@ -2981,7 +3070,7 @@
- (smin:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
- (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
- (clobber (reg:CC CC_REGNUM))]
-- "TARGET_ARM"
-+ "TARGET_ARM && !TARGET_NO_COND_EXEC"
- "@
- cmp\\t%1, %2\;movge\\t%0, %2
- cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
-@@ -2995,7 +3084,7 @@
- (umax:SI (match_operand:SI 1 "s_register_operand" "")
- (match_operand:SI 2 "arm_rhs_operand" "")))
- (clobber (reg:CC CC_REGNUM))])]
-- "TARGET_32BIT"
-+ "TARGET_32BIT && !TARGET_NO_COND_EXEC"
- ""
- )
-
-@@ -3004,7 +3093,7 @@
- (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
- (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
- (clobber (reg:CC CC_REGNUM))]
-- "TARGET_ARM"
-+ "TARGET_ARM && !TARGET_NO_COND_EXEC"
- "@
- cmp\\t%1, %2\;movcc\\t%0, %2
- cmp\\t%1, %2\;movcs\\t%0, %1
-@@ -3019,7 +3108,7 @@
- (umin:SI (match_operand:SI 1 "s_register_operand" "")
- (match_operand:SI 2 "arm_rhs_operand" "")))
- (clobber (reg:CC CC_REGNUM))])]
-- "TARGET_32BIT"
-+ "TARGET_32BIT && !TARGET_NO_COND_EXEC"
- ""
- )
-
-@@ -3028,7 +3117,7 @@
- (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
- (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
- (clobber (reg:CC CC_REGNUM))]
-- "TARGET_ARM"
-+ "TARGET_ARM && !TARGET_NO_COND_EXEC"
- "@
- cmp\\t%1, %2\;movcs\\t%0, %2
- cmp\\t%1, %2\;movcc\\t%0, %1
-@@ -3043,7 +3132,7 @@
- [(match_operand:SI 1 "s_register_operand" "r")
- (match_operand:SI 2 "s_register_operand" "r")]))
- (clobber (reg:CC CC_REGNUM))]
-- "TARGET_32BIT"
-+ "TARGET_32BIT && !TARGET_NO_COND_EXEC"
- "*
- operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode,
- operands[1], operands[2]);
-@@ -3163,11 +3252,23 @@
- [(set (match_operand:SI 0 "register_operand" "=l,l")
- (ashift:SI (match_operand:SI 1 "register_operand" "l,0")
- (match_operand:SI 2 "nonmemory_operand" "N,l")))]
-- "TARGET_THUMB1"
-+ "TARGET_THUMB1 && !janus2_code"
- "lsl\\t%0, %1, %2"
- [(set_attr "length" "2")]
- )
-
-+(define_insn "*thumb1_ashlsi3_janus2"
-+ [(set (match_operand:SI 0 "register_operand" "=l,l")
-+ (ashift:SI (match_operand:SI 1 "register_operand" "l,0")
-+ (match_operand:SI 2 "nonmemory_operand" "N,l")))]
-+ "TARGET_THUMB1 && janus2_code"
-+ "@
-+ lsl\\t%0, %1, %2
-+ lsl\\t%0, %1, %2\;nop"
-+ [(set_attr "length" "2,4")]
-+)
-+
-+
- (define_expand "ashrdi3"
- [(set (match_operand:DI 0 "s_register_operand" "")
- (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "")
-@@ -3200,6 +3301,7 @@
- "TARGET_32BIT"
- "movs\\t%R0, %R1, asr #1\;mov\\t%Q0, %Q1, rrx"
- [(set_attr "conds" "clob")
-+ (set_attr "insn" "mov")
- (set_attr "length" "8")]
- )
-
-@@ -3219,11 +3321,22 @@
- [(set (match_operand:SI 0 "register_operand" "=l,l")
- (ashiftrt:SI (match_operand:SI 1 "register_operand" "l,0")
- (match_operand:SI 2 "nonmemory_operand" "N,l")))]
-- "TARGET_THUMB1"
-+ "TARGET_THUMB1 && !janus2_code"
- "asr\\t%0, %1, %2"
- [(set_attr "length" "2")]
- )
-
-+(define_insn "*thumb1_ashrsi3_janus2"
-+ [(set (match_operand:SI 0 "register_operand" "=l,l")
-+ (ashiftrt:SI (match_operand:SI 1 "register_operand" "l,0")
-+ (match_operand:SI 2 "nonmemory_operand" "N,l")))]
-+ "TARGET_THUMB1 && janus2_code"
-+ "@
-+ asr\\t%0, %1, %2
-+ asr\\t%0, %1, %2\;nop"
-+ [(set_attr "length" "2,4")]
-+)
-+
- (define_expand "lshrdi3"
- [(set (match_operand:DI 0 "s_register_operand" "")
- (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "")
-@@ -3256,6 +3369,7 @@
- "TARGET_32BIT"
- "movs\\t%R0, %R1, lsr #1\;mov\\t%Q0, %Q1, rrx"
- [(set_attr "conds" "clob")
-+ (set_attr "insn" "mov")
- (set_attr "length" "8")]
- )
-
-@@ -3278,11 +3392,22 @@
- [(set (match_operand:SI 0 "register_operand" "=l,l")
- (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,0")
- (match_operand:SI 2 "nonmemory_operand" "N,l")))]
-- "TARGET_THUMB1"
-+ "TARGET_THUMB1 && !janus2_code"
- "lsr\\t%0, %1, %2"
- [(set_attr "length" "2")]
- )
-
-+(define_insn "*thumb1_lshrsi3_janus2"
-+ [(set (match_operand:SI 0 "register_operand" "=l,l")
-+ (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,0")
-+ (match_operand:SI 2 "nonmemory_operand" "N,l")))]
-+ "TARGET_THUMB1 && janus2_code"
-+ "@
-+ lsr\\t%0, %1, %2
-+ lsr\\t%0, %1, %2; nop"
-+ [(set_attr "length" "2,4")]
-+)
-+
- (define_expand "rotlsi3"
- [(set (match_operand:SI 0 "s_register_operand" "")
- (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
-@@ -3324,11 +3449,20 @@
- [(set (match_operand:SI 0 "register_operand" "=l")
- (rotatert:SI (match_operand:SI 1 "register_operand" "0")
- (match_operand:SI 2 "register_operand" "l")))]
-- "TARGET_THUMB1"
-+ "TARGET_THUMB1 && !janus2_code"
- "ror\\t%0, %0, %2"
- [(set_attr "length" "2")]
- )
-
-+(define_insn "*thumb1_rotrsi3_janus2"
-+ [(set (match_operand:SI 0 "register_operand" "=l")
-+ (rotatert:SI (match_operand:SI 1 "register_operand" "0")
-+ (match_operand:SI 2 "register_operand" "l")))]
-+ "TARGET_THUMB1 && janus2_code"
-+ "ror\\t%0, %0, %2; nop"
-+ [(set_attr "length" "4")]
-+)
-+
- (define_insn "*arm_shiftsi3"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
- (match_operator:SI 3 "shift_operator"
-@@ -3340,7 +3474,11 @@
- (set_attr "shift" "1")
- (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
- (const_string "alu_shift")
-- (const_string "alu_shift_reg")))]
-+ (const_string "alu_shift_reg")))
-+ (set (attr "length") (if_then_else (and (eq_attr "type" "alu_shift_reg")
-+ (eq_attr "fix_janus" "yes"))
-+ (const_int 8)
-+ (const_int 4)))]
- )
-
- (define_insn "*shiftsi3_compare0"
-@@ -3357,7 +3495,11 @@
- (set_attr "shift" "1")
- (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
- (const_string "alu_shift")
-- (const_string "alu_shift_reg")))]
-+ (const_string "alu_shift_reg")))
-+ (set (attr "length") (if_then_else (and (eq_attr "type" "alu_shift_reg")
-+ (eq_attr "fix_janus" "yes"))
-+ (const_int 8)
-+ (const_int 4)))]
- )
-
- (define_insn "*shiftsi3_compare0_scratch"
-@@ -3370,7 +3512,11 @@
- "TARGET_32BIT"
- "* return arm_output_shift(operands, 1);"
- [(set_attr "conds" "set")
-- (set_attr "shift" "1")]
-+ (set_attr "shift" "1")
-+ (set (attr "length") (if_then_else (and (match_operand 2 "s_register_operand" "")
-+ (eq_attr "fix_janus" "yes"))
-+ (const_int 8)
-+ (const_int 4)))]
- )
-
- (define_insn "*arm_notsi_shiftsi"
-@@ -3382,9 +3528,14 @@
- "mvn%?\\t%0, %1%S3"
- [(set_attr "predicable" "yes")
- (set_attr "shift" "1")
-+ (set_attr "insn" "mvn")
- (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
- (const_string "alu_shift")
-- (const_string "alu_shift_reg")))]
-+ (const_string "alu_shift_reg")))
-+ (set (attr "length") (if_then_else (and (eq_attr "type" "alu_shift_reg")
-+ (eq_attr "fix_janus" "yes"))
-+ (const_int 8)
-+ (const_int 4)))]
- )
-
- (define_insn "*arm_notsi_shiftsi_compare0"
-@@ -3399,9 +3550,14 @@
- "mvn%.\\t%0, %1%S3"
- [(set_attr "conds" "set")
- (set_attr "shift" "1")
-+ (set_attr "insn" "mvn")
- (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
- (const_string "alu_shift")
-- (const_string "alu_shift_reg")))]
-+ (const_string "alu_shift_reg")))
-+ (set (attr "length") (if_then_else (and (eq_attr "type" "alu_shift_reg")
-+ (eq_attr "fix_janus" "yes"))
-+ (const_int 8)
-+ (const_int 4)))]
- )
-
- (define_insn "*arm_not_shiftsi_compare0_scratch"
-@@ -3415,9 +3571,14 @@
- "mvn%.\\t%0, %1%S3"
- [(set_attr "conds" "set")
- (set_attr "shift" "1")
-+ (set_attr "insn" "mvn")
- (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
- (const_string "alu_shift")
-- (const_string "alu_shift_reg")))]
-+ (const_string "alu_shift_reg")))
-+ (set (attr "length") (if_then_else (and (eq_attr "type" "alu_shift_reg")
-+ (eq_attr "fix_janus" "yes"))
-+ (const_int 8)
-+ (const_int 4)))]
- )
-
- ;; We don't really have extzv, but defining this using shifts helps
-@@ -3550,12 +3711,12 @@
- (define_expand "negdf2"
- [(set (match_operand:DF 0 "s_register_operand" "")
- (neg:DF (match_operand:DF 1 "s_register_operand" "")))]
-- "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
-+ "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP_DOUBLE)"
- "")
-
- ;; abssi2 doesn't really clobber the condition codes if a different register
- ;; is being set. To keep things simple, assume during rtl manipulations that
--;; it does, but tell the final scan operator the truth. Similarly for
-+;; it does, and the splitter will eliminate it. Similarly for
- ;; (neg (abs...))
-
- (define_expand "abssi2"
-@@ -3567,22 +3728,28 @@
- "
- if (TARGET_THUMB1)
- operands[2] = gen_rtx_SCRATCH (SImode);
-+ else if (TARGET_NO_SINGLE_COND_EXEC)
-+ {
-+ emit_insn(gen_rtx_SET(VOIDmode, operands[0],
-+ gen_rtx_ABS(SImode, operands[1])));
-+ DONE;
-+ }
- else
- operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
- ")
-
- (define_insn "*arm_abssi2"
-- [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
-- (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
-+ [(set (match_operand:SI 0 "s_register_operand" "=r")
-+ (abs:SI (match_operand:SI 1 "s_register_operand" "r")))
- (clobber (reg:CC CC_REGNUM))]
-- "TARGET_ARM"
-- "@
-- cmp\\t%0, #0\;rsblt\\t%0, %0, #0
-- eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31"
-- [(set_attr "conds" "clob,*")
-- (set_attr "shift" "1")
-+ "TARGET_32BIT && !TARGET_NO_SINGLE_COND_EXEC"
-+ "#"
-+ [(set_attr "shift" "1")
- ;; predicable can't be set based on the variant, so left as no
-- (set_attr "length" "8")]
-+ (set (attr "length")
-+ (if_then_else (eq_attr "is_thumb" "yes")
-+ (const_int 10)
-+ (const_int 8)))]
- )
-
- (define_insn_and_split "*thumb1_abssi2"
-@@ -3600,17 +3767,17 @@
- )
-
- (define_insn "*arm_neg_abssi2"
-- [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
-- (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
-+ [(set (match_operand:SI 0 "s_register_operand" "=r")
-+ (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "r"))))
- (clobber (reg:CC CC_REGNUM))]
-- "TARGET_ARM"
-- "@
-- cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
-- eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31"
-- [(set_attr "conds" "clob,*")
-- (set_attr "shift" "1")
-+ "TARGET_32BIT && !TARGET_NO_SINGLE_COND_EXEC"
-+ "#"
-+ [(set_attr "shift" "1")
- ;; predicable can't be set based on the variant, so left as no
-- (set_attr "length" "8")]
-+ (set (attr "length")
-+ (if_then_else (eq_attr "is_thumb" "yes")
-+ (const_int 10)
-+ (const_int 8)))]
- )
-
- (define_insn_and_split "*thumb1_neg_abssi2"
-@@ -3627,6 +3794,93 @@
- [(set_attr "length" "6")]
- )
-
-+;; Simplified version for when avoiding conditional execution
-+(define_insn "*arm_nocond_abssi2"
-+ [(set (match_operand:SI 0 "s_register_operand" "=&r")
-+ (abs:SI (match_operand:SI 1 "s_register_operand" "r")))]
-+ "TARGET_32BIT && TARGET_NO_SINGLE_COND_EXEC"
-+ "#"
-+ [(set_attr "shift" "1")
-+ (set_attr "length" "8")
-+ (set_attr "predicable" "yes")]
-+)
-+
-+(define_insn "*arm_nocond_neg_abssi2"
-+ [(set (match_operand:SI 0 "s_register_operand" "=&r")
-+ (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "r"))))]
-+ "TARGET_32BIT && TARGET_NO_SINGLE_COND_EXEC"
-+ "#"
-+ [(set_attr "shift" "1")
-+ (set_attr "length" "8")
-+ (set_attr "predicable" "yes")]
-+)
-+
-+;; Splitters for ABS patterns.
-+
-+(define_split
-+ [(set (match_operand:SI 0 "s_register_operand" "")
-+ (abs:SI (match_operand:SI 1 "s_register_operand" "")))
-+ (clobber (reg:CC CC_REGNUM))]
-+ "TARGET_32BIT && reload_completed && rtx_equal_p(operands[0], operands[1])"
-+ [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
-+ (cond_exec (lt (reg:CC CC_REGNUM) (const_int 0))
-+ (set (match_dup 0) (neg:SI (match_dup 1))))]
-+)
-+
-+(define_split
-+ [(set (match_operand:SI 0 "s_register_operand" "")
-+ (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" ""))))
-+ (clobber (reg:CC CC_REGNUM))]
-+ "TARGET_32BIT && reload_completed && rtx_equal_p(operands[0], operands[1])"
-+ [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
-+ (cond_exec (gt (reg:CC CC_REGNUM) (const_int 0))
-+ (set (match_dup 0) (neg:SI (match_dup 1))))]
-+)
-+
-+;; GCC does not add/remove clobbers when matching splitters, so we need
-+;; variants with and without the CC clobber.
-+(define_split
-+ [(set (match_operand:SI 0 "s_register_operand" "")
-+ (abs:SI (match_operand:SI 1 "s_register_operand" "")))]
-+ "TARGET_32BIT && reload_completed && !rtx_equal_p(operands[0], operands[1])"
-+ [(set (match_dup 0) (xor:SI (ashiftrt:SI (match_dup 1) (const_int 31))
-+ (match_dup 1)))
-+ (set (match_dup 0) (minus:SI (match_dup 0)
-+ (ashiftrt:SI (match_dup 1) (const_int 31))))]
-+)
-+
-+(define_split
-+ [(set (match_operand:SI 0 "s_register_operand" "")
-+ (abs:SI (match_operand:SI 1 "s_register_operand" "")))
-+ (clobber (reg:CC CC_REGNUM))]
-+ "TARGET_32BIT && reload_completed && !rtx_equal_p(operands[0], operands[1])"
-+ [(set (match_dup 0) (xor:SI (ashiftrt:SI (match_dup 1) (const_int 31))
-+ (match_dup 1)))
-+ (set (match_dup 0) (minus:SI (match_dup 0)
-+ (ashiftrt:SI (match_dup 1) (const_int 31))))]
-+)
-+
-+(define_split
-+ [(set (match_operand:SI 0 "s_register_operand" "")
-+ (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" ""))))]
-+ "TARGET_32BIT && reload_completed && !rtx_equal_p(operands[0], operands[1])"
-+ [(set (match_dup 0) (xor:SI (ashiftrt:SI (match_dup 1) (const_int 31))
-+ (match_dup 1)))
-+ (set (match_dup 0) (minus:SI (ashiftrt:SI (match_dup 1) (const_int 31))
-+ (match_dup 0)))]
-+)
-+
-+(define_split
-+ [(set (match_operand:SI 0 "s_register_operand" "")
-+ (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" ""))))
-+ (clobber (reg:CC CC_REGNUM))]
-+ "TARGET_32BIT && reload_completed && !rtx_equal_p(operands[0], operands[1])"
-+ [(set (match_dup 0) (xor:SI (ashiftrt:SI (match_dup 1) (const_int 31))
-+ (match_dup 1)))
-+ (set (match_dup 0) (minus:SI (ashiftrt:SI (match_dup 1) (const_int 31))
-+ (match_dup 0)))]
-+)
-+
- (define_expand "abssf2"
- [(set (match_operand:SF 0 "s_register_operand" "")
- (abs:SF (match_operand:SF 1 "s_register_operand" "")))]
-@@ -3636,7 +3890,7 @@
- (define_expand "absdf2"
- [(set (match_operand:DF 0 "s_register_operand" "")
- (abs:DF (match_operand:DF 1 "s_register_operand" "")))]
-- "TARGET_32BIT && TARGET_HARD_FLOAT"
-+ "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
- "")
-
- (define_expand "sqrtsf2"
-@@ -3648,7 +3902,7 @@
- (define_expand "sqrtdf2"
- [(set (match_operand:DF 0 "s_register_operand" "")
- (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
-- "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
-+ "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP_DOUBLE)"
- "")
-
- (define_insn_and_split "one_cmpldi2"
-@@ -3682,7 +3936,8 @@
- (not:SI (match_operand:SI 1 "s_register_operand" "r")))]
- "TARGET_32BIT"
- "mvn%?\\t%0, %1"
-- [(set_attr "predicable" "yes")]
-+ [(set_attr "predicable" "yes")
-+ (set_attr "insn" "mvn")]
- )
-
- (define_insn "*thumb1_one_cmplsi2"
-@@ -3690,7 +3945,8 @@
- (not:SI (match_operand:SI 1 "register_operand" "l")))]
- "TARGET_THUMB1"
- "mvn\\t%0, %1"
-- [(set_attr "length" "2")]
-+ [(set_attr "length" "2")
-+ (set_attr "insn" "mvn")]
- )
-
- (define_insn "*notsi_compare0"
-@@ -3701,7 +3957,8 @@
- (not:SI (match_dup 1)))]
- "TARGET_32BIT"
- "mvn%.\\t%0, %1"
-- [(set_attr "conds" "set")]
-+ [(set_attr "conds" "set")
-+ (set_attr "insn" "mvn")]
- )
-
- (define_insn "*notsi_compare0_scratch"
-@@ -3711,11 +3968,40 @@
- (clobber (match_scratch:SI 0 "=r"))]
- "TARGET_32BIT"
- "mvn%.\\t%0, %1"
-- [(set_attr "conds" "set")]
-+ [(set_attr "conds" "set")
-+ (set_attr "insn" "mvn")]
- )
- \f
- ;; Fixed <--> Floating conversion insns
-
-+(define_expand "floatsihf2"
-+ [(set (match_operand:HF 0 "general_operand" "")
-+ (float:HF (match_operand:SI 1 "general_operand" "")))]
-+ "TARGET_EITHER"
-+ "
-+ {
-+ rtx op1 = gen_reg_rtx (SFmode);
-+ expand_float (op1, operands[1], 0);
-+ op1 = convert_to_mode (HFmode, op1, 0);
-+ emit_move_insn (operands[0], op1);
-+ DONE;
-+ }"
-+)
-+
-+(define_expand "floatdihf2"
-+ [(set (match_operand:HF 0 "general_operand" "")
-+ (float:HF (match_operand:DI 1 "general_operand" "")))]
-+ "TARGET_EITHER"
-+ "
-+ {
-+ rtx op1 = gen_reg_rtx (SFmode);
-+ expand_float (op1, operands[1], 0);
-+ op1 = convert_to_mode (HFmode, op1, 0);
-+ emit_move_insn (operands[0], op1);
-+ DONE;
-+ }"
-+)
-+
- (define_expand "floatsisf2"
- [(set (match_operand:SF 0 "s_register_operand" "")
- (float:SF (match_operand:SI 1 "s_register_operand" "")))]
-@@ -3731,7 +4017,7 @@
- (define_expand "floatsidf2"
- [(set (match_operand:DF 0 "s_register_operand" "")
- (float:DF (match_operand:SI 1 "s_register_operand" "")))]
-- "TARGET_32BIT && TARGET_HARD_FLOAT"
-+ "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
- "
- if (TARGET_MAVERICK)
- {
-@@ -3740,6 +4026,30 @@
- }
- ")
-
-+(define_expand "fix_trunchfsi2"
-+ [(set (match_operand:SI 0 "general_operand" "")
-+ (fix:SI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
-+ "TARGET_EITHER"
-+ "
-+ {
-+ rtx op1 = convert_to_mode (SFmode, operands[1], 0);
-+ expand_fix (operands[0], op1, 0);
-+ DONE;
-+ }"
-+)
-+
-+(define_expand "fix_trunchfdi2"
-+ [(set (match_operand:DI 0 "general_operand" "")
-+ (fix:DI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
-+ "TARGET_EITHER"
-+ "
-+ {
-+ rtx op1 = convert_to_mode (SFmode, operands[1], 0);
-+ expand_fix (operands[0], op1, 0);
-+ DONE;
-+ }"
-+)
-+
- (define_expand "fix_truncsfsi2"
- [(set (match_operand:SI 0 "s_register_operand" "")
- (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" ""))))]
-@@ -3759,7 +4069,7 @@
- (define_expand "fix_truncdfsi2"
- [(set (match_operand:SI 0 "s_register_operand" "")
- (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" ""))))]
-- "TARGET_32BIT && TARGET_HARD_FLOAT"
-+ "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
- "
- if (TARGET_MAVERICK)
- {
-@@ -3776,9 +4086,25 @@
- [(set (match_operand:SF 0 "s_register_operand" "")
- (float_truncate:SF
- (match_operand:DF 1 "s_register_operand" "")))]
-- "TARGET_32BIT && TARGET_HARD_FLOAT"
-+ "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
- ""
- )
-+
-+/* DFmode -> HFmode conversions have to go through SFmode. */
-+(define_expand "truncdfhf2"
-+ [(set (match_operand:HF 0 "general_operand" "")
-+ (float_truncate:HF
-+ (match_operand:DF 1 "general_operand" "")))]
-+ "TARGET_EITHER"
-+ "
-+ {
-+ rtx op1;
-+ op1 = convert_to_mode (SFmode, operands[1], 0);
-+ op1 = convert_to_mode (HFmode, op1, 0);
-+ emit_move_insn (operands[0], op1);
-+ DONE;
-+ }"
-+)
- \f
- ;; Zero and sign extension instructions.
-
-@@ -3800,6 +4126,7 @@
- return \"mov%?\\t%R0, #0\";
- "
- [(set_attr "length" "8")
-+ (set_attr "insn" "mov")
- (set_attr "predicable" "yes")]
- )
-
-@@ -3843,6 +4170,7 @@
- "
- [(set_attr "length" "8")
- (set_attr "shift" "1")
-+ (set_attr "insn" "mov")
- (set_attr "predicable" "yes")]
- )
-
-@@ -4123,6 +4451,28 @@
- ""
- )
-
-+(define_code_iterator ior_xor [ior xor])
-+
-+(define_split
-+ [(set (match_operand:SI 0 "s_register_operand" "")
-+ (ior_xor:SI (and:SI (ashift:SI
-+ (match_operand:SI 1 "s_register_operand" "")
-+ (match_operand:SI 2 "const_int_operand" ""))
-+ (match_operand:SI 3 "const_int_operand" ""))
-+ (zero_extend:SI
-+ (match_operator 5 "subreg_lowpart_operator"
-+ [(match_operand:SI 4 "s_register_operand" "")]))))]
-+ "TARGET_32BIT
-+ && (INTVAL (operands[3])
-+ == (GET_MODE_MASK (GET_MODE (operands[5]))
-+ & (GET_MODE_MASK (GET_MODE (operands[5]))
-+ << (INTVAL (operands[2])))))"
-+ [(set (match_dup 0) (ior_xor:SI (ashift:SI (match_dup 1) (match_dup 2))
-+ (match_dup 4)))
-+ (set (match_dup 0) (zero_extend:SI (match_dup 5)))]
-+ "operands[5] = gen_lowpart (GET_MODE (operands[5]), operands[0]);"
-+)
-+
- (define_insn "*compareqi_eq0"
- [(set (reg:CC_Z CC_REGNUM)
- (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
-@@ -4639,9 +4989,24 @@
- (define_expand "extendsfdf2"
- [(set (match_operand:DF 0 "s_register_operand" "")
- (float_extend:DF (match_operand:SF 1 "s_register_operand" "")))]
-- "TARGET_32BIT && TARGET_HARD_FLOAT"
-+ "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
- ""
- )
-+
-+/* HFmode -> DFmode conversions have to go through SFmode. */
-+(define_expand "extendhfdf2"
-+ [(set (match_operand:DF 0 "general_operand" "")
-+ (float_extend:DF (match_operand:HF 1 "general_operand" "")))]
-+ "TARGET_EITHER"
-+ "
-+ {
-+ rtx op1;
-+ op1 = convert_to_mode (SFmode, operands[1], 0);
-+ op1 = convert_to_mode (DFmode, op1, 0);
-+ emit_insn (gen_movdf (operands[0], op1));
-+ DONE;
-+ }"
-+)
- \f
- ;; Move insns (including loads and stores)
-
-@@ -4877,6 +5242,7 @@
- }"
- [(set_attr "length" "4,4,6,2,2,6,4,4")
- (set_attr "type" "*,*,*,load2,store2,load2,store2,*")
-+ (set_attr "insn" "*,mov,*,*,*,*,*,mov")
- (set_attr "pool_range" "*,*,*,*,*,1020,*,*")]
- )
-
-@@ -4903,14 +5269,6 @@
- optimize && can_create_pseudo_p ());
- DONE;
- }
--
-- if (TARGET_USE_MOVT && !target_word_relocations
-- && GET_CODE (operands[1]) == SYMBOL_REF
-- && !flag_pic && !arm_tls_referenced_p (operands[1]))
-- {
-- arm_emit_movpair (operands[0], operands[1]);
-- DONE;
-- }
- }
- else /* TARGET_THUMB1... */
- {
-@@ -4984,18 +5342,9 @@
- (set_attr "length" "4")]
- )
-
--(define_insn "*arm_movw"
-- [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
-- (high:SI (match_operand:SI 1 "general_operand" "i")))]
-- "TARGET_32BIT"
-- "movw%?\t%0, #:lower16:%c1"
-- [(set_attr "predicable" "yes")
-- (set_attr "length" "4")]
--)
--
- (define_insn "*arm_movsi_insn"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
-- (match_operand:SI 1 "general_operand" "rk, I,K,N,mi,rk"))]
-+ (match_operand:SI 1 "general_operand" "rk, I,K,j,mi,rk"))]
- "TARGET_ARM && ! TARGET_IWMMXT
- && !(TARGET_HARD_FLOAT && TARGET_VFP)
- && ( register_operand (operands[0], SImode)
-@@ -5008,6 +5357,7 @@
- ldr%?\\t%0, %1
- str%?\\t%1, %0"
- [(set_attr "type" "*,*,*,*,load1,store1")
-+ (set_attr "insn" "mov,mov,mvn,mov,*,*")
- (set_attr "predicable" "yes")
- (set_attr "pool_range" "*,*,*,*,4096,*")
- (set_attr "neg_pool_range" "*,*,*,*,4084,*")]
-@@ -5027,6 +5377,19 @@
- "
- )
-
-+(define_split
-+ [(set (match_operand:SI 0 "arm_general_register_operand" "")
-+ (match_operand:SI 1 "general_operand" ""))]
-+ "TARGET_32BIT
-+ && TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF
-+ && !flag_pic && !target_word_relocations
-+ && !arm_tls_referenced_p (operands[1])"
-+ [(clobber (const_int 0))]
-+{
-+ arm_emit_movpair (operands[0], operands[1]);
-+ DONE;
-+})
-+
- (define_insn "*thumb1_movsi_insn"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=l,l,l,l,l,>,l, m,*lhk")
- (match_operand:SI 1 "general_operand" "l, I,J,K,>,l,mi,l,*lhk"))]
-@@ -5065,7 +5428,7 @@
- (set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))]
- "
- {
-- unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
-+ unsigned HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffffffffu;
- unsigned HOST_WIDE_INT mask = 0xff;
- int i;
-
-@@ -5627,6 +5990,7 @@
- ldr%(h%)\\t%0, %1\\t%@ movhi"
- [(set_attr "type" "*,*,store1,load1")
- (set_attr "predicable" "yes")
-+ (set_attr "insn" "mov,mvn,*,*")
- (set_attr "pool_range" "*,*,*,256")
- (set_attr "neg_pool_range" "*,*,*,244")]
- )
-@@ -5638,7 +6002,8 @@
- "@
- mov%?\\t%0, %1\\t%@ movhi
- mvn%?\\t%0, #%B1\\t%@ movhi"
-- [(set_attr "predicable" "yes")]
-+ [(set_attr "predicable" "yes")
-+ (set_attr "insn" "mov,mvn")]
- )
-
- (define_expand "thumb_movhi_clobber"
-@@ -5769,6 +6134,7 @@
- ldr%(b%)\\t%0, %1
- str%(b%)\\t%1, %0"
- [(set_attr "type" "*,*,load1,store1")
-+ (set_attr "insn" "mov,mvn,*,*")
- (set_attr "predicable" "yes")]
- )
-
-@@ -5787,9 +6153,111 @@
- mov\\t%0, %1"
- [(set_attr "length" "2")
- (set_attr "type" "*,load1,store1,*,*,*")
-+ (set_attr "insn" "*,*,*,mov,mov,mov")
- (set_attr "pool_range" "*,32,*,*,*,*")]
- )
-
-+;; HFmode moves
-+(define_expand "movhf"
-+ [(set (match_operand:HF 0 "general_operand" "")
-+ (match_operand:HF 1 "general_operand" ""))]
-+ "TARGET_EITHER"
-+ "
-+ if (TARGET_32BIT)
-+ {
-+ if (GET_CODE (operands[0]) == MEM)
-+ operands[1] = force_reg (HFmode, operands[1]);
-+ }
-+ else /* TARGET_THUMB1 */
-+ {
-+ if (can_create_pseudo_p ())
-+ {
-+ if (GET_CODE (operands[0]) != REG)
-+ operands[1] = force_reg (HFmode, operands[1]);
-+ }
-+ }
-+ "
-+)
-+
-+(define_insn "*arm32_movhf"
-+ [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r")
-+ (match_operand:HF 1 "general_operand" " m,r,r,F"))]
-+ "TARGET_32BIT && !(TARGET_HARD_FLOAT && TARGET_FP16)
-+ && ( s_register_operand (operands[0], HFmode)
-+ || s_register_operand (operands[1], HFmode))"
-+ "*
-+ switch (which_alternative)
-+ {
-+ case 0: /* ARM register from memory */
-+ return \"ldr%(h%)\\t%0, %1\\t%@ __fp16\";
-+ case 1: /* memory from ARM register */
-+ return \"str%(h%)\\t%1, %0\\t%@ __fp16\";
-+ case 2: /* ARM register from ARM register */
-+ return \"mov%?\\t%0, %1\\t%@ __fp16\";
-+ case 3: /* ARM register from constant */
-+ {
-+ REAL_VALUE_TYPE r;
-+ long bits;
-+ rtx ops[4];
-+
-+ REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
-+ bits = real_to_target (NULL, &r, HFmode);
-+ ops[0] = operands[0];
-+ ops[1] = GEN_INT (bits);
-+ ops[2] = GEN_INT (bits & 0xff00);
-+ ops[3] = GEN_INT (bits & 0x00ff);
-+
-+ if (arm_arch_thumb2)
-+ output_asm_insn (\"movw%?\\t%0, %1\", ops);
-+ else
-+ output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
-+ return \"\";
-+ }
-+ default:
-+ gcc_unreachable ();
-+ }
-+ "
-+ [(set_attr "conds" "unconditional")
-+ (set_attr "type" "load1,store1,*,*")
-+ (set_attr "length" "4,4,4,8")
-+ (set_attr "predicable" "yes")
-+ ]
-+)
-+
-+(define_insn "*thumb1_movhf"
-+ [(set (match_operand:HF 0 "nonimmediate_operand" "=l,l,m,*r,*h")
-+ (match_operand:HF 1 "general_operand" "l,mF,l,*h,*r"))]
-+ "TARGET_THUMB1
-+ && ( s_register_operand (operands[0], HFmode)
-+ || s_register_operand (operands[1], HFmode))"
-+ "*
-+ switch (which_alternative)
-+ {
-+ case 1:
-+ {
-+ rtx addr;
-+ gcc_assert (GET_CODE(operands[1]) == MEM);
-+ addr = XEXP (operands[1], 0);
-+ if (GET_CODE (addr) == LABEL_REF
-+ || (GET_CODE (addr) == CONST
-+ && GET_CODE (XEXP (addr, 0)) == PLUS
-+ && GET_CODE (XEXP (XEXP (addr, 0), 0)) == LABEL_REF
-+ && GET_CODE (XEXP (XEXP (addr, 0), 1)) == CONST_INT))
-+ {
-+ /* Constant pool entry. */
-+ return \"ldr\\t%0, %1\";
-+ }
-+ return \"ldrh\\t%0, %1\";
-+ }
-+ case 2: return \"strh\\t%1, %0\";
-+ default: return \"mov\\t%0, %1\";
-+ }
-+ "
-+ [(set_attr "length" "2")
-+ (set_attr "type" "*,load1,store1,*,*")
-+ (set_attr "pool_range" "*,1020,*,*,*")]
-+)
-+
- (define_expand "movsf"
- [(set (match_operand:SF 0 "general_operand" "")
- (match_operand:SF 1 "general_operand" ""))]
-@@ -5842,6 +6310,7 @@
- [(set_attr "length" "4,4,4")
- (set_attr "predicable" "yes")
- (set_attr "type" "*,load1,store1")
-+ (set_attr "insn" "mov,*,*")
- (set_attr "pool_range" "*,4096,*")
- (set_attr "neg_pool_range" "*,4084,*")]
- )
-@@ -6297,7 +6766,7 @@
- (match_operand:BLK 1 "general_operand" "")
- (match_operand:SI 2 "const_int_operand" "")
- (match_operand:SI 3 "const_int_operand" "")]
-- "TARGET_EITHER"
-+ "TARGET_EITHER && !low_irq_latency"
- "
- if (TARGET_32BIT)
- {
-@@ -7476,7 +7945,7 @@
- (define_expand "cmpdf"
- [(match_operand:DF 0 "s_register_operand" "")
- (match_operand:DF 1 "arm_float_compare_operand" "")]
-- "TARGET_32BIT && TARGET_HARD_FLOAT"
-+ "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
- "
- arm_compare_op0 = operands[0];
- arm_compare_op1 = operands[1];
-@@ -7507,7 +7976,11 @@
- (set_attr "shift" "1")
- (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
- (const_string "alu_shift")
-- (const_string "alu_shift_reg")))]
-+ (const_string "alu_shift_reg")))
-+ (set (attr "length") (if_then_else (and (eq_attr "type" "alu_shift_reg")
-+ (eq_attr "fix_janus" "yes"))
-+ (const_int 8)
-+ (const_int 4)))]
- )
-
- (define_insn "*arm_cmpsi_shiftsi_swp"
-@@ -7522,7 +7995,11 @@
- (set_attr "shift" "1")
- (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
- (const_string "alu_shift")
-- (const_string "alu_shift_reg")))]
-+ (const_string "alu_shift_reg")))
-+ (set (attr "length") (if_then_else (and (eq_attr "type" "alu_shift_reg")
-+ (eq_attr "fix_janus" "yes"))
-+ (const_int 8)
-+ (const_int 4)))]
- )
-
- (define_insn "*arm_cmpsi_negshiftsi_si"
-@@ -7537,7 +8014,11 @@
- [(set_attr "conds" "set")
- (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
- (const_string "alu_shift")
-- (const_string "alu_shift_reg")))]
-+ (const_string "alu_shift_reg")))
-+ (set (attr "length") (if_then_else (and (eq_attr "type" "alu_shift_reg")
-+ (eq_attr "fix_janus" "yes"))
-+ (const_int 8)
-+ (const_int 4)))]
- )
-
- ;; Cirrus SF compare instruction
-@@ -7879,77 +8360,77 @@
- (define_expand "seq"
- [(set (match_operand:SI 0 "s_register_operand" "")
- (eq:SI (match_dup 1) (const_int 0)))]
-- "TARGET_32BIT"
-+ "TARGET_32BIT && !TARGET_NO_COND_EXEC"
- "operands[1] = arm_gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1);"
- )
-
- (define_expand "sne"
- [(set (match_operand:SI 0 "s_register_operand" "")
- (ne:SI (match_dup 1) (const_int 0)))]
-- "TARGET_32BIT"
-+ "TARGET_32BIT && !TARGET_NO_COND_EXEC"
- "operands[1] = arm_gen_compare_reg (NE, arm_compare_op0, arm_compare_op1);"
- )
-
- (define_expand "sgt"
- [(set (match_operand:SI 0 "s_register_operand" "")
- (gt:SI (match_dup 1) (const_int 0)))]
-- "TARGET_32BIT"
-+ "TARGET_32BIT && !TARGET_NO_COND_EXEC"
- "operands[1] = arm_gen_compare_reg (GT, arm_compare_op0, arm_compare_op1);"
- )
-
- (define_expand "sle"
- [(set (match_operand:SI 0 "s_register_operand" "")
- (le:SI (match_dup 1) (const_int 0)))]
-- "TARGET_32BIT"
-+ "TARGET_32BIT && !TARGET_NO_COND_EXEC"
- "operands[1] = arm_gen_compare_reg (LE, arm_compare_op0, arm_compare_op1);"
- )
-
- (define_expand "sge"
- [(set (match_operand:SI 0 "s_register_operand" "")
- (ge:SI (match_dup 1) (const_int 0)))]
-- "TARGET_32BIT"
-+ "TARGET_32BIT && !TARGET_NO_COND_EXEC"
- "operands[1] = arm_gen_compare_reg (GE, arm_compare_op0, arm_compare_op1);"
- )
-
- (define_expand "slt"
- [(set (match_operand:SI 0 "s_register_operand" "")
- (lt:SI (match_dup 1) (const_int 0)))]
-- "TARGET_32BIT"
-+ "TARGET_32BIT && !TARGET_NO_COND_EXEC"
- "operands[1] = arm_gen_compare_reg (LT, arm_compare_op0, arm_compare_op1);"
- )
-
- (define_expand "sgtu"
- [(set (match_operand:SI 0 "s_register_operand" "")
- (gtu:SI (match_dup 1) (const_int 0)))]
-- "TARGET_32BIT"
-+ "TARGET_32BIT && !TARGET_NO_COND_EXEC"
- "operands[1] = arm_gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1);"
- )
-
- (define_expand "sleu"
- [(set (match_operand:SI 0 "s_register_operand" "")
- (leu:SI (match_dup 1) (const_int 0)))]
-- "TARGET_32BIT"
-+ "TARGET_32BIT && !TARGET_NO_COND_EXEC"
- "operands[1] = arm_gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1);"
- )
-
- (define_expand "sgeu"
- [(set (match_operand:SI 0 "s_register_operand" "")
- (geu:SI (match_dup 1) (const_int 0)))]
-- "TARGET_32BIT"
-+ "TARGET_32BIT && !TARGET_NO_COND_EXEC"
- "operands[1] = arm_gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1);"
- )
-
- (define_expand "sltu"
- [(set (match_operand:SI 0 "s_register_operand" "")
- (ltu:SI (match_dup 1) (const_int 0)))]
-- "TARGET_32BIT"
-+ "TARGET_32BIT && !TARGET_NO_COND_EXEC"
- "operands[1] = arm_gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1);"
- )
-
- (define_expand "sunordered"
- [(set (match_operand:SI 0 "s_register_operand" "")
- (unordered:SI (match_dup 1) (const_int 0)))]
-- "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
-+ "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP) && !TARGET_NO_COND_EXEC"
- "operands[1] = arm_gen_compare_reg (UNORDERED, arm_compare_op0,
- arm_compare_op1);"
- )
-@@ -7957,7 +8438,7 @@
- (define_expand "sordered"
- [(set (match_operand:SI 0 "s_register_operand" "")
- (ordered:SI (match_dup 1) (const_int 0)))]
-- "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
-+ "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP) && !TARGET_NO_COND_EXEC"
- "operands[1] = arm_gen_compare_reg (ORDERED, arm_compare_op0,
- arm_compare_op1);"
- )
-@@ -7965,7 +8446,7 @@
- (define_expand "sungt"
- [(set (match_operand:SI 0 "s_register_operand" "")
- (ungt:SI (match_dup 1) (const_int 0)))]
-- "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
-+ "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP) && !TARGET_NO_COND_EXEC"
- "operands[1] = arm_gen_compare_reg (UNGT, arm_compare_op0,
- arm_compare_op1);"
- )
-@@ -7973,7 +8454,7 @@
- (define_expand "sunge"
- [(set (match_operand:SI 0 "s_register_operand" "")
- (unge:SI (match_dup 1) (const_int 0)))]
-- "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
-+ "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP) && !TARGET_NO_COND_EXEC"
- "operands[1] = arm_gen_compare_reg (UNGE, arm_compare_op0,
- arm_compare_op1);"
- )
-@@ -7981,7 +8462,7 @@
- (define_expand "sunlt"
- [(set (match_operand:SI 0 "s_register_operand" "")
- (unlt:SI (match_dup 1) (const_int 0)))]
-- "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
-+ "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP) && !TARGET_NO_COND_EXEC"
- "operands[1] = arm_gen_compare_reg (UNLT, arm_compare_op0,
- arm_compare_op1);"
- )
-@@ -7989,7 +8470,7 @@
- (define_expand "sunle"
- [(set (match_operand:SI 0 "s_register_operand" "")
- (unle:SI (match_dup 1) (const_int 0)))]
-- "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
-+ "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP) && !TARGET_NO_COND_EXEC"
- "operands[1] = arm_gen_compare_reg (UNLE, arm_compare_op0,
- arm_compare_op1);"
- )
-@@ -8018,6 +8499,7 @@
- "TARGET_ARM"
- "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
- [(set_attr "conds" "use")
-+ (set_attr "insn" "mov")
- (set_attr "length" "8")]
- )
-
-@@ -8028,6 +8510,7 @@
- "TARGET_ARM"
- "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
- [(set_attr "conds" "use")
-+ (set_attr "insn" "mov")
- (set_attr "length" "8")]
- )
-
-@@ -8038,6 +8521,7 @@
- "TARGET_ARM"
- "mov%D1\\t%0, #0\;mvn%d1\\t%0, #1"
- [(set_attr "conds" "use")
-+ (set_attr "insn" "mov")
- (set_attr "length" "8")]
- )
-
-@@ -8241,7 +8725,7 @@
- (if_then_else:SI (match_operand 1 "arm_comparison_operator" "")
- (match_operand:SI 2 "arm_not_operand" "")
- (match_operand:SI 3 "arm_not_operand" "")))]
-- "TARGET_32BIT"
-+ "TARGET_32BIT && !TARGET_NO_COND_EXEC"
- "
- {
- enum rtx_code code = GET_CODE (operands[1]);
-@@ -8260,7 +8744,7 @@
- (if_then_else:SF (match_operand 1 "arm_comparison_operator" "")
- (match_operand:SF 2 "s_register_operand" "")
- (match_operand:SF 3 "nonmemory_operand" "")))]
-- "TARGET_32BIT && TARGET_HARD_FLOAT"
-+ "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_NO_COND_EXEC"
- "
- {
- enum rtx_code code = GET_CODE (operands[1]);
-@@ -8285,7 +8769,7 @@
- (if_then_else:DF (match_operand 1 "arm_comparison_operator" "")
- (match_operand:DF 2 "s_register_operand" "")
- (match_operand:DF 3 "arm_float_add_operand" "")))]
-- "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
-+ "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP_DOUBLE) && !TARGET_NO_COND_EXEC"
- "
- {
- enum rtx_code code = GET_CODE (operands[1]);
-@@ -8317,7 +8801,8 @@
- mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
- mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
- [(set_attr "length" "4,4,4,4,8,8,8,8")
-- (set_attr "conds" "use")]
-+ (set_attr "conds" "use")
-+ (set_attr "insn" "mov,mvn,mov,mvn,mov,mov,mvn,mvn")]
- )
-
- (define_insn "*movsfcc_soft_insn"
-@@ -8330,7 +8815,8 @@
- "@
- mov%D3\\t%0, %2
- mov%d3\\t%0, %1"
-- [(set_attr "conds" "use")]
-+ [(set_attr "conds" "use")
-+ (set_attr "insn" "mov")]
- )
-
- \f
-@@ -8733,7 +9219,7 @@
- [(match_operand 1 "cc_register" "") (const_int 0)])
- (return)
- (pc)))]
-- "TARGET_ARM && USE_RETURN_INSN (TRUE)"
-+ "TARGET_ARM && USE_RETURN_INSN (TRUE) && !TARGET_NO_COND_EXEC"
- "*
- {
- if (arm_ccfsm_state == 2)
-@@ -8754,7 +9240,7 @@
- [(match_operand 1 "cc_register" "") (const_int 0)])
- (pc)
- (return)))]
-- "TARGET_ARM && USE_RETURN_INSN (TRUE)"
-+ "TARGET_ARM && USE_RETURN_INSN (TRUE) && !TARGET_NO_COND_EXEC"
- "*
- {
- if (arm_ccfsm_state == 2)
-@@ -9072,7 +9558,11 @@
- (set_attr "shift" "4")
- (set (attr "type") (if_then_else (match_operand 5 "const_int_operand" "")
- (const_string "alu_shift")
-- (const_string "alu_shift_reg")))]
-+ (const_string "alu_shift_reg")))
-+ (set (attr "length") (if_then_else (and (eq_attr "type" "alu_shift_reg")
-+ (eq_attr "fix_janus" "yes"))
-+ (const_int 8)
-+ (const_int 4)))]
- )
-
- (define_split
-@@ -9110,7 +9600,11 @@
- (set_attr "shift" "4")
- (set (attr "type") (if_then_else (match_operand 5 "const_int_operand" "")
- (const_string "alu_shift")
-- (const_string "alu_shift_reg")))]
-+ (const_string "alu_shift_reg")))
-+ (set (attr "length") (if_then_else (and (eq_attr "type" "alu_shift_reg")
-+ (eq_attr "fix_janus" "yes"))
-+ (const_int 8)
-+ (const_int 4)))]
- )
-
- (define_insn "*arith_shiftsi_compare0_scratch"
-@@ -9128,7 +9622,11 @@
- (set_attr "shift" "4")
- (set (attr "type") (if_then_else (match_operand 5 "const_int_operand" "")
- (const_string "alu_shift")
-- (const_string "alu_shift_reg")))]
-+ (const_string "alu_shift_reg")))
-+ (set (attr "length") (if_then_else (and (eq_attr "type" "alu_shift_reg")
-+ (eq_attr "fix_janus" "yes"))
-+ (const_int 8)
-+ (const_int 4)))]
- )
-
- (define_insn "*sub_shiftsi"
-@@ -9143,7 +9641,11 @@
- (set_attr "shift" "3")
- (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
- (const_string "alu_shift")
-- (const_string "alu_shift_reg")))]
-+ (const_string "alu_shift_reg")))
-+ (set (attr "length") (if_then_else (and (eq_attr "type" "alu_shift_reg")
-+ (eq_attr "fix_janus" "yes"))
-+ (const_int 8)
-+ (const_int 4)))]
- )
-
- (define_insn "*sub_shiftsi_compare0"
-@@ -9163,7 +9665,11 @@
- (set_attr "shift" "3")
- (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
- (const_string "alu_shift")
-- (const_string "alu_shift_reg")))]
-+ (const_string "alu_shift_reg")))
-+ (set (attr "length") (if_then_else (and (eq_attr "type" "alu_shift_reg")
-+ (eq_attr "fix_janus" "yes"))
-+ (const_int 8)
-+ (const_int 4)))]
- )
-
- (define_insn "*sub_shiftsi_compare0_scratch"
-@@ -9181,7 +9687,11 @@
- (set_attr "shift" "3")
- (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
- (const_string "alu_shift")
-- (const_string "alu_shift_reg")))]
-+ (const_string "alu_shift_reg")))
-+ (set (attr "length") (if_then_else (and (eq_attr "type" "alu_shift_reg")
-+ (eq_attr "fix_janus" "yes"))
-+ (const_int 8)
-+ (const_int 4)))]
- )
-
- \f
-@@ -9194,6 +9704,7 @@
- "TARGET_ARM"
- "mov%D1\\t%0, #0\;and%d1\\t%0, %2, #1"
- [(set_attr "conds" "use")
-+ (set_attr "insn" "mov")
- (set_attr "length" "8")]
- )
-
-@@ -9207,6 +9718,7 @@
- orr%d2\\t%0, %1, #1
- mov%D2\\t%0, %1\;orr%d2\\t%0, %1, #1"
- [(set_attr "conds" "use")
-+ (set_attr "insn" "orr")
- (set_attr "length" "4,8")]
- )
-
-@@ -9216,7 +9728,7 @@
- [(match_operand:SI 2 "s_register_operand" "r,r")
- (match_operand:SI 3 "arm_add_operand" "rI,L")]))
- (clobber (reg:CC CC_REGNUM))]
-- "TARGET_ARM"
-+ "TARGET_ARM && !TARGET_NO_COND_EXEC"
- "*
- if (operands[3] == const0_rtx)
- {
-@@ -9271,6 +9783,7 @@
- return \"\";
- "
- [(set_attr "conds" "use")
-+ (set_attr "insn" "mov")
- (set_attr "length" "4,4,8")]
- )
-
-@@ -9282,7 +9795,7 @@
- (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
- (match_operand:SI 1 "s_register_operand" "0,?r")]))
- (clobber (reg:CC CC_REGNUM))]
-- "TARGET_ARM"
-+ "TARGET_ARM && !TARGET_NO_SINGLE_COND_EXEC"
- "*
- if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
- return \"%i5\\t%0, %1, %2, lsr #31\";
-@@ -9678,7 +10191,7 @@
- (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
- (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
- (clobber (reg:CC CC_REGNUM))]
-- "TARGET_ARM"
-+ "TARGET_ARM && !TARGET_NO_COND_EXEC"
- "*
- if (GET_CODE (operands[5]) == LT
- && (operands[4] == const0_rtx))
-@@ -9744,7 +10257,7 @@
- (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
- (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
- (clobber (reg:CC CC_REGNUM))]
-- "TARGET_ARM"
-+ "TARGET_ARM && !TARGET_NO_SINGLE_COND_EXEC"
- "#"
- [(set_attr "conds" "clob")
- (set_attr "length" "8,12")]
-@@ -9780,7 +10293,7 @@
- (match_operand:SI 2 "s_register_operand" "r,r")
- (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
- (clobber (reg:CC CC_REGNUM))]
-- "TARGET_ARM"
-+ "TARGET_ARM && !TARGET_NO_SINGLE_COND_EXEC"
- "#"
- [(set_attr "conds" "clob")
- (set_attr "length" "8,12")]
-@@ -9818,7 +10331,7 @@
- [(match_operand:SI 3 "s_register_operand" "r")
- (match_operand:SI 4 "arm_rhs_operand" "rI")])))
- (clobber (reg:CC CC_REGNUM))]
-- "TARGET_ARM"
-+ "TARGET_ARM && !TARGET_NO_SINGLE_COND_EXEC"
- "#"
- [(set_attr "conds" "clob")
- (set_attr "length" "12")]
-@@ -9968,7 +10481,7 @@
- (not:SI
- (match_operand:SI 2 "s_register_operand" "r,r"))))
- (clobber (reg:CC CC_REGNUM))]
-- "TARGET_ARM"
-+ "TARGET_ARM && !TARGET_NO_SINGLE_COND_EXEC"
- "#"
- [(set_attr "conds" "clob")
- (set_attr "length" "8,12")]
-@@ -9987,6 +10500,7 @@
- mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
- mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
- [(set_attr "conds" "use")
-+ (set_attr "insn" "mvn")
- (set_attr "length" "4,8,8")]
- )
-
-@@ -10000,7 +10514,7 @@
- (match_operand:SI 2 "s_register_operand" "r,r"))
- (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
- (clobber (reg:CC CC_REGNUM))]
-- "TARGET_ARM"
-+ "TARGET_ARM && !TARGET_NO_SINGLE_COND_EXEC"
- "#"
- [(set_attr "conds" "clob")
- (set_attr "length" "8,12")]
-@@ -10019,6 +10533,7 @@
- mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
- mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
- [(set_attr "conds" "use")
-+ (set_attr "insn" "mvn")
- (set_attr "length" "4,8,8")]
- )
-
-@@ -10033,7 +10548,7 @@
- (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
- (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
- (clobber (reg:CC CC_REGNUM))]
-- "TARGET_ARM"
-+ "TARGET_ARM && !TARGET_NO_SINGLE_COND_EXEC"
- "#"
- [(set_attr "conds" "clob")
- (set_attr "length" "8,12")]
-@@ -10055,10 +10570,23 @@
- mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
- [(set_attr "conds" "use")
- (set_attr "shift" "2")
-- (set_attr "length" "4,8,8")
-+ (set_attr "insn" "mov")
- (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
- (const_string "alu_shift")
-- (const_string "alu_shift_reg")))]
-+ (const_string "alu_shift_reg")))
-+ (set_attr_alternative "length"
-+ [(if_then_else (and (eq_attr "type" "alu_shift_reg")
-+ (eq_attr "fix_janus" "yes"))
-+ (const_int 8)
-+ (const_int 4))
-+ (if_then_else (and (eq_attr "type" "alu_shift_reg")
-+ (eq_attr "fix_janus" "yes"))
-+ (const_int 12)
-+ (const_int 8))
-+ (if_then_else (and (eq_attr "type" "alu_shift_reg")
-+ (eq_attr "fix_janus" "yes"))
-+ (const_int 12)
-+ (const_int 8))])]
- )
-
- (define_insn "*ifcompare_move_shift"
-@@ -10072,7 +10600,7 @@
- [(match_operand:SI 2 "s_register_operand" "r,r")
- (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
- (clobber (reg:CC CC_REGNUM))]
-- "TARGET_ARM"
-+ "TARGET_ARM && !TARGET_NO_SINGLE_COND_EXEC"
- "#"
- [(set_attr "conds" "clob")
- (set_attr "length" "8,12")]
-@@ -10094,10 +10622,24 @@
- mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
- [(set_attr "conds" "use")
- (set_attr "shift" "2")
-- (set_attr "length" "4,8,8")
-+ (set_attr "insn" "mov")
- (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
- (const_string "alu_shift")
-- (const_string "alu_shift_reg")))]
-+ (const_string "alu_shift_reg")))
-+ (set_attr_alternative "length"
-+ [(if_then_else (and (eq_attr "type" "alu_shift_reg")
-+ (eq_attr "fix_janus" "yes"))
-+ (const_int 8)
-+ (const_int 4))
-+ (if_then_else (and (eq_attr "type" "alu_shift_reg")
-+ (eq_attr "fix_janus" "yes"))
-+ (const_int 12)
-+ (const_int 8))
-+ (if_then_else (and (eq_attr "type" "alu_shift_reg")
-+ (eq_attr "fix_janus" "yes"))
-+ (const_int 12)
-+ (const_int 8))])
-+ (set_attr "insn" "mov")]
- )
-
- (define_insn "*ifcompare_shift_shift"
-@@ -10113,7 +10655,7 @@
- [(match_operand:SI 3 "s_register_operand" "r")
- (match_operand:SI 4 "arm_rhs_operand" "rM")])))
- (clobber (reg:CC CC_REGNUM))]
-- "TARGET_ARM"
-+ "TARGET_ARM && !TARGET_NO_SINGLE_COND_EXEC"
- "#"
- [(set_attr "conds" "clob")
- (set_attr "length" "12")]
-@@ -10134,12 +10676,16 @@
- "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
- [(set_attr "conds" "use")
- (set_attr "shift" "1")
-- (set_attr "length" "8")
-+ (set_attr "insn" "mov")
- (set (attr "type") (if_then_else
- (and (match_operand 2 "const_int_operand" "")
- (match_operand 4 "const_int_operand" ""))
- (const_string "alu_shift")
-- (const_string "alu_shift_reg")))]
-+ (const_string "alu_shift_reg")))
-+ (set (attr "length") (if_then_else (and (eq_attr "type" "alu_shift_reg")
-+ (eq_attr "fix_janus" "yes"))
-+ (const_int 16)
-+ (const_int 8)))]
- )
-
- (define_insn "*ifcompare_not_arith"
-@@ -10153,7 +10699,7 @@
- [(match_operand:SI 2 "s_register_operand" "r")
- (match_operand:SI 3 "arm_rhs_operand" "rI")])))
- (clobber (reg:CC CC_REGNUM))]
-- "TARGET_ARM"
-+ "TARGET_ARM && !TARGET_NO_SINGLE_COND_EXEC"
- "#"
- [(set_attr "conds" "clob")
- (set_attr "length" "12")]
-@@ -10171,6 +10717,7 @@
- "TARGET_ARM"
- "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
- [(set_attr "conds" "use")
-+ (set_attr "insn" "mvn")
- (set_attr "length" "8")]
- )
-
-@@ -10185,7 +10732,7 @@
- (match_operand:SI 3 "arm_rhs_operand" "rI")])
- (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
- (clobber (reg:CC CC_REGNUM))]
-- "TARGET_ARM"
-+ "TARGET_ARM && !TARGET_NO_SINGLE_COND_EXEC"
- "#"
- [(set_attr "conds" "clob")
- (set_attr "length" "12")]
-@@ -10203,6 +10750,7 @@
- "TARGET_ARM"
- "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
- [(set_attr "conds" "use")
-+ (set_attr "insn" "mvn")
- (set_attr "length" "8")]
- )
-
-@@ -10215,7 +10763,7 @@
- (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
- (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
- (clobber (reg:CC CC_REGNUM))]
-- "TARGET_ARM"
-+ "TARGET_ARM && !TARGET_NO_SINGLE_COND_EXEC"
- "#"
- [(set_attr "conds" "clob")
- (set_attr "length" "8,12")]
-@@ -10246,7 +10794,7 @@
- (match_operand:SI 1 "arm_not_operand" "0,?rIK")
- (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
- (clobber (reg:CC CC_REGNUM))]
-- "TARGET_ARM"
-+ "TARGET_ARM && !TARGET_NO_SINGLE_COND_EXEC"
- "#"
- [(set_attr "conds" "clob")
- (set_attr "length" "8,12")]
-@@ -10614,7 +11162,7 @@
- (match_dup 0)
- (match_operand 4 "" "")))
- (clobber (reg:CC CC_REGNUM))]
-- "TARGET_ARM && reload_completed"
-+ "TARGET_ARM && reload_completed && !TARGET_NO_SINGLE_COND_EXEC"
- [(set (match_dup 5) (match_dup 6))
- (cond_exec (match_dup 7)
- (set (match_dup 0) (match_dup 4)))]
-@@ -10642,7 +11190,7 @@
- (match_operand 4 "" "")
- (match_dup 0)))
- (clobber (reg:CC CC_REGNUM))]
-- "TARGET_ARM && reload_completed"
-+ "TARGET_ARM && reload_completed && !TARGET_NO_SINGLE_COND_EXEC"
- [(set (match_dup 5) (match_dup 6))
- (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
- (set (match_dup 0) (match_dup 4)))]
-@@ -10663,7 +11211,7 @@
- (match_operand 4 "" "")
- (match_operand 5 "" "")))
- (clobber (reg:CC CC_REGNUM))]
-- "TARGET_ARM && reload_completed"
-+ "TARGET_ARM && reload_completed && !TARGET_NO_SINGLE_COND_EXEC"
- [(set (match_dup 6) (match_dup 7))
- (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
- (set (match_dup 0) (match_dup 4)))
-@@ -10695,7 +11243,7 @@
- (not:SI
- (match_operand:SI 5 "s_register_operand" ""))))
- (clobber (reg:CC CC_REGNUM))]
-- "TARGET_ARM && reload_completed"
-+ "TARGET_ARM && reload_completed && !TARGET_NO_SINGLE_COND_EXEC"
- [(set (match_dup 6) (match_dup 7))
- (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
- (set (match_dup 0) (match_dup 4)))
-@@ -10730,6 +11278,7 @@
- mvn%D4\\t%0, %2
- mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
- [(set_attr "conds" "use")
-+ (set_attr "insn" "mvn")
- (set_attr "length" "4,8")]
- )
-
-@@ -10864,6 +11413,24 @@
- "
- )
-
-+(define_insn "align_16"
-+ [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN16)]
-+ "TARGET_EITHER"
-+ "*
-+ assemble_align (128);
-+ return \"\";
-+ "
-+)
-+
-+(define_insn "align_32"
-+ [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN32)]
-+ "TARGET_EITHER"
-+ "*
-+ assemble_align (256);
-+ return \"\";
-+ "
-+)
-+
- (define_insn "consttable_end"
- [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
- "TARGET_EITHER"
-@@ -10890,6 +11457,7 @@
- "TARGET_THUMB1"
- "*
- making_const_table = TRUE;
-+ gcc_assert (GET_MODE_CLASS (GET_MODE (operands[0])) != MODE_FLOAT);
- assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
- assemble_zeros (2);
- return \"\";
-@@ -10902,19 +11470,30 @@
- "TARGET_EITHER"
- "*
- {
-+ rtx x = operands[0];
- making_const_table = TRUE;
-- switch (GET_MODE_CLASS (GET_MODE (operands[0])))
-+ switch (GET_MODE_CLASS (GET_MODE (x)))
- {
- case MODE_FLOAT:
-- {
-- REAL_VALUE_TYPE r;
-- REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
-- assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
-- break;
-- }
-+ if (GET_MODE (x) == HFmode)
-+ arm_emit_fp16_const (x);
-+ else
-+ {
-+ REAL_VALUE_TYPE r;
-+ REAL_VALUE_FROM_CONST_DOUBLE (r, x);
-+ assemble_real (r, GET_MODE (x), BITS_PER_WORD);
-+ }
-+ break;
- default:
-- assemble_integer (operands[0], 4, BITS_PER_WORD, 1);
-- mark_symbol_refs_as_used (operands[0]);
-+ /* XXX: Sometimes gcc does something really dumb and ends up with
-+ a HIGH in a constant pool entry, usually because it's trying to
-+ load into a VFP register. We know this will always be used in
-+ combination with a LO_SUM which ignores the high bits, so just
-+ strip off the HIGH. */
-+ if (GET_CODE (x) == HIGH)
-+ x = XEXP (x, 0);
-+ assemble_integer (x, 4, BITS_PER_WORD, 1);
-+ mark_symbol_refs_as_used (x);
- break;
- }
- return \"\";
-@@ -11008,6 +11587,28 @@
- [(set_attr "predicable" "yes")
- (set_attr "insn" "clz")])
-
-+(define_insn "rbitsi2"
-+ [(set (match_operand:SI 0 "s_register_operand" "=r")
-+ (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
-+ "TARGET_32BIT && arm_arch_thumb2"
-+ "rbit%?\\t%0, %1"
-+ [(set_attr "predicable" "yes")
-+ (set_attr "insn" "clz")])
-+
-+(define_expand "ctzsi2"
-+ [(set (match_operand:SI 0 "s_register_operand" "")
-+ (ctz:SI (match_operand:SI 1 "s_register_operand" "")))]
-+ "TARGET_32BIT && arm_arch_thumb2"
-+ "
-+ {
-+ rtx tmp = gen_reg_rtx (SImode);
-+ emit_insn (gen_rbitsi2 (tmp, operands[1]));
-+ emit_insn (gen_clzsi2 (operands[0], tmp));
-+ }
-+ DONE;
-+ "
-+)
-+
- ;; V5E instructions.
-
- (define_insn "prefetch"
-@@ -11017,13 +11618,15 @@
- "TARGET_32BIT && arm_arch5e"
- "pld\\t%a0")
-
--;; General predication pattern
-+;; General predication pattern.
-+;; Conditional branches are available as both arm_cond_branch and
-+;; predicated arm_jump, so it doesn't matter if we disable the latter.
-
- (define_cond_exec
- [(match_operator 0 "arm_comparison_operator"
- [(match_operand 1 "cc_register" "")
- (const_int 0)])]
-- "TARGET_32BIT"
-+ "TARGET_32BIT && !TARGET_NO_SINGLE_COND_EXEC"
- ""
- )
-
---- a/gcc/config/arm/arm.opt
-+++ b/gcc/config/arm/arm.opt
-@@ -78,6 +78,10 @@ Specify if floating point hardware shoul
- mfp=
- Target RejectNegative Joined Undocumented Var(target_fpe_name)
-
-+mfp16-format=
-+Target RejectNegative Joined Var(target_fp16_format_name)
-+Specify the __fp16 floating-point format
-+
- ;; Now ignored.
- mfpe
- Target RejectNegative Mask(FPE) Undocumented
-@@ -93,6 +97,10 @@ mhard-float
- Target RejectNegative
- Alias for -mfloat-abi=hard
-
-+mfix-janus-2cc
-+Target Report Mask(FIX_JANUS)
-+Work around hardware errata for Avalent Janus 2CC cores.
-+
- mlittle-endian
- Target Report RejectNegative InverseMask(BIG_END)
- Assume target CPU is configured as little endian
-@@ -101,6 +109,10 @@ mlong-calls
- Target Report Mask(LONG_CALLS)
- Generate call insns as indirect calls, if necessary
-
-+mmarvell-div
-+Target Report Mask(MARVELL_DIV)
-+Generate hardware integer division instructions supported by some Marvell cores.
-+
- mpic-register=
- Target RejectNegative Joined Var(arm_pic_register_string)
- Specify the register to be used for PIC addressing
-@@ -157,6 +169,10 @@ mvectorize-with-neon-quad
- Target Report Mask(NEON_VECTORIZE_QUAD)
- Use Neon quad-word (rather than double-word) registers for vectorization
-
-+mlow-irq-latency
-+Target Report Var(low_irq_latency)
-+Try to reduce interrupt latency of the generated code
-+
- mword-relocations
- Target Report Var(target_word_relocations) Init(TARGET_DEFAULT_WORD_RELOCATIONS)
- Only generate absolute relocations on word sized values.
---- a/gcc/config/arm/arm_neon.h
-+++ b/gcc/config/arm/arm_neon.h
-@@ -36,7 +36,11 @@
- extern "C" {
- #endif
-
-+#if defined (__vxworks) && defined (_WRS_KERNEL)
-+#include <vxWorks.h>
-+#else
- #include <stdint.h>
-+#endif
-
- typedef __builtin_neon_qi int8x8_t __attribute__ ((__vector_size__ (8)));
- typedef __builtin_neon_hi int16x4_t __attribute__ ((__vector_size__ (8)));
-@@ -61,7 +65,7 @@ typedef __builtin_neon_uhi uint16x8_t __
- typedef __builtin_neon_usi uint32x4_t __attribute__ ((__vector_size__ (16)));
- typedef __builtin_neon_udi uint64x2_t __attribute__ ((__vector_size__ (16)));
-
--typedef __builtin_neon_sf float32_t;
-+typedef float float32_t;
- typedef __builtin_neon_poly8 poly8_t;
- typedef __builtin_neon_poly16 poly16_t;
-
-@@ -5085,7 +5089,7 @@ vset_lane_s32 (int32_t __a, int32x2_t __
- __extension__ static __inline float32x2_t __attribute__ ((__always_inline__))
- vset_lane_f32 (float32_t __a, float32x2_t __b, const int __c)
- {
-- return (float32x2_t)__builtin_neon_vset_lanev2sf (__a, __b, __c);
-+ return (float32x2_t)__builtin_neon_vset_lanev2sf ((__builtin_neon_sf) __a, __b, __c);
- }
-
- __extension__ static __inline uint8x8_t __attribute__ ((__always_inline__))
-@@ -5151,7 +5155,7 @@ vsetq_lane_s32 (int32_t __a, int32x4_t _
- __extension__ static __inline float32x4_t __attribute__ ((__always_inline__))
- vsetq_lane_f32 (float32_t __a, float32x4_t __b, const int __c)
- {
-- return (float32x4_t)__builtin_neon_vset_lanev4sf (__a, __b, __c);
-+ return (float32x4_t)__builtin_neon_vset_lanev4sf ((__builtin_neon_sf) __a, __b, __c);
- }
-
- __extension__ static __inline uint8x16_t __attribute__ ((__always_inline__))
-@@ -5283,7 +5287,7 @@ vdup_n_s32 (int32_t __a)
- __extension__ static __inline float32x2_t __attribute__ ((__always_inline__))
- vdup_n_f32 (float32_t __a)
- {
-- return (float32x2_t)__builtin_neon_vdup_nv2sf (__a);
-+ return (float32x2_t)__builtin_neon_vdup_nv2sf ((__builtin_neon_sf) __a);
- }
-
- __extension__ static __inline uint8x8_t __attribute__ ((__always_inline__))
-@@ -5349,7 +5353,7 @@ vdupq_n_s32 (int32_t __a)
- __extension__ static __inline float32x4_t __attribute__ ((__always_inline__))
- vdupq_n_f32 (float32_t __a)
- {
-- return (float32x4_t)__builtin_neon_vdup_nv4sf (__a);
-+ return (float32x4_t)__builtin_neon_vdup_nv4sf ((__builtin_neon_sf) __a);
- }
-
- __extension__ static __inline uint8x16_t __attribute__ ((__always_inline__))
-@@ -5415,7 +5419,7 @@ vmov_n_s32 (int32_t __a)
- __extension__ static __inline float32x2_t __attribute__ ((__always_inline__))
- vmov_n_f32 (float32_t __a)
- {
-- return (float32x2_t)__builtin_neon_vdup_nv2sf (__a);
-+ return (float32x2_t)__builtin_neon_vdup_nv2sf ((__builtin_neon_sf) __a);
- }
-
- __extension__ static __inline uint8x8_t __attribute__ ((__always_inline__))
-@@ -5481,7 +5485,7 @@ vmovq_n_s32 (int32_t __a)
- __extension__ static __inline float32x4_t __attribute__ ((__always_inline__))
- vmovq_n_f32 (float32_t __a)
- {
-- return (float32x4_t)__builtin_neon_vdup_nv4sf (__a);
-+ return (float32x4_t)__builtin_neon_vdup_nv4sf ((__builtin_neon_sf) __a);
- }
-
- __extension__ static __inline uint8x16_t __attribute__ ((__always_inline__))
-@@ -6591,7 +6595,7 @@ vmul_n_s32 (int32x2_t __a, int32_t __b)
- __extension__ static __inline float32x2_t __attribute__ ((__always_inline__))
- vmul_n_f32 (float32x2_t __a, float32_t __b)
- {
-- return (float32x2_t)__builtin_neon_vmul_nv2sf (__a, __b, 3);
-+ return (float32x2_t)__builtin_neon_vmul_nv2sf (__a, (__builtin_neon_sf) __b, 3);
- }
-
- __extension__ static __inline uint16x4_t __attribute__ ((__always_inline__))
-@@ -6621,7 +6625,7 @@ vmulq_n_s32 (int32x4_t __a, int32_t __b)
- __extension__ static __inline float32x4_t __attribute__ ((__always_inline__))
- vmulq_n_f32 (float32x4_t __a, float32_t __b)
- {
-- return (float32x4_t)__builtin_neon_vmul_nv4sf (__a, __b, 3);
-+ return (float32x4_t)__builtin_neon_vmul_nv4sf (__a, (__builtin_neon_sf) __b, 3);
- }
-
- __extension__ static __inline uint16x8_t __attribute__ ((__always_inline__))
-@@ -6735,7 +6739,7 @@ vmla_n_s32 (int32x2_t __a, int32x2_t __b
- __extension__ static __inline float32x2_t __attribute__ ((__always_inline__))
- vmla_n_f32 (float32x2_t __a, float32x2_t __b, float32_t __c)
- {
-- return (float32x2_t)__builtin_neon_vmla_nv2sf (__a, __b, __c, 3);
-+ return (float32x2_t)__builtin_neon_vmla_nv2sf (__a, __b, (__builtin_neon_sf) __c, 3);
- }
-
- __extension__ static __inline uint16x4_t __attribute__ ((__always_inline__))
-@@ -6765,7 +6769,7 @@ vmlaq_n_s32 (int32x4_t __a, int32x4_t __
- __extension__ static __inline float32x4_t __attribute__ ((__always_inline__))
- vmlaq_n_f32 (float32x4_t __a, float32x4_t __b, float32_t __c)
- {
-- return (float32x4_t)__builtin_neon_vmla_nv4sf (__a, __b, __c, 3);
-+ return (float32x4_t)__builtin_neon_vmla_nv4sf (__a, __b, (__builtin_neon_sf) __c, 3);
- }
-
- __extension__ static __inline uint16x8_t __attribute__ ((__always_inline__))
-@@ -6831,7 +6835,7 @@ vmls_n_s32 (int32x2_t __a, int32x2_t __b
- __extension__ static __inline float32x2_t __attribute__ ((__always_inline__))
- vmls_n_f32 (float32x2_t __a, float32x2_t __b, float32_t __c)
- {
-- return (float32x2_t)__builtin_neon_vmls_nv2sf (__a, __b, __c, 3);
-+ return (float32x2_t)__builtin_neon_vmls_nv2sf (__a, __b, (__builtin_neon_sf) __c, 3);
- }
-
- __extension__ static __inline uint16x4_t __attribute__ ((__always_inline__))
-@@ -6861,7 +6865,7 @@ vmlsq_n_s32 (int32x4_t __a, int32x4_t __
- __extension__ static __inline float32x4_t __attribute__ ((__always_inline__))
- vmlsq_n_f32 (float32x4_t __a, float32x4_t __b, float32_t __c)
- {
-- return (float32x4_t)__builtin_neon_vmls_nv4sf (__a, __b, __c, 3);
-+ return (float32x4_t)__builtin_neon_vmls_nv4sf (__a, __b, (__builtin_neon_sf) __c, 3);
- }
-
- __extension__ static __inline uint16x8_t __attribute__ ((__always_inline__))
-@@ -7851,7 +7855,7 @@ vld1_s64 (const int64_t * __a)
- __extension__ static __inline float32x2_t __attribute__ ((__always_inline__))
- vld1_f32 (const float32_t * __a)
- {
-- return (float32x2_t)__builtin_neon_vld1v2sf (__a);
-+ return (float32x2_t)__builtin_neon_vld1v2sf ((const __builtin_neon_sf *) __a);
- }
-
- __extension__ static __inline uint8x8_t __attribute__ ((__always_inline__))
-@@ -7917,7 +7921,7 @@ vld1q_s64 (const int64_t * __a)
- __extension__ static __inline float32x4_t __attribute__ ((__always_inline__))
- vld1q_f32 (const float32_t * __a)
- {
-- return (float32x4_t)__builtin_neon_vld1v4sf (__a);
-+ return (float32x4_t)__builtin_neon_vld1v4sf ((const __builtin_neon_sf *) __a);
- }
-
- __extension__ static __inline uint8x16_t __attribute__ ((__always_inline__))
-@@ -7977,7 +7981,7 @@ vld1_lane_s32 (const int32_t * __a, int3
- __extension__ static __inline float32x2_t __attribute__ ((__always_inline__))
- vld1_lane_f32 (const float32_t * __a, float32x2_t __b, const int __c)
- {
-- return (float32x2_t)__builtin_neon_vld1_lanev2sf (__a, __b, __c);
-+ return (float32x2_t)__builtin_neon_vld1_lanev2sf ((const __builtin_neon_sf *) __a, __b, __c);
- }
-
- __extension__ static __inline uint8x8_t __attribute__ ((__always_inline__))
-@@ -8043,7 +8047,7 @@ vld1q_lane_s32 (const int32_t * __a, int
- __extension__ static __inline float32x4_t __attribute__ ((__always_inline__))
- vld1q_lane_f32 (const float32_t * __a, float32x4_t __b, const int __c)
- {
-- return (float32x4_t)__builtin_neon_vld1_lanev4sf (__a, __b, __c);
-+ return (float32x4_t)__builtin_neon_vld1_lanev4sf ((const __builtin_neon_sf *) __a, __b, __c);
- }
-
- __extension__ static __inline uint8x16_t __attribute__ ((__always_inline__))
-@@ -8109,7 +8113,7 @@ vld1_dup_s32 (const int32_t * __a)
- __extension__ static __inline float32x2_t __attribute__ ((__always_inline__))
- vld1_dup_f32 (const float32_t * __a)
- {
-- return (float32x2_t)__builtin_neon_vld1_dupv2sf (__a);
-+ return (float32x2_t)__builtin_neon_vld1_dupv2sf ((const __builtin_neon_sf *) __a);
- }
-
- __extension__ static __inline uint8x8_t __attribute__ ((__always_inline__))
-@@ -8175,7 +8179,7 @@ vld1q_dup_s32 (const int32_t * __a)
- __extension__ static __inline float32x4_t __attribute__ ((__always_inline__))
- vld1q_dup_f32 (const float32_t * __a)
- {
-- return (float32x4_t)__builtin_neon_vld1_dupv4sf (__a);
-+ return (float32x4_t)__builtin_neon_vld1_dupv4sf ((const __builtin_neon_sf *) __a);
- }
-
- __extension__ static __inline uint8x16_t __attribute__ ((__always_inline__))
-@@ -8247,7 +8251,7 @@ vst1_s64 (int64_t * __a, int64x1_t __b)
- __extension__ static __inline void __attribute__ ((__always_inline__))
- vst1_f32 (float32_t * __a, float32x2_t __b)
- {
-- __builtin_neon_vst1v2sf (__a, __b);
-+ __builtin_neon_vst1v2sf ((__builtin_neon_sf *) __a, __b);
- }
-
- __extension__ static __inline void __attribute__ ((__always_inline__))
-@@ -8313,7 +8317,7 @@ vst1q_s64 (int64_t * __a, int64x2_t __b)
- __extension__ static __inline void __attribute__ ((__always_inline__))
- vst1q_f32 (float32_t * __a, float32x4_t __b)
- {
-- __builtin_neon_vst1v4sf (__a, __b);
-+ __builtin_neon_vst1v4sf ((__builtin_neon_sf *) __a, __b);
- }
-
- __extension__ static __inline void __attribute__ ((__always_inline__))
-@@ -8373,7 +8377,7 @@ vst1_lane_s32 (int32_t * __a, int32x2_t
- __extension__ static __inline void __attribute__ ((__always_inline__))
- vst1_lane_f32 (float32_t * __a, float32x2_t __b, const int __c)
- {
-- __builtin_neon_vst1_lanev2sf (__a, __b, __c);
-+ __builtin_neon_vst1_lanev2sf ((__builtin_neon_sf *) __a, __b, __c);
- }
-
- __extension__ static __inline void __attribute__ ((__always_inline__))
-@@ -8439,7 +8443,7 @@ vst1q_lane_s32 (int32_t * __a, int32x4_t
- __extension__ static __inline void __attribute__ ((__always_inline__))
- vst1q_lane_f32 (float32_t * __a, float32x4_t __b, const int __c)
- {
-- __builtin_neon_vst1_lanev4sf (__a, __b, __c);
-+ __builtin_neon_vst1_lanev4sf ((__builtin_neon_sf *) __a, __b, __c);
- }
-
- __extension__ static __inline void __attribute__ ((__always_inline__))
-@@ -8512,7 +8516,7 @@ __extension__ static __inline float32x2x
- vld2_f32 (const float32_t * __a)
- {
- union { float32x2x2_t __i; __builtin_neon_ti __o; } __rv;
-- __rv.__o = __builtin_neon_vld2v2sf (__a);
-+ __rv.__o = __builtin_neon_vld2v2sf ((const __builtin_neon_sf *) __a);
- return __rv.__i;
- }
-
-@@ -8600,7 +8604,7 @@ __extension__ static __inline float32x4x
- vld2q_f32 (const float32_t * __a)
- {
- union { float32x4x2_t __i; __builtin_neon_oi __o; } __rv;
-- __rv.__o = __builtin_neon_vld2v4sf (__a);
-+ __rv.__o = __builtin_neon_vld2v4sf ((const __builtin_neon_sf *) __a);
- return __rv.__i;
- }
-
-@@ -8676,7 +8680,7 @@ vld2_lane_f32 (const float32_t * __a, fl
- {
- union { float32x2x2_t __i; __builtin_neon_ti __o; } __bu = { __b };
- union { float32x2x2_t __i; __builtin_neon_ti __o; } __rv;
-- __rv.__o = __builtin_neon_vld2_lanev2sf (__a, __bu.__o, __c);
-+ __rv.__o = __builtin_neon_vld2_lanev2sf ((const __builtin_neon_sf *) __a, __bu.__o, __c);
- return __rv.__i;
- }
-
-@@ -8748,7 +8752,7 @@ vld2q_lane_f32 (const float32_t * __a, f
- {
- union { float32x4x2_t __i; __builtin_neon_oi __o; } __bu = { __b };
- union { float32x4x2_t __i; __builtin_neon_oi __o; } __rv;
-- __rv.__o = __builtin_neon_vld2_lanev4sf (__a, __bu.__o, __c);
-+ __rv.__o = __builtin_neon_vld2_lanev4sf ((const __builtin_neon_sf *) __a, __bu.__o, __c);
- return __rv.__i;
- }
-
-@@ -8807,7 +8811,7 @@ __extension__ static __inline float32x2x
- vld2_dup_f32 (const float32_t * __a)
- {
- union { float32x2x2_t __i; __builtin_neon_ti __o; } __rv;
-- __rv.__o = __builtin_neon_vld2_dupv2sf (__a);
-+ __rv.__o = __builtin_neon_vld2_dupv2sf ((const __builtin_neon_sf *) __a);
- return __rv.__i;
- }
-
-@@ -8892,7 +8896,7 @@ __extension__ static __inline void __att
- vst2_f32 (float32_t * __a, float32x2x2_t __b)
- {
- union { float32x2x2_t __i; __builtin_neon_ti __o; } __bu = { __b };
-- __builtin_neon_vst2v2sf (__a, __bu.__o);
-+ __builtin_neon_vst2v2sf ((__builtin_neon_sf *) __a, __bu.__o);
- }
-
- __extension__ static __inline void __attribute__ ((__always_inline__))
-@@ -8969,7 +8973,7 @@ __extension__ static __inline void __att
- vst2q_f32 (float32_t * __a, float32x4x2_t __b)
- {
- union { float32x4x2_t __i; __builtin_neon_oi __o; } __bu = { __b };
-- __builtin_neon_vst2v4sf (__a, __bu.__o);
-+ __builtin_neon_vst2v4sf ((__builtin_neon_sf *) __a, __bu.__o);
- }
-
- __extension__ static __inline void __attribute__ ((__always_inline__))
-@@ -9032,7 +9036,7 @@ __extension__ static __inline void __att
- vst2_lane_f32 (float32_t * __a, float32x2x2_t __b, const int __c)
- {
- union { float32x2x2_t __i; __builtin_neon_ti __o; } __bu = { __b };
-- __builtin_neon_vst2_lanev2sf (__a, __bu.__o, __c);
-+ __builtin_neon_vst2_lanev2sf ((__builtin_neon_sf *) __a, __bu.__o, __c);
- }
-
- __extension__ static __inline void __attribute__ ((__always_inline__))
-@@ -9088,7 +9092,7 @@ __extension__ static __inline void __att
- vst2q_lane_f32 (float32_t * __a, float32x4x2_t __b, const int __c)
- {
- union { float32x4x2_t __i; __builtin_neon_oi __o; } __bu = { __b };
-- __builtin_neon_vst2_lanev4sf (__a, __bu.__o, __c);
-+ __builtin_neon_vst2_lanev4sf ((__builtin_neon_sf *) __a, __bu.__o, __c);
- }
-
- __extension__ static __inline void __attribute__ ((__always_inline__))
-@@ -9140,7 +9144,7 @@ __extension__ static __inline float32x2x
- vld3_f32 (const float32_t * __a)
- {
- union { float32x2x3_t __i; __builtin_neon_ei __o; } __rv;
-- __rv.__o = __builtin_neon_vld3v2sf (__a);
-+ __rv.__o = __builtin_neon_vld3v2sf ((const __builtin_neon_sf *) __a);
- return __rv.__i;
- }
-
-@@ -9228,7 +9232,7 @@ __extension__ static __inline float32x4x
- vld3q_f32 (const float32_t * __a)
- {
- union { float32x4x3_t __i; __builtin_neon_ci __o; } __rv;
-- __rv.__o = __builtin_neon_vld3v4sf (__a);
-+ __rv.__o = __builtin_neon_vld3v4sf ((const __builtin_neon_sf *) __a);
- return __rv.__i;
- }
-
-@@ -9304,7 +9308,7 @@ vld3_lane_f32 (const float32_t * __a, fl
- {
- union { float32x2x3_t __i; __builtin_neon_ei __o; } __bu = { __b };
- union { float32x2x3_t __i; __builtin_neon_ei __o; } __rv;
-- __rv.__o = __builtin_neon_vld3_lanev2sf (__a, __bu.__o, __c);
-+ __rv.__o = __builtin_neon_vld3_lanev2sf ((const __builtin_neon_sf *) __a, __bu.__o, __c);
- return __rv.__i;
- }
-
-@@ -9376,7 +9380,7 @@ vld3q_lane_f32 (const float32_t * __a, f
- {
- union { float32x4x3_t __i; __builtin_neon_ci __o; } __bu = { __b };
- union { float32x4x3_t __i; __builtin_neon_ci __o; } __rv;
-- __rv.__o = __builtin_neon_vld3_lanev4sf (__a, __bu.__o, __c);
-+ __rv.__o = __builtin_neon_vld3_lanev4sf ((const __builtin_neon_sf *) __a, __bu.__o, __c);
- return __rv.__i;
- }
-
-@@ -9435,7 +9439,7 @@ __extension__ static __inline float32x2x
- vld3_dup_f32 (const float32_t * __a)
- {
- union { float32x2x3_t __i; __builtin_neon_ei __o; } __rv;
-- __rv.__o = __builtin_neon_vld3_dupv2sf (__a);
-+ __rv.__o = __builtin_neon_vld3_dupv2sf ((const __builtin_neon_sf *) __a);
- return __rv.__i;
- }
-
-@@ -9520,7 +9524,7 @@ __extension__ static __inline void __att
- vst3_f32 (float32_t * __a, float32x2x3_t __b)
- {
- union { float32x2x3_t __i; __builtin_neon_ei __o; } __bu = { __b };
-- __builtin_neon_vst3v2sf (__a, __bu.__o);
-+ __builtin_neon_vst3v2sf ((__builtin_neon_sf *) __a, __bu.__o);
- }
-
- __extension__ static __inline void __attribute__ ((__always_inline__))
-@@ -9597,7 +9601,7 @@ __extension__ static __inline void __att
- vst3q_f32 (float32_t * __a, float32x4x3_t __b)
- {
- union { float32x4x3_t __i; __builtin_neon_ci __o; } __bu = { __b };
-- __builtin_neon_vst3v4sf (__a, __bu.__o);
-+ __builtin_neon_vst3v4sf ((__builtin_neon_sf *) __a, __bu.__o);
- }
-
- __extension__ static __inline void __attribute__ ((__always_inline__))
-@@ -9660,7 +9664,7 @@ __extension__ static __inline void __att
- vst3_lane_f32 (float32_t * __a, float32x2x3_t __b, const int __c)
- {
- union { float32x2x3_t __i; __builtin_neon_ei __o; } __bu = { __b };
-- __builtin_neon_vst3_lanev2sf (__a, __bu.__o, __c);
-+ __builtin_neon_vst3_lanev2sf ((__builtin_neon_sf *) __a, __bu.__o, __c);
- }
-
- __extension__ static __inline void __attribute__ ((__always_inline__))
-@@ -9716,7 +9720,7 @@ __extension__ static __inline void __att
- vst3q_lane_f32 (float32_t * __a, float32x4x3_t __b, const int __c)
- {
- union { float32x4x3_t __i; __builtin_neon_ci __o; } __bu = { __b };
-- __builtin_neon_vst3_lanev4sf (__a, __bu.__o, __c);
-+ __builtin_neon_vst3_lanev4sf ((__builtin_neon_sf *) __a, __bu.__o, __c);
- }
-
- __extension__ static __inline void __attribute__ ((__always_inline__))
-@@ -9768,7 +9772,7 @@ __extension__ static __inline float32x2x
- vld4_f32 (const float32_t * __a)
- {
- union { float32x2x4_t __i; __builtin_neon_oi __o; } __rv;
-- __rv.__o = __builtin_neon_vld4v2sf (__a);
-+ __rv.__o = __builtin_neon_vld4v2sf ((const __builtin_neon_sf *) __a);
- return __rv.__i;
- }
-
-@@ -9856,7 +9860,7 @@ __extension__ static __inline float32x4x
- vld4q_f32 (const float32_t * __a)
- {
- union { float32x4x4_t __i; __builtin_neon_xi __o; } __rv;
-- __rv.__o = __builtin_neon_vld4v4sf (__a);
-+ __rv.__o = __builtin_neon_vld4v4sf ((const __builtin_neon_sf *) __a);
- return __rv.__i;
- }
-
-@@ -9932,7 +9936,7 @@ vld4_lane_f32 (const float32_t * __a, fl
- {
- union { float32x2x4_t __i; __builtin_neon_oi __o; } __bu = { __b };
- union { float32x2x4_t __i; __builtin_neon_oi __o; } __rv;
-- __rv.__o = __builtin_neon_vld4_lanev2sf (__a, __bu.__o, __c);
-+ __rv.__o = __builtin_neon_vld4_lanev2sf ((const __builtin_neon_sf *) __a, __bu.__o, __c);
- return __rv.__i;
- }
-
-@@ -10004,7 +10008,7 @@ vld4q_lane_f32 (const float32_t * __a, f
- {
- union { float32x4x4_t __i; __builtin_neon_xi __o; } __bu = { __b };
- union { float32x4x4_t __i; __builtin_neon_xi __o; } __rv;
-- __rv.__o = __builtin_neon_vld4_lanev4sf (__a, __bu.__o, __c);
-+ __rv.__o = __builtin_neon_vld4_lanev4sf ((const __builtin_neon_sf *) __a, __bu.__o, __c);
- return __rv.__i;
- }
-
-@@ -10063,7 +10067,7 @@ __extension__ static __inline float32x2x
- vld4_dup_f32 (const float32_t * __a)
- {
- union { float32x2x4_t __i; __builtin_neon_oi __o; } __rv;
-- __rv.__o = __builtin_neon_vld4_dupv2sf (__a);
-+ __rv.__o = __builtin_neon_vld4_dupv2sf ((const __builtin_neon_sf *) __a);
- return __rv.__i;
- }
-
-@@ -10148,7 +10152,7 @@ __extension__ static __inline void __att
- vst4_f32 (float32_t * __a, float32x2x4_t __b)
- {
- union { float32x2x4_t __i; __builtin_neon_oi __o; } __bu = { __b };
-- __builtin_neon_vst4v2sf (__a, __bu.__o);
-+ __builtin_neon_vst4v2sf ((__builtin_neon_sf *) __a, __bu.__o);
- }
-
- __extension__ static __inline void __attribute__ ((__always_inline__))
-@@ -10225,7 +10229,7 @@ __extension__ static __inline void __att
- vst4q_f32 (float32_t * __a, float32x4x4_t __b)
- {
- union { float32x4x4_t __i; __builtin_neon_xi __o; } __bu = { __b };
-- __builtin_neon_vst4v4sf (__a, __bu.__o);
-+ __builtin_neon_vst4v4sf ((__builtin_neon_sf *) __a, __bu.__o);
- }
-
- __extension__ static __inline void __attribute__ ((__always_inline__))
-@@ -10288,7 +10292,7 @@ __extension__ static __inline void __att
- vst4_lane_f32 (float32_t * __a, float32x2x4_t __b, const int __c)
- {
- union { float32x2x4_t __i; __builtin_neon_oi __o; } __bu = { __b };
-- __builtin_neon_vst4_lanev2sf (__a, __bu.__o, __c);
-+ __builtin_neon_vst4_lanev2sf ((__builtin_neon_sf *) __a, __bu.__o, __c);
- }
-
- __extension__ static __inline void __attribute__ ((__always_inline__))
-@@ -10344,7 +10348,7 @@ __extension__ static __inline void __att
- vst4q_lane_f32 (float32_t * __a, float32x4x4_t __b, const int __c)
- {
- union { float32x4x4_t __i; __builtin_neon_xi __o; } __bu = { __b };
-- __builtin_neon_vst4_lanev4sf (__a, __bu.__o, __c);
-+ __builtin_neon_vst4_lanev4sf ((__builtin_neon_sf *) __a, __bu.__o, __c);
- }
-
- __extension__ static __inline void __attribute__ ((__always_inline__))
---- a/gcc/config/arm/bpabi-v6m.S
-+++ b/gcc/config/arm/bpabi-v6m.S
-@@ -69,9 +69,52 @@ FUNC_START aeabi_ulcmp
-
- #endif /* L_aeabi_ulcmp */
-
-+.macro test_div_by_zero signed
-+ cmp yyh, #0
-+ bne 7f
-+ cmp yyl, #0
-+ bne 7f
-+ cmp xxh, #0
-+ bne 2f
-+ cmp xxl, #0
-+2:
-+ .ifc \signed, unsigned
-+ beq 3f
-+ mov xxh, #0
-+ mvn xxh, xxh @ 0xffffffff
-+ mov xxl, xxh
-+3:
-+ .else
-+ beq 5f
-+ blt 6f
-+ mov xxl, #0
-+ mvn xxl, xxl @ 0xffffffff
-+ lsr xxh, xxl, #1 @ 0x7fffffff
-+ b 5f
-+6: mov xxh, #0x80
-+ lsl xxh, xxh, #24 @ 0x80000000
-+ mov xxl, #0
-+5:
-+ .endif
-+ @ tailcalls are tricky on v6-m.
-+ push {r0, r1, r2}
-+ ldr r0, 1f
-+ adr r1, 1f
-+ add r0, r1
-+ str r0, [sp, #8]
-+ @ We know we are not on armv4t, so pop pc is safe.
-+ pop {r0, r1, pc}
-+ .align 2
-+1:
-+ .word __aeabi_ldiv0 - 1b
-+7:
-+.endm
-+
- #ifdef L_aeabi_ldivmod
-
- FUNC_START aeabi_ldivmod
-+ test_div_by_zero signed
-+
- push {r0, r1}
- mov r0, sp
- push {r0, lr}
-@@ -89,6 +132,8 @@ FUNC_START aeabi_ldivmod
- #ifdef L_aeabi_uldivmod
-
- FUNC_START aeabi_uldivmod
-+ test_div_by_zero unsigned
-+
- push {r0, r1}
- mov r0, sp
- push {r0, lr}
---- a/gcc/config/arm/bpabi.S
-+++ b/gcc/config/arm/bpabi.S
-@@ -64,20 +64,69 @@ ARM_FUNC_START aeabi_ulcmp
-
- #endif /* L_aeabi_ulcmp */
-
-+.macro test_div_by_zero signed
-+/* Tail-call to divide-by-zero handlers which may be overridden by the user,
-+ so unwinding works properly. */
-+#if defined(__thumb2__)
-+ cbnz yyh, 1f
-+ cbnz yyl, 1f
-+ cmp xxh, #0
-+ do_it eq
-+ cmpeq xxl, #0
-+ .ifc \signed, unsigned
-+ beq 2f
-+ mov xxh, #0xffffffff
-+ mov xxl, xxh
-+2:
-+ .else
-+ do_it lt, t
-+ movlt xxl, #0
-+ movlt xxh, #0x80000000
-+ do_it gt, t
-+ movgt xxh, #0x7fffffff
-+ movgt xxl, #0xffffffff
-+ .endif
-+ b SYM (__aeabi_ldiv0) __PLT__
-+1:
-+#else
-+ /* Note: Thumb-1 code calls via an ARM shim on processors which
-+ support ARM mode. */
-+ cmp yyh, #0
-+ cmpeq yyl, #0
-+ bne 2f
-+ cmp xxh, #0
-+ cmpeq xxl, #0
-+ .ifc \signed, unsigned
-+ movne xxh, #0xffffffff
-+ movne xxl, #0xffffffff
-+ .else
-+ movlt xxh, #0x80000000
-+ movlt xxl, #0
-+ movgt xxh, #0x7fffffff
-+ movgt xxl, #0xffffffff
-+ .endif
-+ b SYM (__aeabi_ldiv0) __PLT__
-+2:
-+#endif
-+.endm
-+
- #ifdef L_aeabi_ldivmod
-
- ARM_FUNC_START aeabi_ldivmod
-+ test_div_by_zero signed
-+
- sub sp, sp, #8
--#if defined(__thumb2__)
-+/* Low latency and Thumb-2 do_push implementations can't push sp directly. */
-+#if defined(__thumb2__) || defined(__irq_low_latency__)
- mov ip, sp
-- push {ip, lr}
-+ do_push (ip, lr)
- #else
-- do_push {sp, lr}
-+ stmfd sp!, {sp, lr}
- #endif
- bl SYM(__gnu_ldivmod_helper) __PLT__
- ldr lr, [sp, #4]
- add sp, sp, #8
-- do_pop {r2, r3}
-+ do_pop (r2, r3)
- RET
-
- #endif /* L_aeabi_ldivmod */
-@@ -85,17 +134,20 @@ ARM_FUNC_START aeabi_ldivmod
- #ifdef L_aeabi_uldivmod
-
- ARM_FUNC_START aeabi_uldivmod
-+ test_div_by_zero unsigned
-+
- sub sp, sp, #8
--#if defined(__thumb2__)
-+/* Low latency and Thumb-2 do_push implementations can't push sp directly. */
-+#if defined(__thumb2__) || defined(__irq_low_latency__)
- mov ip, sp
-- push {ip, lr}
-+ do_push (ip, lr)
- #else
-- do_push {sp, lr}
-+ stmfd sp!, {sp, lr}
- #endif
- bl SYM(__gnu_uldivmod_helper) __PLT__
- ldr lr, [sp, #4]
- add sp, sp, #8
-- do_pop {r2, r3}
-+ do_pop (r2, r3)
- RET
-
- #endif /* L_aeabi_divmod */
---- a/gcc/config/arm/bpabi.h
-+++ b/gcc/config/arm/bpabi.h
-@@ -30,7 +30,7 @@
-
- /* Section 4.1 of the AAPCS requires the use of VFP format. */
- #undef FPUTYPE_DEFAULT
--#define FPUTYPE_DEFAULT FPUTYPE_VFP
-+#define FPUTYPE_DEFAULT "vfp"
-
- /* TARGET_BIG_ENDIAN_DEFAULT is set in
- config.gcc for big endian configurations. */
-@@ -53,6 +53,8 @@
-
- #define TARGET_FIX_V4BX_SPEC " %{mcpu=arm8|mcpu=arm810|mcpu=strongarm*|march=armv4:--fix-v4bx}"
-
-+#define BE8_LINK_SPEC " %{mbig-endian:%{march=armv7-a|mcpu=cortex-a5|mcpu=cortex-a8|mcpu=cortex-a9:%{!r:--be8}}}"
-+
- /* Tell the assembler to build BPABI binaries. */
- #undef SUBTARGET_EXTRA_ASM_SPEC
- #define SUBTARGET_EXTRA_ASM_SPEC "%{mabi=apcs-gnu|mabi=atpcs:-meabi=gnu;:-meabi=5}" TARGET_FIX_V4BX_SPEC
-@@ -65,7 +67,7 @@
- #define BPABI_LINK_SPEC \
- "%{mbig-endian:-EB} %{mlittle-endian:-EL} " \
- "%{static:-Bstatic} %{shared:-shared} %{symbolic:-Bsymbolic} " \
-- "-X" SUBTARGET_EXTRA_LINK_SPEC TARGET_FIX_V4BX_SPEC
-+ "-X" SUBTARGET_EXTRA_LINK_SPEC TARGET_FIX_V4BX_SPEC BE8_LINK_SPEC
-
- #undef LINK_SPEC
- #define LINK_SPEC BPABI_LINK_SPEC
-@@ -90,16 +92,22 @@
- #define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (muldi3, lmul)
- #endif
- #ifdef L_fixdfdi
--#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (fixdfdi, d2lz)
-+#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (fixdfdi, d2lz) \
-+ extern DWtype __fixdfdi (DFtype) __attribute__((pcs("aapcs"))); \
-+ extern UDWtype __fixunsdfdi (DFtype) __asm__("__aeabi_d2ulz") __attribute__((pcs("aapcs")));
- #endif
- #ifdef L_fixunsdfdi
--#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (fixunsdfdi, d2ulz)
-+#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (fixunsdfdi, d2ulz) \
-+ extern UDWtype __fixunsdfdi (DFtype) __attribute__((pcs("aapcs")));
- #endif
- #ifdef L_fixsfdi
--#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (fixsfdi, f2lz)
-+#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (fixsfdi, f2lz) \
-+ extern DWtype __fixsfdi (SFtype) __attribute__((pcs("aapcs"))); \
-+ extern UDWtype __fixunssfdi (SFtype) __asm__("__aeabi_f2ulz") __attribute__((pcs("aapcs")));
- #endif
- #ifdef L_fixunssfdi
--#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (fixunssfdi, f2ulz)
-+#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (fixunssfdi, f2ulz) \
-+ extern UDWtype __fixunssfdi (SFtype) __attribute__((pcs("aapcs")));
- #endif
- #ifdef L_floatdidf
- #define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (floatdidf, l2d)
---- a/gcc/config/arm/constraints.md
-+++ b/gcc/config/arm/constraints.md
-@@ -25,14 +25,15 @@
- ;; In ARM state, 'l' is an alias for 'r'
-
- ;; The following normal constraints have been used:
--;; in ARM/Thumb-2 state: G, H, I, J, K, L, M
-+;; in ARM/Thumb-2 state: G, H, I, j, J, K, L, M
- ;; in Thumb-1 state: I, J, K, L, M, N, O
-
- ;; The following multi-letter normal constraints have been used:
--;; in ARM/Thumb-2 state: Da, Db, Dc, Dn, Dl, DL, Dv
-+;; in ARM/Thumb-2 state: Da, Db, Dc, Dn, Dl, DL, Dv, Dy
-+;; in Thumb-1 state: Pa, Pb
-
- ;; The following memory constraints have been used:
--;; in ARM/Thumb-2 state: Q, Ut, Uv, Uy, Un, Us
-+;; in ARM/Thumb-2 state: Q, Ut, Uv, Uy, Un, Um, Us
- ;; in ARM state: Uq
-
-
-@@ -65,6 +66,13 @@
- (define_register_constraint "h" "TARGET_THUMB ? HI_REGS : NO_REGS"
- "In Thumb state the core registers @code{r8}-@code{r15}.")
-
-+(define_constraint "j"
-+ "A constant suitable for a MOVW instruction. (ARM/Thumb-2)"
-+ (and (match_test "TARGET_32BIT && arm_arch_thumb2")
-+ (ior (match_code "high")
-+ (and (match_code "const_int")
-+ (match_test "(ival & 0xffff0000) == 0")))))
-+
- (define_register_constraint "k" "STACK_REG"
- "@internal The stack register.")
-
-@@ -116,11 +124,9 @@
- : ((ival >= 0 && ival <= 1020) && ((ival & 3) == 0))")))
-
- (define_constraint "N"
-- "In ARM/Thumb-2 state a constant suitable for a MOVW instruction.
-- In Thumb-1 state a constant in the range 0-31."
-+ "Thumb-1 state a constant in the range 0-31."
- (and (match_code "const_int")
-- (match_test "TARGET_32BIT ? arm_arch_thumb2 && ((ival & 0xffff0000) == 0)
-- : (ival >= 0 && ival <= 31)")))
-+ (match_test "!TARGET_32BIT && (ival >= 0 && ival <= 31)")))
-
- (define_constraint "O"
- "In Thumb-1 state a constant that is a multiple of 4 in the range
-@@ -129,6 +135,18 @@
- (match_test "TARGET_THUMB1 && ival >= -508 && ival <= 508
- && ((ival & 3) == 0)")))
-
-+(define_constraint "Pa"
-+ "@internal In Thumb-1 state a constant in the range -510 to +510"
-+ (and (match_code "const_int")
-+ (match_test "TARGET_THUMB1 && ival >= -510 && ival <= 510
-+ && (ival > 255 || ival < -255)")))
-+
-+(define_constraint "Pb"
-+ "@internal In Thumb-1 state a constant in the range -262 to +262"
-+ (and (match_code "const_int")
-+ (match_test "TARGET_THUMB1 && ival >= -262 && ival <= 262
-+ && (ival > 255 || ival < -255)")))
-+
- (define_constraint "G"
- "In ARM/Thumb-2 state a valid FPA immediate constant."
- (and (match_code "const_double")
-@@ -189,10 +207,17 @@
- (define_constraint "Dv"
- "@internal
- In ARM/Thumb-2 state a const_double which can be used with a VFP fconsts
-- or fconstd instruction."
-+ instruction."
- (and (match_code "const_double")
- (match_test "TARGET_32BIT && vfp3_const_double_rtx (op)")))
-
-+(define_constraint "Dy"
-+ "@internal
-+ In ARM/Thumb-2 state a const_double which can be used with a VFP fconstd
-+ instruction."
-+ (and (match_code "const_double")
-+ (match_test "TARGET_32BIT && TARGET_VFP_DOUBLE && vfp3_const_double_rtx (op)")))
-+
- (define_memory_constraint "Ut"
- "@internal
- In ARM/Thumb-2 state an address valid for loading/storing opaque structure
-@@ -214,17 +239,24 @@
-
- (define_memory_constraint "Un"
- "@internal
-+ In ARM/Thumb-2 state a valid address for Neon doubleword vector
-+ load/store instructions."
-+ (and (match_code "mem")
-+ (match_test "TARGET_32BIT && neon_vector_mem_operand (op, 0)")))
-+
-+(define_memory_constraint "Um"
-+ "@internal
- In ARM/Thumb-2 state a valid address for Neon element and structure
- load/store instructions."
- (and (match_code "mem")
-- (match_test "TARGET_32BIT && neon_vector_mem_operand (op, FALSE)")))
-+ (match_test "TARGET_32BIT && neon_vector_mem_operand (op, 2)")))
-
- (define_memory_constraint "Us"
- "@internal
- In ARM/Thumb-2 state a valid address for non-offset loads/stores of
- quad-word values in four ARM registers."
- (and (match_code "mem")
-- (match_test "TARGET_32BIT && neon_vector_mem_operand (op, TRUE)")))
-+ (match_test "TARGET_32BIT && neon_vector_mem_operand (op, 1)")))
-
- (define_memory_constraint "Uq"
- "@internal
---- /dev/null
-+++ b/gcc/config/arm/fp16.c
-@@ -0,0 +1,145 @@
-+/* Half-float conversion routines.
-+
-+ Copyright (C) 2008, 2009 Free Software Foundation, Inc.
-+ Contributed by CodeSourcery.
-+
-+ This file is free software; you can redistribute it and/or modify it
-+ under the terms of the GNU General Public License as published by the
-+ Free Software Foundation; either version 3, or (at your option) any
-+ later version.
-+
-+ This file is distributed in the hope that it will be useful, but
-+ WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ General Public License for more details.
-+
-+ Under Section 7 of GPL version 3, you are granted additional
-+ permissions described in the GCC Runtime Library Exception, version
-+ 3.1, as published by the Free Software Foundation.
-+
-+ You should have received a copy of the GNU General Public License and
-+ a copy of the GCC Runtime Library Exception along with this program;
-+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
-+ <http://www.gnu.org/licenses/>. */
-+
-+static inline unsigned short
-+__gnu_f2h_internal(unsigned int a, int ieee)
-+{
-+ unsigned short sign = (a >> 16) & 0x8000;
-+ int aexp = (a >> 23) & 0xff;
-+ unsigned int mantissa = a & 0x007fffff;
-+ unsigned int mask;
-+ unsigned int increment;
-+
-+ if (aexp == 0xff)
-+ {
-+ if (!ieee)
-+ return sign;
-+ return sign | 0x7e00 | (mantissa >> 13);
-+ }
-+
-+ if (aexp == 0 && mantissa == 0)
-+ return sign;
-+
-+ aexp -= 127;
-+
-+ /* Decimal point between bits 22 and 23. */
-+ mantissa |= 0x00800000;
-+ if (aexp < -14)
-+ {
-+ mask = 0x007fffff;
-+ if (aexp < -25)
-+ aexp = -26;
-+ else if (aexp != -25)
-+ mask >>= 24 + aexp;
-+ }
-+ else
-+ mask = 0x00001fff;
-+
-+ /* Round. */
-+ if (mantissa & mask)
-+ {
-+ increment = (mask + 1) >> 1;
-+ if ((mantissa & mask) == increment)
-+ increment = mantissa & (increment << 1);
-+ mantissa += increment;
-+ if (mantissa >= 0x01000000)
-+ {
-+ mantissa >>= 1;
-+ aexp++;
-+ }
-+ }
-+
-+ if (ieee)
-+ {
-+ if (aexp > 15)
-+ return sign | 0x7c00;
-+ }
-+ else
-+ {
-+ if (aexp > 16)
-+ return sign | 0x7fff;
-+ }
-+
-+ if (aexp < -24)
-+ return sign;
-+
-+ if (aexp < -14)
-+ {
-+ mantissa >>= -14 - aexp;
-+ aexp = -14;
-+ }
-+
-+ /* We leave the leading 1 in the mantissa, and subtract one
-+ from the exponent bias to compensate. */
-+ return sign | (((aexp + 14) << 10) + (mantissa >> 13));
-+}
-+
-+unsigned int
-+__gnu_h2f_internal(unsigned short a, int ieee)
-+{
-+ unsigned int sign = (unsigned int)(a & 0x8000) << 16;
-+ int aexp = (a >> 10) & 0x1f;
-+ unsigned int mantissa = a & 0x3ff;
-+
-+ if (aexp == 0x1f && ieee)
-+ return sign | 0x7f800000 | (mantissa << 13);
-+
-+ if (aexp == 0)
-+ {
-+ int shift;
-+
-+ if (mantissa == 0)
-+ return sign;
-+
-+ shift = __builtin_clz(mantissa) - 21;
-+ mantissa <<= shift;
-+ aexp = -shift;
-+ }
-+
-+ return sign | (((aexp + 0x70) << 23) + (mantissa << 13));
-+}
-+
-+unsigned short
-+__gnu_f2h_ieee(unsigned int a)
-+{
-+ return __gnu_f2h_internal(a, 1);
-+}
-+
-+unsigned int
-+__gnu_h2f_ieee(unsigned short a)
-+{
-+ return __gnu_h2f_internal(a, 1);
-+}
-+
-+unsigned short
-+__gnu_f2h_alternative(unsigned int x)
-+{
-+ return __gnu_f2h_internal(x, 0);
-+}
-+
-+unsigned int
-+__gnu_h2f_alternative(unsigned short a)
-+{
-+ return __gnu_h2f_internal(a, 0);
-+}
---- a/gcc/config/arm/fpa.md
-+++ b/gcc/config/arm/fpa.md
-@@ -599,10 +599,10 @@
- {
- default:
- case 0: return \"mvf%?e\\t%0, %1\";
-- case 1: if (arm_fpu_arch == FPUTYPE_FPA_EMU2)
-+ case 1: if (TARGET_FPA_EMU2)
- return \"ldf%?e\\t%0, %1\";
- return \"lfm%?\\t%0, 1, %1\";
-- case 2: if (arm_fpu_arch == FPUTYPE_FPA_EMU2)
-+ case 2: if (TARGET_FPA_EMU2)
- return \"stf%?e\\t%1, %0\";
- return \"sfm%?\\t%1, 1, %0\";
- }
---- /dev/null
-+++ b/gcc/config/arm/hwdiv.md
-@@ -0,0 +1,41 @@
-+;; ARM instruction patterns for hardware division
-+;; Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc.
-+;; Written by CodeSourcery, LLC.
-+;;
-+;; This file is part of GCC.
-+;;
-+;; GCC is free software; you can redistribute it and/or modify it
-+;; under the terms of the GNU General Public License as published by
-+;; the Free Software Foundation; either version 2, or (at your option)
-+;; any later version.
-+;;
-+;; GCC is distributed in the hope that it will be useful, but
-+;; WITHOUT ANY WARRANTY; without even the implied warranty of
-+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+;; General Public License for more details.
-+;;
-+;; You should have received a copy of the GNU General Public License
-+;; along with GCC; see the file COPYING. If not, write to
-+;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
-+;; Boston, MA 02110-1301, USA.
-+
-+(define_insn "divsi3"
-+ [(set (match_operand:SI 0 "s_register_operand" "=r")
-+ (div:SI (match_operand:SI 1 "s_register_operand" "r")
-+ (match_operand:SI 2 "s_register_operand" "r")))]
-+ "arm_arch_hwdiv"
-+ "sdiv%?\t%0, %1, %2"
-+ [(set_attr "predicable" "yes")
-+ (set_attr "insn" "sdiv")]
-+)
-+
-+(define_insn "udivsi3"
-+ [(set (match_operand:SI 0 "s_register_operand" "=r")
-+ (udiv:SI (match_operand:SI 1 "s_register_operand" "r")
-+ (match_operand:SI 2 "s_register_operand" "r")))]
-+ "arm_arch_hwdiv"
-+ "udiv%?\t%0, %1, %2"
-+ [(set_attr "predicable" "yes")
-+ (set_attr "insn" "udiv")]
-+)
-+
---- a/gcc/config/arm/ieee754-df.S
-+++ b/gcc/config/arm/ieee754-df.S
-@@ -83,7 +83,7 @@ ARM_FUNC_ALIAS aeabi_dsub subdf3
- ARM_FUNC_START adddf3
- ARM_FUNC_ALIAS aeabi_dadd adddf3
-
--1: do_push {r4, r5, lr}
-+1: do_push (r4, r5, lr)
-
- @ Look for zeroes, equal values, INF, or NAN.
- shift1 lsl, r4, xh, #1
-@@ -427,7 +427,7 @@ ARM_FUNC_ALIAS aeabi_ui2d floatunsidf
- do_it eq, t
- moveq r1, #0
- RETc(eq)
-- do_push {r4, r5, lr}
-+ do_push (r4, r5, lr)
- mov r4, #0x400 @ initial exponent
- add r4, r4, #(52-1 - 1)
- mov r5, #0 @ sign bit is 0
-@@ -447,7 +447,7 @@ ARM_FUNC_ALIAS aeabi_i2d floatsidf
- do_it eq, t
- moveq r1, #0
- RETc(eq)
-- do_push {r4, r5, lr}
-+ do_push (r4, r5, lr)
- mov r4, #0x400 @ initial exponent
- add r4, r4, #(52-1 - 1)
- ands r5, r0, #0x80000000 @ sign bit in r5
-@@ -481,7 +481,7 @@ ARM_FUNC_ALIAS aeabi_f2d extendsfdf2
- RETc(eq) @ we are done already.
-
- @ value was denormalized. We can normalize it now.
-- do_push {r4, r5, lr}
-+ do_push (r4, r5, lr)
- mov r4, #0x380 @ setup corresponding exponent
- and r5, xh, #0x80000000 @ move sign bit in r5
- bic xh, xh, #0x80000000
-@@ -508,9 +508,9 @@ ARM_FUNC_ALIAS aeabi_ul2d floatundidf
- @ compatibility.
- adr ip, LSYM(f0_ret)
- @ Push pc as well so that RETLDM works correctly.
-- do_push {r4, r5, ip, lr, pc}
-+ do_push (r4, r5, ip, lr, pc)
- #else
-- do_push {r4, r5, lr}
-+ do_push (r4, r5, lr)
- #endif
-
- mov r5, #0
-@@ -534,9 +534,9 @@ ARM_FUNC_ALIAS aeabi_l2d floatdidf
- @ compatibility.
- adr ip, LSYM(f0_ret)
- @ Push pc as well so that RETLDM works correctly.
-- do_push {r4, r5, ip, lr, pc}
-+ do_push (r4, r5, ip, lr, pc)
- #else
-- do_push {r4, r5, lr}
-+ do_push (r4, r5, lr)
- #endif
-
- ands r5, ah, #0x80000000 @ sign bit in r5
-@@ -585,7 +585,7 @@ ARM_FUNC_ALIAS aeabi_l2d floatdidf
- @ Legacy code expects the result to be returned in f0. Copy it
- @ there as well.
- LSYM(f0_ret):
-- do_push {r0, r1}
-+ do_push (r0, r1)
- ldfd f0, [sp], #8
- RETLDM
-
-@@ -602,7 +602,7 @@ LSYM(f0_ret):
-
- ARM_FUNC_START muldf3
- ARM_FUNC_ALIAS aeabi_dmul muldf3
-- do_push {r4, r5, r6, lr}
-+ do_push (r4, r5, r6, lr)
-
- @ Mask out exponents, trap any zero/denormal/INF/NAN.
- mov ip, #0xff
-@@ -910,7 +910,7 @@ LSYM(Lml_n):
- ARM_FUNC_START divdf3
- ARM_FUNC_ALIAS aeabi_ddiv divdf3
-
-- do_push {r4, r5, r6, lr}
-+ do_push (r4, r5, r6, lr)
-
- @ Mask out exponents, trap any zero/denormal/INF/NAN.
- mov ip, #0xff
-@@ -1195,7 +1195,7 @@ ARM_FUNC_ALIAS aeabi_cdcmple aeabi_cdcmp
-
- @ The status-returning routines are required to preserve all
- @ registers except ip, lr, and cpsr.
--6: do_push {r0, lr}
-+6: do_push (r0, lr)
- ARM_CALL cmpdf2
- @ Set the Z flag correctly, and the C flag unconditionally.
- cmp r0, #0
---- a/gcc/config/arm/ieee754-sf.S
-+++ b/gcc/config/arm/ieee754-sf.S
-@@ -481,7 +481,7 @@ LSYM(Lml_x):
- and r3, ip, #0x80000000
-
- @ Well, no way to make it shorter without the umull instruction.
-- do_push {r3, r4, r5}
-+ do_push (r3, r4, r5)
- mov r4, r0, lsr #16
- mov r5, r1, lsr #16
- bic r0, r0, r4, lsl #16
-@@ -492,7 +492,7 @@ LSYM(Lml_x):
- mla r0, r4, r1, r0
- adds r3, r3, r0, lsl #16
- adc r1, ip, r0, lsr #16
-- do_pop {r0, r4, r5}
-+ do_pop (r0, r4, r5)
-
- #else
-
-@@ -882,7 +882,7 @@ ARM_FUNC_ALIAS aeabi_cfcmple aeabi_cfcmp
-
- @ The status-returning routines are required to preserve all
- @ registers except ip, lr, and cpsr.
--6: do_push {r0, r1, r2, r3, lr}
-+6: do_push (r0, r1, r2, r3, lr)
- ARM_CALL cmpsf2
- @ Set the Z flag correctly, and the C flag unconditionally.
- cmp r0, #0
---- a/gcc/config/arm/lib1funcs.asm
-+++ b/gcc/config/arm/lib1funcs.asm
-@@ -27,8 +27,17 @@ see the files COPYING3 and COPYING.RUNTI
- #if defined(__ELF__) && defined(__linux__)
- .section .note.GNU-stack,"",%progbits
- .previous
--#endif
-+#endif /* __ELF__ and __linux__ */
-
-+#ifdef __ARM_EABI__
-+/* Some attributes that are common to all routines in this file. */
-+ /* Tag_ABI_align8_needed: This code does not require 8-byte
-+ alignment from the caller. */
-+ /* .eabi_attribute 24, 0 -- default setting. */
-+ /* Tag_ABI_align8_preserved: This code preserves 8-byte
-+ alignment in any callee. */
-+ .eabi_attribute 25, 1
-+#endif /* __ARM_EABI__ */
- /* ------------------------------------------------------------------------ */
-
- /* We need to know what prefix to add to function names. */
-@@ -233,8 +242,8 @@ LSYM(Lend_fde):
- .macro shift1 op, arg0, arg1, arg2
- \op \arg0, \arg1, \arg2
- .endm
--#define do_push push
--#define do_pop pop
-+#define do_push(...) push {__VA_ARGS__}
-+#define do_pop(...) pop {__VA_ARGS__}
- #define COND(op1, op2, cond) op1 ## op2 ## cond
- /* Perform an arithmetic operation with a variable shift operand. This
- requires two instructions and a scratch register on Thumb-2. */
-@@ -248,24 +257,133 @@ LSYM(Lend_fde):
- .macro shift1 op, arg0, arg1, arg2
- mov \arg0, \arg1, \op \arg2
- .endm
--#define do_push stmfd sp!,
--#define do_pop ldmfd sp!,
-+#if defined(__low_irq_latency__)
-+#define do_push(...) \
-+ _buildN1(do_push, _buildC1(__VA_ARGS__))( __VA_ARGS__)
-+#define _buildN1(BASE, X) _buildN2(BASE, X)
-+#define _buildN2(BASE, X) BASE##X
-+#define _buildC1(...) _buildC2(__VA_ARGS__,9,8,7,6,5,4,3,2,1)
-+#define _buildC2(a1,a2,a3,a4,a5,a6,a7,a8,a9,c,...) c
-+
-+#define do_push1(r1) str r1, [sp, #-4]!
-+#define do_push2(r1, r2) str r2, [sp, #-4]! ; str r1, [sp, #-4]!
-+#define do_push3(r1, r2, r3) str r3, [sp, #-4]! ; str r2, [sp, #-4]!; str r1, [sp, #-4]!
-+#define do_push4(r1, r2, r3, r4) \
-+ do_push3 (r2, r3, r4);\
-+ do_push1 (r1)
-+#define do_push5(r1, r2, r3, r4, r5) \
-+ do_push4 (r2, r3, r4, r5);\
-+ do_push1 (r1)
-+
-+#define do_pop(...) \
-+_buildN1(do_pop, _buildC1(__VA_ARGS__))( __VA_ARGS__)
-+
-+#define do_pop1(r1) ldr r1, [sp], #4
-+#define do_pop2(r1, r2) ldr r1, [sp], #4 ; ldr r2, [sp], #4
-+#define do_pop3(r1, r2, r3) ldr r1, [sp], #4 ; str r2, [sp], #4; str r3, [sp], #4
-+#define do_pop4(r1, r2, r3, r4) \
-+ do_pop1 (r1);\
-+ do_pup3 (r2, r3, r4)
-+#define do_pop5(r1, r2, r3, r4, r5) \
-+ do_pop1 (r1);\
-+ do_pop4 (r2, r3, r4, r5)
-+#else
-+#define do_push(...) stmfd sp!, { __VA_ARGS__}
-+#define do_pop(...) ldmfd sp!, {__VA_ARGS__}
-+#endif
-+
-+
- #define COND(op1, op2, cond) op1 ## cond ## op2
- .macro shiftop name, dest, src1, src2, shiftop, shiftreg, tmp
- \name \dest, \src1, \src2, \shiftop \shiftreg
- .endm
- #endif
-
--.macro ARM_LDIV0 name
-+#ifdef __ARM_EABI__
-+.macro ARM_LDIV0 name signed
-+ cmp r0, #0
-+ .ifc \signed, unsigned
-+ movne r0, #0xffffffff
-+ .else
-+ movgt r0, #0x7fffffff
-+ movlt r0, #0x80000000
-+ .endif
-+ b SYM (__aeabi_idiv0) __PLT__
-+.endm
-+#else
-+.macro ARM_LDIV0 name signed
- str lr, [sp, #-8]!
- 98: cfi_push 98b - __\name, 0xe, -0x8, 0x8
- bl SYM (__div0) __PLT__
- mov r0, #0 @ About as wrong as it could be.
- RETLDM unwind=98b
- .endm
-+#endif
-
-
--.macro THUMB_LDIV0 name
-+#ifdef __ARM_EABI__
-+.macro THUMB_LDIV0 name signed
-+#if defined(__ARM_ARCH_6M__)
-+ .ifc \signed, unsigned
-+ cmp r0, #0
-+ beq 1f
-+ mov r0, #0
-+ mvn r0, r0 @ 0xffffffff
-+1:
-+ .else
-+ cmp r0, #0
-+ beq 2f
-+ blt 3f
-+ mov r0, #0
-+ mvn r0, r0
-+ lsr r0, r0, #1 @ 0x7fffffff
-+ b 2f
-+3: mov r0, #0x80
-+ lsl r0, r0, #24 @ 0x80000000
-+2:
-+ .endif
-+ push {r0, r1, r2}
-+ ldr r0, 4f
-+ adr r1, 4f
-+ add r0, r1
-+ str r0, [sp, #8]
-+ @ We know we are not on armv4t, so pop pc is safe.
-+ pop {r0, r1, pc}
-+ .align 2
-+4:
-+ .word __aeabi_idiv0 - 4b
-+#elif defined(__thumb2__)
-+ .syntax unified
-+ .ifc \signed, unsigned
-+ cbz r0, 1f
-+ mov r0, #0xffffffff
-+1:
-+ .else
-+ cmp r0, #0
-+ do_it gt
-+ movgt r0, #0x7fffffff
-+ do_it lt
-+ movlt r0, #0x80000000
-+ .endif
-+ b.w SYM(__aeabi_idiv0) __PLT__
-+#else
-+ .align 2
-+ bx pc
-+ nop
-+ .arm
-+ cmp r0, #0
-+ .ifc \signed, unsigned
-+ movne r0, #0xffffffff
-+ .else
-+ movgt r0, #0x7fffffff
-+ movlt r0, #0x80000000
-+ .endif
-+ b SYM(__aeabi_idiv0) __PLT__
-+ .thumb
-+#endif
-+.endm
-+#else
-+.macro THUMB_LDIV0 name signed
- push { r1, lr }
- 98: cfi_push 98b - __\name, 0xe, -0x4, 0x8
- bl SYM (__div0)
-@@ -277,18 +395,19 @@ LSYM(Lend_fde):
- pop { r1, pc }
- #endif
- .endm
-+#endif
-
- .macro FUNC_END name
- SIZE (__\name)
- .endm
-
--.macro DIV_FUNC_END name
-+.macro DIV_FUNC_END name signed
- cfi_start __\name, LSYM(Lend_div0)
- LSYM(Ldiv0):
- #ifdef __thumb__
-- THUMB_LDIV0 \name
-+ THUMB_LDIV0 \name \signed
- #else
-- ARM_LDIV0 \name
-+ ARM_LDIV0 \name \signed
- #endif
- cfi_end LSYM(Lend_div0)
- FUNC_END \name
-@@ -413,6 +532,12 @@ SYM (__\name):
- #define yyl r2
- #endif
-
-+#ifdef __ARM_EABI__
-+.macro WEAK name
-+ .weak SYM (__\name)
-+.endm
-+#endif
-+
- #ifdef __thumb__
- /* Register aliases. */
-
-@@ -437,6 +562,43 @@ pc .req r15
-
- #if __ARM_ARCH__ >= 5 && ! defined (__OPTIMIZE_SIZE__)
-
-+#if defined (__thumb2__)
-+ clz \curbit, \dividend
-+ clz \result, \divisor
-+ sub \curbit, \result, \curbit
-+ rsb \curbit, \curbit, #31
-+ adr \result, 1f
-+ add \curbit, \result, \curbit, lsl #4
-+ mov \result, #0
-+ mov pc, \curbit
-+.p2align 3
-+1:
-+ .set shift, 32
-+ .rept 32
-+ .set shift, shift - 1
-+ cmp.w \dividend, \divisor, lsl #shift
-+ nop.n
-+ adc.w \result, \result, \result
-+ it cs
-+ subcs.w \dividend, \dividend, \divisor, lsl #shift
-+ .endr
-+#elif defined(__ARM_TUNE_MARVELL_F__)
-+ clz \curbit, \dividend
-+ clz \result, \divisor
-+ sub \curbit, \result, \curbit
-+ mov \divisor, \divisor, lsl \curbit
-+ rsb \curbit, \curbit, #31
-+ mov \curbit, \curbit, lsl #2
-+ mov \result, #0
-+ add pc, pc, \curbit, lsl #2
-+ nop
-+ .rept 32
-+ cmp \dividend, \divisor
-+ subcs \dividend, \dividend, \divisor
-+ mov \divisor, \divisor, lsr #1
-+ adc \result, \result, \result
-+ .endr
-+#else /* ! defined(__ARM_TUNE_MARVELL_F__) */
- clz \curbit, \dividend
- clz \result, \divisor
- sub \curbit, \result, \curbit
-@@ -452,6 +614,7 @@ pc .req r15
- adc \result, \result, \result
- subcs \dividend, \dividend, \divisor, lsl #shift
- .endr
-+#endif /* defined(__ARM_TUNE_MARVELL_F__) */
-
- #else /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
- #if __ARM_ARCH__ >= 5
-@@ -499,18 +662,23 @@ pc .req r15
-
- @ Division loop
- 1: cmp \dividend, \divisor
-+ do_it hs, t
- subhs \dividend, \dividend, \divisor
- orrhs \result, \result, \curbit
- cmp \dividend, \divisor, lsr #1
-+ do_it hs, t
- subhs \dividend, \dividend, \divisor, lsr #1
- orrhs \result, \result, \curbit, lsr #1
- cmp \dividend, \divisor, lsr #2
-+ do_it hs, t
- subhs \dividend, \dividend, \divisor, lsr #2
- orrhs \result, \result, \curbit, lsr #2
- cmp \dividend, \divisor, lsr #3
-+ do_it hs, t
- subhs \dividend, \dividend, \divisor, lsr #3
- orrhs \result, \result, \curbit, lsr #3
- cmp \dividend, #0 @ Early termination?
-+ do_it ne, t
- movnes \curbit, \curbit, lsr #4 @ No, any more bits to do?
- movne \divisor, \divisor, lsr #4
- bne 1b
-@@ -799,13 +967,14 @@ LSYM(Lgot_result):
- /* ------------------------------------------------------------------------ */
- #ifdef L_udivsi3
-
-+#if defined(__ARM_ARCH_6M__)
-+
- FUNC_START udivsi3
- FUNC_ALIAS aeabi_uidiv udivsi3
-
--#ifdef __thumb__
--
- cmp divisor, #0
- beq LSYM(Ldiv0)
-+LSYM(udivsi3_nodiv0):
- mov curbit, #1
- mov result, #0
-
-@@ -819,9 +988,16 @@ LSYM(Lgot_result):
- pop { work }
- RET
-
--#else /* ARM version. */
-+#else /* ARM/Thumb-2 version. */
-+
-+ ARM_FUNC_START udivsi3
-+ ARM_FUNC_ALIAS aeabi_uidiv udivsi3
-
-+ /* Note: if called via udivsi3_nodiv0, this will unnecessarily check
-+ for division-by-zero a second time. */
-+LSYM(udivsi3_nodiv0):
- subs r2, r1, #1
-+ do_it eq
- RETc(eq)
- bcc LSYM(Ldiv0)
- cmp r0, r1
-@@ -834,7 +1010,8 @@ LSYM(Lgot_result):
- mov r0, r2
- RET
-
--11: moveq r0, #1
-+11: do_it eq, e
-+ moveq r0, #1
- movne r0, #0
- RET
-
-@@ -845,19 +1022,24 @@ LSYM(Lgot_result):
-
- #endif /* ARM version */
-
-- DIV_FUNC_END udivsi3
-+ DIV_FUNC_END udivsi3 unsigned
-
-+#if defined(__ARM_ARCH_6M__)
- FUNC_START aeabi_uidivmod
--#ifdef __thumb__
-+ cmp r1, #0
-+ beq LSYM(Ldiv0)
- push {r0, r1, lr}
-- bl SYM(__udivsi3)
-+ bl LSYM(udivsi3_nodiv0)
- POP {r1, r2, r3}
- mul r2, r0
- sub r1, r1, r2
- bx r3
- #else
-+ARM_FUNC_START aeabi_uidivmod
-+ cmp r1, #0
-+ beq LSYM(Ldiv0)
- stmfd sp!, { r0, r1, lr }
-- bl SYM(__udivsi3)
-+ bl LSYM(udivsi3_nodiv0)
- ldmfd sp!, { r1, r2, lr }
- mul r3, r2, r0
- sub r1, r1, r3
-@@ -904,19 +1086,20 @@ LSYM(Lover10):
-
- #endif /* ARM version. */
-
-- DIV_FUNC_END umodsi3
-+ DIV_FUNC_END umodsi3 unsigned
-
- #endif /* L_umodsi3 */
- /* ------------------------------------------------------------------------ */
- #ifdef L_divsi3
-
-+#if defined(__ARM_ARCH_6M__)
-+
- FUNC_START divsi3
- FUNC_ALIAS aeabi_idiv divsi3
-
--#ifdef __thumb__
- cmp divisor, #0
- beq LSYM(Ldiv0)
--
-+LSYM(divsi3_nodiv0):
- push { work }
- mov work, dividend
- eor work, divisor @ Save the sign of the result.
-@@ -945,15 +1128,21 @@ LSYM(Lover12):
- pop { work }
- RET
-
--#else /* ARM version. */
-+#else /* ARM/Thumb-2 version. */
-
-+ ARM_FUNC_START divsi3
-+ ARM_FUNC_ALIAS aeabi_idiv divsi3
-+
- cmp r1, #0
-- eor ip, r0, r1 @ save the sign of the result.
- beq LSYM(Ldiv0)
-+LSYM(divsi3_nodiv0):
-+ eor ip, r0, r1 @ save the sign of the result.
-+ do_it mi
- rsbmi r1, r1, #0 @ loops below use unsigned.
- subs r2, r1, #1 @ division by 1 or -1 ?
- beq 10f
- movs r3, r0
-+ do_it mi
- rsbmi r3, r0, #0 @ positive dividend value
- cmp r3, r1
- bls 11f
-@@ -963,14 +1152,18 @@ LSYM(Lover12):
- ARM_DIV_BODY r3, r1, r0, r2
-
- cmp ip, #0
-+ do_it mi
- rsbmi r0, r0, #0
- RET
-
- 10: teq ip, r0 @ same sign ?
-+ do_it mi
- rsbmi r0, r0, #0
- RET
-
--11: movlo r0, #0
-+11: do_it lo
-+ movlo r0, #0
-+ do_it eq,t
- moveq r0, ip, asr #31
- orreq r0, r0, #1
- RET
-@@ -979,24 +1172,30 @@ LSYM(Lover12):
-
- cmp ip, #0
- mov r0, r3, lsr r2
-+ do_it mi
- rsbmi r0, r0, #0
- RET
-
- #endif /* ARM version */
-
-- DIV_FUNC_END divsi3
-+ DIV_FUNC_END divsi3 signed
-
-+#if defined(__ARM_ARCH_6M__)
- FUNC_START aeabi_idivmod
--#ifdef __thumb__
-+ cmp r1, #0
-+ beq LSYM(Ldiv0)
- push {r0, r1, lr}
-- bl SYM(__divsi3)
-+ bl LSYM(divsi3_nodiv0)
- POP {r1, r2, r3}
- mul r2, r0
- sub r1, r1, r2
- bx r3
- #else
-+ARM_FUNC_START aeabi_idivmod
-+ cmp r1, #0
-+ beq LSYM(Ldiv0)
- stmfd sp!, { r0, r1, lr }
-- bl SYM(__divsi3)
-+ bl LSYM(divsi3_nodiv0)
- ldmfd sp!, { r1, r2, lr }
- mul r3, r2, r0
- sub r1, r1, r3
-@@ -1062,21 +1261,25 @@ LSYM(Lover12):
-
- #endif /* ARM version */
-
-- DIV_FUNC_END modsi3
-+ DIV_FUNC_END modsi3 signed
-
- #endif /* L_modsi3 */
- /* ------------------------------------------------------------------------ */
- #ifdef L_dvmd_tls
-
-- FUNC_START div0
-- FUNC_ALIAS aeabi_idiv0 div0
-- FUNC_ALIAS aeabi_ldiv0 div0
--
-+#ifdef __ARM_EABI__
-+ WEAK aeabi_idiv0
-+ WEAK aeabi_ldiv0
-+ FUNC_START aeabi_idiv0
-+ FUNC_START aeabi_ldiv0
- RET
--
- FUNC_END aeabi_ldiv0
- FUNC_END aeabi_idiv0
-+#else
-+ FUNC_START div0
-+ RET
- FUNC_END div0
-+#endif
-
- #endif /* L_divmodsi_tools */
- /* ------------------------------------------------------------------------ */
-@@ -1086,16 +1289,49 @@ LSYM(Lover12):
- /* Constant taken from <asm/signal.h>. */
- #define SIGFPE 8
-
-+#ifdef __ARM_EABI__
-+ WEAK aeabi_idiv0
-+ WEAK aeabi_ldiv0
-+ ARM_FUNC_START aeabi_idiv0
-+ ARM_FUNC_START aeabi_ldiv0
-+#else
- ARM_FUNC_START div0
-+#endif
-
-- do_push {r1, lr}
-+ do_push (r1, lr)
- mov r0, #SIGFPE
- bl SYM(raise) __PLT__
- RETLDM r1
-
-+#ifdef __ARM_EABI__
-+ FUNC_END aeabi_ldiv0
-+ FUNC_END aeabi_idiv0
-+#else
- FUNC_END div0
-+#endif
-
- #endif /* L_dvmd_lnx */
-+#ifdef L_clear_cache
-+#if defined __ARM_EABI__ && defined __linux__
-+@ EABI GNU/Linux call to cacheflush syscall.
-+ ARM_FUNC_START clear_cache
-+ do_push (r7)
-+#if __ARM_ARCH__ >= 7 || defined(__ARM_ARCH_6T2__)
-+ movw r7, #2
-+ movt r7, #0xf
-+#else
-+ mov r7, #0xf0000
-+ add r7, r7, #2
-+#endif
-+ mov r2, #0
-+ swi 0
-+ do_pop (r7)
-+ RET
-+ FUNC_END clear_cache
-+#else
-+#error "This is only for ARM EABI GNU/Linux"
-+#endif
-+#endif /* L_clear_cache */
- /* ------------------------------------------------------------------------ */
- /* Dword shift operations. */
- /* All the following Dword shift variants rely on the fact that
-@@ -1292,7 +1528,7 @@ FUNC_START clzdi2
- push {r4, lr}
- # else
- ARM_FUNC_START clzdi2
-- do_push {r4, lr}
-+ do_push (r4, lr)
- # endif
- cmp xxh, #0
- bne 1f
---- a/gcc/config/arm/linux-eabi.h
-+++ b/gcc/config/arm/linux-eabi.h
-@@ -66,22 +66,14 @@
- /* At this point, bpabi.h will have clobbered LINK_SPEC. We want to
- use the GNU/Linux version, not the generic BPABI version. */
- #undef LINK_SPEC
--#define LINK_SPEC LINUX_TARGET_LINK_SPEC
-+#define LINK_SPEC LINUX_TARGET_LINK_SPEC BE8_LINK_SPEC
-
- /* Use the default LIBGCC_SPEC, not the version in linux-elf.h, as we
- do not use -lfloat. */
- #undef LIBGCC_SPEC
-
--/* Clear the instruction cache from `beg' to `end'. This makes an
-- inline system call to SYS_cacheflush. */
-+/* Clear the instruction cache from `beg' to `end'. This is
-+ implemented in lib1funcs.asm, so ensure an error if this definition
-+ is used. */
- #undef CLEAR_INSN_CACHE
--#define CLEAR_INSN_CACHE(BEG, END) \
--{ \
-- register unsigned long _beg __asm ("a1") = (unsigned long) (BEG); \
-- register unsigned long _end __asm ("a2") = (unsigned long) (END); \
-- register unsigned long _flg __asm ("a3") = 0; \
-- register unsigned long _scno __asm ("r7") = 0xf0002; \
-- __asm __volatile ("swi 0 @ sys_cacheflush" \
-- : "=r" (_beg) \
-- : "0" (_beg), "r" (_end), "r" (_flg), "r" (_scno)); \
--}
-+#define CLEAR_INSN_CACHE(BEG, END) not used
---- a/gcc/config/arm/linux-elf.h
-+++ b/gcc/config/arm/linux-elf.h
-@@ -98,7 +98,7 @@
-
- /* NWFPE always understands FPA instructions. */
- #undef FPUTYPE_DEFAULT
--#define FPUTYPE_DEFAULT FPUTYPE_FPA_EMU3
-+#define FPUTYPE_DEFAULT "fpe3"
-
- /* Call the function profiler with a given profile label. */
- #undef ARM_FUNCTION_PROFILER
---- /dev/null
-+++ b/gcc/config/arm/marvell-f-vfp.md
-@@ -0,0 +1,153 @@
-+;; Marvell 2850 VFP pipeline description
-+;; Copyright (C) 2007 Free Software Foundation, Inc.
-+;; Written by CodeSourcery, Inc.
-+
-+;; This file is part of GCC.
-+
-+;; GCC is distributed in the hope that it will be useful, but WITHOUT
-+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-+;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
-+;; License for more details.
-+
-+;; You should have received a copy of the GNU General Public License
-+;; along with GCC; see the file COPYING. If not, write to
-+;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
-+;; Boston, MA 02110-1301, USA.
-+
-+;; This automaton provides a pipeline description for the Marvell
-+;; 2850 core.
-+;;
-+;; The model given here assumes that the condition for all conditional
-+;; instructions is "true", i.e., that all of the instructions are
-+;; actually executed.
-+
-+(define_automaton "marvell_f_vfp")
-+
-+;; This is a single-issue VFPv2 implementation with the following execution
-+;; units:
-+;;
-+;; 1. Addition/subtraction unit; takes three cycles, pipelined.
-+;; 2. Multiplication unit; takes four cycles, pipelined.
-+;; 3. Add buffer, used for multiply-accumulate (see below).
-+;; 4. Divide/square root unit, not pipelined.
-+;; For single-precision: takes sixteen cycles, can accept another insn
-+;; after fifteen cycles.
-+;; For double-precision: takes thirty-one cycles, can accept another insn
-+;; after thirty cycles.
-+;; 5. Single-cycle unit, pipelined.
-+;; This does absolute value/copy/negate/compare in one cycle and
-+;; conversion in two cycles.
-+;;
-+;; When all three operands of a multiply-accumulate instruction are ready,
-+;; one is issued to the add buffer (which can hold six operands in a FIFO)
-+;; and the two to be multiplied are issued to the multiply unit. After
-+;; four cycles in the multiply unit, one cycle is taken to issue the
-+;; operand from the add buffer plus the multiplication result to the
-+;; addition/subtraction unit. That issue takes priority over any add/sub
-+;; instruction waiting at the normal issue stage, but may be performed in
-+;; parallel with the issue of a non-add/sub instruction. The total time
-+;; for a multiply-accumulate instruction to pass through the execution
-+;; units is hence eight cycles.
-+;;
-+;; We do not need to explicitly model the add buffer because it can
-+;; always issue the instruction at the head of its FIFO (due to the above
-+;; priority rule) and there are more spaces in the add buffer (six) than
-+;; there are stages (four) in the multiplication unit.
-+;;
-+;; Two instructions may be retired at once from the head of an 8-entry
-+;; reorder buffer. Data from these first two instructions only may be
-+;; forwarded to the inputs of the issue unit. We assume that the
-+;; pressure on the reorder buffer will be sufficiently low that every
-+;; instruction entering it will be eligible for data forwarding. Since
-+;; data is forwarded to the issue unit and not the execution units (so
-+;; for example single-cycle instructions cannot be issued back-to-back),
-+;; the latencies given below are the cycle counts above plus one.
-+
-+(define_cpu_unit "mf_vfp_issue" "marvell_f_vfp")
-+(define_cpu_unit "mf_vfp_add" "marvell_f_vfp")
-+(define_cpu_unit "mf_vfp_mul" "marvell_f_vfp")
-+(define_cpu_unit "mf_vfp_div" "marvell_f_vfp")
-+(define_cpu_unit "mf_vfp_single_cycle" "marvell_f_vfp")
-+
-+;; An attribute to indicate whether our reservations are applicable.
-+
-+(define_attr "marvell_f_vfp" "yes,no"
-+ (const (if_then_else (and (eq_attr "tune" "marvell_f")
-+ (eq_attr "fpu" "vfp"))
-+ (const_string "yes") (const_string "no"))))
-+
-+;; Reservations of functional units. The nothing*2 reservations at the
-+;; start of many of the reservation strings correspond to the decode
-+;; stages. We need to have these reservations so that we can correctly
-+;; reserve parts of the core's A1 pipeline for loads and stores. For
-+;; that case (since loads skip E1) the pipelines line up thus:
-+;; A1 pipe: Issue E2 OF WR WB ...
-+;; VFP pipe: Fetch Decode1 Decode2 Issue Execute1 ...
-+;; For a load, we need to make a reservation of E2, and thus we must
-+;; use Decode1 as the starting point for all VFP reservations here.
-+;;
-+;; For reservations of pipelined VFP execution units we only reserve
-+;; the execution unit for the first execution cycle, omitting any trailing
-+;; "nothing" reservations.
-+
-+(define_insn_reservation "marvell_f_vfp_add" 4
-+ (and (eq_attr "marvell_f_vfp" "yes")
-+ (eq_attr "type" "farith"))
-+ "nothing*2,mf_vfp_issue,mf_vfp_add")
-+
-+(define_insn_reservation "marvell_f_vfp_mul" 5
-+ (and (eq_attr "marvell_f_vfp" "yes")
-+ (eq_attr "type" "fmuls,fmuld"))
-+ "nothing*2,mf_vfp_issue,mf_vfp_mul")
-+
-+(define_insn_reservation "marvell_f_vfp_divs" 17
-+ (and (eq_attr "marvell_f_vfp" "yes")
-+ (eq_attr "type" "fdivs"))
-+ "nothing*2,mf_vfp_issue,mf_vfp_div*15")
-+
-+(define_insn_reservation "marvell_f_vfp_divd" 32
-+ (and (eq_attr "marvell_f_vfp" "yes")
-+ (eq_attr "type" "fdivd"))
-+ "nothing*2,mf_vfp_issue,mf_vfp_div*30")
-+
-+;; The DFA lookahead is small enough that the "add" reservation here
-+;; will always take priority over any addition/subtraction instruction
-+;; issued five cycles after the multiply-accumulate instruction, as
-+;; required.
-+(define_insn_reservation "marvell_f_vfp_mac" 9
-+ (and (eq_attr "marvell_f_vfp" "yes")
-+ (eq_attr "type" "fmacs,fmacd"))
-+ "nothing*2,mf_vfp_issue,mf_vfp_mul,nothing*4,mf_vfp_add")
-+
-+(define_insn_reservation "marvell_f_vfp_single" 2
-+ (and (eq_attr "marvell_f_vfp" "yes")
-+ (eq_attr "type" "ffarith"))
-+ "nothing*2,mf_vfp_issue,mf_vfp_single_cycle")
-+
-+(define_insn_reservation "marvell_f_vfp_convert" 3
-+ (and (eq_attr "marvell_f_vfp" "yes")
-+ (eq_attr "type" "f_cvt"))
-+ "nothing*2,mf_vfp_issue,mf_vfp_single_cycle")
-+
-+(define_insn_reservation "marvell_f_vfp_load" 2
-+ (and (eq_attr "marvell_f_vfp" "yes")
-+ (eq_attr "type" "f_loads,f_loadd"))
-+ "a1_e2+sram,a1_of,a1_wr+mf_vfp_issue,a1_wb+mf_vfp_single_cycle")
-+
-+(define_insn_reservation "marvell_f_vfp_from_core" 2
-+ (and (eq_attr "marvell_f_vfp" "yes")
-+ (eq_attr "type" "r_2_f"))
-+ "a1_e2,a1_of,a1_wr+mf_vfp_issue,a1_wb+mf_vfp_single_cycle")
-+
-+;; The interaction between the core and VFP pipelines during VFP
-+;; store operations and core <-> VFP moves is not clear, so we guess.
-+(define_insn_reservation "marvell_f_vfp_store" 3
-+ (and (eq_attr "marvell_f_vfp" "yes")
-+ (eq_attr "type" "f_stores,f_stored"))
-+ "a1_e2,a1_of,mf_vfp_issue,a1_wr+sram+mf_vfp_single_cycle")
-+
-+(define_insn_reservation "marvell_f_vfp_to_core" 4
-+ (and (eq_attr "marvell_f_vfp" "yes")
-+ (eq_attr "type" "f_2_r"))
-+ "a1_e2,a1_of,a1_wr+mf_vfp_issue,a1_wb+mf_vfp_single_cycle")
-+
---- /dev/null
-+++ b/gcc/config/arm/marvell-f.md
-@@ -0,0 +1,365 @@
-+;; Marvell 2850 pipeline description
-+;; Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc.
-+;; Written by Marvell and CodeSourcery, Inc.
-+
-+;; This file is part of GCC.
-+
-+;; GCC is free software; you can redistribute it and/or modify it
-+;; under the terms of the GNU General Public License as published
-+;; by the Free Software Foundation; either version 2, or (at your
-+;; option) any later version.
-+
-+;; GCC is distributed in the hope that it will be useful, but WITHOUT
-+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-+;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
-+;; License for more details.
-+
-+;; You should have received a copy of the GNU General Public License
-+;; along with GCC; see the file COPYING. If not, write to
-+;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
-+;; Boston, MA 02110-1301, USA.
-+
-+;; This automaton provides a pipeline description for the Marvell
-+;; 2850 core.
-+;;
-+;; The model given here assumes that the condition for all conditional
-+;; instructions is "true", i.e., that all of the instructions are
-+;; actually executed.
-+
-+(define_automaton "marvell_f")
-+
-+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-+;; Pipelines
-+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-+
-+;; This is a dual-issue processor with three pipelines:
-+;;
-+;; 1. Arithmetic and load/store pipeline A1.
-+;; Issue | E1 | E2 | OF | WR | WB for load-store instructions
-+;; Issue | E1 | E2 | WB for arithmetic instructions
-+;;
-+;; 2. Arithmetic pipeline A2.
-+;; Issue | E1 | E2 | WB
-+;;
-+;; 3. Multiply and multiply-accumulate pipeline.
-+;; Issue | MAC1 | MAC2 | MAC3 | WB
-+;;
-+;; There are various bypasses modelled to a greater or lesser extent.
-+;;
-+;; Latencies in this file correspond to the number of cycles after
-+;; the issue stage that it takes for the result of the instruction to
-+;; be computed, or for its side-effects to occur.
-+
-+(define_cpu_unit "a1_e1,a1_e2,a1_of,a1_wr,a1_wb" "marvell_f") ; ALU 1
-+(define_cpu_unit "a2_e1,a2_e2,a2_wb" "marvell_f") ; ALU 2
-+(define_cpu_unit "m_1,m_2,m_3,m_wb" "marvell_f") ; MAC
-+
-+;; We define an SRAM cpu unit to enable us to describe conflicts
-+;; between loads at the E2 stage and stores at the WR stage.
-+
-+(define_cpu_unit "sram" "marvell_f")
-+
-+;; Handling of dual-issue constraints.
-+;;
-+;; Certain pairs of instructions can be issued in parallel, and certain
-+;; pairs cannot. We divide a subset of the instructions into groups as
-+;; follows.
-+;;
-+;; - data processing 1 (mov, mvn);
-+;; - data processing 2 (adc, add, and, bic, cmn, cmp, eor, orr, rsb,
-+;; rsc, sbc, sub, teq, tst);
-+;; - load single (ldr, ldrb, ldrbt, ldrt, ldrh, ldrsb, ldrsh);
-+;; - store single (str, strb, strbt, strt, strh);
-+;; - swap (swp, swpb);
-+;; - pld;
-+;; - count leading zeros and DSP add/sub (clz, qadd, qdadd, qsub, qdsub);
-+;; - multiply 2 (mul, muls, smull, umull, smulxy, smulls, umulls);
-+;; - multiply 3 (mla, mlas, smlal, umlal, smlaxy, smlalxy, smlawx,
-+;; smlawy, smlals, umlals);
-+;; - branches (b, bl, blx, bx).
-+;;
-+;; Ignoring conditional execution, it is a good approximation to the core
-+;; to model that two instructions may only be issued in parallel if the
-+;; following conditions are met.
-+;; I. The instructions both fall into one of the above groups and their
-+;; corresponding groups have a entry in the matrix below that is not X.
-+;; II. The second instruction does not read any register updated by the
-+;; first instruction (already enforced by the GCC scheduler).
-+;; III. The second instruction does not need the carry flag updated by the
-+;; first instruction. Currently we do not model this.
-+;;
-+;; First Second instruction group
-+;; insn
-+;; DP1 DP2 L S SWP PLD CLZ M2 M3 B
-+;;
-+;; DP1 ok ok ok ok ok ok ok ok ok ok
-+;; DP2(1) ok ok ok ok ok ok ok ok ok ok
-+;; DP2(2) ok (2) ok (4) ok ok ok ok X ok
-+;; L }
-+;; SWP } ok ok X X X X ok ok ok ok
-+;; PLD }
-+;; S(3) ok ok X X X X ok ok ok ok
-+;; S(4) ok (2) X X X X ok ok X ok
-+;; CLZ ok ok ok ok ok ok ok ok ok ok
-+;; M2 ok ok ok ok ok ok ok X X ok
-+;; M3 ok (2) ok (4) ok ok ok X X ok
-+;; B ok ok ok ok ok ok ok ok ok ok
-+;;
-+;; (1) without register shift
-+;; (2) with register shift
-+;; (3) with immediate offset
-+;; (4) with register offset
-+;;
-+;; We define a fake cpu unit "reg_shift_lock" to enforce constraints
-+;; between instructions in groups DP2(2) and M3. All other
-+;; constraints are enforced automatically by virtue of the limited
-+;; number of pipelines available for the various operations, with
-+;; the exception of constraints involving S(4) that we do not model.
-+
-+(define_cpu_unit "reg_shift_lock" "marvell_f")
-+
-+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-+;; ALU instructions
-+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-+
-+;; 1. Certain logic operations can be retired after the E1 stage if
-+;; the pipeline is not already retiring another instruction. In this
-+;; model we assume this behaviour always holds for mov, mvn, and, orr, eor
-+;; instructions. If a register shift is involved and the instruction is
-+;; not mov or mvn, then a dual-issue constraint must be enforced.
-+
-+;; The first two cases are separate so they can be identified for
-+;; bypasses below.
-+
-+(define_insn_reservation "marvell_f_alu_early_retire" 1
-+ (and (eq_attr "tune" "marvell_f")
-+ (and (eq_attr "type" "alu")
-+ (eq_attr "insn" "mov,mvn,and,orr,eor")))
-+ "(a1_e1,a1_wb)|(a2_e1,a2_wb)")
-+
-+(define_insn_reservation "marvell_f_alu_early_retire_shift" 1
-+ (and (eq_attr "tune" "marvell_f")
-+ (and (eq_attr "type" "alu_shift_reg")
-+ (eq_attr "insn" "mov,mvn,and,orr,eor")))
-+ "(a1_e1,a1_wb)|(a2_e1,a2_wb)")
-+
-+(define_insn_reservation "marvell_f_alu_early_retire_reg_shift1" 1
-+ (and (eq_attr "tune" "marvell_f")
-+ (and (eq_attr "type" "alu_shift_reg")
-+ (eq_attr "insn" "mov,mvn")))
-+ "(a1_e1,a1_wb)|(a2_e1,a2_wb)")
-+
-+(define_insn_reservation "marvell_f_alu_early_retire_reg_shift2" 1
-+ (and (eq_attr "tune" "marvell_f")
-+ (and (eq_attr "type" "alu_shift_reg")
-+ (eq_attr "insn" "and,orr,eor")))
-+ "(reg_shift_lock+a1_e1,a1_wb)|(reg_shift_lock+a2_e1,a2_wb)")
-+
-+;; 2. ALU operations with no shifted operand. These bypass the E1 stage if
-+;; the E2 stage of the corresponding pipeline is clear; here, we always
-+;; model this scenario [*]. We give the operation a latency of 1 yet reserve
-+;; both E1 and E2 for it (thus preventing the GCC scheduler, in the case
-+;; where both E1 and E2 of one pipeline are clear, from issuing one
-+;; instruction to each).
-+;;
-+;; [*] The non-bypass case is a latency of two, reserving E1 on the first
-+;; cycle and E2 on the next. Due to the way the scheduler works we
-+;; have to choose between taking this as the default and taking the
-+;; above case (with latency one) as the default; we choose the latter.
-+
-+(define_insn_reservation "marvell_f_alu_op_bypass_e1" 1
-+ (and (eq_attr "tune" "marvell_f")
-+ (and (eq_attr "type" "alu")
-+ (not (eq_attr "insn" "mov,mvn,and,orr,eor"))))
-+ "(a1_e1+a1_e2,a1_wb)|(a2_e1+a2_e2,a2_wb)")
-+
-+;; 3. ALU operations with a shift-by-constant operand.
-+
-+(define_insn_reservation "marvell_f_alu_shift_op" 2
-+ (and (eq_attr "tune" "marvell_f")
-+ (and (eq_attr "type" "alu_shift")
-+ (not (eq_attr "insn" "mov,mvn,and,orr,eor"))))
-+ "(a1_e1,a1_e2,a1_wb)|(a2_e1,a2_e2,a2_wb)")
-+
-+;; 4. ALU operations with a shift-by-register operand. Since the
-+;; instruction is never mov or mvn, a dual-issue constraint must
-+;; be enforced.
-+
-+(define_insn_reservation "marvell_f_alu_shift_reg_op" 2
-+ (and (eq_attr "tune" "marvell_f")
-+ (and (eq_attr "type" "alu_shift_reg")
-+ (not (eq_attr "insn" "mov,mvn,and,orr,eor"))))
-+ "(reg_shift_lock+a1_e1,a1_e2,a1_wb)|(reg_shift_lock+a2_e1,a2_e2,a2_wb)")
-+
-+;; Given an ALU operation with shift (I1) followed by another ALU
-+;; operation (I2), with I2 depending on the destination register Rd of I1
-+;; and with I2 not using that value as the amount or the starting value for
-+;; a shift, then I1 and I2 may be issued to the same pipeline on
-+;; consecutive cycles. In terms of this model that corresponds to I1
-+;; having a latency of one cycle. There are three cases for various
-+;; I1 and I2 as follows.
-+
-+;; (a) I1 has a constant or register shift and I2 doesn't have a shift at all.
-+(define_bypass 1 "marvell_f_alu_shift_op,\
-+ marvell_f_alu_shift_reg_op"
-+ "marvell_f_alu_op_bypass_e1,marvell_f_alu_early_retire")
-+
-+;; (b) I1 has a constant or register shift and I2 has a constant shift.
-+;; Rd must not provide the starting value for the shift.
-+(define_bypass 1 "marvell_f_alu_shift_op,\
-+ marvell_f_alu_shift_reg_op"
-+ "marvell_f_alu_shift_op,marvell_f_alu_early_retire_shift"
-+ "arm_no_early_alu_shift_value_dep")
-+
-+;; (c) I1 has a constant or register shift and I2 has a register shift.
-+;; Rd must not provide the amount by which to shift.
-+(define_bypass 1 "marvell_f_alu_shift_op,\
-+ marvell_f_alu_shift_reg_op"
-+ "marvell_f_alu_shift_reg_op,\
-+ marvell_f_alu_early_retire_reg_shift1,\
-+ marvell_f_alu_early_retire_reg_shift2"
-+ "arm_no_early_alu_shift_dep")
-+
-+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-+;; Multiplication instructions
-+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-+
-+;; Multiplication instructions in group "Multiply 2".
-+
-+(define_insn_reservation "marvell_f_multiply_2" 3
-+ (and (eq_attr "tune" "marvell_f")
-+ (eq_attr "insn" "mul,muls,smull,umull,smulxy,smulls,umulls"))
-+ "m_1,m_2,m_3,m_wb")
-+
-+;; Multiplication instructions in group "Multiply 3". There is a
-+;; dual-issue constraint with non-multiplication ALU instructions
-+;; to be respected here.
-+
-+(define_insn_reservation "marvell_f_multiply_3" 3
-+ (and (eq_attr "tune" "marvell_f")
-+ (eq_attr "insn" "mla,mlas,smlal,umlal,smlaxy,smlalxy,smlawx,\
-+ smlawy,smlals,umlals"))
-+ "reg_shift_lock+m_1,m_2,m_3,m_wb")
-+
-+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-+;; Branch instructions
-+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-+
-+;; Conditional backward b instructions can have a zero-cycle penalty, and
-+;; other conditional b and bl instructions have a one-cycle penalty if
-+;; predicted correctly. Currently we model the zero-cycle case for all
-+;; branches.
-+
-+(define_insn_reservation "marvell_f_branches" 0
-+ (and (eq_attr "tune" "marvell_f")
-+ (eq_attr "type" "branch"))
-+ "nothing")
-+
-+;; Call latencies are not predictable; a semi-arbitrary very large
-+;; number is used as "positive infinity" for such latencies.
-+
-+(define_insn_reservation "marvell_f_call" 32
-+ (and (eq_attr "tune" "marvell_f")
-+ (eq_attr "type" "call"))
-+ "nothing")
-+
-+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-+;; Load/store instructions
-+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-+
-+;; The models for load/store instructions do not accurately describe
-+;; the difference between operations with a base register writeback.
-+;; These models assume that all memory references hit in dcache.
-+
-+;; 1. Load/store for single registers.
-+
-+;; The worst case for a load is when the load result is needed in E1
-+;; (for example for a register shift), giving a latency of four. Loads
-+;; skip E1 and access memory at the E2 stage.
-+
-+(define_insn_reservation "marvell_f_load1" 4
-+ (and (eq_attr "tune" "marvell_f")
-+ (eq_attr "type" "load1,load_byte"))
-+ "a1_e2+sram,a1_of,a1_wr,a1_wb")
-+
-+;; The result for a load may be bypassed (to be available at the same
-+;; time as the load arrives in the WR stage, so effectively at the OF
-+;; stage) to the Rn operand at E2 with a latency of two. The result may
-+;; be bypassed to a non-Rn operand at E2 with a latency of three. For
-+;; instructions without shifts, detection of an Rn bypass situation is
-+;; difficult (because some of the instruction patterns switch their
-+;; operands), and so we do not model that here. For instructions with
-+;; shifts, the operand used at E2 will always be Rn, and so we can
-+;; model the latency-two bypass for these.
-+
-+(define_bypass 2 "marvell_f_load1"
-+ "marvell_f_alu_shift_op"
-+ "arm_no_early_alu_shift_value_dep")
-+
-+(define_bypass 2 "marvell_f_load1"
-+ "marvell_f_alu_shift_reg_op"
-+ "arm_no_early_alu_shift_dep")
-+
-+;; Stores write at the WR stage and loads read at the E2 stage, giving
-+;; a store latency of three.
-+
-+(define_insn_reservation "marvell_f_store1" 3
-+ (and (eq_attr "tune" "marvell_f")
-+ (eq_attr "type" "store1"))
-+ "a1_e2,a1_of,a1_wr+sram,a1_wb")
-+
-+;; 2. Load/store for two consecutive registers. These may be dealt
-+;; with in the same number of cycles as single loads and stores.
-+
-+(define_insn_reservation "marvell_f_load2" 4
-+ (and (eq_attr "tune" "marvell_f")
-+ (eq_attr "type" "load2"))
-+ "a1_e2+sram,a1_of,a1_wr,a1_wb")
-+
-+(define_insn_reservation "marvell_f_store2" 3
-+ (and (eq_attr "tune" "marvell_f")
-+ (eq_attr "type" "store2"))
-+ "a1_e2,a1_of,a1_wr+sram,a1_wb")
-+
-+;; The first word of a doubleword load is eligible for the latency-two
-+;; bypass described above for single loads, but this is not modelled here.
-+;; We do however assume that either word may also be bypassed with
-+;; latency three for ALU operations with shifts (where the shift value and
-+;; amount do not depend on the loaded value) and latency four for ALU
-+;; operations without shifts. The latency four case is of course the default.
-+
-+(define_bypass 3 "marvell_f_load2"
-+ "marvell_f_alu_shift_op"
-+ "arm_no_early_alu_shift_value_dep")
-+
-+(define_bypass 3 "marvell_f_load2"
-+ "marvell_f_alu_shift_reg_op"
-+ "arm_no_early_alu_shift_dep")
-+
-+;; 3. Load/store for more than two registers.
-+
-+;; These instructions stall for an extra cycle in the decode stage;
-+;; individual load/store instructions for each register are then issued.
-+;; The load/store multiple instruction itself is removed from the decode
-+;; stage at the same time as the final load/store instruction is issued.
-+;; To complicate matters, pairs of loads/stores referencing two
-+;; consecutive registers will be issued together as doubleword operations.
-+;; We model a 3-word load as an LDR plus an LDRD, and a 4-word load
-+;; as two LDRDs; thus, these are allocated the same latencies (the
-+;; latency for two consecutive loads plus one for the setup stall).
-+;; The extra stall is modelled by reserving E1.
-+
-+(define_insn_reservation "marvell_f_load3_4" 6
-+ (and (eq_attr "tune" "marvell_f")
-+ (eq_attr "type" "load3,load4"))
-+ "a1_e1,a1_e1+a1_e2+sram,a1_e2+sram+a1_of,a1_of+a1_wr,a1_wr+a1_wb,a1_wb")
-+
-+;; Bypasses are possible for ldm as for single loads, but we do not
-+;; model them here since the order of the constituent loads is
-+;; difficult to predict.
-+
-+(define_insn_reservation "marvell_f_store3_4" 5
-+ (and (eq_attr "tune" "marvell_f")
-+ (eq_attr "type" "store3,store4"))
-+ "a1_e1,a1_e1+a1_e2,a1_e2+a1_of,a1_of+a1_wr+sram,a1_wr+sram+a1_wb,a1_wb")
-+
---- a/gcc/config/arm/neon-gen.ml
-+++ b/gcc/config/arm/neon-gen.ml
-@@ -122,6 +122,7 @@ let rec signed_ctype = function
- | T_uint16 | T_int16 -> T_intHI
- | T_uint32 | T_int32 -> T_intSI
- | T_uint64 | T_int64 -> T_intDI
-+ | T_float32 -> T_floatSF
- | T_poly8 -> T_intQI
- | T_poly16 -> T_intHI
- | T_arrayof (n, elt) -> T_arrayof (n, signed_ctype elt)
-@@ -320,7 +321,7 @@ let deftypes () =
- typeinfo;
- Format.print_newline ();
- (* Extra types not in <stdint.h>. *)
-- Format.printf "typedef __builtin_neon_sf float32_t;\n";
-+ Format.printf "typedef float float32_t;\n";
- Format.printf "typedef __builtin_neon_poly8 poly8_t;\n";
- Format.printf "typedef __builtin_neon_poly16 poly16_t;\n"
-
-@@ -399,7 +400,11 @@ let _ =
- "extern \"C\" {";
- "#endif";
- "";
-+"#if defined (__vxworks) && defined (_WRS_KERNEL)";
-+"#include <vxWorks.h>";
-+"#else";
- "#include <stdint.h>";
-+"#endif";
- ""];
- deftypes ();
- arrtypes ();
---- a/gcc/config/arm/neon-testgen.ml
-+++ b/gcc/config/arm/neon-testgen.ml
-@@ -51,8 +51,8 @@ let emit_prologue chan test_name =
- Printf.fprintf chan "/* This file was autogenerated by neon-testgen. */\n\n";
- Printf.fprintf chan "/* { dg-do assemble } */\n";
- Printf.fprintf chan "/* { dg-require-effective-target arm_neon_ok } */\n";
-- Printf.fprintf chan
-- "/* { dg-options \"-save-temps -O0 -mfpu=neon -mfloat-abi=softfp\" } */\n";
-+ Printf.fprintf chan "/* { dg-options \"-save-temps -O0\" } */\n";
-+ Printf.fprintf chan "/* { dg-add-options arm_neon } */\n";
- Printf.fprintf chan "\n#include \"arm_neon.h\"\n\n";
- Printf.fprintf chan "void test_%s (void)\n{\n" test_name
-
---- a/gcc/config/arm/neon.md
-+++ b/gcc/config/arm/neon.md
-@@ -159,7 +159,8 @@
- (UNSPEC_VUZP1 201)
- (UNSPEC_VUZP2 202)
- (UNSPEC_VZIP1 203)
-- (UNSPEC_VZIP2 204)])
-+ (UNSPEC_VZIP2 204)
-+ (UNSPEC_MISALIGNED_ACCESS 205)])
-
- ;; Double-width vector modes.
- (define_mode_iterator VD [V8QI V4HI V2SI V2SF])
-@@ -459,7 +460,9 @@
- "=w,Uv,w, w, ?r,?w,?r,?r, ?Us")
- (match_operand:VD 1 "general_operand"
- " w,w, Dn,Uvi, w, r, r, Usi,r"))]
-- "TARGET_NEON"
-+ "TARGET_NEON
-+ && (register_operand (operands[0], <MODE>mode)
-+ || register_operand (operands[1], <MODE>mode))"
- {
- if (which_alternative == 2)
- {
-@@ -481,7 +484,7 @@
-
- /* FIXME: If the memory layout is changed in big-endian mode, output_move_vfp
- below must be changed to output_move_neon (which will use the
-- element/structure loads/stores), and the constraint changed to 'Un' instead
-+ element/structure loads/stores), and the constraint changed to 'Um' instead
- of 'Uv'. */
-
- switch (which_alternative)
-@@ -506,7 +509,9 @@
- "=w,Un,w, w, ?r,?w,?r,?r, ?Us")
- (match_operand:VQXMOV 1 "general_operand"
- " w,w, Dn,Uni, w, r, r, Usi, r"))]
-- "TARGET_NEON"
-+ "TARGET_NEON
-+ && (register_operand (operands[0], <MODE>mode)
-+ || register_operand (operands[1], <MODE>mode))"
- {
- if (which_alternative == 2)
- {
-@@ -549,6 +554,11 @@
- (match_operand:TI 1 "general_operand" ""))]
- "TARGET_NEON"
- {
-+ if (can_create_pseudo_p ())
-+ {
-+ if (GET_CODE (operands[0]) != REG)
-+ operands[1] = force_reg (TImode, operands[1]);
-+ }
- })
-
- (define_expand "mov<mode>"
-@@ -556,12 +566,19 @@
- (match_operand:VSTRUCT 1 "general_operand" ""))]
- "TARGET_NEON"
- {
-+ if (can_create_pseudo_p ())
-+ {
-+ if (GET_CODE (operands[0]) != REG)
-+ operands[1] = force_reg (<MODE>mode, operands[1]);
-+ }
- })
-
- (define_insn "*neon_mov<mode>"
- [(set (match_operand:VSTRUCT 0 "nonimmediate_operand" "=w,Ut,w")
- (match_operand:VSTRUCT 1 "general_operand" " w,w, Ut"))]
-- "TARGET_NEON"
-+ "TARGET_NEON
-+ && (register_operand (operands[0], <MODE>mode)
-+ || register_operand (operands[1], <MODE>mode))"
- {
- switch (which_alternative)
- {
-@@ -658,6 +675,49 @@
- neon_disambiguate_copy (operands, dest, src, 4);
- })
-
-+(define_expand "movmisalign<mode>"
-+ [(set (match_operand:VDQX 0 "nonimmediate_operand" "")
-+ (unspec:VDQX [(match_operand:VDQX 1 "general_operand" "")]
-+ UNSPEC_MISALIGNED_ACCESS))]
-+ "TARGET_NEON && !BYTES_BIG_ENDIAN"
-+{
-+ if (!s_register_operand (operands[0], <MODE>mode)
-+ && !s_register_operand (operands[1], <MODE>mode))
-+ FAIL;
-+})
-+
-+(define_insn "*movmisalign<mode>_neon_store"
-+ [(set (match_operand:VDX 0 "memory_operand" "=Um")
-+ (unspec:VDX [(match_operand:VDX 1 "s_register_operand" " w")]
-+ UNSPEC_MISALIGNED_ACCESS))]
-+ "TARGET_NEON && !BYTES_BIG_ENDIAN"
-+ "vst1.<V_sz_elem>\t{%P1}, %A0"
-+ [(set_attr "neon_type" "neon_vst1_1_2_regs_vst2_2_regs")])
-+
-+(define_insn "*movmisalign<mode>_neon_load"
-+ [(set (match_operand:VDX 0 "s_register_operand" "=w")
-+ (unspec:VDX [(match_operand:VDX 1 "memory_operand" " Um")]
-+ UNSPEC_MISALIGNED_ACCESS))]
-+ "TARGET_NEON && !BYTES_BIG_ENDIAN"
-+ "vld1.<V_sz_elem>\t{%P0}, %A1"
-+ [(set_attr "neon_type" "neon_vld1_1_2_regs")])
-+
-+(define_insn "*movmisalign<mode>_neon_store"
-+ [(set (match_operand:VQX 0 "memory_operand" "=Um")
-+ (unspec:VQX [(match_operand:VQX 1 "s_register_operand" " w")]
-+ UNSPEC_MISALIGNED_ACCESS))]
-+ "TARGET_NEON && !BYTES_BIG_ENDIAN"
-+ "vst1.<V_sz_elem>\t{%q1}, %A0"
-+ [(set_attr "neon_type" "neon_vst1_1_2_regs_vst2_2_regs")])
-+
-+(define_insn "*movmisalign<mode>_neon_load"
-+ [(set (match_operand:VQX 0 "s_register_operand" "=w")
-+ (unspec:VQX [(match_operand:VQX 1 "general_operand" " Um")]
-+ UNSPEC_MISALIGNED_ACCESS))]
-+ "TARGET_NEON && !BYTES_BIG_ENDIAN"
-+ "vld1.<V_sz_elem>\t{%q0}, %A1"
-+ [(set_attr "neon_type" "neon_vld1_1_2_regs")])
-+
- (define_insn "vec_set<mode>_internal"
- [(set (match_operand:VD 0 "s_register_operand" "=w")
- (vec_merge:VD
-@@ -862,6 +922,50 @@
- (const_string "neon_mul_qqq_8_16_32_ddd_32")))))]
- )
-
-+(define_insn "*mul<mode>3add<mode>_neon"
-+ [(set (match_operand:VDQ 0 "s_register_operand" "=w")
-+ (plus:VDQ (mult:VDQ (match_operand:VDQ 2 "s_register_operand" "w")
-+ (match_operand:VDQ 3 "s_register_operand" "w"))
-+ (match_operand:VDQ 1 "s_register_operand" "0")))]
-+ "TARGET_NEON"
-+ "vmla.<V_if_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3"
-+ [(set (attr "neon_type")
-+ (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
-+ (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
-+ (const_string "neon_fp_vmla_ddd")
-+ (const_string "neon_fp_vmla_qqq"))
-+ (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
-+ (if_then_else
-+ (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
-+ (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
-+ (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))
-+ (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
-+ (const_string "neon_mla_qqq_8_16")
-+ (const_string "neon_mla_qqq_32_qqd_32_scalar")))))]
-+)
-+
-+(define_insn "*mul<mode>3neg<mode>add<mode>_neon"
-+ [(set (match_operand:VDQ 0 "s_register_operand" "=w")
-+ (minus:VDQ (match_operand:VDQ 1 "s_register_operand" "0")
-+ (mult:VDQ (match_operand:VDQ 2 "s_register_operand" "w")
-+ (match_operand:VDQ 3 "s_register_operand" "w"))))]
-+ "TARGET_NEON"
-+ "vmls.<V_if_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3"
-+ [(set (attr "neon_type")
-+ (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
-+ (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
-+ (const_string "neon_fp_vmla_ddd")
-+ (const_string "neon_fp_vmla_qqq"))
-+ (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
-+ (if_then_else
-+ (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
-+ (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
-+ (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))
-+ (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
-+ (const_string "neon_mla_qqq_8_16")
-+ (const_string "neon_mla_qqq_32_qqd_32_scalar")))))]
-+)
-+
- (define_insn "ior<mode>3"
- [(set (match_operand:VDQ 0 "s_register_operand" "=w,w")
- (ior:VDQ (match_operand:VDQ 1 "s_register_operand" "w,0")
---- a/gcc/config/arm/neon.ml
-+++ b/gcc/config/arm/neon.ml
-@@ -50,7 +50,7 @@ type vectype = T_int8x8 | T_int8x16
- | T_ptrto of vectype | T_const of vectype
- | T_void | T_intQI
- | T_intHI | T_intSI
-- | T_intDI
-+ | T_intDI | T_floatSF
-
- (* The meanings of the following are:
- TImode : "Tetra", two registers (four words).
-@@ -1693,6 +1693,7 @@ let string_of_vectype vt =
- | T_intHI -> "__builtin_neon_hi"
- | T_intSI -> "__builtin_neon_si"
- | T_intDI -> "__builtin_neon_di"
-+ | T_floatSF -> "__builtin_neon_sf"
- | T_arrayof (num, base) ->
- let basename = name (fun x -> x) base in
- affix (Printf.sprintf "%sx%d" basename num)
---- a/gcc/config/arm/netbsd-elf.h
-+++ b/gcc/config/arm/netbsd-elf.h
-@@ -153,5 +153,5 @@ do \
- while (0)
-
- #undef FPUTYPE_DEFAULT
--#define FPUTYPE_DEFAULT FPUTYPE_VFP
-+#define FPUTYPE_DEFAULT "vfp"
-
---- /dev/null
-+++ b/gcc/config/arm/nocrt0.h
-@@ -0,0 +1,25 @@
-+/* Definitions for generic libgloss based cofigs where crt0 is supplied by
-+ the linker script.
-+ Copyright (C) 2006 Free Software Foundation, Inc.
-+
-+ This file is part of GCC.
-+
-+ GCC is free software; you can redistribute it and/or modify it
-+ under the terms of the GNU General Public License as published
-+ by the Free Software Foundation; either version 3, or (at your
-+ option) any later version.
-+
-+ GCC is distributed in the hope that it will be useful, but WITHOUT
-+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
-+ License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with GCC; see the file COPYING3. If not see
-+ <http://www.gnu.org/licenses/>. */
-+
-+#undef STARTFILE_SPEC
-+#define STARTFILE_SPEC " crti%O%s crtbegin%O%s"
-+
-+#undef LIB_SPEC
-+#define LIB_SPEC "-lc"
---- a/gcc/config/arm/predicates.md
-+++ b/gcc/config/arm/predicates.md
-@@ -73,6 +73,10 @@
- || REGNO_REG_CLASS (REGNO (op)) == FPA_REGS));
- })
-
-+(define_special_predicate "subreg_lowpart_operator"
-+ (and (match_code "subreg")
-+ (match_test "subreg_lowpart_p (op)")))
-+
- ;; Reg, subreg(reg) or const_int.
- (define_predicate "reg_or_int_operand"
- (ior (match_code "const_int")
-@@ -168,6 +172,11 @@
- (and (match_code "plus,minus,ior,xor,and")
- (match_test "mode == GET_MODE (op)")))
-
-+;; True for plus/minus operators
-+(define_special_predicate "plusminus_operator"
-+ (and (match_code "plus,minus")
-+ (match_test "mode == GET_MODE (op)")))
-+
- ;; True for logical binary operators.
- (define_special_predicate "logical_binary_operator"
- (and (match_code "ior,xor,and")
-@@ -295,6 +304,9 @@
- HOST_WIDE_INT i = 1, base = 0;
- rtx elt;
-
-+ if (low_irq_latency)
-+ return false;
-+
- if (count <= 1
- || GET_CODE (XVECEXP (op, 0, 0)) != SET)
- return false;
-@@ -352,6 +364,9 @@
- HOST_WIDE_INT i = 1, base = 0;
- rtx elt;
-
-+ if (low_irq_latency)
-+ return false;
-+
- if (count <= 1
- || GET_CODE (XVECEXP (op, 0, 0)) != SET)
- return false;
---- a/gcc/config/arm/sfp-machine.h
-+++ b/gcc/config/arm/sfp-machine.h
-@@ -14,9 +14,11 @@
- #define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_2_udiv(D,R,X,Y)
- #define _FP_DIV_MEAT_Q(R,X,Y) _FP_DIV_MEAT_4_udiv(Q,R,X,Y)
-
-+#define _FP_NANFRAC_H ((_FP_QNANBIT_H << 1) - 1)
- #define _FP_NANFRAC_S ((_FP_QNANBIT_S << 1) - 1)
- #define _FP_NANFRAC_D ((_FP_QNANBIT_D << 1) - 1), -1
- #define _FP_NANFRAC_Q ((_FP_QNANBIT_Q << 1) - 1), -1, -1, -1
-+#define _FP_NANSIGN_H 0
- #define _FP_NANSIGN_S 0
- #define _FP_NANSIGN_D 0
- #define _FP_NANSIGN_Q 0
-@@ -92,5 +94,7 @@
- #define __fixdfdi __aeabi_d2lz
- #define __fixunsdfdi __aeabi_d2ulz
- #define __floatdidf __aeabi_l2d
-+#define __extendhfsf2 __gnu_h2f_ieee
-+#define __truncsfhf2 __gnu_f2h_ieee
-
- #endif /* __ARM_EABI__ */
---- a/gcc/config/arm/t-arm
-+++ b/gcc/config/arm/t-arm
-@@ -13,7 +13,9 @@ MD_INCLUDES= $(srcdir)/config/arm/arm-t
- $(srcdir)/config/arm/iwmmxt.md \
- $(srcdir)/config/arm/vfp.md \
- $(srcdir)/config/arm/neon.md \
-- $(srcdir)/config/arm/thumb2.md
-+ $(srcdir)/config/arm/thumb2.md \
-+ $(srcdir)/config/arm/marvell-f.md \
-+ $(srcdir)/config/arm/hwdiv.md
-
- s-config s-conditions s-flags s-codes s-constants s-emit s-recog s-preds \
- s-opinit s-extract s-peep s-attr s-attrtab s-output: $(MD_INCLUDES)
---- a/gcc/config/arm/t-arm-elf
-+++ b/gcc/config/arm/t-arm-elf
-@@ -24,10 +24,18 @@ MULTILIB_MATCHES =
- #MULTILIB_MATCHES += march?armv7=march?armv7-a
- #MULTILIB_MATCHES += march?armv7=march?armv7-r
- #MULTILIB_MATCHES += march?armv7=march?armv7-m
-+#MULTILIB_MATCHES += march?armv7=march?armv7e-m
- #MULTILIB_MATCHES += march?armv7=mcpu?cortex-a8
- #MULTILIB_MATCHES += march?armv7=mcpu?cortex-r4
- #MULTILIB_MATCHES += march?armv7=mcpu?cortex-m3
-
-+# Not quite true. We can support hard-vfp calling in Thumb2, but how do we
-+# express that here? Also, we really need architecture v5e or later
-+# (mcrr etc).
-+MULTILIB_OPTIONS += mfloat-abi=hard
-+MULTILIB_DIRNAMES += fpu
-+MULTILIB_EXCEPTIONS += *mthumb/*mfloat-abi=hard*
-+
- # MULTILIB_OPTIONS += mcpu=ep9312
- # MULTILIB_DIRNAMES += ep9312
- # MULTILIB_EXCEPTIONS += *mthumb/*mcpu=ep9312*
---- /dev/null
-+++ b/gcc/config/arm/t-asa
-@@ -0,0 +1,45 @@
-+# Overrides for ASA
-+
-+# Here is the expected output from xgcc -print-multi-lib.
-+#
-+# .;@fno-omit-frame-pointer@mapcs-frame
-+# armv4t;@march=armv4t@fno-omit-frame-pointer@mapcs-frame
-+# armv6;@march=armv6@fno-omit-frame-pointer@mapcs-frame
-+# armv7a;@march=armv7-a@fno-omit-frame-pointer@mapcs-frame
-+# armv6f;@march=armv6@mfloat-abi=softfp@fno-omit-frame-pointer@mapcs-frame
-+# armv7af;@march=armv7-a@mfpu=neon@mfloat-abi=softfp@fno-omit-frame-pointer@mapcs-frame
-+# thumb2;@mthumb@march=armv7-a@fno-omit-frame-pointer@mapcs-frame
-+# thumb2f;@mthumb@march=armv7-a@mfpu=neon@mfloat-abi=softfp@fno-omit-frame-pointer@mapcs-frame
-+
-+MULTILIB_OPTIONS = mthumb march=armv4t/march=armv6/march=armv7-a mfpu=neon mfloat-abi=softfp
-+MULTILIB_DIRNAMES = thumb v4t v6 v7a neon softfp
-+MULTILIB_MATCHES =
-+
-+MULTILIB_EXTRA_OPTS = fno-omit-frame-pointer mapcs-frame
-+
-+MULTILIB_EXCEPTIONS = mthumb
-+MULTILIB_EXCEPTIONS += mfpu=neon*
-+MULTILIB_EXCEPTIONS += mfloat-abi=softfp
-+MULTILIB_EXCEPTIONS += *march=armv4t*/*mfpu=neon*
-+MULTILIB_EXCEPTIONS += *march=armv4t*/*mfloat-abi=softfp*
-+MULTILIB_EXCEPTIONS += march=armv6/*mfpu=neon*
-+MULTILIB_EXCEPTIONS += mthumb/mfpu=neon
-+MULTILIB_EXCEPTIONS += mthumb/mfloat-abi=softfp
-+MULTILIB_EXCEPTIONS += mthumb/mfpu=neon*
-+MULTILIB_EXCEPTIONS += mthumb/march=armv6/mfpu=neon*
-+
-+MULTILIB_OSDIRNAMES = march.armv4t=!armv4t
-+MULTILIB_OSDIRNAMES += march.armv6=!armv6
-+MULTILIB_OSDIRNAMES += march.armv6/mfloat-abi.softfp=!armv6f
-+MULTILIB_OSDIRNAMES += march.armv7-a=!armv7a
-+MULTILIB_OSDIRNAMES += march.armv7-a/mfpu.neon/mfloat-abi.softfp=!armv7af
-+MULTILIB_OSDIRNAMES += mthumb/march.armv7-a=!thumb2
-+MULTILIB_OSDIRNAMES += mthumb/march.armv7-a/mfpu.neon/mfloat-abi.softfp=!thumb2f
-+
-+MULTILIB_ALIASES = march?armv4t=mthumb/march?armv4t
-+MULTILIB_ALIASES += march?armv6=mthumb/march?armv6
-+MULTILIB_ALIASES += march?armv6/mfloat-abi?softfp=mthumb/march?armv6/mfloat-abi?softfp
-+MULTILIB_ALIASES += march?armv7-a/mfpu?neon/mfloat-abi?softfp=march?armv7-a/mfpu?neon
-+MULTILIB_ALIASES += march?armv7-a/mfpu?neon/mfloat-abi?softfp=march?armv7-a/mfloat-abi?softfp
-+MULTILIB_ALIASES += mthumb/march?armv7-a/mfpu?neon/mfloat-abi?softfp=mthumb/march?armv7-a/mfpu?neon
-+MULTILIB_ALIASES += mthumb/march?armv7-a/mfpu?neon/mfloat-abi?softfp=mthumb/march?armv7-a/mfloat-abi?softfp
---- a/gcc/config/arm/t-bpabi
-+++ b/gcc/config/arm/t-bpabi
-@@ -1,10 +1,13 @@
- # Add the bpabi.S functions.
--LIB1ASMFUNCS += _aeabi_lcmp _aeabi_ulcmp _aeabi_ldivmod _aeabi_uldivmod
-+LIB1ASMFUNCS += _aeabi_lcmp _aeabi_ulcmp _aeabi_ldivmod _aeabi_uldivmod \
-+ _aeabi_idiv0 _aeabi_ldiv0
-
- # Add the BPABI C functions.
- LIB2FUNCS_EXTRA = $(srcdir)/config/arm/bpabi.c \
- $(srcdir)/config/arm/unaligned-funcs.c
-
-+LIB2FUNCS_STATIC_EXTRA = $(srcdir)/config/arm/fp16.c
-+
- UNWIND_H = $(srcdir)/config/arm/unwind-arm.h
- LIB2ADDEH = $(srcdir)/config/arm/unwind-arm.c \
- $(srcdir)/config/arm/libunwind.S \
---- a/gcc/config/arm/t-linux-eabi
-+++ b/gcc/config/arm/t-linux-eabi
-@@ -6,8 +6,8 @@ TARGET_LIBGCC2_CFLAGS = -fPIC
- MULTILIB_OPTIONS =
- MULTILIB_DIRNAMES =
-
--# Use a version of div0 which raises SIGFPE.
--LIB1ASMFUNCS := $(filter-out _dvmd_tls,$(LIB1ASMFUNCS)) _dvmd_lnx
-+# Use a version of div0 which raises SIGFPE, and a special __clear_cache.
-+LIB1ASMFUNCS := $(filter-out _dvmd_tls,$(LIB1ASMFUNCS)) _dvmd_lnx _clear_cache
-
- # Multilib the standard Linux files. Don't include crti.o or crtn.o,
- # which are provided by glibc.
---- a/gcc/config/arm/t-symbian
-+++ b/gcc/config/arm/t-symbian
-@@ -17,6 +17,9 @@ UNWIND_H = $(srcdir)/config/arm/unwind-a
- LIB2ADDEH = $(srcdir)/unwind-c.c $(srcdir)/config/arm/pr-support.c
- LIB2ADDEHDEP = $(UNWIND_H)
-
-+# Include half-float helpers.
-+LIB2FUNCS_STATIC_EXTRA = $(srcdir)/config/arm/fp16.c
-+
- # Create a multilib for processors with VFP floating-point, and a
- # multilib for those without -- using the soft-float ABI in both
- # cases. Symbian OS object should be compiled with interworking
---- a/gcc/config/arm/thumb2.md
-+++ b/gcc/config/arm/thumb2.md
-@@ -24,6 +24,8 @@
- ;; changes made in armv5t as "thumb2". These are considered part
- ;; the 16-bit Thumb-1 instruction set.
-
-+(include "hwdiv.md")
-+
- (define_insn "*thumb2_incscc"
- [(set (match_operand:SI 0 "s_register_operand" "=r,r")
- (plus:SI (match_operator:SI 2 "arm_comparison_operator"
-@@ -172,34 +174,6 @@
- (set_attr "length" "8")]
- )
-
--(define_insn "*thumb2_abssi2"
-- [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
-- (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
-- (clobber (reg:CC CC_REGNUM))]
-- "TARGET_THUMB2"
-- "@
-- cmp\\t%0, #0\;it\tlt\;rsblt\\t%0, %0, #0
-- eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31"
-- [(set_attr "conds" "clob,*")
-- (set_attr "shift" "1")
-- ;; predicable can't be set based on the variant, so left as no
-- (set_attr "length" "10,8")]
--)
--
--(define_insn "*thumb2_neg_abssi2"
-- [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
-- (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
-- (clobber (reg:CC CC_REGNUM))]
-- "TARGET_THUMB2"
-- "@
-- cmp\\t%0, #0\;it\\tgt\;rsbgt\\t%0, %0, #0
-- eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31"
-- [(set_attr "conds" "clob,*")
-- (set_attr "shift" "1")
-- ;; predicable can't be set based on the variant, so left as no
-- (set_attr "length" "10,8")]
--)
--
- (define_insn "*thumb2_movdi"
- [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, r, m")
- (match_operand:DI 1 "di_operand" "rDa,Db,Dc,mi,r"))]
-@@ -223,9 +197,14 @@
- (set_attr "neg_pool_range" "*,*,*,0,*")]
- )
-
-+;; We have two alternatives here for memory loads (and similarly for stores)
-+;; to reflect the fact that the permissible constant pool ranges differ
-+;; between ldr instructions taking low regs and ldr instructions taking high
-+;; regs. The high register alternatives are not taken into account when
-+;; choosing register preferences in order to reflect their expense.
- (define_insn "*thumb2_movsi_insn"
-- [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
-- (match_operand:SI 1 "general_operand" "rk ,I,K,N,mi,rk"))]
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,l,*hk,m,*m")
-+ (match_operand:SI 1 "general_operand" "rk ,I,K,j,mi,*mi,l,*hk"))]
- "TARGET_THUMB2 && ! TARGET_IWMMXT
- && !(TARGET_HARD_FLOAT && TARGET_VFP)
- && ( register_operand (operands[0], SImode)
-@@ -236,11 +215,13 @@
- mvn%?\\t%0, #%B1
- movw%?\\t%0, %1
- ldr%?\\t%0, %1
-+ ldr%?\\t%0, %1
-+ str%?\\t%1, %0
- str%?\\t%1, %0"
-- [(set_attr "type" "*,*,*,*,load1,store1")
-+ [(set_attr "type" "*,*,*,*,load1,load1,store1,store1")
- (set_attr "predicable" "yes")
-- (set_attr "pool_range" "*,*,*,*,4096,*")
-- (set_attr "neg_pool_range" "*,*,*,*,0,*")]
-+ (set_attr "pool_range" "*,*,*,*,1020,4096,*,*")
-+ (set_attr "neg_pool_range" "*,*,*,*,0,0,*,*")]
- )
-
- ;; ??? We can probably do better with thumb2
-@@ -1128,27 +1109,7 @@
- return \"add%!\\t%0, %1, %2\";
- "
- [(set_attr "predicable" "yes")
-- (set_attr "length" "2")]
--)
--
--(define_insn "divsi3"
-- [(set (match_operand:SI 0 "s_register_operand" "=r")
-- (div:SI (match_operand:SI 1 "s_register_operand" "r")
-- (match_operand:SI 2 "s_register_operand" "r")))]
-- "TARGET_THUMB2 && arm_arch_hwdiv"
-- "sdiv%?\t%0, %1, %2"
-- [(set_attr "predicable" "yes")
-- (set_attr "insn" "sdiv")]
--)
--
--(define_insn "udivsi3"
-- [(set (match_operand:SI 0 "s_register_operand" "=r")
-- (udiv:SI (match_operand:SI 1 "s_register_operand" "r")
-- (match_operand:SI 2 "s_register_operand" "r")))]
-- "TARGET_THUMB2 && arm_arch_hwdiv"
-- "udiv%?\t%0, %1, %2"
-- [(set_attr "predicable" "yes")
-- (set_attr "insn" "udiv")]
-+ (set_attr "length" "4")]
- )
-
- (define_insn "*thumb2_subsi_short"
-@@ -1162,6 +1123,71 @@
- (set_attr "length" "2")]
- )
-
-+;; 16-bit encodings of "muls" and "mul<c>". We only use these when
-+;; optimizing for size since "muls" is slow on all known
-+;; implementations and since "mul<c>" will be generated by
-+;; "*arm_mulsi3_v6" anyhow. The assembler will use a 16-bit encoding
-+;; for "mul<c>" whenever possible anyhow.
-+(define_peephole2
-+ [(set (match_operand:SI 0 "low_register_operand" "")
-+ (mult:SI (match_operand:SI 1 "low_register_operand" "")
-+ (match_dup 0)))]
-+ "TARGET_THUMB2 && optimize_size && peep2_regno_dead_p (0, CC_REGNUM)"
-+ [(parallel
-+ [(set (match_dup 0)
-+ (mult:SI (match_dup 0) (match_dup 1)))
-+ (clobber (reg:CC CC_REGNUM))])]
-+ ""
-+)
-+
-+(define_peephole2
-+ [(set (match_operand:SI 0 "low_register_operand" "")
-+ (mult:SI (match_dup 0)
-+ (match_operand:SI 1 "low_register_operand" "")))]
-+ "TARGET_THUMB2 && optimize_size && peep2_regno_dead_p (0, CC_REGNUM)"
-+ [(parallel
-+ [(set (match_dup 0)
-+ (mult:SI (match_dup 0) (match_dup 1)))
-+ (clobber (reg:CC CC_REGNUM))])]
-+ ""
-+)
-+
-+(define_insn "*thumb2_mulsi_short"
-+ [(set (match_operand:SI 0 "low_register_operand" "=l")
-+ (mult:SI (match_operand:SI 1 "low_register_operand" "%0")
-+ (match_operand:SI 2 "low_register_operand" "l")))
-+ (clobber (reg:CC CC_REGNUM))]
-+ "TARGET_THUMB2 && optimize_size && reload_completed"
-+ "mul%!\\t%0, %2, %0"
-+ [(set_attr "predicable" "yes")
-+ (set_attr "length" "2")
-+ (set_attr "insn" "muls")])
-+
-+(define_insn "*thumb2_mulsi_short_compare0"
-+ [(set (reg:CC_NOOV CC_REGNUM)
-+ (compare:CC_NOOV
-+ (mult:SI (match_operand:SI 1 "register_operand" "%0")
-+ (match_operand:SI 2 "register_operand" "l"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "register_operand" "=l")
-+ (mult:SI (match_dup 1) (match_dup 2)))]
-+ "TARGET_THUMB2 && optimize_size"
-+ "muls\\t%0, %2, %0"
-+ [(set_attr "length" "2")
-+ (set_attr "insn" "muls")])
-+
-+(define_insn "*thumb2_mulsi_short_compare0_scratch"
-+ [(set (reg:CC_NOOV CC_REGNUM)
-+ (compare:CC_NOOV
-+ (mult:SI (match_operand:SI 1 "register_operand" "%0")
-+ (match_operand:SI 2 "register_operand" "l"))
-+ (const_int 0)))
-+ (clobber (match_scratch:SI 0 "=r"))]
-+ "TARGET_THUMB2 && optimize_size"
-+ "muls\\t%0, %2, %0"
-+ [(set_attr "length" "2")
-+ (set_attr "insn" "muls")])
-+
- (define_insn "*thumb2_cbz"
- [(set (pc) (if_then_else
- (eq (match_operand:SI 0 "s_register_operand" "l,?r")
-@@ -1171,7 +1197,7 @@
- (clobber (reg:CC CC_REGNUM))]
- "TARGET_THUMB2"
- "*
-- if (get_attr_length (insn) == 2 && which_alternative == 0)
-+ if (get_attr_length (insn) == 2)
- return \"cbz\\t%0, %l1\";
- else
- return \"cmp\\t%0, #0\;beq\\t%l1\";
-@@ -1179,7 +1205,8 @@
- [(set (attr "length")
- (if_then_else
- (and (ge (minus (match_dup 1) (pc)) (const_int 2))
-- (le (minus (match_dup 1) (pc)) (const_int 128)))
-+ (le (minus (match_dup 1) (pc)) (const_int 128))
-+ (eq (symbol_ref ("which_alternative")) (const_int 0)))
- (const_int 2)
- (const_int 8)))]
- )
-@@ -1193,7 +1220,7 @@
- (clobber (reg:CC CC_REGNUM))]
- "TARGET_THUMB2"
- "*
-- if (get_attr_length (insn) == 2 && which_alternative == 0)
-+ if (get_attr_length (insn) == 2)
- return \"cbnz\\t%0, %l1\";
- else
- return \"cmp\\t%0, #0\;bne\\t%l1\";
-@@ -1201,7 +1228,8 @@
- [(set (attr "length")
- (if_then_else
- (and (ge (minus (match_dup 1) (pc)) (const_int 2))
-- (le (minus (match_dup 1) (pc)) (const_int 128)))
-+ (le (minus (match_dup 1) (pc)) (const_int 128))
-+ (eq (symbol_ref ("which_alternative")) (const_int 0)))
- (const_int 2)
- (const_int 8)))]
- )
---- a/gcc/config/arm/uclinux-eabi.h
-+++ b/gcc/config/arm/uclinux-eabi.h
-@@ -50,6 +50,10 @@
- #undef ARM_DEFAULT_ABI
- #define ARM_DEFAULT_ABI ARM_ABI_AAPCS_LINUX
-
-+#undef LINK_GCC_C_SEQUENCE_SPEC
-+#define LINK_GCC_C_SEQUENCE_SPEC \
-+ "--start-group %G %L --end-group"
-+
- /* Clear the instruction cache from `beg' to `end'. This makes an
- inline system call to SYS_cacheflush. */
- #undef CLEAR_INSN_CACHE
---- a/gcc/config/arm/unwind-arm.c
-+++ b/gcc/config/arm/unwind-arm.c
-@@ -1000,7 +1000,6 @@ __gnu_Unwind_Backtrace(_Unwind_Trace_Fn
- while (code != _URC_END_OF_STACK
- && code != _URC_FAILURE);
-
-- finish:
- restore_non_core_regs (&saved_vrs);
- return code;
- }
-@@ -1168,6 +1167,9 @@ __gnu_unwind_pr_common (_Unwind_State st
- {
- matched = (void *)(ucbp + 1);
- rtti = _Unwind_decode_target2 ((_uw) &data[i + 1]);
-+ /* There is no way to encode an exception
-+ specification for 'class X * &', so
-+ always pass false for is_reference. */
- if (__cxa_type_match (ucbp, (type_info *) rtti, 0,
- &matched))
- break;
-@@ -1197,8 +1199,6 @@ __gnu_unwind_pr_common (_Unwind_State st
- ucbp->barrier_cache.bitpattern[4] = (_uw) &data[1];
-
- if (data[0] & uint32_highbit)
-- phase2_call_unexpected_after_unwind = 1;
-- else
- {
- data += rtti_count + 1;
- /* Setup for entry to the handler. */
-@@ -1208,6 +1208,8 @@ __gnu_unwind_pr_common (_Unwind_State st
- _Unwind_SetGR (context, 0, (_uw) ucbp);
- return _URC_INSTALL_CONTEXT;
- }
-+ else
-+ phase2_call_unexpected_after_unwind = 1;
- }
- if (data[0] & uint32_highbit)
- data++;
---- a/gcc/config/arm/unwind-arm.h
-+++ b/gcc/config/arm/unwind-arm.h
-@@ -229,9 +229,10 @@ extern "C" {
- return 0;
-
- #if (defined(linux) && !defined(__uClinux__)) || defined(__NetBSD__)
-- /* Pc-relative indirect. */
-+ /* Pc-relative indirect. Propagate the bottom 2 bits, which can
-+ contain referenceness information in gnu unwinding tables. */
- tmp += ptr;
-- tmp = *(_Unwind_Word *) tmp;
-+ tmp = *(_Unwind_Word *) (tmp & ~(_Unwind_Word)3) | (tmp & 3);
- #elif defined(__symbian__) || defined(__uClinux__)
- /* Absolute pointer. Nothing more to do. */
- #else
---- a/gcc/config/arm/vec-common.md
-+++ b/gcc/config/arm/vec-common.md
-@@ -38,6 +38,11 @@
- "TARGET_NEON
- || (TARGET_REALLY_IWMMXT && VALID_IWMMXT_REG_MODE (<MODE>mode))"
- {
-+ if (can_create_pseudo_p ())
-+ {
-+ if (GET_CODE (operands[0]) != REG)
-+ operands[1] = force_reg (<MODE>mode, operands[1]);
-+ }
- })
-
- ;; Vector arithmetic. Expanders are blank, then unnamed insns implement
---- a/gcc/config/arm/vfp.md
-+++ b/gcc/config/arm/vfp.md
-@@ -51,7 +51,7 @@
- ;; problems because small constants get converted into adds.
- (define_insn "*arm_movsi_vfp"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m ,*t,r,*t,*t, *Uv")
-- (match_operand:SI 1 "general_operand" "rk, I,K,N,mi,rk,r,*t,*t,*Uvi,*t"))]
-+ (match_operand:SI 1 "general_operand" "rk, I,K,j,mi,rk,r,*t,*t,*Uvi,*t"))]
- "TARGET_ARM && TARGET_VFP && TARGET_HARD_FLOAT
- && ( s_register_operand (operands[0], SImode)
- || s_register_operand (operands[1], SImode))"
-@@ -82,13 +82,17 @@
- "
- [(set_attr "predicable" "yes")
- (set_attr "type" "*,*,*,*,load1,store1,r_2_f,f_2_r,fcpys,f_loads,f_stores")
-+ (set_attr "neon_type" "*,*,*,*,*,*,neon_mcr,neon_mrc,neon_vmov,*,*")
-+ (set_attr "insn" "mov,mov,mvn,mov,*,*,*,*,*,*,*")
- (set_attr "pool_range" "*,*,*,*,4096,*,*,*,*,1020,*")
- (set_attr "neg_pool_range" "*,*,*,*,4084,*,*,*,*,1008,*")]
- )
-
-+;; See thumb2.md:thumb2_movsi_insn for an explanation of the split
-+;; high/low register alternatives for loads and stores here.
- (define_insn "*thumb2_movsi_vfp"
-- [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m,*t,r, *t,*t, *Uv")
-- (match_operand:SI 1 "general_operand" "rk, I,K,N,mi,rk,r,*t,*t,*Uvi,*t"))]
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,l,*hk,m,*m,*t,r, *t,*t, *Uv")
-+ (match_operand:SI 1 "general_operand" "rk, I,K,j,mi,*mi,l,*hk,r,*t,*t,*Uvi,*t"))]
- "TARGET_THUMB2 && TARGET_VFP && TARGET_HARD_FLOAT
- && ( s_register_operand (operands[0], SImode)
- || s_register_operand (operands[1], SImode))"
-@@ -102,25 +106,29 @@
- case 3:
- return \"movw%?\\t%0, %1\";
- case 4:
-- return \"ldr%?\\t%0, %1\";
- case 5:
-- return \"str%?\\t%1, %0\";
-+ return \"ldr%?\\t%0, %1\";
- case 6:
-- return \"fmsr%?\\t%0, %1\\t%@ int\";
- case 7:
-- return \"fmrs%?\\t%0, %1\\t%@ int\";
-+ return \"str%?\\t%1, %0\";
- case 8:
-+ return \"fmsr%?\\t%0, %1\\t%@ int\";
-+ case 9:
-+ return \"fmrs%?\\t%0, %1\\t%@ int\";
-+ case 10:
- return \"fcpys%?\\t%0, %1\\t%@ int\";
-- case 9: case 10:
-+ case 11: case 12:
- return output_move_vfp (operands);
- default:
- gcc_unreachable ();
- }
- "
- [(set_attr "predicable" "yes")
-- (set_attr "type" "*,*,*,*,load1,store1,r_2_f,f_2_r,fcpys,f_load,f_store")
-- (set_attr "pool_range" "*,*,*,*,4096,*,*,*,*,1020,*")
-- (set_attr "neg_pool_range" "*,*,*,*, 0,*,*,*,*,1008,*")]
-+ (set_attr "type" "*,*,*,*,load1,load1,store1,store1,r_2_f,f_2_r,fcpys,f_load,f_store")
-+ (set_attr "neon_type" "*,*,*,*,*,*,*,*,neon_mcr,neon_mrc,neon_vmov,*,*")
-+ (set_attr "insn" "mov,mov,mvn,mov,*,*,*,*,*,*,*,*,*")
-+ (set_attr "pool_range" "*,*,*,*,1020,4096,*,*,*,*,*,1020,*")
-+ (set_attr "neg_pool_range" "*,*,*,*, 0, 0,*,*,*,*,*,1008,*")]
- )
-
-
-@@ -145,7 +153,10 @@
- case 4:
- return \"fmrrd%?\\t%Q0, %R0, %P1\\t%@ int\";
- case 5:
-- return \"fcpyd%?\\t%P0, %P1\\t%@ int\";
-+ if (TARGET_VFP_SINGLE)
-+ return \"fcpys%?\\t%0, %1\\t%@ int\;fcpys%?\\t%p0, %p1\\t%@ int\";
-+ else
-+ return \"fcpyd%?\\t%P0, %P1\\t%@ int\";
- case 6: case 7:
- return output_move_vfp (operands);
- default:
-@@ -153,7 +164,14 @@
- }
- "
- [(set_attr "type" "*,load2,store2,r_2_f,f_2_r,ffarithd,f_loadd,f_stored")
-- (set_attr "length" "8,8,8,4,4,4,4,4")
-+ (set_attr "neon_type" "*,*,*,neon_mcr_2_mcrr,neon_mrrc,neon_vmov,*,*")
-+ (set (attr "length") (cond [(eq_attr "alternative" "0,1,2") (const_int 8)
-+ (eq_attr "alternative" "5")
-+ (if_then_else
-+ (eq (symbol_ref "TARGET_VFP_SINGLE") (const_int 1))
-+ (const_int 8)
-+ (const_int 4))]
-+ (const_int 4)))
- (set_attr "pool_range" "*,1020,*,*,*,*,1020,*")
- (set_attr "neg_pool_range" "*,1008,*,*,*,*,1008,*")]
- )
-@@ -172,7 +190,10 @@
- case 4:
- return \"fmrrd%?\\t%Q0, %R0, %P1\\t%@ int\";
- case 5:
-- return \"fcpyd%?\\t%P0, %P1\\t%@ int\";
-+ if (TARGET_VFP_SINGLE)
-+ return \"fcpys%?\\t%0, %1\\t%@ int\;fcpys%?\\t%p0, %p1\\t%@ int\";
-+ else
-+ return \"fcpyd%?\\t%P0, %P1\\t%@ int\";
- case 6: case 7:
- return output_move_vfp (operands);
- default:
-@@ -180,11 +201,123 @@
- }
- "
- [(set_attr "type" "*,load2,store2,r_2_f,f_2_r,ffarithd,f_load,f_store")
-- (set_attr "length" "8,8,8,4,4,4,4,4")
-+ (set_attr "neon_type" "*,*,*,neon_mcr_2_mcrr,neon_mrrc,neon_vmov,*,*")
-+ (set (attr "length") (cond [(eq_attr "alternative" "0,1,2") (const_int 8)
-+ (eq_attr "alternative" "5")
-+ (if_then_else
-+ (eq (symbol_ref "TARGET_VFP_SINGLE") (const_int 1))
-+ (const_int 8)
-+ (const_int 4))]
-+ (const_int 4)))
- (set_attr "pool_range" "*,4096,*,*,*,*,1020,*")
- (set_attr "neg_pool_range" "*, 0,*,*,*,*,1008,*")]
- )
-
-+;; HFmode moves
-+(define_insn "*movhf_vfp_neon"
-+ [(set (match_operand:HF 0 "nonimmediate_operand" "= t,Um,r,m,t,r,t,r,r")
-+ (match_operand:HF 1 "general_operand" " Um, t,m,r,t,r,r,t,F"))]
-+ "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_NEON_FP16
-+ && ( s_register_operand (operands[0], HFmode)
-+ || s_register_operand (operands[1], HFmode))"
-+ "*
-+ switch (which_alternative)
-+ {
-+ case 0: /* S register from memory */
-+ return \"vld1.16\\t{%z0}, %A1\";
-+ case 1: /* memory from S register */
-+ return \"vst1.16\\t{%z1}, %A0\";
-+ case 2: /* ARM register from memory */
-+ return \"ldrh\\t%0, %1\\t%@ __fp16\";
-+ case 3: /* memory from ARM register */
-+ return \"strh\\t%1, %0\\t%@ __fp16\";
-+ case 4: /* S register from S register */
-+ return \"fcpys\\t%0, %1\";
-+ case 5: /* ARM register from ARM register */
-+ return \"mov\\t%0, %1\\t%@ __fp16\";
-+ case 6: /* S register from ARM register */
-+ return \"fmsr\\t%0, %1\";
-+ case 7: /* ARM register from S register */
-+ return \"fmrs\\t%0, %1\";
-+ case 8: /* ARM register from constant */
-+ {
-+ REAL_VALUE_TYPE r;
-+ long bits;
-+ rtx ops[4];
-+
-+ REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
-+ bits = real_to_target (NULL, &r, HFmode);
-+ ops[0] = operands[0];
-+ ops[1] = GEN_INT (bits);
-+ ops[2] = GEN_INT (bits & 0xff00);
-+ ops[3] = GEN_INT (bits & 0x00ff);
-+
-+ if (arm_arch_thumb2)
-+ output_asm_insn (\"movw\\t%0, %1\", ops);
-+ else
-+ output_asm_insn (\"mov\\t%0, %2\;orr\\t%0, %0, %3\", ops);
-+ return \"\";
-+ }
-+ default:
-+ gcc_unreachable ();
-+ }
-+ "
-+ [(set_attr "conds" "unconditional")
-+ (set_attr "type" "*,*,load1,store1,fcpys,*,r_2_f,f_2_r,*")
-+ (set_attr "neon_type" "neon_vld1_1_2_regs,neon_vst1_1_2_regs_vst2_2_regs,*,*,*,*,*,*,*")
-+ (set_attr "length" "4,4,4,4,4,4,4,4,8")]
-+)
-+
-+;; FP16 without element load/store instructions.
-+(define_insn "*movhf_vfp"
-+ [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,t,r,t,r,r")
-+ (match_operand:HF 1 "general_operand" " m,r,t,r,r,t,F"))]
-+ "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FP16 && !TARGET_NEON_FP16
-+ && ( s_register_operand (operands[0], HFmode)
-+ || s_register_operand (operands[1], HFmode))"
-+ "*
-+ switch (which_alternative)
-+ {
-+ case 0: /* ARM register from memory */
-+ return \"ldrh\\t%0, %1\\t%@ __fp16\";
-+ case 1: /* memory from ARM register */
-+ return \"strh\\t%1, %0\\t%@ __fp16\";
-+ case 2: /* S register from S register */
-+ return \"fcpys\\t%0, %1\";
-+ case 3: /* ARM register from ARM register */
-+ return \"mov\\t%0, %1\\t%@ __fp16\";
-+ case 4: /* S register from ARM register */
-+ return \"fmsr\\t%0, %1\";
-+ case 5: /* ARM register from S register */
-+ return \"fmrs\\t%0, %1\";
-+ case 6: /* ARM register from constant */
-+ {
-+ REAL_VALUE_TYPE r;
-+ long bits;
-+ rtx ops[4];
-+
-+ REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
-+ bits = real_to_target (NULL, &r, HFmode);
-+ ops[0] = operands[0];
-+ ops[1] = GEN_INT (bits);
-+ ops[2] = GEN_INT (bits & 0xff00);
-+ ops[3] = GEN_INT (bits & 0x00ff);
-+
-+ if (arm_arch_thumb2)
-+ output_asm_insn (\"movw\\t%0, %1\", ops);
-+ else
-+ output_asm_insn (\"mov\\t%0, %2\;orr\\t%0, %0, %3\", ops);
-+ return \"\";
-+ }
-+ default:
-+ gcc_unreachable ();
-+ }
-+ "
-+ [(set_attr "conds" "unconditional")
-+ (set_attr "type" "load1,store1,fcpys,*,r_2_f,f_2_r,*")
-+ (set_attr "length" "4,4,4,4,4,4,8")]
-+)
-+
-
- ;; SFmode moves
- ;; Disparage the w<->r cases because reloading an invalid address is
-@@ -222,6 +355,8 @@
- [(set_attr "predicable" "yes")
- (set_attr "type"
- "r_2_f,f_2_r,fconsts,f_loads,f_stores,load1,store1,fcpys,*")
-+ (set_attr "neon_type" "neon_mcr,neon_mrc,*,*,*,*,*,neon_vmov,*")
-+ (set_attr "insn" "*,*,*,*,*,*,*,*,mov")
- (set_attr "pool_range" "*,*,*,1020,*,4096,*,*,*")
- (set_attr "neg_pool_range" "*,*,*,1008,*,4080,*,*,*")]
- )
-@@ -258,6 +393,8 @@
- [(set_attr "predicable" "yes")
- (set_attr "type"
- "r_2_f,f_2_r,fconsts,f_load,f_store,load1,store1,fcpys,*")
-+ (set_attr "neon_type" "neon_mcr,neon_mrc,*,*,*,*,*,neon_vmov,*")
-+ (set_attr "insn" "*,*,*,*,*,*,*,*,mov")
- (set_attr "pool_range" "*,*,*,1020,*,4092,*,*,*")
- (set_attr "neg_pool_range" "*,*,*,1008,*,0,*,*,*")]
- )
-@@ -267,7 +404,7 @@
-
- (define_insn "*movdf_vfp"
- [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=w,?r,w ,r, m,w ,Uv,w,r")
-- (match_operand:DF 1 "soft_df_operand" " ?r,w,Dv,mF,r,UvF,w, w,r"))]
-+ (match_operand:DF 1 "soft_df_operand" " ?r,w,Dy,mF,r,UvF,w, w,r"))]
- "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP
- && ( register_operand (operands[0], DFmode)
- || register_operand (operands[1], DFmode))"
-@@ -280,13 +417,17 @@
- case 1:
- return \"fmrrd%?\\t%Q0, %R0, %P1\";
- case 2:
-+ gcc_assert (TARGET_VFP_DOUBLE);
- return \"fconstd%?\\t%P0, #%G1\";
- case 3: case 4:
- return output_move_double (operands);
- case 5: case 6:
- return output_move_vfp (operands);
- case 7:
-- return \"fcpyd%?\\t%P0, %P1\";
-+ if (TARGET_VFP_SINGLE)
-+ return \"fcpys%?\\t%0, %1\;fcpys%?\\t%p0, %p1\";
-+ else
-+ return \"fcpyd%?\\t%P0, %P1\";
- case 8:
- return \"#\";
- default:
-@@ -296,14 +437,21 @@
- "
- [(set_attr "type"
- "r_2_f,f_2_r,fconstd,f_loadd,f_stored,load2,store2,ffarithd,*")
-- (set_attr "length" "4,4,4,8,8,4,4,4,8")
-+ (set_attr "neon_type" "neon_mcr_2_mcrr,neon_mrrc,*,*,*,*,*,neon_vmov,*")
-+ (set (attr "length") (cond [(eq_attr "alternative" "3,4,8") (const_int 8)
-+ (eq_attr "alternative" "7")
-+ (if_then_else
-+ (eq (symbol_ref "TARGET_VFP_SINGLE") (const_int 1))
-+ (const_int 8)
-+ (const_int 4))]
-+ (const_int 4)))
- (set_attr "pool_range" "*,*,*,1020,*,1020,*,*,*")
- (set_attr "neg_pool_range" "*,*,*,1008,*,1008,*,*,*")]
- )
-
- (define_insn "*thumb2_movdf_vfp"
- [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=w,?r,w ,r, m,w ,Uv,w,r")
-- (match_operand:DF 1 "soft_df_operand" " ?r,w,Dv,mF,r,UvF,w, w,r"))]
-+ (match_operand:DF 1 "soft_df_operand" " ?r,w,Dy,mF,r,UvF,w, w,r"))]
- "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP"
- "*
- {
-@@ -314,13 +462,17 @@
- case 1:
- return \"fmrrd%?\\t%Q0, %R0, %P1\";
- case 2:
-+ gcc_assert (TARGET_VFP_DOUBLE);
- return \"fconstd%?\\t%P0, #%G1\";
- case 3: case 4: case 8:
- return output_move_double (operands);
- case 5: case 6:
- return output_move_vfp (operands);
- case 7:
-- return \"fcpyd%?\\t%P0, %P1\";
-+ if (TARGET_VFP_SINGLE)
-+ return \"fcpys%?\\t%0, %1\;fcpys%?\\t%p0, %p1\";
-+ else
-+ return \"fcpyd%?\\t%P0, %P1\";
- default:
- abort ();
- }
-@@ -328,7 +480,14 @@
- "
- [(set_attr "type"
- "r_2_f,f_2_r,fconstd,load2,store2,f_load,f_store,ffarithd,*")
-- (set_attr "length" "4,4,4,8,8,4,4,4,8")
-+ (set_attr "neon_type" "neon_mcr_2_mcrr,neon_mrrc,*,*,*,*,*,neon_vmov,*")
-+ (set (attr "length") (cond [(eq_attr "alternative" "3,4,8") (const_int 8)
-+ (eq_attr "alternative" "7")
-+ (if_then_else
-+ (eq (symbol_ref "TARGET_VFP_SINGLE") (const_int 1))
-+ (const_int 8)
-+ (const_int 4))]
-+ (const_int 4)))
- (set_attr "pool_range" "*,*,*,4096,*,1020,*,*,*")
- (set_attr "neg_pool_range" "*,*,*,0,*,1008,*,*,*")]
- )
-@@ -356,7 +515,8 @@
- fmrs%D3\\t%0, %2\;fmrs%d3\\t%0, %1"
- [(set_attr "conds" "use")
- (set_attr "length" "4,4,8,4,4,8,4,4,8")
-- (set_attr "type" "fcpys,fcpys,fcpys,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r")]
-+ (set_attr "type" "fcpys,fcpys,fcpys,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r")
-+ (set_attr "neon_type" "neon_vmov,neon_vmov,neon_vmov,neon_mcr,neon_mcr,neon_mcr,neon_mrc,neon_mrc,neon_mrc")]
- )
-
- (define_insn "*thumb2_movsfcc_vfp"
-@@ -379,7 +539,8 @@
- ite\\t%D3\;fmrs%D3\\t%0, %2\;fmrs%d3\\t%0, %1"
- [(set_attr "conds" "use")
- (set_attr "length" "6,6,10,6,6,10,6,6,10")
-- (set_attr "type" "fcpys,fcpys,fcpys,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r")]
-+ (set_attr "type" "fcpys,fcpys,fcpys,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r")
-+ (set_attr "neon_type" "neon_vmov,neon_vmov,neon_vmov,neon_mcr,neon_mcr,neon_mcr,neon_mrc,neon_mrc,neon_mrc")]
- )
-
- (define_insn "*movdfcc_vfp"
-@@ -389,7 +550,7 @@
- [(match_operand 4 "cc_register" "") (const_int 0)])
- (match_operand:DF 1 "s_register_operand" "0,w,w,0,?r,?r,0,w,w")
- (match_operand:DF 2 "s_register_operand" "w,0,w,?r,0,?r,w,0,w")))]
-- "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
-+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
- "@
- fcpyd%D3\\t%P0, %P2
- fcpyd%d3\\t%P0, %P1
-@@ -402,7 +563,8 @@
- fmrrd%D3\\t%Q0, %R0, %P2\;fmrrd%d3\\t%Q0, %R0, %P1"
- [(set_attr "conds" "use")
- (set_attr "length" "4,4,8,4,4,8,4,4,8")
-- (set_attr "type" "ffarithd,ffarithd,ffarithd,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r")]
-+ (set_attr "type" "ffarithd,ffarithd,ffarithd,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r")
-+ (set_attr "neon_type" "neon_vmov,neon_vmov,neon_vmov,neon_mcr_2_mcrr,neon_mcr_2_mcrr,neon_mcr_2_mcrr,neon_mrrc,neon_mrrc,neon_mrrc")]
- )
-
- (define_insn "*thumb2_movdfcc_vfp"
-@@ -412,7 +574,7 @@
- [(match_operand 4 "cc_register" "") (const_int 0)])
- (match_operand:DF 1 "s_register_operand" "0,w,w,0,?r,?r,0,w,w")
- (match_operand:DF 2 "s_register_operand" "w,0,w,?r,0,?r,w,0,w")))]
-- "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP"
-+ "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
- "@
- it\\t%D3\;fcpyd%D3\\t%P0, %P2
- it\\t%d3\;fcpyd%d3\\t%P0, %P1
-@@ -425,7 +587,8 @@
- ite\\t%D3\;fmrrd%D3\\t%Q0, %R0, %P2\;fmrrd%d3\\t%Q0, %R0, %P1"
- [(set_attr "conds" "use")
- (set_attr "length" "6,6,10,6,6,10,6,6,10")
-- (set_attr "type" "ffarithd,ffarithd,ffarithd,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r")]
-+ (set_attr "type" "ffarithd,ffarithd,ffarithd,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r")
-+ (set_attr "neon_type" "neon_vmov,neon_vmov,neon_vmov,neon_mcr_2_mcrr,neon_mcr_2_mcrr,neon_mcr_2_mcrr,neon_mrrc,neon_mrrc,neon_mrrc")]
- )
-
-
-@@ -443,7 +606,7 @@
- (define_insn "*absdf2_vfp"
- [(set (match_operand:DF 0 "s_register_operand" "=w")
- (abs:DF (match_operand:DF 1 "s_register_operand" "w")))]
-- "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
-+ "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
- "fabsd%?\\t%P0, %P1"
- [(set_attr "predicable" "yes")
- (set_attr "type" "ffarithd")]
-@@ -463,12 +626,12 @@
- (define_insn_and_split "*negdf2_vfp"
- [(set (match_operand:DF 0 "s_register_operand" "=w,?r,?r")
- (neg:DF (match_operand:DF 1 "s_register_operand" "w,0,r")))]
-- "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
-+ "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
- "@
- fnegd%?\\t%P0, %P1
- #
- #"
-- "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP && reload_completed
-+ "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE && reload_completed
- && arm_general_register_operand (operands[0], DFmode)"
- [(set (match_dup 0) (match_dup 1))]
- "
-@@ -523,7 +686,7 @@
- [(set (match_operand:DF 0 "s_register_operand" "=w")
- (plus:DF (match_operand:DF 1 "s_register_operand" "w")
- (match_operand:DF 2 "s_register_operand" "w")))]
-- "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
-+ "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
- "faddd%?\\t%P0, %P1, %P2"
- [(set_attr "predicable" "yes")
- (set_attr "type" "faddd")]
-@@ -544,7 +707,7 @@
- [(set (match_operand:DF 0 "s_register_operand" "=w")
- (minus:DF (match_operand:DF 1 "s_register_operand" "w")
- (match_operand:DF 2 "s_register_operand" "w")))]
-- "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
-+ "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
- "fsubd%?\\t%P0, %P1, %P2"
- [(set_attr "predicable" "yes")
- (set_attr "type" "faddd")]
-@@ -567,7 +730,7 @@
- [(set (match_operand:DF 0 "s_register_operand" "+w")
- (div:DF (match_operand:DF 1 "s_register_operand" "w")
- (match_operand:DF 2 "s_register_operand" "w")))]
-- "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
-+ "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
- "fdivd%?\\t%P0, %P1, %P2"
- [(set_attr "predicable" "yes")
- (set_attr "type" "fdivd")]
-@@ -590,7 +753,7 @@
- [(set (match_operand:DF 0 "s_register_operand" "+w")
- (mult:DF (match_operand:DF 1 "s_register_operand" "w")
- (match_operand:DF 2 "s_register_operand" "w")))]
-- "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
-+ "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
- "fmuld%?\\t%P0, %P1, %P2"
- [(set_attr "predicable" "yes")
- (set_attr "type" "fmuld")]
-@@ -611,7 +774,7 @@
- [(set (match_operand:DF 0 "s_register_operand" "+w")
- (mult:DF (neg:DF (match_operand:DF 1 "s_register_operand" "w"))
- (match_operand:DF 2 "s_register_operand" "w")))]
-- "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
-+ "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
- "fnmuld%?\\t%P0, %P1, %P2"
- [(set_attr "predicable" "yes")
- (set_attr "type" "fmuld")]
-@@ -626,7 +789,8 @@
- (plus:SF (mult:SF (match_operand:SF 2 "s_register_operand" "t")
- (match_operand:SF 3 "s_register_operand" "t"))
- (match_operand:SF 1 "s_register_operand" "0")))]
-- "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
-+ "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP
-+ && (!arm_tune_marvell_f || optimize_size)"
- "fmacs%?\\t%0, %2, %3"
- [(set_attr "predicable" "yes")
- (set_attr "type" "fmacs")]
-@@ -637,7 +801,8 @@
- (plus:DF (mult:DF (match_operand:DF 2 "s_register_operand" "w")
- (match_operand:DF 3 "s_register_operand" "w"))
- (match_operand:DF 1 "s_register_operand" "0")))]
-- "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
-+ "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE
-+ && (!arm_tune_marvell_f || optimize_size)"
- "fmacd%?\\t%P0, %P2, %P3"
- [(set_attr "predicable" "yes")
- (set_attr "type" "fmacd")]
-@@ -649,7 +814,8 @@
- (minus:SF (mult:SF (match_operand:SF 2 "s_register_operand" "t")
- (match_operand:SF 3 "s_register_operand" "t"))
- (match_operand:SF 1 "s_register_operand" "0")))]
-- "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
-+ "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP
-+ && (!arm_tune_marvell_f || optimize_size)"
- "fmscs%?\\t%0, %2, %3"
- [(set_attr "predicable" "yes")
- (set_attr "type" "fmacs")]
-@@ -660,7 +826,8 @@
- (minus:DF (mult:DF (match_operand:DF 2 "s_register_operand" "w")
- (match_operand:DF 3 "s_register_operand" "w"))
- (match_operand:DF 1 "s_register_operand" "0")))]
-- "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
-+ "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE
-+ && (!arm_tune_marvell_f || optimize_size)"
- "fmscd%?\\t%P0, %P2, %P3"
- [(set_attr "predicable" "yes")
- (set_attr "type" "fmacd")]
-@@ -672,7 +839,8 @@
- (minus:SF (match_operand:SF 1 "s_register_operand" "0")
- (mult:SF (match_operand:SF 2 "s_register_operand" "t")
- (match_operand:SF 3 "s_register_operand" "t"))))]
-- "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
-+ "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP
-+ && (!arm_tune_marvell_f || optimize_size)"
- "fnmacs%?\\t%0, %2, %3"
- [(set_attr "predicable" "yes")
- (set_attr "type" "fmacs")]
-@@ -683,7 +851,8 @@
- (minus:DF (match_operand:DF 1 "s_register_operand" "0")
- (mult:DF (match_operand:DF 2 "s_register_operand" "w")
- (match_operand:DF 3 "s_register_operand" "w"))))]
-- "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
-+ "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE
-+ && (!arm_tune_marvell_f || optimize_size)"
- "fnmacd%?\\t%P0, %P2, %P3"
- [(set_attr "predicable" "yes")
- (set_attr "type" "fmacd")]
-@@ -697,7 +866,8 @@
- (neg:SF (match_operand:SF 2 "s_register_operand" "t"))
- (match_operand:SF 3 "s_register_operand" "t"))
- (match_operand:SF 1 "s_register_operand" "0")))]
-- "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
-+ "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP
-+ && (!arm_tune_marvell_f || optimize_size)"
- "fnmscs%?\\t%0, %2, %3"
- [(set_attr "predicable" "yes")
- (set_attr "type" "fmacs")]
-@@ -709,7 +879,8 @@
- (neg:DF (match_operand:DF 2 "s_register_operand" "w"))
- (match_operand:DF 3 "s_register_operand" "w"))
- (match_operand:DF 1 "s_register_operand" "0")))]
-- "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
-+ "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE
-+ && (!arm_tune_marvell_f || optimize_size)"
- "fnmscd%?\\t%P0, %P2, %P3"
- [(set_attr "predicable" "yes")
- (set_attr "type" "fmacd")]
-@@ -721,7 +892,7 @@
- (define_insn "*extendsfdf2_vfp"
- [(set (match_operand:DF 0 "s_register_operand" "=w")
- (float_extend:DF (match_operand:SF 1 "s_register_operand" "t")))]
-- "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
-+ "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
- "fcvtds%?\\t%P0, %1"
- [(set_attr "predicable" "yes")
- (set_attr "type" "f_cvt")]
-@@ -730,12 +901,30 @@
- (define_insn "*truncdfsf2_vfp"
- [(set (match_operand:SF 0 "s_register_operand" "=t")
- (float_truncate:SF (match_operand:DF 1 "s_register_operand" "w")))]
-- "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
-+ "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
- "fcvtsd%?\\t%0, %P1"
- [(set_attr "predicable" "yes")
- (set_attr "type" "f_cvt")]
- )
-
-+(define_insn "extendhfsf2"
-+ [(set (match_operand:SF 0 "s_register_operand" "=t")
-+ (float_extend:SF (match_operand:HF 1 "s_register_operand" "t")))]
-+ "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FP16"
-+ "vcvtb%?.f32.f16\\t%0, %1"
-+ [(set_attr "predicable" "yes")
-+ (set_attr "type" "f_cvt")]
-+)
-+
-+(define_insn "truncsfhf2"
-+ [(set (match_operand:HF 0 "s_register_operand" "=t")
-+ (float_truncate:HF (match_operand:SF 1 "s_register_operand" "t")))]
-+ "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FP16"
-+ "vcvtb%?.f16.f32\\t%0, %1"
-+ [(set_attr "predicable" "yes")
-+ (set_attr "type" "f_cvt")]
-+)
-+
- (define_insn "*truncsisf2_vfp"
- [(set (match_operand:SI 0 "s_register_operand" "=t")
- (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" "t"))))]
-@@ -748,7 +937,7 @@
- (define_insn "*truncsidf2_vfp"
- [(set (match_operand:SI 0 "s_register_operand" "=t")
- (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" "w"))))]
-- "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
-+ "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
- "ftosizd%?\\t%0, %P1"
- [(set_attr "predicable" "yes")
- (set_attr "type" "f_cvt")]
-@@ -767,7 +956,7 @@
- (define_insn "fixuns_truncdfsi2"
- [(set (match_operand:SI 0 "s_register_operand" "=t")
- (unsigned_fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" "t"))))]
-- "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
-+ "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
- "ftouizd%?\\t%0, %P1"
- [(set_attr "predicable" "yes")
- (set_attr "type" "f_cvt")]
-@@ -786,7 +975,7 @@
- (define_insn "*floatsidf2_vfp"
- [(set (match_operand:DF 0 "s_register_operand" "=w")
- (float:DF (match_operand:SI 1 "s_register_operand" "t")))]
-- "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
-+ "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
- "fsitod%?\\t%P0, %1"
- [(set_attr "predicable" "yes")
- (set_attr "type" "f_cvt")]
-@@ -805,7 +994,7 @@
- (define_insn "floatunssidf2"
- [(set (match_operand:DF 0 "s_register_operand" "=w")
- (unsigned_float:DF (match_operand:SI 1 "s_register_operand" "t")))]
-- "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
-+ "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
- "fuitod%?\\t%P0, %1"
- [(set_attr "predicable" "yes")
- (set_attr "type" "f_cvt")]
-@@ -826,7 +1015,7 @@
- (define_insn "*sqrtdf2_vfp"
- [(set (match_operand:DF 0 "s_register_operand" "=w")
- (sqrt:DF (match_operand:DF 1 "s_register_operand" "w")))]
-- "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
-+ "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
- "fsqrtd%?\\t%P0, %P1"
- [(set_attr "predicable" "yes")
- (set_attr "type" "fdivd")]
-@@ -878,9 +1067,9 @@
- [(set (reg:CCFP CC_REGNUM)
- (compare:CCFP (match_operand:DF 0 "s_register_operand" "w")
- (match_operand:DF 1 "vfp_compare_operand" "wG")))]
-- "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
-+ "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
- "#"
-- "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
-+ "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
- [(set (reg:CCFP VFPCC_REGNUM)
- (compare:CCFP (match_dup 0)
- (match_dup 1)))
-@@ -893,9 +1082,9 @@
- [(set (reg:CCFPE CC_REGNUM)
- (compare:CCFPE (match_operand:DF 0 "s_register_operand" "w")
- (match_operand:DF 1 "vfp_compare_operand" "wG")))]
-- "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
-+ "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
- "#"
-- "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
-+ "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
- [(set (reg:CCFPE VFPCC_REGNUM)
- (compare:CCFPE (match_dup 0)
- (match_dup 1)))
-@@ -935,7 +1124,7 @@
- [(set (reg:CCFP VFPCC_REGNUM)
- (compare:CCFP (match_operand:DF 0 "s_register_operand" "w,w")
- (match_operand:DF 1 "vfp_compare_operand" "w,G")))]
-- "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
-+ "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
- "@
- fcmpd%?\\t%P0, %P1
- fcmpzd%?\\t%P0"
-@@ -947,7 +1136,7 @@
- [(set (reg:CCFPE VFPCC_REGNUM)
- (compare:CCFPE (match_operand:DF 0 "s_register_operand" "w,w")
- (match_operand:DF 1 "vfp_compare_operand" "w,G")))]
-- "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
-+ "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
- "@
- fcmped%?\\t%P0, %P1
- fcmpezd%?\\t%P0"
---- a/gcc/config/arm/vxworks.h
-+++ b/gcc/config/arm/vxworks.h
-@@ -97,7 +97,7 @@ along with GCC; see the file COPYING3.
- /* There is no default multilib. */
- #undef MULTILIB_DEFAULTS
-
--#define FPUTYPE_DEFAULT FPUTYPE_VFP
-+#define FPUTYPE_DEFAULT "vfp"
-
- #undef FUNCTION_PROFILER
- #define FUNCTION_PROFILER VXWORKS_FUNCTION_PROFILER
---- /dev/null
-+++ b/gcc/config/i386/atom.md
-@@ -0,0 +1,795 @@
-+;; Atom Scheduling
-+;; Copyright (C) 2009 Free Software Foundation, Inc.
-+;;
-+;; This file is part of GCC.
-+;;
-+;; GCC is free software; you can redistribute it and/or modify
-+;; it under the terms of the GNU General Public License as published by
-+;; the Free Software Foundation; either version 3, or (at your option)
-+;; any later version.
-+;;
-+;; GCC is distributed in the hope that it will be useful,
-+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+;; GNU General Public License for more details.
-+;;
-+;; You should have received a copy of the GNU General Public License
-+;; along with GCC; see the file COPYING3. If not see
-+;; <http://www.gnu.org/licenses/>.
-+;;
-+;; Atom is an in-order core with two integer pipelines.
-+
-+
-+(define_attr "atom_unit" "sishuf,simul,jeu,complex,other"
-+ (const_string "other"))
-+
-+(define_attr "atom_sse_attr" "rcp,movdup,lfence,fence,prefetch,sqrt,mxcsr,other"
-+ (const_string "other"))
-+
-+(define_automaton "atom")
-+
-+;; Atom has two ports: port 0 and port 1 connecting to all execution units
-+(define_cpu_unit "atom-port-0,atom-port-1" "atom")
-+
-+;; EU: Execution Unit
-+;; Atom EUs are connected by port 0 or port 1.
-+
-+(define_cpu_unit "atom-eu-0, atom-eu-1,
-+ atom-imul-1, atom-imul-2, atom-imul-3, atom-imul-4"
-+ "atom")
-+
-+;; Some EUs have duplicated copied and can be accessed via either
-+;; port 0 or port 1
-+;; (define_reservation "atom-port-either" "(atom-port-0 | atom-port-1)")
-+
-+;;; Some instructions is dual-pipe execution, need both ports
-+;;; Complex multi-op macro-instructoins need both ports and all EUs
-+(define_reservation "atom-port-dual" "(atom-port-0 + atom-port-1)")
-+(define_reservation "atom-all-eu" "(atom-eu-0 + atom-eu-1 +
-+ atom-imul-1 + atom-imul-2 + atom-imul-3 +
-+ atom-imul-4)")
-+
-+;;; Most of simple instructions have 1 cycle latency. Some of them
-+;;; issue in port 0, some in port 0 and some in either port.
-+(define_reservation "atom-simple-0" "(atom-port-0 + atom-eu-0)")
-+(define_reservation "atom-simple-1" "(atom-port-1 + atom-eu-1)")
-+(define_reservation "atom-simple-either" "(atom-simple-0 | atom-simple-1)")
-+
-+;;; Some insn issues in port 0 with 3 cycle latency and 1 cycle tput
-+(define_reservation "atom-eu-0-3-1" "(atom-port-0 + atom-eu-0, nothing*2)")
-+
-+;;; fmul insn can have 4 or 5 cycles latency
-+(define_reservation "atom-fmul-5c" "(atom-port-0 + atom-eu-0), nothing*4")
-+(define_reservation "atom-fmul-4c" "(atom-port-0 + atom-eu-0), nothing*3")
-+
-+;;; fadd can has 5 cycles latency depends on instruction forms
-+(define_reservation "atom-fadd-5c" "(atom-port-1 + atom-eu-1), nothing*5")
-+
-+;;; imul insn has 5 cycles latency
-+(define_reservation "atom-imul-32"
-+ "atom-imul-1, atom-imul-2, atom-imul-3, atom-imul-4,
-+ atom-port-0")
-+;;; imul instruction excludes other non-FP instructions.
-+(exclusion_set "atom-eu-0, atom-eu-1"
-+ "atom-imul-1, atom-imul-2, atom-imul-3, atom-imul-4")
-+
-+;;; dual-execution instructions can have 1,2,4,5 cycles latency depends on
-+;;; instruction forms
-+(define_reservation "atom-dual-1c" "(atom-port-dual + atom-eu-0 + atom-eu-1)")
-+(define_reservation "atom-dual-2c"
-+ "(atom-port-dual + atom-eu-0 + atom-eu-1, nothing)")
-+(define_reservation "atom-dual-5c"
-+ "(atom-port-dual + atom-eu-0 + atom-eu-1, nothing*4)")
-+
-+;;; Complex macro-instruction has variants of latency, and uses both ports.
-+(define_reservation "atom-complex" "(atom-port-dual + atom-all-eu)")
-+
-+(define_insn_reservation "atom_other" 9
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "other")
-+ (eq_attr "atom_unit" "!jeu")))
-+ "atom-complex, atom-all-eu*8")
-+
-+;; return has type "other" with atom_unit "jeu"
-+(define_insn_reservation "atom_other_2" 1
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "other")
-+ (eq_attr "atom_unit" "jeu")))
-+ "atom-dual-1c")
-+
-+(define_insn_reservation "atom_multi" 9
-+ (and (eq_attr "cpu" "atom")
-+ (eq_attr "type" "multi"))
-+ "atom-complex, atom-all-eu*8")
-+
-+;; Normal alu insns without carry
-+(define_insn_reservation "atom_alu" 1
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "alu")
-+ (and (eq_attr "memory" "none")
-+ (eq_attr "use_carry" "0"))))
-+ "atom-simple-either")
-+
-+;; Normal alu insns without carry
-+(define_insn_reservation "atom_alu_mem" 1
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "alu")
-+ (and (eq_attr "memory" "!none")
-+ (eq_attr "use_carry" "0"))))
-+ "atom-simple-either")
-+
-+;; Alu insn consuming CF, such as add/sbb
-+(define_insn_reservation "atom_alu_carry" 1
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "alu")
-+ (and (eq_attr "memory" "none")
-+ (eq_attr "use_carry" "1"))))
-+ "atom-simple-either")
-+
-+;; Alu insn consuming CF, such as add/sbb
-+(define_insn_reservation "atom_alu_carry_mem" 1
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "alu")
-+ (and (eq_attr "memory" "!none")
-+ (eq_attr "use_carry" "1"))))
-+ "atom-simple-either")
-+
-+(define_insn_reservation "atom_alu1" 1
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "alu1")
-+ (eq_attr "memory" "none")))
-+ "atom-simple-either")
-+
-+(define_insn_reservation "atom_alu1_mem" 1
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "alu1")
-+ (eq_attr "memory" "!none")))
-+ "atom-simple-either")
-+
-+(define_insn_reservation "atom_negnot" 1
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "negnot")
-+ (eq_attr "memory" "none")))
-+ "atom-simple-either")
-+
-+(define_insn_reservation "atom_negnot_mem" 1
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "negnot")
-+ (eq_attr "memory" "!none")))
-+ "atom-simple-either")
-+
-+(define_insn_reservation "atom_imov" 1
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "imov")
-+ (eq_attr "memory" "none")))
-+ "atom-simple-either")
-+
-+(define_insn_reservation "atom_imov_mem" 1
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "imov")
-+ (eq_attr "memory" "!none")))
-+ "atom-simple-either")
-+
-+;; 16<-16, 32<-32
-+(define_insn_reservation "atom_imovx" 1
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "imovx")
-+ (and (eq_attr "memory" "none")
-+ (ior (and (match_operand:HI 0 "register_operand")
-+ (match_operand:HI 1 "general_operand"))
-+ (and (match_operand:SI 0 "register_operand")
-+ (match_operand:SI 1 "general_operand"))))))
-+ "atom-simple-either")
-+
-+;; 16<-16, 32<-32, mem
-+(define_insn_reservation "atom_imovx_mem" 1
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "imovx")
-+ (and (eq_attr "memory" "!none")
-+ (ior (and (match_operand:HI 0 "register_operand")
-+ (match_operand:HI 1 "general_operand"))
-+ (and (match_operand:SI 0 "register_operand")
-+ (match_operand:SI 1 "general_operand"))))))
-+ "atom-simple-either")
-+
-+;; 32<-16, 32<-8, 64<-16, 64<-8, 64<-32, 8<-8
-+(define_insn_reservation "atom_imovx_2" 1
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "imovx")
-+ (and (eq_attr "memory" "none")
-+ (ior (match_operand:QI 0 "register_operand")
-+ (ior (and (match_operand:SI 0 "register_operand")
-+ (not (match_operand:SI 1 "general_operand")))
-+ (match_operand:DI 0 "register_operand"))))))
-+ "atom-simple-0")
-+
-+;; 32<-16, 32<-8, 64<-16, 64<-8, 64<-32, 8<-8, mem
-+(define_insn_reservation "atom_imovx_2_mem" 1
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "imovx")
-+ (and (eq_attr "memory" "!none")
-+ (ior (match_operand:QI 0 "register_operand")
-+ (ior (and (match_operand:SI 0 "register_operand")
-+ (not (match_operand:SI 1 "general_operand")))
-+ (match_operand:DI 0 "register_operand"))))))
-+ "atom-simple-0")
-+
-+;; 16<-8
-+(define_insn_reservation "atom_imovx_3" 3
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "imovx")
-+ (and (match_operand:HI 0 "register_operand")
-+ (match_operand:QI 1 "general_operand"))))
-+ "atom-complex, atom-all-eu*2")
-+
-+(define_insn_reservation "atom_lea" 1
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "lea")
-+ (eq_attr "mode" "!HI")))
-+ "atom-simple-either")
-+
-+;; lea 16bit address is complex insn
-+(define_insn_reservation "atom_lea_2" 2
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "lea")
-+ (eq_attr "mode" "HI")))
-+ "atom-complex, atom-all-eu")
-+
-+(define_insn_reservation "atom_incdec" 1
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "incdec")
-+ (eq_attr "memory" "none")))
-+ "atom-simple-either")
-+
-+(define_insn_reservation "atom_incdec_mem" 1
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "incdec")
-+ (eq_attr "memory" "!none")))
-+ "atom-simple-either")
-+
-+;; simple shift instruction use SHIFT eu, none memory
-+(define_insn_reservation "atom_ishift" 1
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "ishift")
-+ (and (eq_attr "memory" "none") (eq_attr "prefix_0f" "0"))))
-+ "atom-simple-0")
-+
-+;; simple shift instruction use SHIFT eu, memory
-+(define_insn_reservation "atom_ishift_mem" 1
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "ishift")
-+ (and (eq_attr "memory" "!none") (eq_attr "prefix_0f" "0"))))
-+ "atom-simple-0")
-+
-+;; DF shift (prefixed with 0f) is complex insn with latency of 7 cycles
-+(define_insn_reservation "atom_ishift_3" 7
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "ishift")
-+ (eq_attr "prefix_0f" "1")))
-+ "atom-complex, atom-all-eu*6")
-+
-+(define_insn_reservation "atom_ishift1" 1
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "ishift1")
-+ (eq_attr "memory" "none")))
-+ "atom-simple-0")
-+
-+(define_insn_reservation "atom_ishift1_mem" 1
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "ishift1")
-+ (eq_attr "memory" "!none")))
-+ "atom-simple-0")
-+
-+(define_insn_reservation "atom_rotate" 1
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "rotate")
-+ (eq_attr "memory" "none")))
-+ "atom-simple-0")
-+
-+(define_insn_reservation "atom_rotate_mem" 1
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "rotate")
-+ (eq_attr "memory" "!none")))
-+ "atom-simple-0")
-+
-+(define_insn_reservation "atom_rotate1" 1
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "rotate1")
-+ (eq_attr "memory" "none")))
-+ "atom-simple-0")
-+
-+(define_insn_reservation "atom_rotate1_mem" 1
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "rotate1")
-+ (eq_attr "memory" "!none")))
-+ "atom-simple-0")
-+
-+(define_insn_reservation "atom_imul" 5
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "imul")
-+ (and (eq_attr "memory" "none") (eq_attr "mode" "SI"))))
-+ "atom-imul-32")
-+
-+(define_insn_reservation "atom_imul_mem" 5
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "imul")
-+ (and (eq_attr "memory" "!none") (eq_attr "mode" "SI"))))
-+ "atom-imul-32")
-+
-+;; latency set to 10 as common 64x64 imul
-+(define_insn_reservation "atom_imul_3" 10
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "imul")
-+ (eq_attr "mode" "!SI")))
-+ "atom-complex, atom-all-eu*9")
-+
-+(define_insn_reservation "atom_idiv" 65
-+ (and (eq_attr "cpu" "atom")
-+ (eq_attr "type" "idiv"))
-+ "atom-complex, atom-all-eu*32, nothing*32")
-+
-+(define_insn_reservation "atom_icmp" 1
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "icmp")
-+ (eq_attr "memory" "none")))
-+ "atom-simple-either")
-+
-+(define_insn_reservation "atom_icmp_mem" 1
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "icmp")
-+ (eq_attr "memory" "!none")))
-+ "atom-simple-either")
-+
-+(define_insn_reservation "atom_test" 1
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "test")
-+ (eq_attr "memory" "none")))
-+ "atom-simple-either")
-+
-+(define_insn_reservation "atom_test_mem" 1
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "test")
-+ (eq_attr "memory" "!none")))
-+ "atom-simple-either")
-+
-+(define_insn_reservation "atom_ibr" 1
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "ibr")
-+ (eq_attr "memory" "!load")))
-+ "atom-simple-1")
-+
-+;; complex if jump target is from address
-+(define_insn_reservation "atom_ibr_2" 2
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "ibr")
-+ (eq_attr "memory" "load")))
-+ "atom-complex, atom-all-eu")
-+
-+(define_insn_reservation "atom_setcc" 1
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "setcc")
-+ (eq_attr "memory" "!store")))
-+ "atom-simple-either")
-+
-+;; 2 cycles complex if target is in memory
-+(define_insn_reservation "atom_setcc_2" 2
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "setcc")
-+ (eq_attr "memory" "store")))
-+ "atom-complex, atom-all-eu")
-+
-+(define_insn_reservation "atom_icmov" 1
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "icmov")
-+ (eq_attr "memory" "none")))
-+ "atom-simple-either")
-+
-+(define_insn_reservation "atom_icmov_mem" 1
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "icmov")
-+ (eq_attr "memory" "!none")))
-+ "atom-simple-either")
-+
-+;; UCODE if segreg, ignored
-+(define_insn_reservation "atom_push" 2
-+ (and (eq_attr "cpu" "atom")
-+ (eq_attr "type" "push"))
-+ "atom-dual-2c")
-+
-+;; pop r64 is 1 cycle. UCODE if segreg, ignored
-+(define_insn_reservation "atom_pop" 1
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "pop")
-+ (eq_attr "mode" "DI")))
-+ "atom-dual-1c")
-+
-+;; pop non-r64 is 2 cycles. UCODE if segreg, ignored
-+(define_insn_reservation "atom_pop_2" 2
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "pop")
-+ (eq_attr "mode" "!DI")))
-+ "atom-dual-2c")
-+
-+;; UCODE if segreg, ignored
-+(define_insn_reservation "atom_call" 1
-+ (and (eq_attr "cpu" "atom")
-+ (eq_attr "type" "call"))
-+ "atom-dual-1c")
-+
-+(define_insn_reservation "atom_callv" 1
-+ (and (eq_attr "cpu" "atom")
-+ (eq_attr "type" "callv"))
-+ "atom-dual-1c")
-+
-+(define_insn_reservation "atom_leave" 3
-+ (and (eq_attr "cpu" "atom")
-+ (eq_attr "type" "leave"))
-+ "atom-complex, atom-all-eu*2")
-+
-+(define_insn_reservation "atom_str" 3
-+ (and (eq_attr "cpu" "atom")
-+ (eq_attr "type" "str"))
-+ "atom-complex, atom-all-eu*2")
-+
-+(define_insn_reservation "atom_sselog" 1
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "sselog")
-+ (eq_attr "memory" "none")))
-+ "atom-simple-either")
-+
-+(define_insn_reservation "atom_sselog_mem" 1
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "sselog")
-+ (eq_attr "memory" "!none")))
-+ "atom-simple-either")
-+
-+(define_insn_reservation "atom_sselog1" 1
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "sselog1")
-+ (eq_attr "memory" "none")))
-+ "atom-simple-0")
-+
-+(define_insn_reservation "atom_sselog1_mem" 1
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "sselog1")
-+ (eq_attr "memory" "!none")))
-+ "atom-simple-0")
-+
-+;; not pmad, not psad
-+(define_insn_reservation "atom_sseiadd" 1
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "sseiadd")
-+ (and (not (match_operand:V2DI 0 "register_operand"))
-+ (and (eq_attr "atom_unit" "!simul")
-+ (eq_attr "atom_unit" "!complex")))))
-+ "atom-simple-either")
-+
-+;; pmad, psad and 64
-+(define_insn_reservation "atom_sseiadd_2" 4
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "sseiadd")
-+ (and (not (match_operand:V2DI 0 "register_operand"))
-+ (and (eq_attr "atom_unit" "simul" )
-+ (eq_attr "mode" "DI")))))
-+ "atom-fmul-4c")
-+
-+;; pmad, psad and 128
-+(define_insn_reservation "atom_sseiadd_3" 5
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "sseiadd")
-+ (and (not (match_operand:V2DI 0 "register_operand"))
-+ (and (eq_attr "atom_unit" "simul" )
-+ (eq_attr "mode" "TI")))))
-+ "atom-fmul-5c")
-+
-+;; if paddq(64 bit op), phadd/phsub
-+(define_insn_reservation "atom_sseiadd_4" 6
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "sseiadd")
-+ (ior (match_operand:V2DI 0 "register_operand")
-+ (eq_attr "atom_unit" "complex"))))
-+ "atom-complex, atom-all-eu*5")
-+
-+;; if immediate op.
-+(define_insn_reservation "atom_sseishft" 1
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "sseishft")
-+ (and (eq_attr "atom_unit" "!sishuf")
-+ (match_operand 2 "immediate_operand"))))
-+ "atom-simple-either")
-+
-+;; if palignr or psrldq
-+(define_insn_reservation "atom_sseishft_2" 1
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "sseishft")
-+ (and (eq_attr "atom_unit" "sishuf")
-+ (match_operand 2 "immediate_operand"))))
-+ "atom-simple-0")
-+
-+;; if reg/mem op
-+(define_insn_reservation "atom_sseishft_3" 2
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "sseishft")
-+ (not (match_operand 2 "immediate_operand"))))
-+ "atom-complex, atom-all-eu")
-+
-+(define_insn_reservation "atom_sseimul" 1
-+ (and (eq_attr "cpu" "atom")
-+ (eq_attr "type" "sseimul"))
-+ "atom-simple-0")
-+
-+;; rcpss or rsqrtss
-+(define_insn_reservation "atom_sse" 4
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "sse")
-+ (and (eq_attr "atom_sse_attr" "rcp") (eq_attr "mode" "SF"))))
-+ "atom-fmul-4c")
-+
-+;; movshdup, movsldup. Suggest to type sseishft
-+(define_insn_reservation "atom_sse_2" 1
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "sse")
-+ (eq_attr "atom_sse_attr" "movdup")))
-+ "atom-simple-0")
-+
-+;; lfence
-+(define_insn_reservation "atom_sse_3" 1
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "sse")
-+ (eq_attr "atom_sse_attr" "lfence")))
-+ "atom-simple-either")
-+
-+;; sfence,clflush,mfence, prefetch
-+(define_insn_reservation "atom_sse_4" 1
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "sse")
-+ (ior (eq_attr "atom_sse_attr" "fence")
-+ (eq_attr "atom_sse_attr" "prefetch"))))
-+ "atom-simple-0")
-+
-+;; rcpps, rsqrtss, sqrt, ldmxcsr
-+(define_insn_reservation "atom_sse_5" 7
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "sse")
-+ (ior (ior (eq_attr "atom_sse_attr" "sqrt")
-+ (eq_attr "atom_sse_attr" "mxcsr"))
-+ (and (eq_attr "atom_sse_attr" "rcp")
-+ (eq_attr "mode" "V4SF")))))
-+ "atom-complex, atom-all-eu*6")
-+
-+;; xmm->xmm
-+(define_insn_reservation "atom_ssemov" 1
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "ssemov")
-+ (and (match_operand 0 "register_operand" "xy") (match_operand 1 "register_operand" "xy"))))
-+ "atom-simple-either")
-+
-+;; reg->xmm
-+(define_insn_reservation "atom_ssemov_2" 1
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "ssemov")
-+ (and (match_operand 0 "register_operand" "xy") (match_operand 1 "register_operand" "r"))))
-+ "atom-simple-0")
-+
-+;; xmm->reg
-+(define_insn_reservation "atom_ssemov_3" 3
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "ssemov")
-+ (and (match_operand 0 "register_operand" "r") (match_operand 1 "register_operand" "xy"))))
-+ "atom-eu-0-3-1")
-+
-+;; mov mem
-+(define_insn_reservation "atom_ssemov_4" 1
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "ssemov")
-+ (and (eq_attr "movu" "0") (eq_attr "memory" "!none"))))
-+ "atom-simple-0")
-+
-+;; movu mem
-+(define_insn_reservation "atom_ssemov_5" 2
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "ssemov")
-+ (ior (eq_attr "movu" "1") (eq_attr "memory" "!none"))))
-+ "atom-complex, atom-all-eu")
-+
-+;; no memory simple
-+(define_insn_reservation "atom_sseadd" 5
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "sseadd")
-+ (and (eq_attr "memory" "none")
-+ (and (eq_attr "mode" "!V2DF")
-+ (eq_attr "atom_unit" "!complex")))))
-+ "atom-fadd-5c")
-+
-+;; memory simple
-+(define_insn_reservation "atom_sseadd_mem" 5
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "sseadd")
-+ (and (eq_attr "memory" "!none")
-+ (and (eq_attr "mode" "!V2DF")
-+ (eq_attr "atom_unit" "!complex")))))
-+ "atom-dual-5c")
-+
-+;; maxps, minps, *pd, hadd, hsub
-+(define_insn_reservation "atom_sseadd_3" 8
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "sseadd")
-+ (ior (eq_attr "mode" "V2DF") (eq_attr "atom_unit" "complex"))))
-+ "atom-complex, atom-all-eu*7")
-+
-+;; Except dppd/dpps
-+(define_insn_reservation "atom_ssemul" 5
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "ssemul")
-+ (eq_attr "mode" "!SF")))
-+ "atom-fmul-5c")
-+
-+;; Except dppd/dpps, 4 cycle if mulss
-+(define_insn_reservation "atom_ssemul_2" 4
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "ssemul")
-+ (eq_attr "mode" "SF")))
-+ "atom-fmul-4c")
-+
-+(define_insn_reservation "atom_ssecmp" 1
-+ (and (eq_attr "cpu" "atom")
-+ (eq_attr "type" "ssecmp"))
-+ "atom-simple-either")
-+
-+(define_insn_reservation "atom_ssecomi" 10
-+ (and (eq_attr "cpu" "atom")
-+ (eq_attr "type" "ssecomi"))
-+ "atom-complex, atom-all-eu*9")
-+
-+;; no memory and cvtpi2ps, cvtps2pi, cvttps2pi
-+(define_insn_reservation "atom_ssecvt" 5
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "ssecvt")
-+ (ior (and (match_operand:V2SI 0 "register_operand")
-+ (match_operand:V4SF 1 "register_operand"))
-+ (and (match_operand:V4SF 0 "register_operand")
-+ (match_operand:V2SI 1 "register_operand")))))
-+ "atom-fadd-5c")
-+
-+;; memory and cvtpi2ps, cvtps2pi, cvttps2pi
-+(define_insn_reservation "atom_ssecvt_2" 5
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "ssecvt")
-+ (ior (and (match_operand:V2SI 0 "register_operand")
-+ (match_operand:V4SF 1 "memory_operand"))
-+ (and (match_operand:V4SF 0 "register_operand")
-+ (match_operand:V2SI 1 "memory_operand")))))
-+ "atom-dual-5c")
-+
-+;; otherwise. 7 cycles average for cvtss2sd
-+(define_insn_reservation "atom_ssecvt_3" 7
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "ssecvt")
-+ (not (ior (and (match_operand:V2SI 0 "register_operand")
-+ (match_operand:V4SF 1 "nonimmediate_operand"))
-+ (and (match_operand:V4SF 0 "register_operand")
-+ (match_operand:V2SI 1 "nonimmediate_operand"))))))
-+ "atom-complex, atom-all-eu*6")
-+
-+;; memory and cvtsi2sd
-+(define_insn_reservation "atom_sseicvt" 5
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "sseicvt")
-+ (and (match_operand:V2DF 0 "register_operand")
-+ (match_operand:SI 1 "memory_operand"))))
-+ "atom-dual-5c")
-+
-+;; otherwise. 8 cycles average for cvtsd2si
-+(define_insn_reservation "atom_sseicvt_2" 8
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "sseicvt")
-+ (not (and (match_operand:V2DF 0 "register_operand")
-+ (match_operand:SI 1 "memory_operand")))))
-+ "atom-complex, atom-all-eu*7")
-+
-+(define_insn_reservation "atom_ssediv" 62
-+ (and (eq_attr "cpu" "atom")
-+ (eq_attr "type" "ssediv"))
-+ "atom-complex, atom-all-eu*12, nothing*49")
-+
-+;; simple for fmov
-+(define_insn_reservation "atom_fmov" 1
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "fmov")
-+ (eq_attr "memory" "none")))
-+ "atom-simple-either")
-+
-+;; simple for fmov
-+(define_insn_reservation "atom_fmov_mem" 1
-+ (and (eq_attr "cpu" "atom")
-+ (and (eq_attr "type" "fmov")
-+ (eq_attr "memory" "!none")))
-+ "atom-simple-either")
-+
-+;; Define bypass here
-+
-+;; There will be no stall from lea to non-mem EX insns
-+(define_bypass 0 "atom_lea"
-+ "atom_alu_carry,
-+ atom_alu,atom_alu1,atom_negnot,atom_imov,atom_imovx,
-+ atom_incdec, atom_setcc, atom_icmov, atom_pop")
-+
-+(define_bypass 0 "atom_lea"
-+ "atom_alu_mem, atom_alu_carry_mem, atom_alu1_mem,
-+ atom_imovx_mem, atom_imovx_2_mem,
-+ atom_imov_mem, atom_icmov_mem, atom_fmov_mem"
-+ "!ix86_agi_dependent")
-+
-+;; There will be 3 cycles stall from EX insns to AGAN insns LEA
-+(define_bypass 4 "atom_alu_carry,
-+ atom_alu,atom_alu1,atom_negnot,atom_imov,atom_imovx,
-+ atom_incdec,atom_ishift,atom_ishift1,atom_rotate,
-+ atom_rotate1, atom_setcc, atom_icmov, atom_pop,
-+ atom_alu_mem, atom_alu_carry_mem, atom_alu1_mem,
-+ atom_imovx_mem, atom_imovx_2_mem,
-+ atom_imov_mem, atom_icmov_mem, atom_fmov_mem"
-+ "atom_lea")
-+
-+;; There will be 3 cycles stall from EX insns to insns need addr calculation
-+(define_bypass 4 "atom_alu_carry,
-+ atom_alu,atom_alu1,atom_negnot,atom_imov,atom_imovx,
-+ atom_incdec,atom_ishift,atom_ishift1,atom_rotate,
-+ atom_rotate1, atom_setcc, atom_icmov, atom_pop,
-+ atom_imovx_mem, atom_imovx_2_mem,
-+ atom_alu_mem, atom_alu_carry_mem, atom_alu1_mem,
-+ atom_imov_mem, atom_icmov_mem, atom_fmov_mem"
-+ "atom_alu_mem, atom_alu_carry_mem, atom_alu1_mem,
-+ atom_negnot_mem, atom_imov_mem, atom_incdec_mem,
-+ atom_imovx_mem, atom_imovx_2_mem,
-+ atom_imul_mem, atom_icmp_mem,
-+ atom_test_mem, atom_icmov_mem, atom_sselog_mem,
-+ atom_sselog1_mem, atom_fmov_mem, atom_sseadd_mem,
-+ atom_ishift_mem, atom_ishift1_mem,
-+ atom_rotate_mem, atom_rotate1_mem"
-+ "ix86_agi_dependent")
-+
-+;; Stall from imul to lea is 8 cycles.
-+(define_bypass 9 "atom_imul, atom_imul_mem" "atom_lea")
-+
-+;; Stall from imul to memory address is 8 cycles.
-+(define_bypass 9 "atom_imul, atom_imul_mem"
-+ "atom_alu_mem, atom_alu_carry_mem, atom_alu1_mem,
-+ atom_negnot_mem, atom_imov_mem, atom_incdec_mem,
-+ atom_ishift_mem, atom_ishift1_mem, atom_rotate_mem,
-+ atom_rotate1_mem, atom_imul_mem, atom_icmp_mem,
-+ atom_test_mem, atom_icmov_mem, atom_sselog_mem,
-+ atom_sselog1_mem, atom_fmov_mem, atom_sseadd_mem"
-+ "ix86_agi_dependent")
-+
-+;; There will be 0 cycle stall from cmp/test to jcc
-+
-+;; There will be 1 cycle stall from flag producer to cmov and adc/sbb
-+(define_bypass 2 "atom_icmp, atom_test, atom_alu, atom_alu_carry,
-+ atom_alu1, atom_negnot, atom_incdec, atom_ishift,
-+ atom_ishift1, atom_rotate, atom_rotate1"
-+ "atom_icmov, atom_alu_carry")
-+
-+;; lea to shift count stall is 2 cycles
-+(define_bypass 3 "atom_lea"
-+ "atom_ishift, atom_ishift1, atom_rotate, atom_rotate1,
-+ atom_ishift_mem, atom_ishift1_mem,
-+ atom_rotate_mem, atom_rotate1_mem"
-+ "ix86_dep_by_shift_count")
-+
-+;; lea to shift source stall is 1 cycle
-+(define_bypass 2 "atom_lea"
-+ "atom_ishift, atom_ishift1, atom_rotate, atom_rotate1"
-+ "!ix86_dep_by_shift_count")
-+
-+;; non-lea to shift count stall is 1 cycle
-+(define_bypass 2 "atom_alu_carry,
-+ atom_alu,atom_alu1,atom_negnot,atom_imov,atom_imovx,
-+ atom_incdec,atom_ishift,atom_ishift1,atom_rotate,
-+ atom_rotate1, atom_setcc, atom_icmov, atom_pop,
-+ atom_alu_mem, atom_alu_carry_mem, atom_alu1_mem,
-+ atom_imovx_mem, atom_imovx_2_mem,
-+ atom_imov_mem, atom_icmov_mem, atom_fmov_mem"
-+ "atom_ishift, atom_ishift1, atom_rotate, atom_rotate1,
-+ atom_ishift_mem, atom_ishift1_mem,
-+ atom_rotate_mem, atom_rotate1_mem"
-+ "ix86_dep_by_shift_count")
---- a/gcc/config/i386/cpuid.h
-+++ b/gcc/config/i386/cpuid.h
-@@ -29,6 +29,7 @@
- #define bit_CMPXCHG16B (1 << 13)
- #define bit_SSE4_1 (1 << 19)
- #define bit_SSE4_2 (1 << 20)
-+#define bit_MOVBE (1 << 22)
- #define bit_POPCNT (1 << 23)
- #define bit_AES (1 << 25)
- #define bit_XSAVE (1 << 26)
---- a/gcc/config/i386/cygming.h
-+++ b/gcc/config/i386/cygming.h
-@@ -34,7 +34,7 @@ along with GCC; see the file COPYING3.
- #endif
-
- #undef TARGET_64BIT_MS_ABI
--#define TARGET_64BIT_MS_ABI (!cfun ? DEFAULT_ABI == MS_ABI : TARGET_64BIT && cfun->machine->call_abi == MS_ABI)
-+#define TARGET_64BIT_MS_ABI (!cfun ? ix86_abi == MS_ABI : TARGET_64BIT && cfun->machine->call_abi == MS_ABI)
-
- #undef DEFAULT_ABI
- #define DEFAULT_ABI (TARGET_64BIT ? MS_ABI : SYSV_ABI)
-@@ -202,7 +202,7 @@ do { \
- #define CHECK_STACK_LIMIT 4000
-
- #undef STACK_BOUNDARY
--#define STACK_BOUNDARY (DEFAULT_ABI == MS_ABI ? 128 : BITS_PER_WORD)
-+#define STACK_BOUNDARY (ix86_abi == MS_ABI ? 128 : BITS_PER_WORD)
-
- /* By default, target has a 80387, uses IEEE compatible arithmetic,
- returns float values in the 387 and needs stack probes.
---- a/gcc/config/i386/cygming.opt
-+++ b/gcc/config/i386/cygming.opt
-@@ -45,3 +45,7 @@ Set Windows defines
- mwindows
- Target
- Create GUI application
-+
-+mpe-aligned-commons
-+Target Var(use_pe_aligned_common) Init(HAVE_GAS_ALIGNED_COMM)
-+Use the GNU extension to the PE format for aligned common data
---- a/gcc/config/i386/driver-i386.c
-+++ b/gcc/config/i386/driver-i386.c
-@@ -378,7 +378,7 @@ const char *host_detect_local_cpu (int a
- /* Extended features */
- unsigned int has_lahf_lm = 0, has_sse4a = 0;
- unsigned int has_longmode = 0, has_3dnowp = 0, has_3dnow = 0;
-- unsigned int has_sse4_1 = 0, has_sse4_2 = 0;
-+ unsigned int has_movbe = 0, has_sse4_1 = 0, has_sse4_2 = 0;
- unsigned int has_popcnt = 0, has_aes = 0, has_avx = 0;
- unsigned int has_pclmul = 0;
-
-@@ -398,9 +398,22 @@ const char *host_detect_local_cpu (int a
-
- __cpuid (1, eax, ebx, ecx, edx);
-
-- /* We don't care for extended family. */
- model = (eax >> 4) & 0x0f;
- family = (eax >> 8) & 0x0f;
-+ if (vendor == SIG_INTEL)
-+ {
-+ unsigned int extended_model, extended_family;
-+
-+ extended_model = (eax >> 12) & 0xf0;
-+ extended_family = (eax >> 20) & 0xff;
-+ if (family == 0x0f)
-+ {
-+ family += extended_family;
-+ model += extended_model;
-+ }
-+ else if (family == 0x06)
-+ model += extended_model;
-+ }
-
- has_sse3 = ecx & bit_SSE3;
- has_ssse3 = ecx & bit_SSSE3;
-@@ -408,6 +421,7 @@ const char *host_detect_local_cpu (int a
- has_sse4_2 = ecx & bit_SSE4_2;
- has_avx = ecx & bit_AVX;
- has_cmpxchg16b = ecx & bit_CMPXCHG16B;
-+ has_movbe = ecx & bit_MOVBE;
- has_popcnt = ecx & bit_POPCNT;
- has_aes = ecx & bit_AES;
- has_pclmul = ecx & bit_PCLMUL;
-@@ -505,8 +519,8 @@ const char *host_detect_local_cpu (int a
- break;
- case PROCESSOR_PENTIUMPRO:
- if (has_longmode)
-- /* It is Core 2 Duo. */
-- cpu = "core2";
-+ /* It is Core 2 or Atom. */
-+ cpu = (model == 28) ? "atom" : "core2";
- else if (arch)
- {
- if (has_sse3)
-@@ -597,6 +611,8 @@ const char *host_detect_local_cpu (int a
- options = concat (options, "-mcx16 ", NULL);
- if (has_lahf_lm)
- options = concat (options, "-msahf ", NULL);
-+ if (has_movbe)
-+ options = concat (options, "-mmovbe ", NULL);
- if (has_aes)
- options = concat (options, "-maes ", NULL);
- if (has_pclmul)
---- a/gcc/config/i386/i386-c.c
-+++ b/gcc/config/i386/i386-c.c
-@@ -119,6 +119,10 @@ ix86_target_macros_internal (int isa_fla
- def_or_undef (parse_in, "__core2");
- def_or_undef (parse_in, "__core2__");
- break;
-+ case PROCESSOR_ATOM:
-+ def_or_undef (parse_in, "__atom");
-+ def_or_undef (parse_in, "__atom__");
-+ break;
- /* use PROCESSOR_max to not set/unset the arch macro. */
- case PROCESSOR_max:
- break;
-@@ -187,6 +191,9 @@ ix86_target_macros_internal (int isa_fla
- case PROCESSOR_CORE2:
- def_or_undef (parse_in, "__tune_core2__");
- break;
-+ case PROCESSOR_ATOM:
-+ def_or_undef (parse_in, "__tune_atom__");
-+ break;
- case PROCESSOR_GENERIC32:
- case PROCESSOR_GENERIC64:
- break;
---- a/gcc/config/i386/i386-protos.h
-+++ b/gcc/config/i386/i386-protos.h
-@@ -86,6 +86,9 @@ extern void ix86_fixup_binary_operands_n
- extern void ix86_expand_binary_operator (enum rtx_code,
- enum machine_mode, rtx[]);
- extern int ix86_binary_operator_ok (enum rtx_code, enum machine_mode, rtx[]);
-+extern bool ix86_lea_for_add_ok (enum rtx_code, rtx, rtx[]);
-+extern bool ix86_dep_by_shift_count (const_rtx set_insn, const_rtx use_insn);
-+extern bool ix86_agi_dependent (rtx set_insn, rtx use_insn);
- extern void ix86_expand_unary_operator (enum rtx_code, enum machine_mode,
- rtx[]);
- extern rtx ix86_build_const_vector (enum machine_mode, bool, rtx);
-@@ -140,9 +143,8 @@ extern int ix86_function_arg_boundary (e
- extern bool ix86_sol10_return_in_memory (const_tree,const_tree);
- extern rtx ix86_force_to_memory (enum machine_mode, rtx);
- extern void ix86_free_from_memory (enum machine_mode);
--extern int ix86_cfun_abi (void);
--extern int ix86_function_abi (const_tree);
--extern int ix86_function_type_abi (const_tree);
-+extern enum calling_abi ix86_cfun_abi (void);
-+extern enum calling_abi ix86_function_type_abi (const_tree);
- extern void ix86_call_abi_override (const_tree);
- extern tree ix86_fn_abi_va_list (tree);
- extern tree ix86_canonical_va_list_type (tree);
---- a/gcc/config/i386/i386.c
-+++ b/gcc/config/i386/i386.c
-@@ -1036,6 +1036,79 @@ struct processor_costs core2_cost = {
- 1, /* cond_not_taken_branch_cost. */
- };
-
-+static const
-+struct processor_costs atom_cost = {
-+ COSTS_N_INSNS (1), /* cost of an add instruction */
-+ COSTS_N_INSNS (1) + 1, /* cost of a lea instruction */
-+ COSTS_N_INSNS (1), /* variable shift costs */
-+ COSTS_N_INSNS (1), /* constant shift costs */
-+ {COSTS_N_INSNS (3), /* cost of starting multiply for QI */
-+ COSTS_N_INSNS (4), /* HI */
-+ COSTS_N_INSNS (3), /* SI */
-+ COSTS_N_INSNS (4), /* DI */
-+ COSTS_N_INSNS (2)}, /* other */
-+ 0, /* cost of multiply per each bit set */
-+ {COSTS_N_INSNS (18), /* cost of a divide/mod for QI */
-+ COSTS_N_INSNS (26), /* HI */
-+ COSTS_N_INSNS (42), /* SI */
-+ COSTS_N_INSNS (74), /* DI */
-+ COSTS_N_INSNS (74)}, /* other */
-+ COSTS_N_INSNS (1), /* cost of movsx */
-+ COSTS_N_INSNS (1), /* cost of movzx */
-+ 8, /* "large" insn */
-+ 17, /* MOVE_RATIO */
-+ 2, /* cost for loading QImode using movzbl */
-+ {4, 4, 4}, /* cost of loading integer registers
-+ in QImode, HImode and SImode.
-+ Relative to reg-reg move (2). */
-+ {4, 4, 4}, /* cost of storing integer registers */
-+ 4, /* cost of reg,reg fld/fst */
-+ {12, 12, 12}, /* cost of loading fp registers
-+ in SFmode, DFmode and XFmode */
-+ {6, 6, 8}, /* cost of storing fp registers
-+ in SFmode, DFmode and XFmode */
-+ 2, /* cost of moving MMX register */
-+ {8, 8}, /* cost of loading MMX registers
-+ in SImode and DImode */
-+ {8, 8}, /* cost of storing MMX registers
-+ in SImode and DImode */
-+ 2, /* cost of moving SSE register */
-+ {8, 8, 8}, /* cost of loading SSE registers
-+ in SImode, DImode and TImode */
-+ {8, 8, 8}, /* cost of storing SSE registers
-+ in SImode, DImode and TImode */
-+ 5, /* MMX or SSE register to integer */
-+ 32, /* size of l1 cache. */
-+ 256, /* size of l2 cache. */
-+ 64, /* size of prefetch block */
-+ 6, /* number of parallel prefetches */
-+ 3, /* Branch cost */
-+ COSTS_N_INSNS (8), /* cost of FADD and FSUB insns. */
-+ COSTS_N_INSNS (8), /* cost of FMUL instruction. */
-+ COSTS_N_INSNS (20), /* cost of FDIV instruction. */
-+ COSTS_N_INSNS (8), /* cost of FABS instruction. */
-+ COSTS_N_INSNS (8), /* cost of FCHS instruction. */
-+ COSTS_N_INSNS (40), /* cost of FSQRT instruction. */
-+ {{libcall, {{11, loop}, {-1, rep_prefix_4_byte}}},
-+ {libcall, {{32, loop}, {64, rep_prefix_4_byte},
-+ {8192, rep_prefix_8_byte}, {-1, libcall}}}},
-+ {{libcall, {{8, loop}, {15, unrolled_loop},
-+ {2048, rep_prefix_4_byte}, {-1, libcall}}},
-+ {libcall, {{24, loop}, {32, unrolled_loop},
-+ {8192, rep_prefix_8_byte}, {-1, libcall}}}},
-+ 1, /* scalar_stmt_cost. */
-+ 1, /* scalar load_cost. */
-+ 1, /* scalar_store_cost. */
-+ 1, /* vec_stmt_cost. */
-+ 1, /* vec_to_scalar_cost. */
-+ 1, /* scalar_to_vec_cost. */
-+ 1, /* vec_align_load_cost. */
-+ 2, /* vec_unalign_load_cost. */
-+ 1, /* vec_store_cost. */
-+ 3, /* cond_taken_branch_cost. */
-+ 1, /* cond_not_taken_branch_cost. */
-+};
-+
- /* Generic64 should produce code tuned for Nocona and K8. */
- static const
- struct processor_costs generic64_cost = {
-@@ -1194,6 +1267,7 @@ const struct processor_costs *ix86_cost
- #define m_PENT4 (1<<PROCESSOR_PENTIUM4)
- #define m_NOCONA (1<<PROCESSOR_NOCONA)
- #define m_CORE2 (1<<PROCESSOR_CORE2)
-+#define m_ATOM (1<<PROCESSOR_ATOM)
-
- #define m_GEODE (1<<PROCESSOR_GEODE)
- #define m_K6 (1<<PROCESSOR_K6)
-@@ -1231,10 +1305,11 @@ static unsigned int initial_ix86_tune_fe
- m_486 | m_PENT,
-
- /* X86_TUNE_UNROLL_STRLEN */
-- m_486 | m_PENT | m_PPRO | m_AMD_MULTIPLE | m_K6 | m_CORE2 | m_GENERIC,
-+ m_486 | m_PENT | m_ATOM | m_PPRO | m_AMD_MULTIPLE | m_K6
-+ | m_CORE2 | m_GENERIC,
-
- /* X86_TUNE_DEEP_BRANCH_PREDICTION */
-- m_PPRO | m_K6_GEODE | m_AMD_MULTIPLE | m_PENT4 | m_GENERIC,
-+ m_ATOM | m_PPRO | m_K6_GEODE | m_AMD_MULTIPLE | m_PENT4 | m_GENERIC,
-
- /* X86_TUNE_BRANCH_PREDICTION_HINTS: Branch hints were put in P4 based
- on simulation result. But after P4 was made, no performance benefit
-@@ -1246,12 +1321,12 @@ static unsigned int initial_ix86_tune_fe
- ~m_386,
-
- /* X86_TUNE_USE_SAHF */
-- m_PPRO | m_K6_GEODE | m_K8 | m_AMDFAM10 | m_PENT4
-+ m_ATOM | m_PPRO | m_K6_GEODE | m_K8 | m_AMDFAM10 | m_PENT4
- | m_NOCONA | m_CORE2 | m_GENERIC,
-
- /* X86_TUNE_MOVX: Enable to zero extend integer registers to avoid
- partial dependencies. */
-- m_AMD_MULTIPLE | m_PPRO | m_PENT4 | m_NOCONA
-+ m_AMD_MULTIPLE | m_ATOM | m_PPRO | m_PENT4 | m_NOCONA
- | m_CORE2 | m_GENERIC | m_GEODE /* m_386 | m_K6 */,
-
- /* X86_TUNE_PARTIAL_REG_STALL: We probably ought to watch for partial
-@@ -1271,13 +1346,13 @@ static unsigned int initial_ix86_tune_fe
- m_386 | m_486 | m_K6_GEODE,
-
- /* X86_TUNE_USE_SIMODE_FIOP */
-- ~(m_PPRO | m_AMD_MULTIPLE | m_PENT | m_CORE2 | m_GENERIC),
-+ ~(m_PPRO | m_AMD_MULTIPLE | m_PENT | m_ATOM | m_CORE2 | m_GENERIC),
-
- /* X86_TUNE_USE_MOV0 */
- m_K6,
-
- /* X86_TUNE_USE_CLTD */
-- ~(m_PENT | m_K6 | m_CORE2 | m_GENERIC),
-+ ~(m_PENT | m_ATOM | m_K6 | m_CORE2 | m_GENERIC),
-
- /* X86_TUNE_USE_XCHGB: Use xchgb %rh,%rl instead of rolw/rorw $8,rx. */
- m_PENT4,
-@@ -1292,8 +1367,8 @@ static unsigned int initial_ix86_tune_fe
- ~(m_PENT | m_PPRO),
-
- /* X86_TUNE_PROMOTE_QIMODE */
-- m_K6_GEODE | m_PENT | m_386 | m_486 | m_AMD_MULTIPLE | m_CORE2
-- | m_GENERIC /* | m_PENT4 ? */,
-+ m_K6_GEODE | m_PENT | m_ATOM | m_386 | m_486 | m_AMD_MULTIPLE
-+ | m_CORE2 | m_GENERIC /* | m_PENT4 ? */,
-
- /* X86_TUNE_FAST_PREFIX */
- ~(m_PENT | m_486 | m_386),
-@@ -1317,26 +1392,28 @@ static unsigned int initial_ix86_tune_fe
- m_PPRO,
-
- /* X86_TUNE_ADD_ESP_4: Enable if add/sub is preferred over 1/2 push/pop. */
-- m_AMD_MULTIPLE | m_K6_GEODE | m_PENT4 | m_NOCONA | m_CORE2 | m_GENERIC,
-+ m_ATOM | m_AMD_MULTIPLE | m_K6_GEODE | m_PENT4 | m_NOCONA
-+ | m_CORE2 | m_GENERIC,
-
- /* X86_TUNE_ADD_ESP_8 */
-- m_AMD_MULTIPLE | m_PPRO | m_K6_GEODE | m_386
-+ m_AMD_MULTIPLE | m_ATOM | m_PPRO | m_K6_GEODE | m_386
- | m_486 | m_PENT4 | m_NOCONA | m_CORE2 | m_GENERIC,
-
- /* X86_TUNE_SUB_ESP_4 */
-- m_AMD_MULTIPLE | m_PPRO | m_PENT4 | m_NOCONA | m_CORE2 | m_GENERIC,
-+ m_AMD_MULTIPLE | m_ATOM | m_PPRO | m_PENT4 | m_NOCONA | m_CORE2
-+ | m_GENERIC,
-
- /* X86_TUNE_SUB_ESP_8 */
-- m_AMD_MULTIPLE | m_PPRO | m_386 | m_486
-+ m_AMD_MULTIPLE | m_ATOM | m_PPRO | m_386 | m_486
- | m_PENT4 | m_NOCONA | m_CORE2 | m_GENERIC,
-
- /* X86_TUNE_INTEGER_DFMODE_MOVES: Enable if integer moves are preferred
- for DFmode copies */
-- ~(m_AMD_MULTIPLE | m_PENT4 | m_NOCONA | m_PPRO | m_CORE2
-+ ~(m_AMD_MULTIPLE | m_ATOM | m_PENT4 | m_NOCONA | m_PPRO | m_CORE2
- | m_GENERIC | m_GEODE),
-
- /* X86_TUNE_PARTIAL_REG_DEPENDENCY */
-- m_AMD_MULTIPLE | m_PENT4 | m_NOCONA | m_CORE2 | m_GENERIC,
-+ m_AMD_MULTIPLE | m_ATOM | m_PENT4 | m_NOCONA | m_CORE2 | m_GENERIC,
-
- /* X86_TUNE_SSE_PARTIAL_REG_DEPENDENCY: In the Generic model we have a
- conflict here in between PPro/Pentium4 based chips that thread 128bit
-@@ -1347,7 +1424,8 @@ static unsigned int initial_ix86_tune_fe
- shows that disabling this option on P4 brings over 20% SPECfp regression,
- while enabling it on K8 brings roughly 2.4% regression that can be partly
- masked by careful scheduling of moves. */
-- m_PENT4 | m_NOCONA | m_PPRO | m_CORE2 | m_GENERIC | m_AMDFAM10,
-+ m_ATOM | m_PENT4 | m_NOCONA | m_PPRO | m_CORE2 | m_GENERIC
-+ | m_AMDFAM10,
-
- /* X86_TUNE_SSE_UNALIGNED_MOVE_OPTIMAL */
- m_AMDFAM10,
-@@ -1365,13 +1443,13 @@ static unsigned int initial_ix86_tune_fe
- m_PPRO | m_PENT4 | m_NOCONA,
-
- /* X86_TUNE_MEMORY_MISMATCH_STALL */
-- m_AMD_MULTIPLE | m_PENT4 | m_NOCONA | m_CORE2 | m_GENERIC,
-+ m_AMD_MULTIPLE | m_ATOM | m_PENT4 | m_NOCONA | m_CORE2 | m_GENERIC,
-
- /* X86_TUNE_PROLOGUE_USING_MOVE */
-- m_ATHLON_K8 | m_PPRO | m_CORE2 | m_GENERIC,
-+ m_ATHLON_K8 | m_ATOM | m_PPRO | m_CORE2 | m_GENERIC,
-
- /* X86_TUNE_EPILOGUE_USING_MOVE */
-- m_ATHLON_K8 | m_PPRO | m_CORE2 | m_GENERIC,
-+ m_ATHLON_K8 | m_ATOM | m_PPRO | m_CORE2 | m_GENERIC,
-
- /* X86_TUNE_SHIFT1 */
- ~m_486,
-@@ -1380,29 +1458,32 @@ static unsigned int initial_ix86_tune_fe
- m_AMD_MULTIPLE,
-
- /* X86_TUNE_INTER_UNIT_MOVES */
-- ~(m_AMD_MULTIPLE | m_GENERIC),
-+ ~(m_AMD_MULTIPLE | m_ATOM | m_GENERIC),
-
- /* X86_TUNE_INTER_UNIT_CONVERSIONS */
- ~(m_AMDFAM10),
-
- /* X86_TUNE_FOUR_JUMP_LIMIT: Some CPU cores are not able to predict more
- than 4 branch instructions in the 16 byte window. */
-- m_PPRO | m_AMD_MULTIPLE | m_PENT4 | m_NOCONA | m_CORE2 | m_GENERIC,
-+ m_ATOM | m_PPRO | m_AMD_MULTIPLE | m_PENT4 | m_NOCONA | m_CORE2
-+ | m_GENERIC,
-
- /* X86_TUNE_SCHEDULE */
-- m_PPRO | m_AMD_MULTIPLE | m_K6_GEODE | m_PENT | m_CORE2 | m_GENERIC,
-+ m_PPRO | m_AMD_MULTIPLE | m_K6_GEODE | m_PENT | m_ATOM | m_CORE2
-+ | m_GENERIC,
-
- /* X86_TUNE_USE_BT */
-- m_AMD_MULTIPLE | m_CORE2 | m_GENERIC,
-+ m_AMD_MULTIPLE | m_ATOM | m_CORE2 | m_GENERIC,
-
- /* X86_TUNE_USE_INCDEC */
-- ~(m_PENT4 | m_NOCONA | m_GENERIC),
-+ ~(m_PENT4 | m_NOCONA | m_GENERIC | m_ATOM),
-
- /* X86_TUNE_PAD_RETURNS */
- m_AMD_MULTIPLE | m_CORE2 | m_GENERIC,
-
- /* X86_TUNE_EXT_80387_CONSTANTS */
-- m_K6_GEODE | m_ATHLON_K8 | m_PENT4 | m_NOCONA | m_PPRO | m_CORE2 | m_GENERIC,
-+ m_K6_GEODE | m_ATHLON_K8 | m_ATOM | m_PENT4 | m_NOCONA | m_PPRO
-+ | m_CORE2 | m_GENERIC,
-
- /* X86_TUNE_SHORTEN_X87_SSE */
- ~m_K8,
-@@ -1447,6 +1528,10 @@ static unsigned int initial_ix86_tune_fe
- with a subsequent conditional jump instruction into a single
- compare-and-branch uop. */
- m_CORE2,
-+
-+ /* X86_TUNE_OPT_AGU: Optimize for Address Generation Unit. This flag
-+ will impact LEA instruction selection. */
-+ m_ATOM,
- };
-
- /* Feature tests against the various architecture variations. */
-@@ -1472,10 +1557,11 @@ static unsigned int initial_ix86_arch_fe
- };
-
- static const unsigned int x86_accumulate_outgoing_args
-- = m_AMD_MULTIPLE | m_PENT4 | m_NOCONA | m_PPRO | m_CORE2 | m_GENERIC;
-+ = m_AMD_MULTIPLE | m_ATOM | m_PENT4 | m_NOCONA | m_PPRO | m_CORE2
-+ | m_GENERIC;
-
- static const unsigned int x86_arch_always_fancy_math_387
-- = m_PENT | m_PPRO | m_AMD_MULTIPLE | m_PENT4
-+ = m_PENT | m_ATOM | m_PPRO | m_AMD_MULTIPLE | m_PENT4
- | m_NOCONA | m_CORE2 | m_GENERIC;
-
- static enum stringop_alg stringop_alg = no_stringop;
-@@ -1743,6 +1829,9 @@ static unsigned int ix86_default_incomin
- /* Alignment for incoming stack boundary in bits. */
- unsigned int ix86_incoming_stack_boundary;
-
-+/* The abi used by target. */
-+enum calling_abi ix86_abi;
-+
- /* Values 1-5: see jump.c */
- int ix86_branch_cost;
-
-@@ -1819,6 +1908,8 @@ static bool ix86_valid_target_attribute_
- static bool ix86_can_inline_p (tree, tree);
- static void ix86_set_current_function (tree);
-
-+static enum calling_abi ix86_function_abi (const_tree);
-+
- \f
- /* The svr4 ABI for the i386 says that records and unions are returned
- in memory. */
-@@ -1880,6 +1971,7 @@ static int ix86_isa_flags_explicit;
- #define OPTION_MASK_ISA_POPCNT_SET OPTION_MASK_ISA_POPCNT
- #define OPTION_MASK_ISA_CX16_SET OPTION_MASK_ISA_CX16
- #define OPTION_MASK_ISA_SAHF_SET OPTION_MASK_ISA_SAHF
-+#define OPTION_MASK_ISA_MOVBE_SET OPTION_MASK_ISA_MOVBE
-
- /* Define a set of ISAs which aren't available when a given ISA is
- disabled. MMX and SSE ISAs are handled separately. */
-@@ -1921,6 +2013,7 @@ static int ix86_isa_flags_explicit;
- #define OPTION_MASK_ISA_POPCNT_UNSET OPTION_MASK_ISA_POPCNT
- #define OPTION_MASK_ISA_CX16_UNSET OPTION_MASK_ISA_CX16
- #define OPTION_MASK_ISA_SAHF_UNSET OPTION_MASK_ISA_SAHF
-+#define OPTION_MASK_ISA_MOVBE_UNSET OPTION_MASK_ISA_MOVBE
-
- /* Vectorization library interface and handlers. */
- tree (*ix86_veclib_handler)(enum built_in_function, tree, tree) = NULL;
-@@ -1953,7 +2046,8 @@ static const struct ptt processor_target
- {&core2_cost, 16, 10, 16, 10, 16},
- {&generic32_cost, 16, 7, 16, 7, 16},
- {&generic64_cost, 16, 10, 16, 10, 16},
-- {&amdfam10_cost, 32, 24, 32, 7, 32}
-+ {&amdfam10_cost, 32, 24, 32, 7, 32},
-+ {&atom_cost, 16, 7, 16, 7, 16}
- };
-
- static const char *const cpu_names[TARGET_CPU_DEFAULT_max] =
-@@ -1971,6 +2065,7 @@ static const char *const cpu_names[TARGE
- "prescott",
- "nocona",
- "core2",
-+ "atom",
- "geode",
- "k6",
- "k6-2",
-@@ -2209,6 +2304,19 @@ ix86_handle_option (size_t code, const c
- }
- return true;
-
-+ case OPT_mmovbe:
-+ if (value)
-+ {
-+ ix86_isa_flags |= OPTION_MASK_ISA_MOVBE_SET;
-+ ix86_isa_flags_explicit |= OPTION_MASK_ISA_MOVBE_SET;
-+ }
-+ else
-+ {
-+ ix86_isa_flags &= ~OPTION_MASK_ISA_MOVBE_UNSET;
-+ ix86_isa_flags_explicit |= OPTION_MASK_ISA_MOVBE_UNSET;
-+ }
-+ return true;
-+
- case OPT_maes:
- if (value)
- {
-@@ -2271,6 +2379,7 @@ ix86_target_string (int isa, int flags,
- { "-mmmx", OPTION_MASK_ISA_MMX },
- { "-mabm", OPTION_MASK_ISA_ABM },
- { "-mpopcnt", OPTION_MASK_ISA_POPCNT },
-+ { "-mmovbe", OPTION_MASK_ISA_MOVBE },
- { "-maes", OPTION_MASK_ISA_AES },
- { "-mpclmul", OPTION_MASK_ISA_PCLMUL },
- };
-@@ -2487,7 +2596,8 @@ override_options (bool main_args_p)
- PTA_AES = 1 << 17,
- PTA_PCLMUL = 1 << 18,
- PTA_AVX = 1 << 19,
-- PTA_FMA = 1 << 20
-+ PTA_FMA = 1 << 20,
-+ PTA_MOVBE = 1 << 21
- };
-
- static struct pta
-@@ -2529,6 +2639,9 @@ override_options (bool main_args_p)
- {"core2", PROCESSOR_CORE2, CPU_CORE2,
- PTA_64BIT | PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_SSE3
- | PTA_SSSE3 | PTA_CX16},
-+ {"atom", PROCESSOR_ATOM, CPU_ATOM,
-+ PTA_64BIT | PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_SSE3
-+ | PTA_SSSE3 | PTA_CX16 | PTA_MOVBE},
- {"geode", PROCESSOR_GEODE, CPU_GEODE,
- PTA_MMX | PTA_3DNOW | PTA_3DNOW_A |PTA_PREFETCH_SSE},
- {"k6", PROCESSOR_K6, CPU_K6, PTA_MMX},
-@@ -2716,6 +2829,20 @@ override_options (bool main_args_p)
- error ("bad value (%s) for %sarch=%s %s",
- ix86_arch_string, prefix, suffix, sw);
-
-+ /* Validate -mabi= value. */
-+ if (ix86_abi_string)
-+ {
-+ if (strcmp (ix86_abi_string, "sysv") == 0)
-+ ix86_abi = SYSV_ABI;
-+ else if (strcmp (ix86_abi_string, "ms") == 0)
-+ ix86_abi = MS_ABI;
-+ else
-+ error ("unknown ABI (%s) for %sabi=%s %s",
-+ ix86_abi_string, prefix, suffix, sw);
-+ }
-+ else
-+ ix86_abi = DEFAULT_ABI;
-+
- if (ix86_cmodel_string != 0)
- {
- if (!strcmp (ix86_cmodel_string, "small"))
-@@ -2828,6 +2955,9 @@ override_options (bool main_args_p)
- if (!(TARGET_64BIT && (processor_alias_table[i].flags & PTA_NO_SAHF))
- && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_SAHF))
- ix86_isa_flags |= OPTION_MASK_ISA_SAHF;
-+ if (processor_alias_table[i].flags & PTA_MOVBE
-+ && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_MOVBE))
-+ ix86_isa_flags |= OPTION_MASK_ISA_MOVBE;
- if (processor_alias_table[i].flags & PTA_AES
- && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_AES))
- ix86_isa_flags |= OPTION_MASK_ISA_AES;
-@@ -4592,14 +4722,14 @@ ix86_function_arg_regno_p (int regno)
- default ABI. */
-
- /* RAX is used as hidden argument to va_arg functions. */
-- if (DEFAULT_ABI == SYSV_ABI && regno == AX_REG)
-+ if (ix86_abi == SYSV_ABI && regno == AX_REG)
- return true;
-
-- if (DEFAULT_ABI == MS_ABI)
-+ if (ix86_abi == MS_ABI)
- parm_regs = x86_64_ms_abi_int_parameter_registers;
- else
- parm_regs = x86_64_int_parameter_registers;
-- for (i = 0; i < (DEFAULT_ABI == MS_ABI ? X64_REGPARM_MAX
-+ for (i = 0; i < (ix86_abi == MS_ABI ? X64_REGPARM_MAX
- : X86_64_REGPARM_MAX); i++)
- if (regno == parm_regs[i])
- return true;
-@@ -4627,7 +4757,7 @@ ix86_must_pass_in_stack (enum machine_mo
- int
- ix86_reg_parm_stack_space (const_tree fndecl)
- {
-- int call_abi = SYSV_ABI;
-+ enum calling_abi call_abi = SYSV_ABI;
- if (fndecl != NULL_TREE && TREE_CODE (fndecl) == FUNCTION_DECL)
- call_abi = ix86_function_abi (fndecl);
- else
-@@ -4639,37 +4769,39 @@ ix86_reg_parm_stack_space (const_tree fn
-
- /* Returns value SYSV_ABI, MS_ABI dependent on fntype, specifying the
- call abi used. */
--int
-+enum calling_abi
- ix86_function_type_abi (const_tree fntype)
- {
- if (TARGET_64BIT && fntype != NULL)
- {
-- int abi;
-- if (DEFAULT_ABI == SYSV_ABI)
-- abi = lookup_attribute ("ms_abi", TYPE_ATTRIBUTES (fntype)) ? MS_ABI : SYSV_ABI;
-- else
-- abi = lookup_attribute ("sysv_abi", TYPE_ATTRIBUTES (fntype)) ? SYSV_ABI : MS_ABI;
--
-+ enum calling_abi abi = ix86_abi;
-+ if (abi == SYSV_ABI)
-+ {
-+ if (lookup_attribute ("ms_abi", TYPE_ATTRIBUTES (fntype)))
-+ abi = MS_ABI;
-+ }
-+ else if (lookup_attribute ("sysv_abi", TYPE_ATTRIBUTES (fntype)))
-+ abi = SYSV_ABI;
- return abi;
- }
-- return DEFAULT_ABI;
-+ return ix86_abi;
- }
-
--int
-+static enum calling_abi
- ix86_function_abi (const_tree fndecl)
- {
- if (! fndecl)
-- return DEFAULT_ABI;
-+ return ix86_abi;
- return ix86_function_type_abi (TREE_TYPE (fndecl));
- }
-
- /* Returns value SYSV_ABI, MS_ABI dependent on cfun, specifying the
- call abi used. */
--int
-+enum calling_abi
- ix86_cfun_abi (void)
- {
- if (! cfun || ! TARGET_64BIT)
-- return DEFAULT_ABI;
-+ return ix86_abi;
- return cfun->machine->call_abi;
- }
-
-@@ -4683,7 +4815,7 @@ void
- ix86_call_abi_override (const_tree fndecl)
- {
- if (fndecl == NULL_TREE)
-- cfun->machine->call_abi = DEFAULT_ABI;
-+ cfun->machine->call_abi = ix86_abi;
- else
- cfun->machine->call_abi = ix86_function_type_abi (TREE_TYPE (fndecl));
- }
-@@ -4724,8 +4856,8 @@ init_cumulative_args (CUMULATIVE_ARGS *c
- cum->nregs = ix86_regparm;
- if (TARGET_64BIT)
- {
-- if (cum->call_abi != DEFAULT_ABI)
-- cum->nregs = DEFAULT_ABI != SYSV_ABI ? X86_64_REGPARM_MAX
-+ if (cum->call_abi != ix86_abi)
-+ cum->nregs = ix86_abi != SYSV_ABI ? X86_64_REGPARM_MAX
- : X64_REGPARM_MAX;
- }
- if (TARGET_SSE)
-@@ -4733,8 +4865,8 @@ init_cumulative_args (CUMULATIVE_ARGS *c
- cum->sse_nregs = SSE_REGPARM_MAX;
- if (TARGET_64BIT)
- {
-- if (cum->call_abi != DEFAULT_ABI)
-- cum->sse_nregs = DEFAULT_ABI != SYSV_ABI ? X86_64_SSE_REGPARM_MAX
-+ if (cum->call_abi != ix86_abi)
-+ cum->sse_nregs = ix86_abi != SYSV_ABI ? X86_64_SSE_REGPARM_MAX
- : X64_SSE_REGPARM_MAX;
- }
- }
-@@ -5700,7 +5832,7 @@ function_arg_advance (CUMULATIVE_ARGS *c
- if (type)
- mode = type_natural_mode (type, NULL);
-
-- if (TARGET_64BIT && (cum ? cum->call_abi : DEFAULT_ABI) == MS_ABI)
-+ if (TARGET_64BIT && (cum ? cum->call_abi : ix86_abi) == MS_ABI)
- function_arg_advance_ms_64 (cum, bytes, words);
- else if (TARGET_64BIT)
- function_arg_advance_64 (cum, mode, type, words, named);
-@@ -5846,9 +5978,9 @@ function_arg_64 (CUMULATIVE_ARGS *cum, e
- if (mode == VOIDmode)
- return GEN_INT (cum->maybe_vaarg
- ? (cum->sse_nregs < 0
-- ? (cum->call_abi == DEFAULT_ABI
-+ ? (cum->call_abi == ix86_abi
- ? SSE_REGPARM_MAX
-- : (DEFAULT_ABI != SYSV_ABI ? X86_64_SSE_REGPARM_MAX
-+ : (ix86_abi != SYSV_ABI ? X86_64_SSE_REGPARM_MAX
- : X64_SSE_REGPARM_MAX))
- : cum->sse_regno)
- : -1);
-@@ -5942,7 +6074,7 @@ function_arg (CUMULATIVE_ARGS *cum, enum
- if (type && TREE_CODE (type) == VECTOR_TYPE)
- mode = type_natural_mode (type, cum);
-
-- if (TARGET_64BIT && (cum ? cum->call_abi : DEFAULT_ABI) == MS_ABI)
-+ if (TARGET_64BIT && (cum ? cum->call_abi : ix86_abi) == MS_ABI)
- return function_arg_ms_64 (cum, mode, omode, named, bytes);
- else if (TARGET_64BIT)
- return function_arg_64 (cum, mode, omode, type, named);
-@@ -5962,7 +6094,7 @@ ix86_pass_by_reference (CUMULATIVE_ARGS
- const_tree type, bool named ATTRIBUTE_UNUSED)
- {
- /* See Windows x64 Software Convention. */
-- if (TARGET_64BIT && (cum ? cum->call_abi : DEFAULT_ABI) == MS_ABI)
-+ if (TARGET_64BIT && (cum ? cum->call_abi : ix86_abi) == MS_ABI)
- {
- int msize = (int) GET_MODE_SIZE (mode);
- if (type)
-@@ -6102,7 +6234,7 @@ ix86_function_value_regno_p (int regno)
- /* TODO: The function should depend on current function ABI but
- builtins.c would need updating then. Therefore we use the
- default ABI. */
-- if (TARGET_64BIT && DEFAULT_ABI == MS_ABI)
-+ if (TARGET_64BIT && ix86_abi == MS_ABI)
- return false;
- return TARGET_FLOAT_RETURNS_IN_80387;
-
-@@ -6498,13 +6630,13 @@ ix86_build_builtin_va_list_abi (enum cal
- static tree
- ix86_build_builtin_va_list (void)
- {
-- tree ret = ix86_build_builtin_va_list_abi (DEFAULT_ABI);
-+ tree ret = ix86_build_builtin_va_list_abi (ix86_abi);
-
- /* Initialize abi specific va_list builtin types. */
- if (TARGET_64BIT)
- {
- tree t;
-- if (DEFAULT_ABI == MS_ABI)
-+ if (ix86_abi == MS_ABI)
- {
- t = ix86_build_builtin_va_list_abi (SYSV_ABI);
- if (TREE_CODE (t) != RECORD_TYPE)
-@@ -6518,7 +6650,7 @@ ix86_build_builtin_va_list (void)
- t = build_variant_type_copy (t);
- sysv_va_list_type_node = t;
- }
-- if (DEFAULT_ABI != MS_ABI)
-+ if (ix86_abi != MS_ABI)
- {
- t = ix86_build_builtin_va_list_abi (MS_ABI);
- if (TREE_CODE (t) != RECORD_TYPE)
-@@ -6551,8 +6683,8 @@ setup_incoming_varargs_64 (CUMULATIVE_AR
- int i;
- int regparm = ix86_regparm;
-
-- if (cum->call_abi != DEFAULT_ABI)
-- regparm = DEFAULT_ABI != SYSV_ABI ? X86_64_REGPARM_MAX : X64_REGPARM_MAX;
-+ if (cum->call_abi != ix86_abi)
-+ regparm = ix86_abi != SYSV_ABI ? X86_64_REGPARM_MAX : X64_REGPARM_MAX;
-
- /* GPR size of varargs save area. */
- if (cfun->va_list_gpr_size)
-@@ -6705,7 +6837,7 @@ is_va_list_char_pointer (tree type)
- return true;
- canonic = ix86_canonical_va_list_type (type);
- return (canonic == ms_va_list_type_node
-- || (DEFAULT_ABI == MS_ABI && canonic == va_list_type_node));
-+ || (ix86_abi == MS_ABI && canonic == va_list_type_node));
- }
-
- /* Implement va_start. */
-@@ -12994,6 +13126,316 @@ ix86_expand_unary_operator (enum rtx_cod
- emit_move_insn (operands[0], dst);
- }
-
-+#define LEA_SEARCH_THRESHOLD 12
-+
-+/* Search backward for non-agu definition of register number REGNO1
-+ or register number REGNO2 in INSN's basic block until
-+ 1. Pass LEA_SEARCH_THRESHOLD instructions, or
-+ 2. Reach BB boundary, or
-+ 3. Reach agu definition.
-+ Returns the distance between the non-agu definition point and INSN.
-+ If no definition point, returns -1. */
-+
-+static int
-+distance_non_agu_define (unsigned int regno1, unsigned int regno2,
-+ rtx insn)
-+{
-+ basic_block bb = BLOCK_FOR_INSN (insn);
-+ int distance = 0;
-+ df_ref *def_rec;
-+ enum attr_type insn_type;
-+
-+ if (insn != BB_HEAD (bb))
-+ {
-+ rtx prev = PREV_INSN (insn);
-+ while (prev && distance < LEA_SEARCH_THRESHOLD)
-+ {
-+ if (INSN_P (prev))
-+ {
-+ distance++;
-+ for (def_rec = DF_INSN_DEFS (prev); *def_rec; def_rec++)
-+ if (DF_REF_TYPE (*def_rec) == DF_REF_REG_DEF
-+ && !DF_REF_IS_ARTIFICIAL (*def_rec)
-+ && (regno1 == DF_REF_REGNO (*def_rec)
-+ || regno2 == DF_REF_REGNO (*def_rec)))
-+ {
-+ insn_type = get_attr_type (prev);
-+ if (insn_type != TYPE_LEA)
-+ goto done;
-+ }
-+ }
-+ if (prev == BB_HEAD (bb))
-+ break;
-+ prev = PREV_INSN (prev);
-+ }
-+ }
-+
-+ if (distance < LEA_SEARCH_THRESHOLD)
-+ {
-+ edge e;
-+ edge_iterator ei;
-+ bool simple_loop = false;
-+
-+ FOR_EACH_EDGE (e, ei, bb->preds)
-+ if (e->src == bb)
-+ {
-+ simple_loop = true;
-+ break;
-+ }
-+
-+ if (simple_loop)
-+ {
-+ rtx prev = BB_END (bb);
-+ while (prev
-+ && prev != insn
-+ && distance < LEA_SEARCH_THRESHOLD)
-+ {
-+ if (INSN_P (prev))
-+ {
-+ distance++;
-+ for (def_rec = DF_INSN_DEFS (prev); *def_rec; def_rec++)
-+ if (DF_REF_TYPE (*def_rec) == DF_REF_REG_DEF
-+ && !DF_REF_IS_ARTIFICIAL (*def_rec)
-+ && (regno1 == DF_REF_REGNO (*def_rec)
-+ || regno2 == DF_REF_REGNO (*def_rec)))
-+ {
-+ insn_type = get_attr_type (prev);
-+ if (insn_type != TYPE_LEA)
-+ goto done;
-+ }
-+ }
-+ prev = PREV_INSN (prev);
-+ }
-+ }
-+ }
-+
-+ distance = -1;
-+
-+done:
-+ /* get_attr_type may modify recog data. We want to make sure
-+ that recog data is valid for instruction INSN, on which
-+ distance_non_agu_define is called. INSN is unchanged here. */
-+ extract_insn_cached (insn);
-+ return distance;
-+}
-+
-+/* Return the distance between INSN and the next insn that uses
-+ register number REGNO0 in memory address. Return -1 if no such
-+ a use is found within LEA_SEARCH_THRESHOLD or REGNO0 is set. */
-+
-+static int
-+distance_agu_use (unsigned int regno0, rtx insn)
-+{
-+ basic_block bb = BLOCK_FOR_INSN (insn);
-+ int distance = 0;
-+ df_ref *def_rec;
-+ df_ref *use_rec;
-+
-+ if (insn != BB_END (bb))
-+ {
-+ rtx next = NEXT_INSN (insn);
-+ while (next && distance < LEA_SEARCH_THRESHOLD)
-+ {
-+ if (INSN_P (next))
-+ {
-+ distance++;
-+
-+ for (use_rec = DF_INSN_USES (next); *use_rec; use_rec++)
-+ if ((DF_REF_TYPE (*use_rec) == DF_REF_REG_MEM_LOAD
-+ || DF_REF_TYPE (*use_rec) == DF_REF_REG_MEM_STORE)
-+ && regno0 == DF_REF_REGNO (*use_rec))
-+ {
-+ /* Return DISTANCE if OP0 is used in memory
-+ address in NEXT. */
-+ return distance;
-+ }
-+
-+ for (def_rec = DF_INSN_DEFS (next); *def_rec; def_rec++)
-+ if (DF_REF_TYPE (*def_rec) == DF_REF_REG_DEF
-+ && !DF_REF_IS_ARTIFICIAL (*def_rec)
-+ && regno0 == DF_REF_REGNO (*def_rec))
-+ {
-+ /* Return -1 if OP0 is set in NEXT. */
-+ return -1;
-+ }
-+ }
-+ if (next == BB_END (bb))
-+ break;
-+ next = NEXT_INSN (next);
-+ }
-+ }
-+
-+ if (distance < LEA_SEARCH_THRESHOLD)
-+ {
-+ edge e;
-+ edge_iterator ei;
-+ bool simple_loop = false;
-+
-+ FOR_EACH_EDGE (e, ei, bb->succs)
-+ if (e->dest == bb)
-+ {
-+ simple_loop = true;
-+ break;
-+ }
-+
-+ if (simple_loop)
-+ {
-+ rtx next = BB_HEAD (bb);
-+ while (next
-+ && next != insn
-+ && distance < LEA_SEARCH_THRESHOLD)
-+ {
-+ if (INSN_P (next))
-+ {
-+ distance++;
-+
-+ for (use_rec = DF_INSN_USES (next); *use_rec; use_rec++)
-+ if ((DF_REF_TYPE (*use_rec) == DF_REF_REG_MEM_LOAD
-+ || DF_REF_TYPE (*use_rec) == DF_REF_REG_MEM_STORE)
-+ && regno0 == DF_REF_REGNO (*use_rec))
-+ {
-+ /* Return DISTANCE if OP0 is used in memory
-+ address in NEXT. */
-+ return distance;
-+ }
-+
-+ for (def_rec = DF_INSN_DEFS (next); *def_rec; def_rec++)
-+ if (DF_REF_TYPE (*def_rec) == DF_REF_REG_DEF
-+ && !DF_REF_IS_ARTIFICIAL (*def_rec)
-+ && regno0 == DF_REF_REGNO (*def_rec))
-+ {
-+ /* Return -1 if OP0 is set in NEXT. */
-+ return -1;
-+ }
-+
-+ }
-+ next = NEXT_INSN (next);
-+ }
-+ }
-+ }
-+
-+ return -1;
-+}
-+
-+/* Define this macro to tune LEA priority vs ADD, it take effect when
-+ there is a dilemma of choicing LEA or ADD
-+ Negative value: ADD is more preferred than LEA
-+ Zero: Netrual
-+ Positive value: LEA is more preferred than ADD*/
-+#define IX86_LEA_PRIORITY 2
-+
-+/* Return true if it is ok to optimize an ADD operation to LEA
-+ operation to avoid flag register consumation. For the processors
-+ like ATOM, if the destination register of LEA holds an actual
-+ address which will be used soon, LEA is better and otherwise ADD
-+ is better. */
-+
-+bool
-+ix86_lea_for_add_ok (enum rtx_code code ATTRIBUTE_UNUSED,
-+ rtx insn, rtx operands[])
-+{
-+ unsigned int regno0 = true_regnum (operands[0]);
-+ unsigned int regno1 = true_regnum (operands[1]);
-+ unsigned int regno2;
-+
-+ if (!TARGET_OPT_AGU || optimize_function_for_size_p (cfun))
-+ return regno0 != regno1;
-+
-+ regno2 = true_regnum (operands[2]);
-+
-+ /* If a = b + c, (a!=b && a!=c), must use lea form. */
-+ if (regno0 != regno1 && regno0 != regno2)
-+ return true;
-+ else
-+ {
-+ int dist_define, dist_use;
-+ dist_define = distance_non_agu_define (regno1, regno2, insn);
-+ if (dist_define <= 0)
-+ return true;
-+
-+ /* If this insn has both backward non-agu dependence and forward
-+ agu dependence, the one with short distance take effect. */
-+ dist_use = distance_agu_use (regno0, insn);
-+ if (dist_use <= 0
-+ || (dist_define + IX86_LEA_PRIORITY) < dist_use)
-+ return false;
-+
-+ return true;
-+ }
-+}
-+
-+/* Return true if destination reg of SET_BODY is shift count of
-+ USE_BODY. */
-+
-+static bool
-+ix86_dep_by_shift_count_body (const_rtx set_body, const_rtx use_body)
-+{
-+ rtx set_dest;
-+ rtx shift_rtx;
-+ int i;
-+
-+ /* Retrieve destination of SET_BODY. */
-+ switch (GET_CODE (set_body))
-+ {
-+ case SET:
-+ set_dest = SET_DEST (set_body);
-+ if (!set_dest || !REG_P (set_dest))
-+ return false;
-+ break;
-+ case PARALLEL:
-+ for (i = XVECLEN (set_body, 0) - 1; i >= 0; i--)
-+ if (ix86_dep_by_shift_count_body (XVECEXP (set_body, 0, i),
-+ use_body))
-+ return true;
-+ default:
-+ return false;
-+ break;
-+ }
-+
-+ /* Retrieve shift count of USE_BODY. */
-+ switch (GET_CODE (use_body))
-+ {
-+ case SET:
-+ shift_rtx = XEXP (use_body, 1);
-+ break;
-+ case PARALLEL:
-+ for (i = XVECLEN (use_body, 0) - 1; i >= 0; i--)
-+ if (ix86_dep_by_shift_count_body (set_body,
-+ XVECEXP (use_body, 0, i)))
-+ return true;
-+ default:
-+ return false;
-+ break;
-+ }
-+
-+ if (shift_rtx
-+ && (GET_CODE (shift_rtx) == ASHIFT
-+ || GET_CODE (shift_rtx) == LSHIFTRT
-+ || GET_CODE (shift_rtx) == ASHIFTRT
-+ || GET_CODE (shift_rtx) == ROTATE
-+ || GET_CODE (shift_rtx) == ROTATERT))
-+ {
-+ rtx shift_count = XEXP (shift_rtx, 1);
-+
-+ /* Return true if shift count is dest of SET_BODY. */
-+ if (REG_P (shift_count)
-+ && true_regnum (set_dest) == true_regnum (shift_count))
-+ return true;
-+ }
-+
-+ return false;
-+}
-+
-+/* Return true if destination reg of SET_INSN is shift count of
-+ USE_INSN. */
-+
-+bool
-+ix86_dep_by_shift_count (const_rtx set_insn, const_rtx use_insn)
-+{
-+ return ix86_dep_by_shift_count_body (PATTERN (set_insn),
-+ PATTERN (use_insn));
-+}
-+
- /* Return TRUE or FALSE depending on whether the unary operator meets the
- appropriate constraints. */
-
-@@ -18850,7 +19292,7 @@ ix86_init_machine_status (void)
- f = GGC_CNEW (struct machine_function);
- f->use_fast_prologue_epilogue_nregs = -1;
- f->tls_descriptor_call_expanded_p = 0;
-- f->call_abi = DEFAULT_ABI;
-+ f->call_abi = ix86_abi;
-
- return f;
- }
-@@ -19111,6 +19553,7 @@ ix86_issue_rate (void)
- switch (ix86_tune)
- {
- case PROCESSOR_PENTIUM:
-+ case PROCESSOR_ATOM:
- case PROCESSOR_K6:
- return 2;
-
-@@ -19177,41 +19620,21 @@ ix86_flags_dependent (rtx insn, rtx dep_
- return 1;
- }
-
--/* A subroutine of ix86_adjust_cost -- return true iff INSN has a memory
-- address with operands set by DEP_INSN. */
-+/* Return true iff USE_INSN has a memory address with operands set by
-+ SET_INSN. */
-
--static int
--ix86_agi_dependent (rtx insn, rtx dep_insn, enum attr_type insn_type)
-+bool
-+ix86_agi_dependent (rtx set_insn, rtx use_insn)
- {
-- rtx addr;
--
-- if (insn_type == TYPE_LEA
-- && TARGET_PENTIUM)
-- {
-- addr = PATTERN (insn);
--
-- if (GET_CODE (addr) == PARALLEL)
-- addr = XVECEXP (addr, 0, 0);
--
-- gcc_assert (GET_CODE (addr) == SET);
--
-- addr = SET_SRC (addr);
-- }
-- else
-- {
-- int i;
-- extract_insn_cached (insn);
-- for (i = recog_data.n_operands - 1; i >= 0; --i)
-- if (MEM_P (recog_data.operand[i]))
-- {
-- addr = XEXP (recog_data.operand[i], 0);
-- goto found;
-- }
-- return 0;
-- found:;
-- }
--
-- return modified_in_p (addr, dep_insn);
-+ int i;
-+ extract_insn_cached (use_insn);
-+ for (i = recog_data.n_operands - 1; i >= 0; --i)
-+ if (MEM_P (recog_data.operand[i]))
-+ {
-+ rtx addr = XEXP (recog_data.operand[i], 0);
-+ return modified_in_p (addr, set_insn) != 0;
-+ }
-+ return false;
- }
-
- static int
-@@ -19239,7 +19662,20 @@ ix86_adjust_cost (rtx insn, rtx link, rt
- {
- case PROCESSOR_PENTIUM:
- /* Address Generation Interlock adds a cycle of latency. */
-- if (ix86_agi_dependent (insn, dep_insn, insn_type))
-+ if (insn_type == TYPE_LEA)
-+ {
-+ rtx addr = PATTERN (insn);
-+
-+ if (GET_CODE (addr) == PARALLEL)
-+ addr = XVECEXP (addr, 0, 0);
-+
-+ gcc_assert (GET_CODE (addr) == SET);
-+
-+ addr = SET_SRC (addr);
-+ if (modified_in_p (addr, dep_insn))
-+ cost += 1;
-+ }
-+ else if (ix86_agi_dependent (dep_insn, insn))
- cost += 1;
-
- /* ??? Compares pair with jump/setcc. */
-@@ -19249,7 +19685,7 @@ ix86_adjust_cost (rtx insn, rtx link, rt
- /* Floating point stores require value to be ready one cycle earlier. */
- if (insn_type == TYPE_FMOV
- && get_attr_memory (insn) == MEMORY_STORE
-- && !ix86_agi_dependent (insn, dep_insn, insn_type))
-+ && !ix86_agi_dependent (dep_insn, insn))
- cost += 1;
- break;
-
-@@ -19272,7 +19708,7 @@ ix86_adjust_cost (rtx insn, rtx link, rt
- in parallel with previous instruction in case
- previous instruction is not needed to compute the address. */
- if ((memory == MEMORY_LOAD || memory == MEMORY_BOTH)
-- && !ix86_agi_dependent (insn, dep_insn, insn_type))
-+ && !ix86_agi_dependent (dep_insn, insn))
- {
- /* Claim moves to take one cycle, as core can issue one load
- at time and the next load can start cycle later. */
-@@ -19301,7 +19737,7 @@ ix86_adjust_cost (rtx insn, rtx link, rt
- in parallel with previous instruction in case
- previous instruction is not needed to compute the address. */
- if ((memory == MEMORY_LOAD || memory == MEMORY_BOTH)
-- && !ix86_agi_dependent (insn, dep_insn, insn_type))
-+ && !ix86_agi_dependent (dep_insn, insn))
- {
- /* Claim moves to take one cycle, as core can issue one load
- at time and the next load can start cycle later. */
-@@ -19318,6 +19754,7 @@ ix86_adjust_cost (rtx insn, rtx link, rt
- case PROCESSOR_ATHLON:
- case PROCESSOR_K8:
- case PROCESSOR_AMDFAM10:
-+ case PROCESSOR_ATOM:
- case PROCESSOR_GENERIC32:
- case PROCESSOR_GENERIC64:
- memory = get_attr_memory (insn);
-@@ -19326,7 +19763,7 @@ ix86_adjust_cost (rtx insn, rtx link, rt
- in parallel with previous instruction in case
- previous instruction is not needed to compute the address. */
- if ((memory == MEMORY_LOAD || memory == MEMORY_BOTH)
-- && !ix86_agi_dependent (insn, dep_insn, insn_type))
-+ && !ix86_agi_dependent (dep_insn, insn))
- {
- enum attr_unit unit = get_attr_unit (insn);
- int loadcost = 3;
-@@ -29606,14 +30043,11 @@ x86_builtin_vectorization_cost (bool run
- tree
- ix86_fn_abi_va_list (tree fndecl)
- {
-- int abi;
--
- if (!TARGET_64BIT)
- return va_list_type_node;
- gcc_assert (fndecl != NULL_TREE);
-- abi = ix86_function_abi ((const_tree) fndecl);
-
-- if (abi == MS_ABI)
-+ if (ix86_function_abi ((const_tree) fndecl) == MS_ABI)
- return ms_va_list_type_node;
- else
- return sysv_va_list_type_node;
---- a/gcc/config/i386/i386.h
-+++ b/gcc/config/i386/i386.h
-@@ -59,6 +59,7 @@ see the files COPYING3 and COPYING.RUNTI
- #define TARGET_ABM OPTION_ISA_ABM
- #define TARGET_POPCNT OPTION_ISA_POPCNT
- #define TARGET_SAHF OPTION_ISA_SAHF
-+#define TARGET_MOVBE OPTION_ISA_MOVBE
- #define TARGET_AES OPTION_ISA_AES
- #define TARGET_PCLMUL OPTION_ISA_PCLMUL
- #define TARGET_CMPXCHG16B OPTION_ISA_CX16
-@@ -236,6 +237,7 @@ extern const struct processor_costs ix86
- #define TARGET_GENERIC64 (ix86_tune == PROCESSOR_GENERIC64)
- #define TARGET_GENERIC (TARGET_GENERIC32 || TARGET_GENERIC64)
- #define TARGET_AMDFAM10 (ix86_tune == PROCESSOR_AMDFAM10)
-+#define TARGET_ATOM (ix86_tune == PROCESSOR_ATOM)
-
- /* Feature tests against the various tunings. */
- enum ix86_tune_indices {
-@@ -300,6 +302,7 @@ enum ix86_tune_indices {
- X86_TUNE_USE_VECTOR_FP_CONVERTS,
- X86_TUNE_USE_VECTOR_CONVERTS,
- X86_TUNE_FUSE_CMP_AND_BRANCH,
-+ X86_TUNE_OPT_AGU,
-
- X86_TUNE_LAST
- };
-@@ -387,6 +390,7 @@ extern unsigned char ix86_tune_features[
- ix86_tune_features[X86_TUNE_USE_VECTOR_CONVERTS]
- #define TARGET_FUSE_CMP_AND_BRANCH \
- ix86_tune_features[X86_TUNE_FUSE_CMP_AND_BRANCH]
-+#define TARGET_OPT_AGU ix86_tune_features[X86_TUNE_OPT_AGU]
-
- /* Feature tests against the various architecture variations. */
- enum ix86_arch_indices {
-@@ -470,7 +474,10 @@ enum calling_abi
- MS_ABI = 1
- };
-
--/* The default abi form used by target. */
-+/* The abi used by target. */
-+extern enum calling_abi ix86_abi;
-+
-+/* The default abi used by target. */
- #define DEFAULT_ABI SYSV_ABI
-
- /* Subtargets may reset this to 1 in order to enable 96-bit long double
-@@ -569,6 +576,7 @@ enum target_cpu_default
- TARGET_CPU_DEFAULT_prescott,
- TARGET_CPU_DEFAULT_nocona,
- TARGET_CPU_DEFAULT_core2,
-+ TARGET_CPU_DEFAULT_atom,
-
- TARGET_CPU_DEFAULT_geode,
- TARGET_CPU_DEFAULT_k6,
-@@ -658,7 +666,7 @@ enum target_cpu_default
-
- /* Boundary (in *bits*) on which stack pointer should be aligned. */
- #define STACK_BOUNDARY \
-- (TARGET_64BIT && DEFAULT_ABI == MS_ABI ? 128 : BITS_PER_WORD)
-+ (TARGET_64BIT && ix86_abi == MS_ABI ? 128 : BITS_PER_WORD)
-
- /* Stack boundary of the main function guaranteed by OS. */
- #define MAIN_STACK_BOUNDARY (TARGET_64BIT ? 128 : 32)
-@@ -1584,7 +1592,7 @@ typedef struct ix86_args {
- int maybe_vaarg; /* true for calls to possibly vardic fncts. */
- int float_in_sse; /* 1 if in 32-bit mode SFmode (2 for DFmode) should
- be passed in SSE registers. Otherwise 0. */
-- int call_abi; /* Set to SYSV_ABI for sysv abi. Otherwise
-+ enum calling_abi call_abi; /* Set to SYSV_ABI for sysv abi. Otherwise
- MS_ABI for ms abi. */
- } CUMULATIVE_ARGS;
-
-@@ -2230,6 +2238,7 @@ enum processor_type
- PROCESSOR_GENERIC32,
- PROCESSOR_GENERIC64,
- PROCESSOR_AMDFAM10,
-+ PROCESSOR_ATOM,
- PROCESSOR_max
- };
-
-@@ -2403,7 +2412,7 @@ struct machine_function GTY(())
- int tls_descriptor_call_expanded_p;
- /* This value is used for amd64 targets and specifies the current abi
- to be used. MS_ABI means ms abi. Otherwise SYSV_ABI means sysv abi. */
-- int call_abi;
-+ enum calling_abi call_abi;
- };
-
- #define ix86_stack_locals (cfun->machine->stack_locals)
---- a/gcc/config/i386/i386.md
-+++ b/gcc/config/i386/i386.md
-@@ -316,7 +316,7 @@
-
- \f
- ;; Processor type.
--(define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,
-+(define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,atom,
- generic64,amdfam10"
- (const (symbol_ref "ix86_schedule")))
-
-@@ -612,6 +612,12 @@
- (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
- (const_string "any"))
-
-+;; Define attribute to classify add/sub insns that consumes carry flag (CF)
-+(define_attr "use_carry" "0,1" (const_string "0"))
-+
-+;; Define attribute to indicate unaligned ssemov insns
-+(define_attr "movu" "0,1" (const_string "0"))
-+
- ;; Describe a user's asm statement.
- (define_asm_attributes
- [(set_attr "length" "128")
-@@ -727,6 +733,7 @@
- (include "k6.md")
- (include "athlon.md")
- (include "geode.md")
-+(include "atom.md")
-
- \f
- ;; Operand and operator predicates and constraints
-@@ -5790,6 +5797,7 @@
- "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
- "adc{q}\t{%2, %0|%0, %2}"
- [(set_attr "type" "alu")
-+ (set_attr "use_carry" "1")
- (set_attr "pent_pair" "pu")
- (set_attr "mode" "DI")])
-
-@@ -5864,6 +5872,7 @@
- "ix86_binary_operator_ok (PLUS, QImode, operands)"
- "adc{b}\t{%2, %0|%0, %2}"
- [(set_attr "type" "alu")
-+ (set_attr "use_carry" "1")
- (set_attr "pent_pair" "pu")
- (set_attr "mode" "QI")])
-
-@@ -5876,6 +5885,7 @@
- "ix86_binary_operator_ok (PLUS, HImode, operands)"
- "adc{w}\t{%2, %0|%0, %2}"
- [(set_attr "type" "alu")
-+ (set_attr "use_carry" "1")
- (set_attr "pent_pair" "pu")
- (set_attr "mode" "HI")])
-
-@@ -5888,6 +5898,7 @@
- "ix86_binary_operator_ok (PLUS, SImode, operands)"
- "adc{l}\t{%2, %0|%0, %2}"
- [(set_attr "type" "alu")
-+ (set_attr "use_carry" "1")
- (set_attr "pent_pair" "pu")
- (set_attr "mode" "SI")])
-
-@@ -5901,6 +5912,7 @@
- "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
- "adc{l}\t{%2, %k0|%k0, %2}"
- [(set_attr "type" "alu")
-+ (set_attr "use_carry" "1")
- (set_attr "pent_pair" "pu")
- (set_attr "mode" "SI")])
-
-@@ -6130,9 +6142,9 @@
- (set_attr "mode" "SI")])
-
- (define_insn "*adddi_1_rex64"
-- [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
-- (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
-- (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
-+ (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r,r")
-+ (match_operand:DI 2 "x86_64_general_operand" "rme,re,0,le")))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
- {
-@@ -6153,6 +6165,10 @@
- }
-
- default:
-+ /* Use add as much as possible to replace lea for AGU optimization. */
-+ if (which_alternative == 2 && TARGET_OPT_AGU)
-+ return "add{q}\t{%1, %0|%0, %1}";
-+
- gcc_assert (rtx_equal_p (operands[0], operands[1]));
-
- /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
-@@ -6171,8 +6187,11 @@
- }
- }
- [(set (attr "type")
-- (cond [(eq_attr "alternative" "2")
-+ (cond [(and (eq_attr "alternative" "2")
-+ (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
- (const_string "lea")
-+ (eq_attr "alternative" "3")
-+ (const_string "lea")
- ; Current assemblers are broken and do not allow @GOTOFF in
- ; ought but a memory context.
- (match_operand:DI 2 "pic_symbolic_operand" "")
-@@ -6189,8 +6208,8 @@
- (plus:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
- (clobber (reg:CC FLAGS_REG))]
-- "TARGET_64BIT && reload_completed
-- && true_regnum (operands[0]) != true_regnum (operands[1])"
-+ "TARGET_64BIT && reload_completed
-+ && ix86_lea_for_add_ok (PLUS, insn, operands)"
- [(set (match_dup 0)
- (plus:DI (match_dup 1)
- (match_dup 2)))]
-@@ -6394,9 +6413,9 @@
-
-
- (define_insn "*addsi_1"
-- [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
-- (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
-- (match_operand:SI 2 "general_operand" "g,ri,li")))
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r,r")
-+ (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r,r")
-+ (match_operand:SI 2 "general_operand" "g,ri,0,li")))
- (clobber (reg:CC FLAGS_REG))]
- "ix86_binary_operator_ok (PLUS, SImode, operands)"
- {
-@@ -6417,6 +6436,10 @@
- }
-
- default:
-+ /* Use add as much as possible to replace lea for AGU optimization. */
-+ if (which_alternative == 2 && TARGET_OPT_AGU)
-+ return "add{l}\t{%1, %0|%0, %1}";
-+
- gcc_assert (rtx_equal_p (operands[0], operands[1]));
-
- /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
-@@ -6433,7 +6456,10 @@
- }
- }
- [(set (attr "type")
-- (cond [(eq_attr "alternative" "2")
-+ (cond [(and (eq_attr "alternative" "2")
-+ (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
-+ (const_string "lea")
-+ (eq_attr "alternative" "3")
- (const_string "lea")
- ; Current assemblers are broken and do not allow @GOTOFF in
- ; ought but a memory context.
-@@ -6451,8 +6477,7 @@
- (plus (match_operand 1 "register_operand" "")
- (match_operand 2 "nonmemory_operand" "")))
- (clobber (reg:CC FLAGS_REG))]
-- "reload_completed
-- && true_regnum (operands[0]) != true_regnum (operands[1])"
-+ "reload_completed && ix86_lea_for_add_ok (PLUS, insn, operands)"
- [(const_int 0)]
- {
- rtx pat;
-@@ -7553,6 +7578,7 @@
- "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
- "sbb{q}\t{%2, %0|%0, %2}"
- [(set_attr "type" "alu")
-+ (set_attr "use_carry" "1")
- (set_attr "pent_pair" "pu")
- (set_attr "mode" "DI")])
-
-@@ -7601,6 +7627,7 @@
- "ix86_binary_operator_ok (MINUS, QImode, operands)"
- "sbb{b}\t{%2, %0|%0, %2}"
- [(set_attr "type" "alu")
-+ (set_attr "use_carry" "1")
- (set_attr "pent_pair" "pu")
- (set_attr "mode" "QI")])
-
-@@ -7613,6 +7640,7 @@
- "ix86_binary_operator_ok (MINUS, HImode, operands)"
- "sbb{w}\t{%2, %0|%0, %2}"
- [(set_attr "type" "alu")
-+ (set_attr "use_carry" "1")
- (set_attr "pent_pair" "pu")
- (set_attr "mode" "HI")])
-
-@@ -7625,6 +7653,7 @@
- "ix86_binary_operator_ok (MINUS, SImode, operands)"
- "sbb{l}\t{%2, %0|%0, %2}"
- [(set_attr "type" "alu")
-+ (set_attr "use_carry" "1")
- (set_attr "pent_pair" "pu")
- (set_attr "mode" "SI")])
-
-@@ -15163,7 +15192,7 @@
- ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
- operands[0], const0_rtx,
- GEN_INT ((TARGET_64BIT
-- ? (DEFAULT_ABI == SYSV_ABI
-+ ? (ix86_abi == SYSV_ABI
- ? X86_64_SSE_REGPARM_MAX
- : X64_SSE_REGPARM_MAX)
- : X86_32_SSE_REGPARM_MAX)
-@@ -15243,6 +15272,7 @@
- "reload_completed"
- "ret"
- [(set_attr "length" "1")
-+ (set_attr "atom_unit" "jeu")
- (set_attr "length_immediate" "0")
- (set_attr "modrm" "0")])
-
-@@ -15255,6 +15285,7 @@
- "reload_completed"
- "rep\;ret"
- [(set_attr "length" "1")
-+ (set_attr "atom_unit" "jeu")
- (set_attr "length_immediate" "0")
- (set_attr "prefix_rep" "1")
- (set_attr "modrm" "0")])
-@@ -15265,6 +15296,7 @@
- "reload_completed"
- "ret\t%0"
- [(set_attr "length" "3")
-+ (set_attr "atom_unit" "jeu")
- (set_attr "length_immediate" "2")
- (set_attr "modrm" "0")])
-
-@@ -15618,7 +15650,7 @@
- (bswap:SI (match_operand:SI 1 "register_operand" "")))]
- ""
- {
-- if (!TARGET_BSWAP)
-+ if (!(TARGET_BSWAP || TARGET_MOVBE))
- {
- rtx x = operands[0];
-
-@@ -15630,6 +15662,21 @@
- }
- })
-
-+(define_insn "*bswapsi_movbe"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m")
-+ (bswap:SI (match_operand:SI 1 "nonimmediate_operand" "0,m,r")))]
-+ "TARGET_MOVBE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
-+ "@
-+ bswap\t%0
-+ movbe\t{%1, %0|%0, %1}
-+ movbe\t{%1, %0|%0, %1}"
-+ [(set_attr "type" "*,imov,imov")
-+ (set_attr "modrm" "*,1,1")
-+ (set_attr "prefix_0f" "1")
-+ (set_attr "prefix_extra" "*,1,1")
-+ (set_attr "length" "2,*,*")
-+ (set_attr "mode" "SI")])
-+
- (define_insn "*bswapsi_1"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
-@@ -15658,7 +15705,29 @@
- [(set_attr "length" "4")
- (set_attr "mode" "HI")])
-
--(define_insn "bswapdi2"
-+(define_expand "bswapdi2"
-+ [(set (match_operand:DI 0 "register_operand" "")
-+ (bswap:DI (match_operand:DI 1 "register_operand" "")))]
-+ "TARGET_64BIT"
-+ "")
-+
-+(define_insn "*bswapdi_movbe"
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m")
-+ (bswap:DI (match_operand:DI 1 "nonimmediate_operand" "0,m,r")))]
-+ "TARGET_64BIT && TARGET_MOVBE
-+ && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
-+ "@
-+ bswap\t%0
-+ movbe\t{%1, %0|%0, %1}
-+ movbe\t{%1, %0|%0, %1}"
-+ [(set_attr "type" "*,imov,imov")
-+ (set_attr "modrm" "*,1,1")
-+ (set_attr "prefix_0f" "1")
-+ (set_attr "prefix_extra" "*,1,1")
-+ (set_attr "length" "3,*,*")
-+ (set_attr "mode" "DI")])
-+
-+(define_insn "*bswapdi_1"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
- "TARGET_64BIT"
-@@ -16386,6 +16455,7 @@
- "TARGET_SSE_MATH"
- "%vrcpss\t{%1, %d0|%d0, %1}"
- [(set_attr "type" "sse")
-+ (set_attr "atom_sse_attr" "rcp")
- (set_attr "prefix" "maybe_vex")
- (set_attr "mode" "SF")])
-
-@@ -16737,6 +16807,7 @@
- "TARGET_SSE_MATH"
- "%vrsqrtss\t{%1, %d0|%d0, %1}"
- [(set_attr "type" "sse")
-+ (set_attr "atom_sse_attr" "rcp")
- (set_attr "prefix" "maybe_vex")
- (set_attr "mode" "SF")])
-
-@@ -16757,6 +16828,7 @@
- "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
- "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
- [(set_attr "type" "sse")
-+ (set_attr "atom_sse_attr" "sqrt")
- (set_attr "prefix" "maybe_vex")
- (set_attr "mode" "<MODE>")
- (set_attr "athlon_decode" "*")
-@@ -19810,6 +19882,7 @@
- ; Since we don't have the proper number of operands for an alu insn,
- ; fill in all the blanks.
- [(set_attr "type" "alu")
-+ (set_attr "use_carry" "1")
- (set_attr "pent_pair" "pu")
- (set_attr "memory" "none")
- (set_attr "imm_disp" "false")
-@@ -19825,6 +19898,7 @@
- ""
- "sbb{q}\t%0, %0"
- [(set_attr "type" "alu")
-+ (set_attr "use_carry" "1")
- (set_attr "pent_pair" "pu")
- (set_attr "memory" "none")
- (set_attr "imm_disp" "false")
-@@ -19868,6 +19942,7 @@
- ; Since we don't have the proper number of operands for an alu insn,
- ; fill in all the blanks.
- [(set_attr "type" "alu")
-+ (set_attr "use_carry" "1")
- (set_attr "pent_pair" "pu")
- (set_attr "memory" "none")
- (set_attr "imm_disp" "false")
-@@ -19883,6 +19958,7 @@
- ""
- "sbb{l}\t%0, %0"
- [(set_attr "type" "alu")
-+ (set_attr "use_carry" "1")
- (set_attr "pent_pair" "pu")
- (set_attr "memory" "none")
- (set_attr "imm_disp" "false")
-@@ -20215,7 +20291,8 @@
- }
- }
- [(set (attr "type")
-- (cond [(eq_attr "alternative" "0")
-+ (cond [(and (eq_attr "alternative" "0")
-+ (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
- (const_string "alu")
- (match_operand:SI 2 "const0_operand" "")
- (const_string "imov")
-@@ -20258,7 +20335,8 @@
- }
- }
- [(set (attr "type")
-- (cond [(eq_attr "alternative" "0")
-+ (cond [(and (eq_attr "alternative" "0")
-+ (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
- (const_string "alu")
- (match_operand:DI 2 "const0_operand" "")
- (const_string "imov")
-@@ -21746,6 +21824,7 @@
- return patterns[locality];
- }
- [(set_attr "type" "sse")
-+ (set_attr "atom_sse_attr" "prefetch")
- (set_attr "memory" "none")])
-
- (define_insn "*prefetch_sse_rex"
-@@ -21764,6 +21843,7 @@
- return patterns[locality];
- }
- [(set_attr "type" "sse")
-+ (set_attr "atom_sse_attr" "prefetch")
- (set_attr "memory" "none")])
-
- (define_insn "*prefetch_3dnow"
---- a/gcc/config/i386/i386.opt
-+++ b/gcc/config/i386/i386.opt
-@@ -228,6 +228,10 @@ mtune=
- Target RejectNegative Joined Var(ix86_tune_string)
- Schedule code for given CPU
-
-+mabi=
-+Target RejectNegative Joined Var(ix86_abi_string)
-+Generate code that conforms to the given ABI
-+
- mveclibabi=
- Target RejectNegative Joined Var(ix86_veclibabi_string)
- Vector library ABI to use
-@@ -335,6 +339,10 @@ msahf
- Target Report Mask(ISA_SAHF) Var(ix86_isa_flags) VarExists Save
- Support code generation of sahf instruction in 64bit x86-64 code.
-
-+mmovbe
-+Target Report Mask(ISA_MOVBE) Var(ix86_isa_flags) VarExists Save
-+Support code generation of movbe instruction.
-+
- maes
- Target Report Mask(ISA_AES) Var(ix86_isa_flags) VarExists Save
- Support AES built-in functions and code generation
---- a/gcc/config/i386/mingw32.h
-+++ b/gcc/config/i386/mingw32.h
-@@ -38,7 +38,7 @@ along with GCC; see the file COPYING3.
- builtin_define_std ("WINNT"); \
- builtin_define_with_int_value ("_INTEGRAL_MAX_BITS", \
- TYPE_PRECISION (intmax_type_node));\
-- if (TARGET_64BIT && DEFAULT_ABI == MS_ABI) \
-+ if (TARGET_64BIT && ix86_abi == MS_ABI) \
- { \
- builtin_define ("__MINGW64__"); \
- builtin_define_std ("WIN64"); \
---- a/gcc/config/i386/sse.md
-+++ b/gcc/config/i386/sse.md
-@@ -342,6 +342,7 @@
- && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
- "vmovup<avxmodesuffixf2c>\t{%1, %0|%0, %1}"
- [(set_attr "type" "ssemov")
-+ (set_attr "movu" "1")
- (set_attr "prefix" "vex")
- (set_attr "mode" "<MODE>")])
-
-@@ -367,6 +368,7 @@
- && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
- "movup<ssemodesuffixf2c>\t{%1, %0|%0, %1}"
- [(set_attr "type" "ssemov")
-+ (set_attr "movu" "1")
- (set_attr "mode" "<MODE>")])
-
- (define_insn "avx_movdqu<avxmodesuffix>"
-@@ -377,6 +379,7 @@
- "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
- "vmovdqu\t{%1, %0|%0, %1}"
- [(set_attr "type" "ssemov")
-+ (set_attr "movu" "1")
- (set_attr "prefix" "vex")
- (set_attr "mode" "<avxvecmode>")])
-
-@@ -387,6 +390,7 @@
- "TARGET_SSE2 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
- "movdqu\t{%1, %0|%0, %1}"
- [(set_attr "type" "ssemov")
-+ (set_attr "movu" "1")
- (set_attr "prefix_data16" "1")
- (set_attr "mode" "TI")])
-
-@@ -428,7 +432,7 @@
- UNSPEC_MOVNT))]
- "TARGET_SSE2"
- "movntdq\t{%1, %0|%0, %1}"
-- [(set_attr "type" "ssecvt")
-+ [(set_attr "type" "ssemov")
- (set_attr "prefix_data16" "1")
- (set_attr "mode" "TI")])
-
-@@ -438,7 +442,7 @@
- UNSPEC_MOVNT))]
- "TARGET_SSE2"
- "movnti\t{%1, %0|%0, %1}"
-- [(set_attr "type" "ssecvt")
-+ [(set_attr "type" "ssemov")
- (set_attr "mode" "V2DF")])
-
- (define_insn "avx_lddqu<avxmodesuffix>"
-@@ -449,6 +453,7 @@
- "TARGET_AVX"
- "vlddqu\t{%1, %0|%0, %1}"
- [(set_attr "type" "ssecvt")
-+ (set_attr "movu" "1")
- (set_attr "prefix" "vex")
- (set_attr "mode" "<avxvecmode>")])
-
-@@ -458,7 +463,8 @@
- UNSPEC_LDDQU))]
- "TARGET_SSE3"
- "lddqu\t{%1, %0|%0, %1}"
-- [(set_attr "type" "ssecvt")
-+ [(set_attr "type" "ssemov")
-+ (set_attr "movu" "1")
- (set_attr "prefix_rep" "1")
- (set_attr "mode" "TI")])
-
-@@ -765,6 +771,7 @@
- "TARGET_SSE"
- "%vrcpps\t{%1, %0|%0, %1}"
- [(set_attr "type" "sse")
-+ (set_attr "atom_sse_attr" "rcp")
- (set_attr "prefix" "maybe_vex")
- (set_attr "mode" "V4SF")])
-
-@@ -791,6 +798,7 @@
- "TARGET_SSE"
- "rcpss\t{%1, %0|%0, %1}"
- [(set_attr "type" "sse")
-+ (set_attr "atom_sse_attr" "rcp")
- (set_attr "mode" "SF")])
-
- (define_expand "sqrtv8sf2"
-@@ -836,6 +844,7 @@
- "TARGET_SSE"
- "%vsqrtps\t{%1, %0|%0, %1}"
- [(set_attr "type" "sse")
-+ (set_attr "atom_sse_attr" "sqrt")
- (set_attr "prefix" "maybe_vex")
- (set_attr "mode" "V4SF")])
-
-@@ -880,6 +889,7 @@
- "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
- "sqrts<ssemodesuffixf2c>\t{%1, %0|%0, %1}"
- [(set_attr "type" "sse")
-+ (set_attr "atom_sse_attr" "sqrt")
- (set_attr "mode" "<ssescalarmode>")])
-
- (define_expand "rsqrtv8sf2"
-@@ -1043,7 +1053,7 @@
- (const_int 1)))]
- "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
- "<maxminfprefix>s<ssemodesuffixf2c>\t{%2, %0|%0, %2}"
-- [(set_attr "type" "sse")
-+ [(set_attr "type" "sseadd")
- (set_attr "mode" "<ssescalarmode>")])
-
- ;; These versions of the min/max patterns implement exactly the operations
-@@ -1179,6 +1189,7 @@
- "TARGET_SSE3"
- "addsubpd\t{%2, %0|%0, %2}"
- [(set_attr "type" "sseadd")
-+ (set_attr "atom_unit" "complex")
- (set_attr "mode" "V2DF")])
-
- (define_insn "avx_h<plusminus_insn>v4df3"
-@@ -1302,6 +1313,7 @@
- "TARGET_SSE3"
- "h<plusminus_mnemonic>ps\t{%2, %0|%0, %2}"
- [(set_attr "type" "sseadd")
-+ (set_attr "atom_unit" "complex")
- (set_attr "prefix_rep" "1")
- (set_attr "mode" "V4SF")])
-
-@@ -5069,6 +5081,7 @@
- "TARGET_SSE2 && ix86_binary_operator_ok (MULT, V8HImode, operands)"
- "pmaddwd\t{%2, %0|%0, %2}"
- [(set_attr "type" "sseiadd")
-+ (set_attr "atom_unit" "simul")
- (set_attr "prefix_data16" "1")
- (set_attr "mode" "TI")])
-
-@@ -7035,6 +7048,7 @@
- movq\t{%H1, %0|%0, %H1}
- mov{q}\t{%H1, %0|%0, %H1}"
- [(set_attr "type" "ssemov,sseishft,ssemov,imov")
-+ (set_attr "atom_unit" "*,sishuf,*,*")
- (set_attr "memory" "*,none,*,*")
- (set_attr "mode" "V2SF,TI,TI,DI")])
-
-@@ -7067,6 +7081,7 @@
- psrldq\t{$8, %0|%0, 8}
- movq\t{%H1, %0|%0, %H1}"
- [(set_attr "type" "ssemov,sseishft,ssemov")
-+ (set_attr "atom_unit" "*,sishuf,*")
- (set_attr "memory" "*,none,*")
- (set_attr "mode" "V2SF,TI,TI")])
-
-@@ -7624,6 +7639,7 @@
- "TARGET_SSE2"
- "psadbw\t{%2, %0|%0, %2}"
- [(set_attr "type" "sseiadd")
-+ (set_attr "atom_unit" "simul")
- (set_attr "prefix_data16" "1")
- (set_attr "mode" "TI")])
-
-@@ -7645,7 +7661,7 @@
- UNSPEC_MOVMSK))]
- "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
- "%vmovmskp<ssemodesuffixf2c>\t{%1, %0|%0, %1}"
-- [(set_attr "type" "ssecvt")
-+ [(set_attr "type" "ssemov")
- (set_attr "prefix" "maybe_vex")
- (set_attr "mode" "<MODE>")])
-
-@@ -7655,7 +7671,7 @@
- UNSPEC_MOVMSK))]
- "TARGET_SSE2"
- "%vpmovmskb\t{%1, %0|%0, %1}"
-- [(set_attr "type" "ssecvt")
-+ [(set_attr "type" "ssemov")
- (set_attr "prefix_data16" "1")
- (set_attr "prefix" "maybe_vex")
- (set_attr "mode" "SI")])
-@@ -7678,7 +7694,7 @@
- "TARGET_SSE2 && !TARGET_64BIT"
- ;; @@@ check ordering of operands in intel/nonintel syntax
- "%vmaskmovdqu\t{%2, %1|%1, %2}"
-- [(set_attr "type" "ssecvt")
-+ [(set_attr "type" "ssemov")
- (set_attr "prefix_data16" "1")
- (set_attr "prefix" "maybe_vex")
- (set_attr "mode" "TI")])
-@@ -7692,7 +7708,7 @@
- "TARGET_SSE2 && TARGET_64BIT"
- ;; @@@ check ordering of operands in intel/nonintel syntax
- "%vmaskmovdqu\t{%2, %1|%1, %2}"
-- [(set_attr "type" "ssecvt")
-+ [(set_attr "type" "ssemov")
- (set_attr "prefix_data16" "1")
- (set_attr "prefix" "maybe_vex")
- (set_attr "mode" "TI")])
-@@ -7703,6 +7719,7 @@
- "TARGET_SSE"
- "%vldmxcsr\t%0"
- [(set_attr "type" "sse")
-+ (set_attr "atom_sse_attr" "mxcsr")
- (set_attr "prefix" "maybe_vex")
- (set_attr "memory" "load")])
-
-@@ -7712,6 +7729,7 @@
- "TARGET_SSE"
- "%vstmxcsr\t%0"
- [(set_attr "type" "sse")
-+ (set_attr "atom_sse_attr" "mxcsr")
- (set_attr "prefix" "maybe_vex")
- (set_attr "memory" "store")])
-
-@@ -7730,6 +7748,7 @@
- "TARGET_SSE || TARGET_3DNOW_A"
- "sfence"
- [(set_attr "type" "sse")
-+ (set_attr "atom_sse_attr" "fence")
- (set_attr "memory" "unknown")])
-
- (define_insn "sse2_clflush"
-@@ -7738,6 +7757,7 @@
- "TARGET_SSE2"
- "clflush\t%a0"
- [(set_attr "type" "sse")
-+ (set_attr "atom_sse_attr" "fence")
- (set_attr "memory" "unknown")])
-
- (define_expand "sse2_mfence"
-@@ -7755,6 +7775,7 @@
- "TARGET_64BIT || TARGET_SSE2"
- "mfence"
- [(set_attr "type" "sse")
-+ (set_attr "atom_sse_attr" "fence")
- (set_attr "memory" "unknown")])
-
- (define_expand "sse2_lfence"
-@@ -7772,6 +7793,7 @@
- "TARGET_SSE2"
- "lfence"
- [(set_attr "type" "sse")
-+ (set_attr "atom_sse_attr" "lfence")
- (set_attr "memory" "unknown")])
-
- (define_insn "sse3_mwait"
-@@ -7895,6 +7917,7 @@
- "TARGET_SSSE3"
- "phaddw\t{%2, %0|%0, %2}"
- [(set_attr "type" "sseiadd")
-+ (set_attr "atom_unit" "complex")
- (set_attr "prefix_data16" "1")
- (set_attr "prefix_extra" "1")
- (set_attr "mode" "TI")])
-@@ -7923,6 +7946,7 @@
- "TARGET_SSSE3"
- "phaddw\t{%2, %0|%0, %2}"
- [(set_attr "type" "sseiadd")
-+ (set_attr "atom_unit" "complex")
- (set_attr "prefix_extra" "1")
- (set_attr "mode" "DI")])
-
-@@ -7977,6 +8001,7 @@
- "TARGET_SSSE3"
- "phaddd\t{%2, %0|%0, %2}"
- [(set_attr "type" "sseiadd")
-+ (set_attr "atom_unit" "complex")
- (set_attr "prefix_data16" "1")
- (set_attr "prefix_extra" "1")
- (set_attr "mode" "TI")])
-@@ -7997,6 +8022,7 @@
- "TARGET_SSSE3"
- "phaddd\t{%2, %0|%0, %2}"
- [(set_attr "type" "sseiadd")
-+ (set_attr "atom_unit" "complex")
- (set_attr "prefix_extra" "1")
- (set_attr "mode" "DI")])
-
-@@ -8083,6 +8109,7 @@
- "TARGET_SSSE3"
- "phaddsw\t{%2, %0|%0, %2}"
- [(set_attr "type" "sseiadd")
-+ (set_attr "atom_unit" "complex")
- (set_attr "prefix_data16" "1")
- (set_attr "prefix_extra" "1")
- (set_attr "mode" "TI")])
-@@ -8111,6 +8138,7 @@
- "TARGET_SSSE3"
- "phaddsw\t{%2, %0|%0, %2}"
- [(set_attr "type" "sseiadd")
-+ (set_attr "atom_unit" "complex")
- (set_attr "prefix_extra" "1")
- (set_attr "mode" "DI")])
-
-@@ -8197,6 +8225,7 @@
- "TARGET_SSSE3"
- "phsubw\t{%2, %0|%0, %2}"
- [(set_attr "type" "sseiadd")
-+ (set_attr "atom_unit" "complex")
- (set_attr "prefix_data16" "1")
- (set_attr "prefix_extra" "1")
- (set_attr "mode" "TI")])
-@@ -8225,6 +8254,7 @@
- "TARGET_SSSE3"
- "phsubw\t{%2, %0|%0, %2}"
- [(set_attr "type" "sseiadd")
-+ (set_attr "atom_unit" "complex")
- (set_attr "prefix_extra" "1")
- (set_attr "mode" "DI")])
-
-@@ -8279,6 +8309,7 @@
- "TARGET_SSSE3"
- "phsubd\t{%2, %0|%0, %2}"
- [(set_attr "type" "sseiadd")
-+ (set_attr "atom_unit" "complex")
- (set_attr "prefix_data16" "1")
- (set_attr "prefix_extra" "1")
- (set_attr "mode" "TI")])
-@@ -8299,6 +8330,7 @@
- "TARGET_SSSE3"
- "phsubd\t{%2, %0|%0, %2}"
- [(set_attr "type" "sseiadd")
-+ (set_attr "atom_unit" "complex")
- (set_attr "prefix_extra" "1")
- (set_attr "mode" "DI")])
-
-@@ -8385,6 +8417,7 @@
- "TARGET_SSSE3"
- "phsubsw\t{%2, %0|%0, %2}"
- [(set_attr "type" "sseiadd")
-+ (set_attr "atom_unit" "complex")
- (set_attr "prefix_data16" "1")
- (set_attr "prefix_extra" "1")
- (set_attr "mode" "TI")])
-@@ -8413,6 +8446,7 @@
- "TARGET_SSSE3"
- "phsubsw\t{%2, %0|%0, %2}"
- [(set_attr "type" "sseiadd")
-+ (set_attr "atom_unit" "complex")
- (set_attr "prefix_extra" "1")
- (set_attr "mode" "DI")])
-
-@@ -8519,6 +8553,7 @@
- "TARGET_SSSE3"
- "pmaddubsw\t{%2, %0|%0, %2}"
- [(set_attr "type" "sseiadd")
-+ (set_attr "atom_unit" "simul")
- (set_attr "prefix_data16" "1")
- (set_attr "prefix_extra" "1")
- (set_attr "mode" "TI")])
-@@ -8557,6 +8592,7 @@
- "TARGET_SSSE3"
- "pmaddubsw\t{%2, %0|%0, %2}"
- [(set_attr "type" "sseiadd")
-+ (set_attr "atom_unit" "simul")
- (set_attr "prefix_extra" "1")
- (set_attr "mode" "DI")])
-
-@@ -8764,6 +8800,7 @@
- return "palignr\t{%3, %2, %0|%0, %2, %3}";
- }
- [(set_attr "type" "sseishft")
-+ (set_attr "atom_unit" "sishuf")
- (set_attr "prefix_data16" "1")
- (set_attr "prefix_extra" "1")
- (set_attr "mode" "TI")])
-@@ -8780,6 +8817,7 @@
- return "palignr\t{%3, %2, %0|%0, %2, %3}";
- }
- [(set_attr "type" "sseishft")
-+ (set_attr "atom_unit" "sishuf")
- (set_attr "prefix_extra" "1")
- (set_attr "mode" "DI")])
-
-@@ -8966,7 +9004,7 @@
- UNSPEC_MOVNTDQA))]
- "TARGET_SSE4_1"
- "%vmovntdqa\t{%1, %0|%0, %1}"
-- [(set_attr "type" "ssecvt")
-+ [(set_attr "type" "ssemov")
- (set_attr "prefix_extra" "1")
- (set_attr "prefix" "maybe_vex")
- (set_attr "mode" "TI")])
---- a/gcc/config/i386/winnt.c
-+++ b/gcc/config/i386/winnt.c
-@@ -499,8 +499,11 @@ i386_pe_asm_output_aligned_decl_common (
- {
- HOST_WIDE_INT rounded;
-
-- /* Compute as in assemble_noswitch_variable, since we don't actually
-- support aligned common. */
-+ /* Compute as in assemble_noswitch_variable, since we don't have
-+ support for aligned common on older binutils. We must also
-+ avoid emitting a common symbol of size zero, as this is the
-+ overloaded representation that indicates an undefined external
-+ symbol in the PE object file format. */
- rounded = size ? size : 1;
- rounded += (BIGGEST_ALIGNMENT / BITS_PER_UNIT) - 1;
- rounded = (rounded / (BIGGEST_ALIGNMENT / BITS_PER_UNIT)
-@@ -510,9 +513,13 @@ i386_pe_asm_output_aligned_decl_common (
-
- fprintf (stream, "\t.comm\t");
- assemble_name (stream, name);
-- fprintf (stream, ", " HOST_WIDE_INT_PRINT_DEC "\t" ASM_COMMENT_START
-- " " HOST_WIDE_INT_PRINT_DEC "\n",
-- rounded, size);
-+ if (use_pe_aligned_common)
-+ fprintf (stream, ", " HOST_WIDE_INT_PRINT_DEC ", %d\n",
-+ size ? size : (HOST_WIDE_INT) 1,
-+ exact_log2 (align) - exact_log2 (CHAR_BIT));
-+ else
-+ fprintf (stream, ", " HOST_WIDE_INT_PRINT_DEC "\t" ASM_COMMENT_START
-+ " " HOST_WIDE_INT_PRINT_DEC "\n", rounded, size);
- }
- \f
- /* The Microsoft linker requires that every function be marked as
---- a/gcc/config/m68k/constraints.md
-+++ b/gcc/config/m68k/constraints.md
-@@ -124,6 +124,11 @@
- (and (match_code "const_int")
- (match_test "ival < -0x8000 || ival > 0x7FFF")))
-
-+(define_constraint "Cu"
-+ "16-bit offset for wrapped symbols"
-+ (and (match_code "const")
-+ (match_test "m68k_unwrap_symbol (op, false) != op")))
-+
- (define_constraint "CQ"
- "Integers valid for mvq."
- (and (match_code "const_int")
---- a/gcc/config/m68k/lb1sf68.asm
-+++ b/gcc/config/m68k/lb1sf68.asm
-@@ -163,6 +163,8 @@ see the files COPYING3 and COPYING.RUNTI
- #if defined (__mcoldfire__) && !defined (__mcfisab__) && !defined (__mcfisac__)
- lea \addr-.-8,a0
- jsr pc@(a0)
-+#elif defined (__mcfisab__) || defined (__mcfisac__)
-+ bsr.l \addr
- #else
- bsr \addr
- #endif
-@@ -202,6 +204,8 @@ see the files COPYING3 and COPYING.RUNTI
- #if defined (__mcoldfire__) && !defined (__mcfisab__) && !defined (__mcfisac__)
- lea \addr-.-8,a0
- jsr pc@(a0)
-+#elif defined (__mcfisab__) || defined (__mcfisac__)
-+ bsr.l \addr
- #else
- bsr \addr
- #endif
---- a/gcc/config/m68k/linux-unwind.h
-+++ b/gcc/config/m68k/linux-unwind.h
-@@ -77,9 +77,15 @@ m68k_fallback_frame_state (struct _Unwin
- fs->regs.reg[9].how = REG_SAVED_OFFSET;
- fs->regs.reg[9].loc.offset = (long) &sc->sc_a1 - cfa;
-
-+#ifdef __uClinux__
-+ fs->regs.reg[13].how = REG_SAVED_OFFSET;
-+ fs->regs.reg[13].loc.offset = (long) &sc->sc_a5 - cfa;
-+#endif
-+
- fs->regs.reg[24].how = REG_SAVED_OFFSET;
- fs->regs.reg[24].loc.offset = (long) &sc->sc_pc - cfa;
-
-+#if defined __mcffpu__ && !defined __uClinux__
- if (*(int *) sc->sc_fpstate)
- {
- int *fpregs = (int *) sc->sc_fpregs;
-@@ -89,11 +95,19 @@ m68k_fallback_frame_state (struct _Unwin
- fs->regs.reg[17].how = REG_SAVED_OFFSET;
- fs->regs.reg[17].loc.offset = (long) &fpregs[M68K_FP_SIZE/4] - cfa;
- }
-+#elif defined __mcffpu__
-+# error Implement this when uClinux kernel is ported to an FPU architecture
-+#endif
- }
- #ifdef __mcoldfire__
- /* move.l #__NR_rt_sigreturn,%d0; trap #0 */
-- else if (pc[0] == 0x203c && pc[1] == 0x0000 &&
-- pc[2] == 0x00ad && pc[3] == 0x4e40)
-+ else if ((pc[0] == 0x203c && pc[1] == 0x0000 &&
-+ pc[2] == 0x00ad && pc[3] == 0x4e40) ||
-+ /* Don't ask me why, this is just what some kernels do:
-+ moveq #-__NR_rt_sigreturn,%d0; andil 0xff,%d0; trap #0;
-+ Sigh... */
-+ (pc[0] == 0x70ad && pc[1] == 0x0280 && pc[2] == 0x0000 &&
-+ pc[3] == 0x00ff && pc[4] == 0x4e40 && pc[5] == 0x0000))
- #else
- /* moveq #~__NR_rt_sigreturn,%d0; not.b %d0; trap #0 */
- else if (pc[0] == 0x7052 && pc[1] == 0x4600 && pc[2] == 0x4e40)
---- a/gcc/config/m68k/m68k-devices.def
-+++ b/gcc/config/m68k/m68k-devices.def
-@@ -72,8 +72,8 @@
- /* 680x0 series processors. */
- M68K_DEVICE ("68000", m68000, "68000", "68000", 68000, isa_00, 0)
- M68K_DEVICE ("68010", m68010, "68010", "68000", 68010, isa_10, 0)
--M68K_DEVICE ("68020", m68020, "68020", "68020", 68020, isa_20, FL_MMU)
--M68K_DEVICE ("68030", m68030, "68030", "68020", 68030, isa_20, FL_MMU)
-+M68K_DEVICE ("68020", m68020, "68020", "68020", 68020, isa_20, FL_MMU | FL_UCLINUX)
-+M68K_DEVICE ("68030", m68030, "68030", "68020", 68030, isa_20, FL_MMU | FL_UCLINUX)
- M68K_DEVICE ("68040", m68040, "68040", "68040", 68040, isa_40, FL_MMU)
- M68K_DEVICE ("68060", m68060, "68060", "68060", 68060, isa_40, FL_MMU)
- M68K_DEVICE ("68302", m68302, "68302", "68000", 68000, isa_00, FL_MMU)
-@@ -81,7 +81,13 @@ M68K_DEVICE ("68332", m68332, "68332",
- M68K_DEVICE ("cpu32", cpu32, "cpu32", "cpu32", cpu32, isa_cpu32, FL_MMU)
-
- /* ColdFire CFV1 processor. */
--M68K_DEVICE ("51qe", mcf51qe, "51qe", "51qe", cfv1, isa_c, FL_CF_USP)
-+/* For historical reasons, the 51 multilib is named 51qe. */
-+M68K_DEVICE ("51", mcf51, "51", "51qe", cfv1, isa_c, FL_CF_USP)
-+M68K_DEVICE ("51ac", mcf51ac, "51", "51qe", cfv1, isa_c, FL_CF_USP)
-+M68K_DEVICE ("51cn", mcf51cn, "51", "51qe", cfv1, isa_c, FL_CF_USP)
-+M68K_DEVICE ("51em", mcf51em, "51", "51qe", cfv1, isa_c, FL_CF_USP | FL_CF_MAC)
-+M68K_DEVICE ("51jm", mcf51jm, "51", "51qe", cfv1, isa_c, FL_CF_USP)
-+M68K_DEVICE ("51qe", mcf51qe, "51", "51qe", cfv1, isa_c, FL_CF_USP)
-
- /* ColdFire CFV2 processors. */
- M68K_DEVICE ("5202", mcf5202, "5206", "5206", cfv2, isa_a, 0)
-@@ -97,6 +103,7 @@ M68K_DEVICE ("5212", mcf5212, "5213",
- M68K_DEVICE ("5213", mcf5213, "5213", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_MAC)
- M68K_DEVICE ("5214", mcf5214, "5216", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
- M68K_DEVICE ("5216", mcf5216, "5216", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
-+M68K_DEVICE ("5221x", mcf5221x, "5221x", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_MAC)
- M68K_DEVICE ("52221", mcf52221, "52223", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_MAC)
- M68K_DEVICE ("52223", mcf52223, "52223", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_MAC)
- M68K_DEVICE ("52230", mcf52230, "52235", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
-@@ -107,6 +114,14 @@ M68K_DEVICE ("52234", mcf52234, "52235",
- M68K_DEVICE ("52235", mcf52235, "52235", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
- M68K_DEVICE ("5224", mcf5224, "5225", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_MAC)
- M68K_DEVICE ("5225", mcf5225, "5225", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_MAC)
-+M68K_DEVICE ("52252", mcf52252, "52259", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
-+M68K_DEVICE ("52254", mcf52254, "52259", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
-+M68K_DEVICE ("52255", mcf52255, "52259", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
-+M68K_DEVICE ("52256", mcf52256, "52259", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
-+M68K_DEVICE ("52258", mcf52258, "52259", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
-+M68K_DEVICE ("52259", mcf52259, "52259", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
-+M68K_DEVICE ("52274", mcf52274, "52277", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
-+M68K_DEVICE ("52277", mcf52277, "52277", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
- M68K_DEVICE ("5232", mcf5232, "5235", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
- M68K_DEVICE ("5233", mcf5233, "5235", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
- M68K_DEVICE ("5234", mcf5234, "5235", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
-@@ -126,6 +141,13 @@ M68K_DEVICE ("5282", mcf5282, "5282",
- M68K_DEVICE ("528x", mcf528x, "5282", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
-
- /* CFV3 processors. */
-+M68K_DEVICE ("53011", mcf53011, "53017", "5329", cfv3, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
-+M68K_DEVICE ("53012", mcf53012, "53017", "5329", cfv3, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
-+M68K_DEVICE ("53013", mcf53013, "53017", "5329", cfv3, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
-+M68K_DEVICE ("53014", mcf53014, "53017", "5329", cfv3, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
-+M68K_DEVICE ("53015", mcf53015, "53017", "5329", cfv3, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
-+M68K_DEVICE ("53016", mcf53016, "53017", "5329", cfv3, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
-+M68K_DEVICE ("53017", mcf53017, "53017", "5329", cfv3, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
- M68K_DEVICE ("5307", mcf5307, "5307", "5307", cfv3, isa_a, FL_CF_HWDIV | FL_CF_MAC)
- M68K_DEVICE ("5327", mcf5327, "5329", "5329", cfv3, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
- M68K_DEVICE ("5328", mcf5328, "5329", "5329", cfv3, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
-@@ -137,12 +159,17 @@ M68K_DEVICE ("537x", mcf537x, "5373",
-
- /* CFV4/CFV4e processors. */
- M68K_DEVICE ("5407", mcf5407, "5407", "5407", cfv4, isa_b, FL_CF_MAC)
--M68K_DEVICE ("54450", mcf54450, "54455", "54455", cfv4, isa_c, FL_CF_HWDIV | FL_CF_USP | FL_CF_EMAC | FL_MMU)
--M68K_DEVICE ("54451", mcf54451, "54455", "54455", cfv4, isa_c, FL_CF_HWDIV | FL_CF_USP | FL_CF_EMAC | FL_MMU)
--M68K_DEVICE ("54452", mcf54452, "54455", "54455", cfv4, isa_c, FL_CF_HWDIV | FL_CF_USP | FL_CF_EMAC | FL_MMU)
--M68K_DEVICE ("54453", mcf54453, "54455", "54455", cfv4, isa_c, FL_CF_HWDIV | FL_CF_USP | FL_CF_EMAC | FL_MMU)
--M68K_DEVICE ("54454", mcf54454, "54455", "54455", cfv4, isa_c, FL_CF_HWDIV | FL_CF_USP | FL_CF_EMAC | FL_MMU)
--M68K_DEVICE ("54455", mcf54455, "54455", "54455", cfv4, isa_c, FL_CF_HWDIV | FL_CF_USP | FL_CF_EMAC | FL_MMU)
-+M68K_DEVICE ("54410", mcf54410, "54418", "54455", cfv4, isa_c, FL_CF_HWDIV | FL_CF_USP | FL_CF_EMAC | FL_MMU | FL_UCLINUX)
-+M68K_DEVICE ("54415", mcf54415, "54418", "54455", cfv4, isa_c, FL_CF_HWDIV | FL_CF_USP | FL_CF_EMAC | FL_MMU | FL_UCLINUX)
-+M68K_DEVICE ("54416", mcf54416, "54418", "54455", cfv4, isa_c, FL_CF_HWDIV | FL_CF_USP | FL_CF_EMAC | FL_MMU | FL_UCLINUX)
-+M68K_DEVICE ("54417", mcf54417, "54418", "54455", cfv4, isa_c, FL_CF_HWDIV | FL_CF_USP | FL_CF_EMAC | FL_MMU | FL_UCLINUX)
-+M68K_DEVICE ("54418", mcf54418, "54418", "54455", cfv4, isa_c, FL_CF_HWDIV | FL_CF_USP | FL_CF_EMAC | FL_MMU | FL_UCLINUX)
-+M68K_DEVICE ("54450", mcf54450, "54455", "54455", cfv4, isa_c, FL_CF_HWDIV | FL_CF_USP | FL_CF_EMAC | FL_MMU | FL_UCLINUX)
-+M68K_DEVICE ("54451", mcf54451, "54455", "54455", cfv4, isa_c, FL_CF_HWDIV | FL_CF_USP | FL_CF_EMAC | FL_MMU | FL_UCLINUX)
-+M68K_DEVICE ("54452", mcf54452, "54455", "54455", cfv4, isa_c, FL_CF_HWDIV | FL_CF_USP | FL_CF_EMAC | FL_MMU | FL_UCLINUX)
-+M68K_DEVICE ("54453", mcf54453, "54455", "54455", cfv4, isa_c, FL_CF_HWDIV | FL_CF_USP | FL_CF_EMAC | FL_MMU | FL_UCLINUX)
-+M68K_DEVICE ("54454", mcf54454, "54455", "54455", cfv4, isa_c, FL_CF_HWDIV | FL_CF_USP | FL_CF_EMAC | FL_MMU | FL_UCLINUX)
-+M68K_DEVICE ("54455", mcf54455, "54455", "54455", cfv4, isa_c, FL_CF_HWDIV | FL_CF_USP | FL_CF_EMAC | FL_MMU | FL_UCLINUX)
- M68K_DEVICE ("5470", mcf5470, "5475", "5475", cfv4e, isa_b, FL_CF_USP | FL_CF_EMAC | FL_CF_FPU | FL_MMU)
- M68K_DEVICE ("5471", mcf5471, "5475", "5475", cfv4e, isa_b, FL_CF_USP | FL_CF_EMAC | FL_CF_FPU | FL_MMU)
- M68K_DEVICE ("5472", mcf5472, "5475", "5475", cfv4e, isa_b, FL_CF_USP | FL_CF_EMAC | FL_CF_FPU | FL_MMU)
---- a/gcc/config/m68k/m68k-protos.h
-+++ b/gcc/config/m68k/m68k-protos.h
-@@ -54,19 +54,27 @@ extern void print_operand (FILE *, rtx,
- extern bool m68k_output_addr_const_extra (FILE *, rtx);
- extern void notice_update_cc (rtx, rtx);
- extern bool m68k_legitimate_base_reg_p (rtx, bool);
--extern bool m68k_legitimate_index_reg_p (rtx, bool);
-+extern bool m68k_legitimate_index_reg_p (enum machine_mode, rtx, bool);
- extern bool m68k_illegitimate_symbolic_constant_p (rtx);
- extern bool m68k_legitimate_address_p (enum machine_mode, rtx, bool);
- extern bool m68k_matches_q_p (rtx);
- extern bool m68k_matches_u_p (rtx);
- extern rtx legitimize_pic_address (rtx, enum machine_mode, rtx);
-+extern rtx m68k_legitimize_tls_address (rtx);
-+extern bool m68k_tls_reference_p (rtx, bool);
-+extern rtx m68k_legitimize_address (rtx, rtx, enum machine_mode);
- extern int valid_dbcc_comparison_p_2 (rtx, enum machine_mode);
- extern rtx m68k_libcall_value (enum machine_mode);
- extern rtx m68k_function_value (const_tree, const_tree);
- extern int emit_move_sequence (rtx *, enum machine_mode, rtx);
- extern bool m68k_movem_pattern_p (rtx, rtx, HOST_WIDE_INT, bool);
- extern const char *m68k_output_movem (rtx *, rtx, HOST_WIDE_INT, bool);
-+extern void m68k_final_prescan_insn (rtx, rtx *, int);
-
-+/* Functions from m68k.c used in constraints.md. */
-+extern rtx m68k_unwrap_symbol (rtx, bool);
-+
-+/* Functions from m68k.c used in genattrtab. */
- #ifdef HAVE_ATTR_cpu
- extern enum attr_cpu m68k_sched_cpu;
- extern enum attr_mac m68k_sched_mac;
---- a/gcc/config/m68k/m68k.c
-+++ b/gcc/config/m68k/m68k.c
-@@ -46,6 +46,7 @@ along with GCC; see the file COPYING3.
- /* ??? Need to add a dependency between m68k.o and sched-int.h. */
- #include "sched-int.h"
- #include "insn-codes.h"
-+#include "ggc.h"
-
- enum reg_class regno_reg_class[] =
- {
-@@ -146,10 +147,12 @@ static tree m68k_handle_fndecl_attribute
- static void m68k_compute_frame_layout (void);
- static bool m68k_save_reg (unsigned int regno, bool interrupt_handler);
- static bool m68k_ok_for_sibcall_p (tree, tree);
-+static bool m68k_tls_symbol_p (rtx);
- static bool m68k_rtx_costs (rtx, int, int, int *, bool);
- #if M68K_HONOR_TARGET_STRICT_ALIGNMENT
- static bool m68k_return_in_memory (const_tree, const_tree);
- #endif
-+static void m68k_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
- \f
-
- /* Specify the identification number of the library being built */
-@@ -252,6 +255,14 @@ int m68k_last_compare_had_fp_operands;
- #define TARGET_RETURN_IN_MEMORY m68k_return_in_memory
- #endif
-
-+#ifdef HAVE_AS_TLS
-+#undef TARGET_HAVE_TLS
-+#define TARGET_HAVE_TLS (true)
-+
-+#undef TARGET_ASM_OUTPUT_DWARF_DTPREL
-+#define TARGET_ASM_OUTPUT_DWARF_DTPREL m68k_output_dwarf_dtprel
-+#endif
-+
- static const struct attribute_spec m68k_attribute_table[] =
- {
- /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
-@@ -1150,8 +1161,7 @@ m68k_expand_prologue (void)
- current_frame.reg_mask, true, true));
- }
-
-- if (flag_pic
-- && !TARGET_SEP_DATA
-+ if (!TARGET_SEP_DATA
- && crtl->uses_pic_offset_table)
- insn = emit_insn (gen_load_got (pic_offset_table_rtx));
- }
-@@ -1425,6 +1435,86 @@ m68k_legitimize_sibcall_address (rtx x)
- return replace_equiv_address (x, gen_rtx_REG (Pmode, STATIC_CHAIN_REGNUM));
- }
-
-+/* Convert X to a legitimate address and return it if successful. Otherwise
-+ return X.
-+
-+ For the 68000, we handle X+REG by loading X into a register R and
-+ using R+REG. R will go in an address reg and indexing will be used.
-+ However, if REG is a broken-out memory address or multiplication,
-+ nothing needs to be done because REG can certainly go in an address reg. */
-+
-+rtx
-+m68k_legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
-+{
-+ if (m68k_tls_symbol_p (x))
-+ return m68k_legitimize_tls_address (x);
-+
-+ if (GET_CODE (x) == PLUS)
-+ {
-+ int ch = (x) != (oldx);
-+ int copied = 0;
-+
-+#define COPY_ONCE(Y) if (!copied) { Y = copy_rtx (Y); copied = ch = 1; }
-+
-+ if (GET_CODE (XEXP (x, 0)) == MULT)
-+ {
-+ COPY_ONCE (x);
-+ XEXP (x, 0) = force_operand (XEXP (x, 0), 0);
-+ }
-+ if (GET_CODE (XEXP (x, 1)) == MULT)
-+ {
-+ COPY_ONCE (x);
-+ XEXP (x, 1) = force_operand (XEXP (x, 1), 0);
-+ }
-+ if (ch)
-+ {
-+ if (GET_CODE (XEXP (x, 1)) == REG
-+ && GET_CODE (XEXP (x, 0)) == REG)
-+ {
-+ if (TARGET_COLDFIRE_FPU && GET_MODE_CLASS (mode) == MODE_FLOAT)
-+ {
-+ COPY_ONCE (x);
-+ x = force_operand (x, 0);
-+ }
-+ return x;
-+ }
-+ if (memory_address_p (mode, x))
-+ return x;
-+ }
-+ if (GET_CODE (XEXP (x, 0)) == REG
-+ || (GET_CODE (XEXP (x, 0)) == SIGN_EXTEND
-+ && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
-+ && GET_MODE (XEXP (XEXP (x, 0), 0)) == HImode))
-+ {
-+ rtx temp = gen_reg_rtx (Pmode);
-+ rtx val = force_operand (XEXP (x, 1), 0);
-+ emit_move_insn (temp, val);
-+ COPY_ONCE (x);
-+ XEXP (x, 1) = temp;
-+ if (TARGET_COLDFIRE_FPU && GET_MODE_CLASS (mode) == MODE_FLOAT
-+ && GET_CODE (XEXP (x, 0)) == REG)
-+ x = force_operand (x, 0);
-+ }
-+ else if (GET_CODE (XEXP (x, 1)) == REG
-+ || (GET_CODE (XEXP (x, 1)) == SIGN_EXTEND
-+ && GET_CODE (XEXP (XEXP (x, 1), 0)) == REG
-+ && GET_MODE (XEXP (XEXP (x, 1), 0)) == HImode))
-+ {
-+ rtx temp = gen_reg_rtx (Pmode);
-+ rtx val = force_operand (XEXP (x, 0), 0);
-+ emit_move_insn (temp, val);
-+ COPY_ONCE (x);
-+ XEXP (x, 0) = temp;
-+ if (TARGET_COLDFIRE_FPU && GET_MODE_CLASS (mode) == MODE_FLOAT
-+ && GET_CODE (XEXP (x, 1)) == REG)
-+ x = force_operand (x, 0);
-+ }
-+ }
-+
-+ return x;
-+}
-+
-+
- /* Output a dbCC; jCC sequence. Note we do not handle the
- floating point version of this sequence (Fdbcc). We also
- do not handle alternative conditions when CC_NO_OVERFLOW is
-@@ -1713,15 +1803,16 @@ m68k_legitimate_base_reg_p (rtx x, bool
- whether we need strict checking. */
-
- bool
--m68k_legitimate_index_reg_p (rtx x, bool strict_p)
-+m68k_legitimate_index_reg_p (enum machine_mode mode, rtx x, bool strict_p)
- {
- if (!strict_p && GET_CODE (x) == SUBREG)
- x = SUBREG_REG (x);
-
- return (REG_P (x)
- && (strict_p
-- ? REGNO_OK_FOR_INDEX_P (REGNO (x))
-- : REGNO_OK_FOR_INDEX_NONSTRICT_P (REGNO (x))));
-+ ? REGNO_MODE_OK_FOR_INDEX_P (REGNO (x), mode)
-+ : (MODE_OK_FOR_INDEX_P (mode)
-+ && REGNO_OK_FOR_INDEX_NONSTRICT_P (REGNO (x)))));
- }
-
- /* Return true if X is a legitimate index expression for a (d8,An,Xn) or
-@@ -1729,7 +1820,8 @@ m68k_legitimate_index_reg_p (rtx x, bool
- ADDRESS if so. STRICT_P says whether we need strict checking. */
-
- static bool
--m68k_decompose_index (rtx x, bool strict_p, struct m68k_address *address)
-+m68k_decompose_index (enum machine_mode mode, rtx x, bool strict_p,
-+ struct m68k_address *address)
- {
- int scale;
-
-@@ -1753,7 +1845,7 @@ m68k_decompose_index (rtx x, bool strict
- && GET_MODE (XEXP (x, 0)) == HImode)
- x = XEXP (x, 0);
-
-- if (m68k_legitimate_index_reg_p (x, strict_p))
-+ if (m68k_legitimate_index_reg_p (mode, x, strict_p))
- {
- address->scale = scale;
- address->index = x;
-@@ -1777,7 +1869,7 @@ m68k_illegitimate_symbolic_constant_p (r
- && !offset_within_block_p (base, INTVAL (offset)))
- return true;
- }
-- return false;
-+ return m68k_tls_reference_p (x, false);
- }
-
- /* Return true if X is a legitimate constant address that can reach
-@@ -1805,7 +1897,7 @@ m68k_legitimate_constant_address_p (rtx
- return false;
- }
-
-- return true;
-+ return !m68k_tls_reference_p (x, false);
- }
-
- /* Return true if X is a LABEL_REF for a jump table. Assume that unplaced
-@@ -1872,15 +1964,17 @@ m68k_decompose_address (enum machine_mod
- /* Check for GOT loads. These are (bd,An,Xn) addresses if
- TARGET_68020 && flag_pic == 2, otherwise they are (d16,An)
- addresses. */
-- if (flag_pic
-- && GET_CODE (x) == PLUS
-- && XEXP (x, 0) == pic_offset_table_rtx
-- && (GET_CODE (XEXP (x, 1)) == SYMBOL_REF
-- || GET_CODE (XEXP (x, 1)) == LABEL_REF))
-+ if (GET_CODE (x) == PLUS
-+ && XEXP (x, 0) == pic_offset_table_rtx)
- {
-- address->base = XEXP (x, 0);
-- address->offset = XEXP (x, 1);
-- return true;
-+ /* As we are processing a PLUS, do not unwrap RELOC32 symbols --
-+ they are invalid in this context. */
-+ if (m68k_unwrap_symbol (XEXP (x, 1), false) != XEXP (x, 1))
-+ {
-+ address->base = XEXP (x, 0);
-+ address->offset = XEXP (x, 1);
-+ return true;
-+ }
- }
-
- /* The ColdFire FPU only accepts addressing modes 2-5. */
-@@ -1905,7 +1999,7 @@ m68k_decompose_address (enum machine_mod
- accesses to unplaced labels in other cases. */
- if (GET_CODE (x) == PLUS
- && m68k_jump_table_ref_p (XEXP (x, 1))
-- && m68k_decompose_index (XEXP (x, 0), strict_p, address))
-+ && m68k_decompose_index (mode, XEXP (x, 0), strict_p, address))
- {
- address->offset = XEXP (x, 1);
- return true;
-@@ -1937,7 +2031,7 @@ m68k_decompose_address (enum machine_mod
- worse code. */
- if (address->offset
- && symbolic_operand (address->offset, VOIDmode)
-- && m68k_decompose_index (x, strict_p, address))
-+ && m68k_decompose_index (mode, x, strict_p, address))
- return true;
- }
- else
-@@ -1956,14 +2050,14 @@ m68k_decompose_address (enum machine_mod
- if (GET_CODE (x) == PLUS)
- {
- if (m68k_legitimate_base_reg_p (XEXP (x, 0), strict_p)
-- && m68k_decompose_index (XEXP (x, 1), strict_p, address))
-+ && m68k_decompose_index (mode, XEXP (x, 1), strict_p, address))
- {
- address->base = XEXP (x, 0);
- return true;
- }
-
- if (m68k_legitimate_base_reg_p (XEXP (x, 1), strict_p)
-- && m68k_decompose_index (XEXP (x, 0), strict_p, address))
-+ && m68k_decompose_index (mode, XEXP (x, 0), strict_p, address))
- {
- address->base = XEXP (x, 1);
- return true;
-@@ -2025,6 +2119,243 @@ m68k_matches_u_p (rtx x)
- && !address.index);
- }
-
-+/* Return GOT pointer. */
-+
-+static rtx
-+m68k_get_gp (void)
-+{
-+ if (pic_offset_table_rtx == NULL_RTX)
-+ pic_offset_table_rtx = gen_rtx_REG (Pmode, PIC_REG);
-+
-+ crtl->uses_pic_offset_table = 1;
-+
-+ return pic_offset_table_rtx;
-+}
-+
-+/* M68K relocations, used to distinguish GOT and TLS relocations in UNSPEC
-+ wrappers. */
-+enum m68k_reloc { RELOC_GOT, RELOC_TLSGD, RELOC_TLSLDM, RELOC_TLSLDO,
-+ RELOC_TLSIE, RELOC_TLSLE };
-+
-+#define TLS_RELOC_P(RELOC) ((RELOC) != RELOC_GOT)
-+
-+/* Wrap symbol X into unspec representing relocation RELOC.
-+ BASE_REG - register that should be added to the result.
-+ TEMP_REG - if non-null, temporary register. */
-+
-+static rtx
-+m68k_wrap_symbol (rtx x, enum m68k_reloc reloc, rtx base_reg, rtx temp_reg)
-+{
-+ bool use_x_p;
-+
-+ use_x_p = (base_reg == pic_offset_table_rtx) ? TARGET_XGOT : TARGET_XTLS;
-+
-+ if (TARGET_COLDFIRE && use_x_p)
-+ /* When compiling with -mx{got, tls} switch the code will look like this:
-+
-+ move.l <X>@<RELOC>,<TEMP_REG>
-+ add.l <BASE_REG>,<TEMP_REG> */
-+ {
-+ /* Wrap X in UNSPEC_??? to tip m68k_output_addr_const_extra
-+ to put @RELOC after reference. */
-+ x = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, x, GEN_INT (reloc)),
-+ UNSPEC_RELOC32);
-+ x = gen_rtx_CONST (Pmode, x);
-+
-+ if (temp_reg == NULL)
-+ {
-+ gcc_assert (can_create_pseudo_p ());
-+ temp_reg = gen_reg_rtx (Pmode);
-+ }
-+
-+ emit_move_insn (temp_reg, x);
-+ emit_insn (gen_addsi3 (temp_reg, temp_reg, base_reg));
-+ x = temp_reg;
-+ }
-+ else
-+ {
-+ x = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, x, GEN_INT (reloc)),
-+ UNSPEC_RELOC16);
-+ x = gen_rtx_CONST (Pmode, x);
-+
-+ x = gen_rtx_PLUS (Pmode, base_reg, x);
-+ }
-+
-+ return x;
-+}
-+
-+/* Helper for m68k_unwrap_symbol.
-+ Also, if unwrapping was successful (that is if (ORIG != <return value>)),
-+ sets *RELOC_PTR to relocation type for the symbol. */
-+
-+static rtx
-+m68k_unwrap_symbol_1 (rtx orig, bool unwrap_reloc32_p,
-+ enum m68k_reloc *reloc_ptr)
-+{
-+ if (GET_CODE (orig) == CONST)
-+ {
-+ rtx x;
-+ enum m68k_reloc dummy;
-+
-+ x = XEXP (orig, 0);
-+
-+ if (reloc_ptr == NULL)
-+ reloc_ptr = &dummy;
-+
-+ /* Handle an addend. */
-+ if ((GET_CODE (x) == PLUS || GET_CODE (x) == MINUS)
-+ && CONST_INT_P (XEXP (x, 1)))
-+ x = XEXP (x, 0);
-+
-+ if (GET_CODE (x) == UNSPEC)
-+ {
-+ switch (XINT (x, 1))
-+ {
-+ case UNSPEC_RELOC16:
-+ orig = XVECEXP (x, 0, 0);
-+ *reloc_ptr = (enum m68k_reloc) INTVAL (XVECEXP (x, 0, 1));
-+ break;
-+
-+ case UNSPEC_RELOC32:
-+ if (unwrap_reloc32_p)
-+ {
-+ orig = XVECEXP (x, 0, 0);
-+ *reloc_ptr = (enum m68k_reloc) INTVAL (XVECEXP (x, 0, 1));
-+ }
-+ break;
-+
-+ default:
-+ break;
-+ }
-+ }
-+ }
-+
-+ return orig;
-+}
-+
-+/* Unwrap symbol from UNSPEC_RELOC16 and, if unwrap_reloc32_p,
-+ UNSPEC_RELOC32 wrappers. */
-+
-+rtx
-+m68k_unwrap_symbol (rtx orig, bool unwrap_reloc32_p)
-+{
-+ return m68k_unwrap_symbol_1 (orig, unwrap_reloc32_p, NULL);
-+}
-+
-+/* Helper for m68k_final_prescan_insn. */
-+
-+static int
-+m68k_final_prescan_insn_1 (rtx *x_ptr, void *data ATTRIBUTE_UNUSED)
-+{
-+ rtx x = *x_ptr;
-+
-+ if (m68k_unwrap_symbol (x, true) != x)
-+ /* For rationale of the below, see comment in m68k_final_prescan_insn. */
-+ {
-+ rtx plus;
-+
-+ gcc_assert (GET_CODE (x) == CONST);
-+ plus = XEXP (x, 0);
-+
-+ if (GET_CODE (plus) == PLUS || GET_CODE (plus) == MINUS)
-+ {
-+ rtx unspec;
-+ rtx addend;
-+
-+ unspec = XEXP (plus, 0);
-+ gcc_assert (GET_CODE (unspec) == UNSPEC);
-+ addend = XEXP (plus, 1);
-+ gcc_assert (CONST_INT_P (addend));
-+
-+ /* We now have all the pieces, rearrange them. */
-+
-+ /* Move symbol to plus. */
-+ XEXP (plus, 0) = XVECEXP (unspec, 0, 0);
-+
-+ /* Move plus inside unspec. */
-+ XVECEXP (unspec, 0, 0) = plus;
-+
-+ /* Move unspec to top level of const. */
-+ XEXP (x, 0) = unspec;
-+ }
-+
-+ return -1;
-+ }
-+
-+ return 0;
-+}
-+
-+/* Prescan insn before outputing assembler for it. */
-+
-+void
-+m68k_final_prescan_insn (rtx insn ATTRIBUTE_UNUSED,
-+ rtx *operands, int n_operands)
-+{
-+ int i;
-+
-+ /* Combine and, possibly, other optimizations may do good job
-+ converting
-+ (const (unspec [(symbol)]))
-+ into
-+ (const (plus (unspec [(symbol)])
-+ (const_int N))).
-+ The problem with this is emitting @TLS or @GOT decorations.
-+ The decoration is emitted when processing (unspec), so the
-+ result would be "#symbol@TLSLE+N" instead of "#symbol+N@TLSLE".
-+
-+ It seems that the easiest solution to this is to convert such
-+ operands to
-+ (const (unspec [(plus (symbol)
-+ (const_int N))])).
-+ Note, that the top level of operand remains intact, so we don't have
-+ to patch up anything outside of the operand. */
-+
-+ for (i = 0; i < n_operands; ++i)
-+ {
-+ rtx op;
-+
-+ op = operands[i];
-+
-+ for_each_rtx (&op, m68k_final_prescan_insn_1, NULL);
-+ }
-+}
-+
-+/* Move X to a register and add REG_EQUAL note pointing to ORIG.
-+ If REG is non-null, use it; generate new pseudo otherwise. */
-+
-+static rtx
-+m68k_move_to_reg (rtx x, rtx orig, rtx reg)
-+{
-+ rtx insn;
-+
-+ if (reg == NULL_RTX)
-+ {
-+ gcc_assert (can_create_pseudo_p ());
-+ reg = gen_reg_rtx (Pmode);
-+ }
-+
-+ insn = emit_move_insn (reg, x);
-+ /* Put a REG_EQUAL note on this insn, so that it can be optimized
-+ by loop. */
-+ set_unique_reg_note (insn, REG_EQUAL, orig);
-+
-+ return reg;
-+}
-+
-+/* Does the same as m68k_wrap_symbol, but returns a memory reference to
-+ GOT slot. */
-+
-+static rtx
-+m68k_wrap_symbol_into_got_ref (rtx x, enum m68k_reloc reloc, rtx temp_reg)
-+{
-+ x = m68k_wrap_symbol (x, reloc, m68k_get_gp (), temp_reg);
-+
-+ x = gen_rtx_MEM (Pmode, x);
-+ MEM_READONLY_P (x) = 1;
-+
-+ return x;
-+}
-+
- /* Legitimize PIC addresses. If the address is already
- position-independent, we return ORIG. Newly generated
- position-independent addresses go to REG. If we need more
-@@ -2076,42 +2407,15 @@ legitimize_pic_address (rtx orig, enum m
- {
- gcc_assert (reg);
-
-- if (TARGET_COLDFIRE && TARGET_XGOT)
-- /* When compiling with -mxgot switch the code for the above
-- example will look like this:
--
-- movel a5, a0
-- addl _foo@GOT, a0
-- movel a0@, a0
-- movel #12345, a0@ */
-- {
-- rtx pic_offset;
--
-- /* Wrap ORIG in UNSPEC_GOTOFF to tip m68k_output_addr_const_extra
-- to put @GOT after reference. */
-- pic_offset = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, orig),
-- UNSPEC_GOTOFF);
-- pic_offset = gen_rtx_CONST (Pmode, pic_offset);
-- emit_move_insn (reg, pic_offset);
-- emit_insn (gen_addsi3 (reg, reg, pic_offset_table_rtx));
-- pic_ref = gen_rtx_MEM (Pmode, reg);
-- }
-- else
-- pic_ref = gen_rtx_MEM (Pmode,
-- gen_rtx_PLUS (Pmode,
-- pic_offset_table_rtx, orig));
-- crtl->uses_pic_offset_table = 1;
-- MEM_READONLY_P (pic_ref) = 1;
-- emit_move_insn (reg, pic_ref);
-- return reg;
-+ pic_ref = m68k_wrap_symbol_into_got_ref (orig, RELOC_GOT, reg);
-+ pic_ref = m68k_move_to_reg (pic_ref, orig, reg);
- }
- else if (GET_CODE (orig) == CONST)
- {
- rtx base;
-
- /* Make sure this has not already been legitimized. */
-- if (GET_CODE (XEXP (orig, 0)) == PLUS
-- && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
-+ if (m68k_unwrap_symbol (orig, true) != orig)
- return orig;
-
- gcc_assert (reg);
-@@ -2124,13 +2428,257 @@ legitimize_pic_address (rtx orig, enum m
- base == reg ? 0 : reg);
-
- if (GET_CODE (orig) == CONST_INT)
-- return plus_constant (base, INTVAL (orig));
-- pic_ref = gen_rtx_PLUS (Pmode, base, orig);
-- /* Likewise, should we set special REG_NOTEs here? */
-+ pic_ref = plus_constant (base, INTVAL (orig));
-+ else
-+ pic_ref = gen_rtx_PLUS (Pmode, base, orig);
- }
-+
- return pic_ref;
- }
-
-+/* The __tls_get_addr symbol. */
-+static GTY(()) rtx m68k_tls_get_addr;
-+
-+/* Return SYMBOL_REF for __tls_get_addr. */
-+
-+static rtx
-+m68k_get_tls_get_addr (void)
-+{
-+ if (m68k_tls_get_addr == NULL_RTX)
-+ m68k_tls_get_addr = init_one_libfunc ("__tls_get_addr");
-+
-+ return m68k_tls_get_addr;
-+}
-+
-+/* Return libcall result in A0 instead of usual D0. */
-+static bool m68k_libcall_value_in_a0_p = false;
-+
-+/* Emit instruction sequence that calls __tls_get_addr. X is
-+ the TLS symbol we are referencing and RELOC is the symbol type to use
-+ (either TLSGD or TLSLDM). EQV is the REG_EQUAL note for the sequence
-+ emitted. A pseudo register with result of __tls_get_addr call is
-+ returned. */
-+
-+static rtx
-+m68k_call_tls_get_addr (rtx x, rtx eqv, enum m68k_reloc reloc)
-+{
-+ rtx a0;
-+ rtx insns;
-+ rtx dest;
-+
-+ /* Emit the call sequence. */
-+ start_sequence ();
-+
-+ /* FIXME: Unfortunately, emit_library_call_value does not
-+ consider (plus (%a5) (const (unspec))) to be a good enough
-+ operand for push, so it forces it into a register. The bad
-+ thing about this is that combiner, due to copy propagation and other
-+ optimizations, sometimes can not later fix this. As a consequence,
-+ additional register may be allocated resulting in a spill.
-+ For reference, see args processing loops in
-+ calls.c:emit_library_call_value_1.
-+ For testcase, see gcc.target/m68k/tls-{gd, ld}.c */
-+ x = m68k_wrap_symbol (x, reloc, m68k_get_gp (), NULL_RTX);
-+
-+ /* __tls_get_addr() is not a libcall, but emitting a libcall_value
-+ is the simpliest way of generating a call. The difference between
-+ __tls_get_addr() and libcall is that the result is returned in D0
-+ instead of A0. To workaround this, we use m68k_libcall_value_in_a0_p
-+ which temporarily switches returning the result to A0. */
-+
-+ m68k_libcall_value_in_a0_p = true;
-+ a0 = emit_library_call_value (m68k_get_tls_get_addr (), NULL_RTX, LCT_PURE,
-+ Pmode, 1, x, Pmode);
-+ m68k_libcall_value_in_a0_p = false;
-+
-+ insns = get_insns ();
-+ end_sequence ();
-+
-+ gcc_assert (can_create_pseudo_p ());
-+ dest = gen_reg_rtx (Pmode);
-+ emit_libcall_block (insns, dest, a0, eqv);
-+
-+ return dest;
-+}
-+
-+/* The __tls_get_addr symbol. */
-+static GTY(()) rtx m68k_read_tp;
-+
-+/* Return SYMBOL_REF for __m68k_read_tp. */
-+
-+static rtx
-+m68k_get_m68k_read_tp (void)
-+{
-+ if (m68k_read_tp == NULL_RTX)
-+ m68k_read_tp = init_one_libfunc ("__m68k_read_tp");
-+
-+ return m68k_read_tp;
-+}
-+
-+/* Emit instruction sequence that calls __m68k_read_tp.
-+ A pseudo register with result of __m68k_read_tp call is returned. */
-+
-+static rtx
-+m68k_call_m68k_read_tp (void)
-+{
-+ rtx a0;
-+ rtx eqv;
-+ rtx insns;
-+ rtx dest;
-+
-+ start_sequence ();
-+
-+ /* __m68k_read_tp() is not a libcall, but emitting a libcall_value
-+ is the simpliest way of generating a call. The difference between
-+ __m68k_read_tp() and libcall is that the result is returned in D0
-+ instead of A0. To workaround this, we use m68k_libcall_value_in_a0_p
-+ which temporarily switches returning the result to A0. */
-+
-+ /* Emit the call sequence. */
-+ m68k_libcall_value_in_a0_p = true;
-+ a0 = emit_library_call_value (m68k_get_m68k_read_tp (), NULL_RTX, LCT_PURE,
-+ Pmode, 0);
-+ m68k_libcall_value_in_a0_p = false;
-+ insns = get_insns ();
-+ end_sequence ();
-+
-+ /* Attach a unique REG_EQUIV, to allow the RTL optimizers to
-+ share the m68k_read_tp result with other IE/LE model accesses. */
-+ eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const1_rtx), UNSPEC_RELOC32);
-+
-+ gcc_assert (can_create_pseudo_p ());
-+ dest = gen_reg_rtx (Pmode);
-+ emit_libcall_block (insns, dest, a0, eqv);
-+
-+ return dest;
-+}
-+
-+/* Return a legitimized address for accessing TLS SYMBOL_REF X.
-+ For explanations on instructions sequences see TLS/NPTL ABI for m68k and
-+ ColdFire. */
-+
-+rtx
-+m68k_legitimize_tls_address (rtx orig)
-+{
-+ switch (SYMBOL_REF_TLS_MODEL (orig))
-+ {
-+ case TLS_MODEL_GLOBAL_DYNAMIC:
-+ orig = m68k_call_tls_get_addr (orig, orig, RELOC_TLSGD);
-+ break;
-+
-+ case TLS_MODEL_LOCAL_DYNAMIC:
-+ {
-+ rtx eqv;
-+ rtx a0;
-+ rtx x;
-+
-+ /* Attach a unique REG_EQUIV, to allow the RTL optimizers to
-+ share the LDM result with other LD model accesses. */
-+ eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
-+ UNSPEC_RELOC32);
-+
-+ a0 = m68k_call_tls_get_addr (orig, eqv, RELOC_TLSLDM);
-+
-+ x = m68k_wrap_symbol (orig, RELOC_TLSLDO, a0, NULL_RTX);
-+
-+ if (can_create_pseudo_p ())
-+ x = m68k_move_to_reg (x, orig, NULL_RTX);
-+
-+ orig = x;
-+ break;
-+ }
-+
-+ case TLS_MODEL_INITIAL_EXEC:
-+ {
-+ rtx a0;
-+ rtx x;
-+
-+ a0 = m68k_call_m68k_read_tp ();
-+
-+ x = m68k_wrap_symbol_into_got_ref (orig, RELOC_TLSIE, NULL_RTX);
-+ x = gen_rtx_PLUS (Pmode, x, a0);
-+
-+ if (can_create_pseudo_p ())
-+ x = m68k_move_to_reg (x, orig, NULL_RTX);
-+
-+ orig = x;
-+ break;
-+ }
-+
-+ case TLS_MODEL_LOCAL_EXEC:
-+ {
-+ rtx a0;
-+ rtx x;
-+
-+ a0 = m68k_call_m68k_read_tp ();
-+
-+ x = m68k_wrap_symbol (orig, RELOC_TLSLE, a0, NULL_RTX);
-+
-+ if (can_create_pseudo_p ())
-+ x = m68k_move_to_reg (x, orig, NULL_RTX);
-+
-+ orig = x;
-+ break;
-+ }
-+
-+ default:
-+ gcc_unreachable ();
-+ }
-+
-+ return orig;
-+}
-+
-+/* Return true if X is a TLS symbol. */
-+
-+static bool
-+m68k_tls_symbol_p (rtx x)
-+{
-+ if (!TARGET_HAVE_TLS)
-+ return false;
-+
-+ if (GET_CODE (x) != SYMBOL_REF)
-+ return false;
-+
-+ return SYMBOL_REF_TLS_MODEL (x) != 0;
-+}
-+
-+/* Helper for m68k_tls_referenced_p. */
-+
-+static int
-+m68k_tls_reference_p_1 (rtx *x_ptr, void *data ATTRIBUTE_UNUSED)
-+{
-+ /* Note: this is not the same as m68k_tls_symbol_p. */
-+ if (GET_CODE (*x_ptr) == SYMBOL_REF)
-+ return SYMBOL_REF_TLS_MODEL (*x_ptr) != 0 ? 1 : 0;
-+
-+ /* Don't recurse into legitimate TLS references. */
-+ if (m68k_tls_reference_p (*x_ptr, true))
-+ return -1;
-+
-+ return 0;
-+}
-+
-+/* If !LEGITIMATE_P, return true if X is a TLS symbol reference,
-+ though illegitimate one.
-+ If LEGITIMATE_P, return true if X is a legitimate TLS symbol reference. */
-+
-+bool
-+m68k_tls_reference_p (rtx x, bool legitimate_p)
-+{
-+ if (!TARGET_HAVE_TLS)
-+ return false;
-+
-+ if (!legitimate_p)
-+ return for_each_rtx (&x, m68k_tls_reference_p_1, NULL) == 1 ? true : false;
-+ else
-+ {
-+ enum m68k_reloc reloc = RELOC_GOT;
-+
-+ return (m68k_unwrap_symbol_1 (x, true, &reloc) != x
-+ && TLS_RELOC_P (reloc));
-+ }
-+}
-+
- \f
-
- #define USE_MOVQ(i) ((unsigned) ((i) + 128) <= 255)
-@@ -3918,18 +4466,92 @@ print_operand (FILE *file, rtx op, int l
- }
- }
-
-+/* Return string for TLS relocation RELOC. */
-+
-+static const char *
-+m68k_get_reloc_decoration (enum m68k_reloc reloc)
-+{
-+ /* To my knowledge, !MOTOROLA assemblers don't support TLS. */
-+ gcc_assert (MOTOROLA || reloc == RELOC_GOT);
-+
-+ switch (reloc)
-+ {
-+ case RELOC_GOT:
-+ if (MOTOROLA)
-+ {
-+ if (flag_pic == 1 && TARGET_68020)
-+ return "@GOT.w";
-+ else
-+ return "@GOT";
-+ }
-+ else
-+ {
-+ if (TARGET_68020)
-+ {
-+ switch (flag_pic)
-+ {
-+ case 1:
-+ return ":w";
-+ case 2:
-+ return ":l";
-+ default:
-+ return "";
-+ }
-+ }
-+ }
-+
-+ case RELOC_TLSGD:
-+ return "@TLSGD";
-+
-+ case RELOC_TLSLDM:
-+ return "@TLSLDM";
-+
-+ case RELOC_TLSLDO:
-+ return "@TLSLDO";
-+
-+ case RELOC_TLSIE:
-+ return "@TLSIE";
-+
-+ case RELOC_TLSLE:
-+ return "@TLSLE";
-+
-+ default:
-+ gcc_unreachable ();
-+ }
-+}
-+
- /* m68k implementation of OUTPUT_ADDR_CONST_EXTRA. */
-
- bool
- m68k_output_addr_const_extra (FILE *file, rtx x)
- {
-- if (GET_CODE (x) != UNSPEC || XINT (x, 1) != UNSPEC_GOTOFF)
-- return false;
-+ if (GET_CODE (x) == UNSPEC)
-+ {
-+ switch (XINT (x, 1))
-+ {
-+ case UNSPEC_RELOC16:
-+ case UNSPEC_RELOC32:
-+ output_addr_const (file, XVECEXP (x, 0, 0));
-+ fputs (m68k_get_reloc_decoration (INTVAL (XVECEXP (x, 0, 1))), file);
-+ return true;
-
-- output_addr_const (file, XVECEXP (x, 0, 0));
-- /* ??? What is the non-MOTOROLA syntax? */
-- fputs ("@GOT", file);
-- return true;
-+ default:
-+ break;
-+ }
-+ }
-+
-+ return false;
-+}
-+
-+/* M68K implementation of TARGET_ASM_OUTPUT_DWARF_DTPREL. */
-+
-+static void
-+m68k_output_dwarf_dtprel (FILE *file, int size, rtx x)
-+{
-+ gcc_assert (size == 4);
-+ fputs ("\t.long\t", file);
-+ output_addr_const (file, x);
-+ fputs ("@TLSLDO+0x8000", file);
- }
-
- \f
-@@ -4019,15 +4641,8 @@ print_operand_address (FILE *file, rtx a
- else
- {
- if (address.offset)
-- {
-- output_addr_const (file, address.offset);
-- if (flag_pic && address.base == pic_offset_table_rtx)
-- {
-- fprintf (file, "@GOT");
-- if (flag_pic == 1 && TARGET_68020)
-- fprintf (file, ".w");
-- }
-- }
-+ output_addr_const (file, address.offset);
-+
- putc ('(', file);
- if (address.base)
- fputs (M68K_REGNAME (REGNO (address.base)), file);
-@@ -4060,19 +4675,7 @@ print_operand_address (FILE *file, rtx a
- fputs (M68K_REGNAME (REGNO (address.base)), file);
- fprintf (file, "@(");
- if (address.offset)
-- {
-- output_addr_const (file, address.offset);
-- if (address.base == pic_offset_table_rtx && TARGET_68020)
-- switch (flag_pic)
-- {
-- case 1:
-- fprintf (file, ":w"); break;
-- case 2:
-- fprintf (file, ":l"); break;
-- default:
-- break;
-- }
-- }
-+ output_addr_const (file, address.offset);
- }
- /* Print the ",index" component, if any. */
- if (address.index)
-@@ -4580,7 +5183,8 @@ m68k_libcall_value (enum machine_mode mo
- default:
- break;
- }
-- return gen_rtx_REG (mode, D0_REG);
-+
-+ return gen_rtx_REG (mode, m68k_libcall_value_in_a0_p ? A0_REG : D0_REG);
- }
-
- rtx
-@@ -4846,9 +5450,8 @@ sched_attr_op_type (rtx insn, bool opx_p
- return OP_TYPE_IMM_L;
-
- default:
-- if (GET_CODE (op) == SYMBOL_REF)
-- /* ??? Just a guess. Probably we can guess better using length
-- attribute of the instructions. */
-+ if (symbolic_operand (m68k_unwrap_symbol (op, false), VOIDmode))
-+ /* Just a guess. */
- return OP_TYPE_IMM_W;
-
- return OP_TYPE_IMM_L;
-@@ -5793,3 +6396,5 @@ m68k_sched_indexed_address_bypass_p (rtx
- return 0;
- }
- }
-+
-+#include "gt-m68k.h"
---- a/gcc/config/m68k/m68k.h
-+++ b/gcc/config/m68k/m68k.h
-@@ -232,6 +232,7 @@ along with GCC; see the file COPYING3.
- #define FL_ISA_C (1 << 16)
- #define FL_FIDOA (1 << 17)
- #define FL_MMU 0 /* Used by multilib machinery. */
-+#define FL_UCLINUX 0 /* Used by multilib machinery. */
-
- #define TARGET_68010 ((m68k_cpu_flags & FL_ISA_68010) != 0)
- #define TARGET_68020 ((m68k_cpu_flags & FL_ISA_68020) != 0)
-@@ -501,7 +502,8 @@ enum reg_class {
-
- extern enum reg_class regno_reg_class[];
- #define REGNO_REG_CLASS(REGNO) (regno_reg_class[(REGNO)])
--#define INDEX_REG_CLASS GENERAL_REGS
-+#define MODE_INDEX_REG_CLASS(MODE) \
-+ (MODE_OK_FOR_INDEX_P (MODE) ? GENERAL_REGS : NO_REGS)
- #define BASE_REG_CLASS ADDR_REGS
-
- #define PREFERRED_RELOAD_CLASS(X,CLASS) \
-@@ -644,7 +646,7 @@ extern enum reg_class regno_reg_class[];
- (though the operand list is empty). */
- #define TRANSFER_FROM_TRAMPOLINE \
- void \
--__transfer_from_trampoline () \
-+__transfer_from_trampoline (void) \
- { \
- register char *a0 asm (M68K_STATIC_CHAIN_REG_NAME); \
- asm (GLOBAL_ASM_OP "___trampoline"); \
-@@ -675,6 +677,10 @@ __transfer_from_trampoline () \
- #define HAVE_POST_INCREMENT 1
- #define HAVE_PRE_DECREMENT 1
-
-+/* Return true if addresses of mode MODE can have an index register. */
-+#define MODE_OK_FOR_INDEX_P(MODE) \
-+ (!TARGET_COLDFIRE_FPU || GET_MODE_CLASS (MODE) != MODE_FLOAT)
-+
- /* Macros to check register numbers against specific register classes. */
-
- /* True for data registers, D0 through D7. */
-@@ -689,9 +695,10 @@ __transfer_from_trampoline () \
- /* True for floating point registers, FP0 through FP7. */
- #define FP_REGNO_P(REGNO) IN_RANGE (REGNO, 16, 23)
-
--#define REGNO_OK_FOR_INDEX_P(REGNO) \
-- (INT_REGNO_P (REGNO) \
-- || INT_REGNO_P (reg_renumber[REGNO]))
-+#define REGNO_MODE_OK_FOR_INDEX_P(REGNO, MODE) \
-+ (MODE_OK_FOR_INDEX_P (MODE) \
-+ && (INT_REGNO_P (REGNO) \
-+ || INT_REGNO_P (reg_renumber[REGNO])))
-
- #define REGNO_OK_FOR_BASE_P(REGNO) \
- (ADDRESS_REGNO_P (REGNO) \
-@@ -751,13 +758,14 @@ __transfer_from_trampoline () \
-
- #define LEGITIMATE_PIC_OPERAND_P(X) \
- (!symbolic_operand (X, VOIDmode) \
-- || (TARGET_PCREL && REG_STRICT_P))
-+ || (TARGET_PCREL && REG_STRICT_P) \
-+ || m68k_tls_reference_p (X, true))
-
- #define REG_OK_FOR_BASE_P(X) \
- m68k_legitimate_base_reg_p (X, REG_STRICT_P)
-
--#define REG_OK_FOR_INDEX_P(X) \
-- m68k_legitimate_index_reg_p (X, REG_STRICT_P)
-+#define REG_MODE_OK_FOR_INDEX_P(X, MODE) \
-+ m68k_legitimate_index_reg_p (MODE, X, REG_STRICT_P)
-
- #define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
- do \
-@@ -770,52 +778,19 @@ __transfer_from_trampoline () \
- /* This address is OK as it stands. */
- #define PIC_CASE_VECTOR_ADDRESS(index) index
- \f
--/* For the 68000, we handle X+REG by loading X into a register R and
-- using R+REG. R will go in an address reg and indexing will be used.
-- However, if REG is a broken-out memory address or multiplication,
-- nothing needs to be done because REG can certainly go in an address reg. */
--#define COPY_ONCE(Y) if (!copied) { Y = copy_rtx (Y); copied = ch = 1; }
--#define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN) \
--{ register int ch = (X) != (OLDX); \
-- if (GET_CODE (X) == PLUS) \
-- { int copied = 0; \
-- if (GET_CODE (XEXP (X, 0)) == MULT) \
-- { COPY_ONCE (X); XEXP (X, 0) = force_operand (XEXP (X, 0), 0);} \
-- if (GET_CODE (XEXP (X, 1)) == MULT) \
-- { COPY_ONCE (X); XEXP (X, 1) = force_operand (XEXP (X, 1), 0);} \
-- if (ch && GET_CODE (XEXP (X, 1)) == REG \
-- && GET_CODE (XEXP (X, 0)) == REG) \
-- { if (TARGET_COLDFIRE_FPU \
-- && GET_MODE_CLASS (MODE) == MODE_FLOAT) \
-- { COPY_ONCE (X); X = force_operand (X, 0);} \
-- goto WIN; } \
-- if (ch) { GO_IF_LEGITIMATE_ADDRESS (MODE, X, WIN); } \
-- if (GET_CODE (XEXP (X, 0)) == REG \
-- || (GET_CODE (XEXP (X, 0)) == SIGN_EXTEND \
-- && GET_CODE (XEXP (XEXP (X, 0), 0)) == REG \
-- && GET_MODE (XEXP (XEXP (X, 0), 0)) == HImode)) \
-- { register rtx temp = gen_reg_rtx (Pmode); \
-- register rtx val = force_operand (XEXP (X, 1), 0); \
-- emit_move_insn (temp, val); \
-- COPY_ONCE (X); \
-- XEXP (X, 1) = temp; \
-- if (TARGET_COLDFIRE_FPU && GET_MODE_CLASS (MODE) == MODE_FLOAT \
-- && GET_CODE (XEXP (X, 0)) == REG) \
-- X = force_operand (X, 0); \
-- goto WIN; } \
-- else if (GET_CODE (XEXP (X, 1)) == REG \
-- || (GET_CODE (XEXP (X, 1)) == SIGN_EXTEND \
-- && GET_CODE (XEXP (XEXP (X, 1), 0)) == REG \
-- && GET_MODE (XEXP (XEXP (X, 1), 0)) == HImode)) \
-- { register rtx temp = gen_reg_rtx (Pmode); \
-- register rtx val = force_operand (XEXP (X, 0), 0); \
-- emit_move_insn (temp, val); \
-- COPY_ONCE (X); \
-- XEXP (X, 0) = temp; \
-- if (TARGET_COLDFIRE_FPU && GET_MODE_CLASS (MODE) == MODE_FLOAT \
-- && GET_CODE (XEXP (X, 1)) == REG) \
-- X = force_operand (X, 0); \
-- goto WIN; }}}
-+#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \
-+do { \
-+ rtx __x; \
-+ \
-+ __x = m68k_legitimize_address (X, OLDX, MODE); \
-+ if (__x != NULL_RTX) \
-+ { \
-+ X = __x; \
-+ \
-+ if (memory_address_p (MODE, X)) \
-+ goto WIN; \
-+ } \
-+} while (0)
-
- /* On the 68000, only predecrement and postincrement address depend thus
- (the amount of decrement or increment being the length of the operand).
-@@ -1028,6 +1003,9 @@ do { if (cc_prev_status.flags & CC_IN_68
- assemble_name ((FILE), (NAME)), \
- fprintf ((FILE), ",%u\n", (int)(ROUNDED)))
-
-+#define FINAL_PRESCAN_INSN(INSN, OPVEC, NOPERANDS) \
-+ m68k_final_prescan_insn (INSN, OPVEC, NOPERANDS)
-+
- /* On the 68000, we use several CODE characters:
- '.' for dot needed in Motorola-style opcode names.
- '-' for an operand pushing on the stack:
---- a/gcc/config/m68k/m68k.md
-+++ b/gcc/config/m68k/m68k.md
-@@ -116,7 +116,8 @@
- (UNSPEC_GOT 3)
- (UNSPEC_IB 4)
- (UNSPEC_TIE 5)
-- (UNSPEC_GOTOFF 6)
-+ (UNSPEC_RELOC16 6)
-+ (UNSPEC_RELOC32 7)
- ])
-
- ;; UNSPEC_VOLATILE usage:
-@@ -414,7 +415,7 @@
-
- (define_insn "tst<mode>_cf"
- [(set (cc0)
-- (match_operand:FP 0 "general_operand" "f<FP:dreg><Q>U"))]
-+ (match_operand:FP 0 "general_operand" "f<FP:dreg>m"))]
- "TARGET_COLDFIRE_FPU"
- {
- cc_status.flags = CC_IN_68881;
-@@ -570,8 +571,8 @@
-
- (define_insn "*cmp<mode>_cf"
- [(set (cc0)
-- (compare (match_operand:FP 0 "fp_src_operand" "f,f,<FP:dreg><Q>U")
-- (match_operand:FP 1 "fp_src_operand" "f,<FP:dreg><Q>U,f")))]
-+ (compare (match_operand:FP 0 "fp_src_operand" "f,f,<FP:dreg>m")
-+ (match_operand:FP 1 "fp_src_operand" "f,<FP:dreg>m,f")))]
- "TARGET_COLDFIRE_FPU
- && (register_operand (operands[0], <MODE>mode)
- || register_operand (operands[1], <MODE>mode))"
-@@ -779,7 +780,41 @@
- {
- rtx tmp, base, offset;
-
-- if (flag_pic && !TARGET_PCREL && symbolic_operand (operands[1], SImode))
-+ /* Recognize the case where operand[1] is a reference to thread-local
-+ data and load its address to a register. */
-+ if (!TARGET_PCREL && m68k_tls_reference_p (operands[1], false))
-+ {
-+ rtx tmp = operands[1];
-+ rtx addend = NULL;
-+
-+ if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
-+ {
-+ addend = XEXP (XEXP (tmp, 0), 1);
-+ tmp = XEXP (XEXP (tmp, 0), 0);
-+ }
-+
-+ gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
-+ gcc_assert (SYMBOL_REF_TLS_MODEL (tmp) != 0);
-+
-+ tmp = m68k_legitimize_tls_address (tmp);
-+
-+ if (addend)
-+ {
-+ if (!REG_P (tmp))
-+ {
-+ rtx reg;
-+
-+ reg = gen_reg_rtx (Pmode);
-+ emit_move_insn (reg, tmp);
-+ tmp = reg;
-+ }
-+
-+ tmp = gen_rtx_PLUS (SImode, tmp, addend);
-+ }
-+
-+ operands[1] = tmp;
-+ }
-+ else if (flag_pic && !TARGET_PCREL && symbolic_operand (operands[1], SImode))
- {
- /* The source is an address which requires PIC relocation.
- Call legitimize_pic_address with the source, mode, and a relocation
-@@ -1070,10 +1105,8 @@
- ;; SFmode MEMs are restricted to modes 2-4 if TARGET_COLDFIRE_FPU.
- ;; The move instructions can handle all combinations.
- (define_insn "movsf_cf_hard"
-- [(set (match_operand:SF 0 "nonimmediate_operand" "=r<Q>U, f, f,mr,f,r<Q>,f
--,m")
-- (match_operand:SF 1 "general_operand" " f, r<Q>U,f,rm,F,F, m
--,f"))]
-+ [(set (match_operand:SF 0 "nonimmediate_operand" "=rm,f, f,rm,f,r<Q>,f,m")
-+ (match_operand:SF 1 "general_operand" " f, rm,f,rm,F,F, m,f"))]
- "TARGET_COLDFIRE_FPU"
- {
- if (which_alternative == 4 || which_alternative == 5) {
-@@ -1215,8 +1248,8 @@
- })
-
- (define_insn "movdf_cf_hard"
-- [(set (match_operand:DF 0 "nonimmediate_operand" "=f, <Q>U,r,f,r,r,m,f")
-- (match_operand:DF 1 "general_operand" " f<Q>U,f, f,r,r,m,r,E"))]
-+ [(set (match_operand:DF 0 "nonimmediate_operand" "=f, m,r,f,r,r,m,f")
-+ (match_operand:DF 1 "general_operand" " fm,f,f,r,r,m,r,E"))]
- "TARGET_COLDFIRE_FPU"
- {
- rtx xoperands[3];
-@@ -1857,7 +1890,7 @@
- (define_insn "extendsfdf2_cf"
- [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f")
- (float_extend:DF
-- (match_operand:SF 1 "general_operand" "f,<Q>U")))]
-+ (match_operand:SF 1 "general_operand" "f,m")))]
- "TARGET_COLDFIRE_FPU"
- {
- if (FP_REG_P (operands[0]) && FP_REG_P (operands[1]))
-@@ -1897,9 +1930,9 @@
- })
-
- (define_insn "truncdfsf2_cf"
-- [(set (match_operand:SF 0 "nonimmediate_operand" "=f,d<Q>U")
-+ [(set (match_operand:SF 0 "nonimmediate_operand" "=f,dm")
- (float_truncate:SF
-- (match_operand:DF 1 "general_operand" "<Q>U,f")))]
-+ (match_operand:DF 1 "general_operand" "m,f")))]
- "TARGET_COLDFIRE_FPU"
- "@
- fsmove%.d %1,%0
-@@ -2045,7 +2078,7 @@
-
- (define_insn "ftrunc<mode>2_cf"
- [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
-- (fix:FP (match_operand:FP 1 "general_operand" "f<FP:dreg><Q>U")))]
-+ (fix:FP (match_operand:FP 1 "general_operand" "f<FP:dreg>m")))]
- "TARGET_COLDFIRE_FPU"
- {
- if (FP_REG_P (operands[1]))
-@@ -2338,9 +2371,9 @@
- "* return output_addsi3 (operands);")
-
- (define_insn_and_split "*addsi3_5200"
-- [(set (match_operand:SI 0 "nonimmediate_operand" "=mr,mr,a,m,r, ?a, ?a,?a,?a")
-- (plus:SI (match_operand:SI 1 "general_operand" "%0, 0, 0,0,0, a, a, r, a")
-- (match_operand:SI 2 "general_src_operand" " I, L, J,d,mrKi,Cj, r, a, J")))]
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=mr,mr,a, m,r, ?a, ?a,?a,?a")
-+ (plus:SI (match_operand:SI 1 "general_operand" "%0, 0, 0, 0,0, a, a, r, a")
-+ (match_operand:SI 2 "general_src_operand" " I, L, JCu,d,mrKi,Cj, r, a, JCu")))]
- "TARGET_COLDFIRE"
- {
- switch (which_alternative)
-@@ -2382,9 +2415,9 @@
- (plus:SI (match_dup 0)
- (match_dup 1)))]
- ""
-- [(set_attr "type" "aluq_l,aluq_l,lea,alu_l,alu_l,*,lea,lea,lea")
-- (set_attr "opy" "2,2,*,2,2,*,*,*,*")
-- (set_attr "opy_type" "*,*,mem5,*,*,*,mem6,mem6,mem5")])
-+ [(set_attr "type" "aluq_l,aluq_l,lea, alu_l,alu_l,*,lea, lea, lea")
-+ (set_attr "opy" "2, 2, *, 2, 2, *,*, *, *")
-+ (set_attr "opy_type" "*, *, mem5,*, *, *,mem6,mem6,mem5")])
-
- (define_insn ""
- [(set (match_operand:SI 0 "nonimmediate_operand" "=a")
-@@ -2666,7 +2699,7 @@
- (define_insn "add<mode>3_cf"
- [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
- (plus:FP (match_operand:FP 1 "general_operand" "%0")
-- (match_operand:FP 2 "general_operand" "f<FP:dreg><Q>U")))]
-+ (match_operand:FP 2 "general_operand" "f<FP:dreg>m")))]
- "TARGET_COLDFIRE_FPU"
- {
- if (FP_REG_P (operands[2]))
-@@ -2889,7 +2922,7 @@
- (define_insn "sub<mode>3_cf"
- [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
- (minus:FP (match_operand:FP 1 "general_operand" "0")
-- (match_operand:FP 2 "general_operand" "f<FP:dreg><Q>U")))]
-+ (match_operand:FP 2 "general_operand" "f<FP:dreg>m")))]
- "TARGET_COLDFIRE_FPU"
- {
- if (FP_REG_P (operands[2]))
-@@ -3245,7 +3278,7 @@
- (define_insn "fmul<mode>3_cf"
- [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
- (mult:FP (match_operand:FP 1 "general_operand" "%0")
-- (match_operand:FP 2 "general_operand" "f<Q>U<FP:dreg>")))]
-+ (match_operand:FP 2 "general_operand" "fm<FP:dreg>")))]
- "TARGET_COLDFIRE_FPU"
- {
- if (FP_REG_P (operands[2]))
-@@ -3315,7 +3348,7 @@
- (define_insn "div<mode>3_cf"
- [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
- (div:FP (match_operand:FP 1 "general_operand" "0")
-- (match_operand:FP 2 "general_operand" "f<Q>U<FP:dreg>")))]
-+ (match_operand:FP 2 "general_operand" "fm<FP:dreg>")))]
- "TARGET_COLDFIRE_FPU"
- {
- if (FP_REG_P (operands[2]))
-@@ -4163,7 +4196,7 @@
-
- (define_insn "neg<mode>2_cf"
- [(set (match_operand:FP 0 "nonimmediate_operand" "=f,d")
-- (neg:FP (match_operand:FP 1 "general_operand" "f<FP:dreg><Q>U,0")))]
-+ (neg:FP (match_operand:FP 1 "general_operand" "f<FP:dreg>m,0")))]
- "TARGET_COLDFIRE_FPU"
- {
- if (DATA_REG_P (operands[0]))
-@@ -4197,7 +4230,7 @@
-
- (define_insn "sqrt<mode>2_cf"
- [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
-- (sqrt:FP (match_operand:FP 1 "general_operand" "f<FP:dreg><Q>U")))]
-+ (sqrt:FP (match_operand:FP 1 "general_operand" "f<FP:dreg>m")))]
- "TARGET_COLDFIRE_FPU"
- {
- if (FP_REG_P (operands[1]))
-@@ -4316,7 +4349,7 @@
-
- (define_insn "abs<mode>2_cf"
- [(set (match_operand:FP 0 "nonimmediate_operand" "=f,d")
-- (abs:FP (match_operand:FP 1 "general_operand" "f<FP:dreg><Q>U,0")))]
-+ (abs:FP (match_operand:FP 1 "general_operand" "f<FP:dreg>m,0")))]
- "TARGET_COLDFIRE_FPU"
- {
- if (DATA_REG_P (operands[0]))
---- a/gcc/config/m68k/m68k.opt
-+++ b/gcc/config/m68k/m68k.opt
-@@ -182,3 +182,7 @@ Tune for the specified target CPU or arc
- mxgot
- Target Report Mask(XGOT)
- Support more than 8192 GOT entries on ColdFire
-+
-+mxtls
-+Target Report Mask(XTLS)
-+Support TLS segment larger than 64K
---- a/gcc/config/m68k/predicates.md
-+++ b/gcc/config/m68k/predicates.md
-@@ -130,7 +130,9 @@
- (match_code "sign_extend,zero_extend"))
-
- ;; Returns true if OP is either a symbol reference or a sum of a
--;; symbol reference and a constant.
-+;; symbol reference and a constant. This predicate is for "raw"
-+;; symbol references not yet processed by legitimize*_address,
-+;; hence we do not handle UNSPEC_{XGOT, TLS, XTLS} here.
-
- (define_predicate "symbolic_operand"
- (match_code "symbol_ref,label_ref,const")
---- a/gcc/config/m68k/t-uclinux
-+++ b/gcc/config/m68k/t-uclinux
-@@ -1,8 +1,8 @@
- # crti and crtn are provided by uClibc.
- EXTRA_MULTILIB_PARTS=crtbegin.o crtend.o
-
--# Only include multilibs for the 68020 and for CPUs without an MMU.
--M68K_MLIB_CPU += && (MLIB == "68020" || !match(FLAGS, "FL_MMU"))
-+# Include multilibs for CPUs without an MMU or with FL_UCLINUX
-+M68K_MLIB_CPU += && (!match(FLAGS, "FL_MMU") || match(FLAGS, "FL_UCLINUX"))
-
- # Add multilibs for execute-in-place and shared-library code.
- M68K_MLIB_OPTIONS += msep-data/mid-shared-library
---- a/gcc/config/mips/74k.md
-+++ b/gcc/config/mips/74k.md
-@@ -118,8 +118,7 @@
- ;; stores
- (define_insn_reservation "r74k_int_store" 1
- (and (eq_attr "cpu" "74kc,74kf2_1,74kf1_1,74kf3_2")
-- (and (eq_attr "type" "store")
-- (eq_attr "mode" "!unknown")))
-+ (eq_attr "type" "store"))
- "r74k_agen")
-
-
-@@ -145,33 +144,123 @@
- ;; load->load base: 4 cycles
- ;; load->store base: 4 cycles
- (define_bypass 4 "r74k_int_load" "r74k_int_load")
--(define_bypass 4 "r74k_int_load" "r74k_int_store" "!store_data_bypass_p")
-+(define_bypass 4 "r74k_int_load" "r74k_int_store" "!mips_store_data_bypass_p")
-
- ;; logical/move/slt/signext->next use : 1 cycles (Default)
- ;; logical/move/slt/signext->load base: 2 cycles
- ;; logical/move/slt/signext->store base: 2 cycles
- (define_bypass 2 "r74k_int_logical" "r74k_int_load")
--(define_bypass 2 "r74k_int_logical" "r74k_int_store" "!store_data_bypass_p")
-+(define_bypass 2 "r74k_int_logical" "r74k_int_store"
-+ "!mips_store_data_bypass_p")
-
- ;; arith->next use : 2 cycles (Default)
- ;; arith->load base: 3 cycles
- ;; arith->store base: 3 cycles
- (define_bypass 3 "r74k_int_arith" "r74k_int_load")
--(define_bypass 3 "r74k_int_arith" "r74k_int_store" "!store_data_bypass_p")
-+(define_bypass 3 "r74k_int_arith" "r74k_int_store" "!mips_store_data_bypass_p")
-
- ;; cmove->next use : 4 cycles (Default)
- ;; cmove->load base: 5 cycles
- ;; cmove->store base: 5 cycles
- (define_bypass 5 "r74k_int_cmove" "r74k_int_load")
--(define_bypass 5 "r74k_int_cmove" "r74k_int_store" "!store_data_bypass_p")
-+(define_bypass 5 "r74k_int_cmove" "r74k_int_store"
-+ "!mips_store_data_bypass_p")
-
- ;; mult/madd/msub->int_mfhilo : 4 cycles (default)
- ;; mult->madd/msub : 1 cycles
- ;; madd/msub->madd/msub : 1 cycles
--(define_bypass 1 "r74k_int_mult,r74k_int_mul3" "r74k_int_madd"
-- "mips_linked_madd_p")
--(define_bypass 1 "r74k_int_madd" "r74k_int_madd"
-- "mips_linked_madd_p")
-+(define_bypass 1 "r74k_int_mult" "r74k_int_madd")
-+(define_bypass 1 "r74k_int_madd" "r74k_int_madd")
-+
-+(define_bypass 1 "r74k_int_mul3" "r74k_int_madd"
-+ "mips_mult_madd_chain_bypass_p")
-+
-+
-+;; --------------------------------------------------------------
-+;; DSP instructins
-+;; --------------------------------------------------------------
-+
-+;; Non-saturating insn have the same latency as normal ALU operations,
-+(define_insn_reservation "r74k_dsp_alu" 2
-+ (and (eq_attr "cpu" "74kc,74kf2_1,74kf1_1,74kf3_2")
-+ (eq_attr "type" "dspalu"))
-+ "r74k_alu")
-+
-+;; Saturating insn takes an extra cycle.
-+(define_insn_reservation "r74k_dsp_alu_sat" 3
-+ (and (eq_attr "cpu" "74kc,74kf2_1,74kf1_1,74kf3_2")
-+ (eq_attr "type" "dspalusat"))
-+ "r74k_alu")
-+
-+;; dpaq_s, dpau, dpsq_s, dpsu, maq_s, mulsaq
-+;; - delivers result to hi/lo in 6 cycle (bypass at M4)
-+(define_insn_reservation "r74k_dsp_mac" 6
-+ (and (eq_attr "cpu" "74kc,74kf2_1,74kf1_1,74kf3_2")
-+ (eq_attr "type" "dspmac"))
-+ "r74k_alu+r74k_mul")
-+
-+;; dpaq_sa, dpsq_sa, maq_sa
-+;; - delivers result to hi/lo in 7 cycle (bypass at WB)
-+(define_insn_reservation "r74k_dsp_mac_sat" 7
-+ (and (eq_attr "cpu" "74kc,74kf2_1,74kf1_1,74kf3_2")
-+ (eq_attr "type" "dspmacsat"))
-+ "r74k_alu+r74k_mul")
-+
-+;; extp, extpdp, extpdpv, extpv, extr, extrv
-+;; - same latency as "mul"
-+(define_insn_reservation "r74k_dsp_acc_ext" 7
-+ (and (eq_attr "cpu" "74kc,74kf2_1,74kf1_1,74kf3_2")
-+ (eq_attr "type" "accext"))
-+ "r74k_alu+r74k_mul")
-+
-+;; mthlip, shilo, shilov
-+;; - same latency as "mul"
-+(define_insn_reservation "r74k_dsp_acc_mod" 7
-+ (and (eq_attr "cpu" "74kc,74kf2_1,74kf1_1,74kf3_2")
-+ (eq_attr "type" "accmod"))
-+ "r74k_alu+r74k_mul")
-+
-+;; dspalu ->load/store base
-+;; dspalusat->load/store base
-+;; - we should never see these in real life.
-+
-+;; dsp_mac->dsp_mac : 1 cycles (repeat rate of 1)
-+;; dsp_mac->dsp_mac_sat : 1 cycles (repeat rate of 1)
-+(define_bypass 1 "r74k_dsp_mac" "r74k_dsp_mac")
-+(define_bypass 1 "r74k_dsp_mac" "r74k_dsp_mac_sat")
-+
-+;; dsp_mac_sat->dsp_mac_sat : 2 cycles (repeat rate of 2)
-+;; dsp_mac_sat->dsp_mac : 2 cycles (repeat rate of 2)
-+(define_bypass 2 "r74k_dsp_mac_sat" "r74k_dsp_mac_sat")
-+(define_bypass 2 "r74k_dsp_mac_sat" "r74k_dsp_mac")
-+
-+(define_bypass 1 "r74k_int_mult" "r74k_dsp_mac")
-+(define_bypass 1 "r74k_int_mult" "r74k_dsp_mac_sat")
-+
-+;; Before reload, all multiplier is registered as imul3 (which has a long
-+;; latency). We temporary jig the latency such that the macc groups
-+;; are scheduled closely together during the first scheduler pass.
-+(define_bypass 1 "r74k_int_mul3" "r74k_dsp_mac"
-+ "mips_mult_madd_chain_bypass_p")
-+(define_bypass 1 "r74k_int_mul3" "r74k_dsp_mac_sat"
-+ "mips_mult_madd_chain_bypass_p")
-+
-+;; Assuming the following is true (bypass at M4)
-+;; AP AF AM MB M1 M2 M3 M4 WB GR GC
-+;; AP AF AM MB M1 M2 M3 M4 WB GR GC
-+;; dsp_mac->dsp_acc_ext : 4 cycles
-+;; dsp_mac->dsp_acc_mod : 4 cycles
-+(define_bypass 4 "r74k_dsp_mac" "r74k_dsp_acc_ext")
-+(define_bypass 4 "r74k_dsp_mac" "r74k_dsp_acc_mod")
-+
-+;; Assuming the following is true (bypass at WB)
-+;; AP AF AM MB M1 M2 M3 M4 WB GR GC
-+;; AP AF AM MB M1 M2 M3 M4 WB GR GC
-+;; dsp_mac_sat->dsp_acc_ext : 5 cycles
-+;; dsp_mac_sat->dsp_acc_mod : 5 cycles
-+(define_bypass 5 "r74k_dsp_mac_sat" "r74k_dsp_acc_ext")
-+(define_bypass 5 "r74k_dsp_mac_sat" "r74k_dsp_acc_mod")
-+
-
- ;; --------------------------------------------------------------
- ;; Floating Point Instructions
---- /dev/null
-+++ b/gcc/config/mips/crtfastmath.c
-@@ -0,0 +1,53 @@
-+/* Copyright (C) 2008, 2009 Free Software Foundation, Inc.
-+
-+ This file is part of GCC.
-+
-+ GCC is free software; you can redistribute it and/or modify it
-+ under the terms of the GNU General Public License as published by
-+ the Free Software Foundation; either version 3, or (at your option)
-+ any later version.
-+
-+ GCC is distributed in the hope that it will be useful, but WITHOUT
-+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
-+ License for more details.
-+
-+ Under Section 7 of GPL version 3, you are granted additional
-+ permissions described in the GCC Runtime Library Exception, version
-+ 3.1, as published by the Free Software Foundation.
-+
-+ You should have received a copy of the GNU General Public License
-+ and a copy of the GCC Runtime Library Exception along with this
-+ program; see the files COPYING3 and COPYING.RUNTIME respectively.
-+ If not, see <http://www.gnu.org/licenses/>. */
-+
-+#ifdef __mips_hard_float
-+
-+/* flush denormalized numbers to zero */
-+#define _FPU_FLUSH_TZ 0x1000000
-+
-+/* rounding control */
-+#define _FPU_RC_NEAREST 0x0 /* RECOMMENDED */
-+#define _FPU_RC_ZERO 0x1
-+#define _FPU_RC_UP 0x2
-+#define _FPU_RC_DOWN 0x3
-+
-+/* enable interrupts for IEEE exceptions */
-+#define _FPU_IEEE 0x00000F80
-+
-+/* Macros for accessing the hardware control word. */
-+#define _FPU_GETCW(cw) __asm__ ("cfc1 %0,$31" : "=r" (cw))
-+#define _FPU_SETCW(cw) __asm__ ("ctc1 %0,$31" : : "r" (cw))
-+
-+static void __attribute__((constructor))
-+set_fast_math (void)
-+{
-+ unsigned int fcr;
-+
-+ /* fastmath: flush to zero, round to nearest, ieee exceptions disabled */
-+ fcr = _FPU_FLUSH_TZ | _FPU_RC_NEAREST;
-+
-+ _FPU_SETCW(fcr);
-+}
-+
-+#endif /* __mips_hard_float */
---- a/gcc/config/mips/linux.h
-+++ b/gcc/config/mips/linux.h
-@@ -147,3 +147,17 @@ extern const char *host_detect_local_cpu
- #define DRIVER_SELF_SPECS \
- BASE_DRIVER_SELF_SPECS, \
- LINUX_DRIVER_SELF_SPECS
-+
-+/* Similar to standard Linux, but adding -ffast-math support. */
-+#undef ENDFILE_SPEC
-+#define ENDFILE_SPEC \
-+ "%{ffast-math|funsafe-math-optimizations:crtfastmath.o%s} \
-+ %{shared|pie:crtendS.o%s;:crtend.o%s} crtn.o%s"
-+
-+#undef SUBTARGET_OVERRIDE_OPTIONS
-+#define SUBTARGET_OVERRIDE_OPTIONS \
-+do { \
-+ /* __thread_support is not supported by uClibc. */ \
-+ if (linux_uclibc) \
-+ targetm.have_tls = 0; \
-+} while (0)
---- a/gcc/config/mips/linux64.h
-+++ b/gcc/config/mips/linux64.h
-@@ -69,3 +69,9 @@ along with GCC; see the file COPYING3.
- ieee_quad_format is the default, but let's put this here to make
- sure nobody thinks we just forgot to set it to something else. */
- #define MIPS_TFMODE_FORMAT mips_quad_format
-+
-+/* Similar to standard Linux, but adding -ffast-math support. */
-+#undef ENDFILE_SPEC
-+#define ENDFILE_SPEC \
-+ "%{ffast-math|funsafe-math-optimizations:crtfastmath.o%s} \
-+ %{shared|pie:crtendS.o%s;:crtend.o%s} crtn.o%s"
---- a/gcc/config/mips/mips-dsp.md
-+++ b/gcc/config/mips/mips-dsp.md
-@@ -42,9 +42,9 @@
- (match_operand:DSPV 2 "register_operand" "d")))
- (set (reg:CCDSP CCDSP_OU_REGNUM)
- (unspec:CCDSP [(match_dup 1) (match_dup 2)] UNSPEC_ADDQ))])]
-- ""
-+ "ISA_HAS_DSP"
- "add<DSPV:dspfmt1>.<DSPV:dspfmt2>\t%0,%1,%2"
-- [(set_attr "type" "arith")
-+ [(set_attr "type" "dspalu")
- (set_attr "mode" "SI")])
-
- (define_insn "mips_add<DSP:dspfmt1>_s_<DSP:dspfmt2>"
-@@ -55,9 +55,9 @@
- UNSPEC_ADDQ_S))
- (set (reg:CCDSP CCDSP_OU_REGNUM)
- (unspec:CCDSP [(match_dup 1) (match_dup 2)] UNSPEC_ADDQ_S))])]
-- ""
-+ "ISA_HAS_DSP"
- "add<DSP:dspfmt1>_s.<DSP:dspfmt2>\t%0,%1,%2"
-- [(set_attr "type" "arith")
-+ [(set_attr "type" "dspalusat")
- (set_attr "mode" "SI")])
-
- ;; SUBQ*
-@@ -70,7 +70,7 @@
- (unspec:CCDSP [(match_dup 1) (match_dup 2)] UNSPEC_SUBQ))])]
- "ISA_HAS_DSP"
- "sub<DSPV:dspfmt1>.<DSPV:dspfmt2>\t%0,%1,%2"
-- [(set_attr "type" "arith")
-+ [(set_attr "type" "dspalu")
- (set_attr "mode" "SI")])
-
- (define_insn "mips_sub<DSP:dspfmt1>_s_<DSP:dspfmt2>"
-@@ -83,7 +83,7 @@
- (unspec:CCDSP [(match_dup 1) (match_dup 2)] UNSPEC_SUBQ_S))])]
- "ISA_HAS_DSP"
- "sub<DSP:dspfmt1>_s.<DSP:dspfmt2>\t%0,%1,%2"
-- [(set_attr "type" "arith")
-+ [(set_attr "type" "dspalusat")
- (set_attr "mode" "SI")])
-
- ;; ADDSC
-@@ -97,7 +97,7 @@
- (unspec:CCDSP [(match_dup 1) (match_dup 2)] UNSPEC_ADDSC))])]
- "ISA_HAS_DSP"
- "addsc\t%0,%1,%2"
-- [(set_attr "type" "arith")
-+ [(set_attr "type" "dspalu")
- (set_attr "mode" "SI")])
-
- ;; ADDWC
-@@ -112,7 +112,7 @@
- (unspec:CCDSP [(match_dup 1) (match_dup 2)] UNSPEC_ADDWC))])]
- "ISA_HAS_DSP"
- "addwc\t%0,%1,%2"
-- [(set_attr "type" "arith")
-+ [(set_attr "type" "dspalu")
- (set_attr "mode" "SI")])
-
- ;; MODSUB
-@@ -123,7 +123,7 @@
- UNSPEC_MODSUB))]
- "ISA_HAS_DSP"
- "modsub\t%0,%1,%2"
-- [(set_attr "type" "arith")
-+ [(set_attr "type" "dspalu")
- (set_attr "mode" "SI")])
-
- ;; RADDU*
-@@ -133,7 +133,7 @@
- UNSPEC_RADDU_W_QB))]
- "ISA_HAS_DSP"
- "raddu.w.qb\t%0,%1"
-- [(set_attr "type" "arith")
-+ [(set_attr "type" "dspalu")
- (set_attr "mode" "SI")])
-
- ;; ABSQ*
-@@ -146,7 +146,7 @@
- (unspec:CCDSP [(match_dup 1)] UNSPEC_ABSQ_S))])]
- "ISA_HAS_DSP"
- "absq_s.<DSPQ:dspfmt2>\t%0,%1"
-- [(set_attr "type" "arith")
-+ [(set_attr "type" "dspalusat")
- (set_attr "mode" "SI")])
-
- ;; PRECRQ*
-@@ -157,7 +157,7 @@
- UNSPEC_PRECRQ_QB_PH))]
- "ISA_HAS_DSP"
- "precrq.qb.ph\t%0,%1,%2"
-- [(set_attr "type" "arith")
-+ [(set_attr "type" "dspalu")
- (set_attr "mode" "SI")])
-
- (define_insn "mips_precrq_ph_w"
-@@ -167,7 +167,7 @@
- UNSPEC_PRECRQ_PH_W))]
- "ISA_HAS_DSP"
- "precrq.ph.w\t%0,%1,%2"
-- [(set_attr "type" "arith")
-+ [(set_attr "type" "dspalu")
- (set_attr "mode" "SI")])
-
- (define_insn "mips_precrq_rs_ph_w"
-@@ -181,7 +181,7 @@
- UNSPEC_PRECRQ_RS_PH_W))])]
- "ISA_HAS_DSP"
- "precrq_rs.ph.w\t%0,%1,%2"
-- [(set_attr "type" "arith")
-+ [(set_attr "type" "dspalu")
- (set_attr "mode" "SI")])
-
- ;; PRECRQU*
-@@ -196,7 +196,7 @@
- UNSPEC_PRECRQU_S_QB_PH))])]
- "ISA_HAS_DSP"
- "precrqu_s.qb.ph\t%0,%1,%2"
-- [(set_attr "type" "arith")
-+ [(set_attr "type" "dspalusat")
- (set_attr "mode" "SI")])
-
- ;; PRECEQ*
-@@ -206,7 +206,7 @@
- UNSPEC_PRECEQ_W_PHL))]
- "ISA_HAS_DSP"
- "preceq.w.phl\t%0,%1"
-- [(set_attr "type" "arith")
-+ [(set_attr "type" "dspalu")
- (set_attr "mode" "SI")])
-
- (define_insn "mips_preceq_w_phr"
-@@ -215,7 +215,7 @@
- UNSPEC_PRECEQ_W_PHR))]
- "ISA_HAS_DSP"
- "preceq.w.phr\t%0,%1"
-- [(set_attr "type" "arith")
-+ [(set_attr "type" "dspalu")
- (set_attr "mode" "SI")])
-
- ;; PRECEQU*
-@@ -225,7 +225,7 @@
- UNSPEC_PRECEQU_PH_QBL))]
- "ISA_HAS_DSP"
- "precequ.ph.qbl\t%0,%1"
-- [(set_attr "type" "arith")
-+ [(set_attr "type" "dspalu")
- (set_attr "mode" "SI")])
-
- (define_insn "mips_precequ_ph_qbr"
-@@ -234,7 +234,7 @@
- UNSPEC_PRECEQU_PH_QBR))]
- "ISA_HAS_DSP"
- "precequ.ph.qbr\t%0,%1"
-- [(set_attr "type" "arith")
-+ [(set_attr "type" "dspalu")
- (set_attr "mode" "SI")])
-
- (define_insn "mips_precequ_ph_qbla"
-@@ -243,7 +243,7 @@
- UNSPEC_PRECEQU_PH_QBLA))]
- "ISA_HAS_DSP"
- "precequ.ph.qbla\t%0,%1"
-- [(set_attr "type" "arith")
-+ [(set_attr "type" "dspalu")
- (set_attr "mode" "SI")])
-
- (define_insn "mips_precequ_ph_qbra"
-@@ -252,7 +252,7 @@
- UNSPEC_PRECEQU_PH_QBRA))]
- "ISA_HAS_DSP"
- "precequ.ph.qbra\t%0,%1"
-- [(set_attr "type" "arith")
-+ [(set_attr "type" "dspalu")
- (set_attr "mode" "SI")])
-
- ;; PRECEU*
-@@ -262,7 +262,7 @@
- UNSPEC_PRECEU_PH_QBL))]
- "ISA_HAS_DSP"
- "preceu.ph.qbl\t%0,%1"
-- [(set_attr "type" "arith")
-+ [(set_attr "type" "dspalu")
- (set_attr "mode" "SI")])
-
- (define_insn "mips_preceu_ph_qbr"
-@@ -271,7 +271,7 @@
- UNSPEC_PRECEU_PH_QBR))]
- "ISA_HAS_DSP"
- "preceu.ph.qbr\t%0,%1"
-- [(set_attr "type" "arith")
-+ [(set_attr "type" "dspalu")
- (set_attr "mode" "SI")])
-
- (define_insn "mips_preceu_ph_qbla"
-@@ -280,7 +280,7 @@
- UNSPEC_PRECEU_PH_QBLA))]
- "ISA_HAS_DSP"
- "preceu.ph.qbla\t%0,%1"
-- [(set_attr "type" "arith")
-+ [(set_attr "type" "dspalu")
- (set_attr "mode" "SI")])
-
- (define_insn "mips_preceu_ph_qbra"
-@@ -289,7 +289,7 @@
- UNSPEC_PRECEU_PH_QBRA))]
- "ISA_HAS_DSP"
- "preceu.ph.qbra\t%0,%1"
-- [(set_attr "type" "arith")
-+ [(set_attr "type" "dspalu")
- (set_attr "mode" "SI")])
-
- ;; Table 2-2. MIPS DSP ASE Instructions: Shift
-@@ -313,7 +313,7 @@
- }
- return "shllv.<DSPV:dspfmt2>\t%0,%1,%2";
- }
-- [(set_attr "type" "shift")
-+ [(set_attr "type" "dspalu")
- (set_attr "mode" "SI")])
-
- (define_insn "mips_shll_s_<DSPQ:dspfmt2>"
-@@ -335,7 +335,7 @@
- }
- return "shllv_s.<DSPQ:dspfmt2>\t%0,%1,%2";
- }
-- [(set_attr "type" "shift")
-+ [(set_attr "type" "dspalusat")
- (set_attr "mode" "SI")])
-
- ;; SHRL*
-@@ -354,7 +354,7 @@
- }
- return "shrlv.qb\t%0,%1,%2";
- }
-- [(set_attr "type" "shift")
-+ [(set_attr "type" "dspalu")
- (set_attr "mode" "SI")])
-
- ;; SHRA*
-@@ -373,7 +373,7 @@
- }
- return "shrav.ph\t%0,%1,%2";
- }
-- [(set_attr "type" "shift")
-+ [(set_attr "type" "dspalu")
- (set_attr "mode" "SI")])
-
- (define_insn "mips_shra_r_<DSPQ:dspfmt2>"
-@@ -392,7 +392,7 @@
- }
- return "shrav_r.<DSPQ:dspfmt2>\t%0,%1,%2";
- }
-- [(set_attr "type" "shift")
-+ [(set_attr "type" "dspalu")
- (set_attr "mode" "SI")])
-
- ;; Table 2-3. MIPS DSP ASE Instructions: Multiply
-@@ -478,7 +478,7 @@
- UNSPEC_DPAU_H_QBL))]
- "ISA_HAS_DSP && !TARGET_64BIT"
- "dpau.h.qbl\t%q0,%2,%3"
-- [(set_attr "type" "imadd")
-+ [(set_attr "type" "dspmac")
- (set_attr "mode" "SI")])
-
- (define_insn "mips_dpau_h_qbr"
-@@ -489,7 +489,7 @@
- UNSPEC_DPAU_H_QBR))]
- "ISA_HAS_DSP && !TARGET_64BIT"
- "dpau.h.qbr\t%q0,%2,%3"
-- [(set_attr "type" "imadd")
-+ [(set_attr "type" "dspmac")
- (set_attr "mode" "SI")])
-
- ;; DPSU*
-@@ -501,7 +501,7 @@
- UNSPEC_DPSU_H_QBL))]
- "ISA_HAS_DSP && !TARGET_64BIT"
- "dpsu.h.qbl\t%q0,%2,%3"
-- [(set_attr "type" "imadd")
-+ [(set_attr "type" "dspmac")
- (set_attr "mode" "SI")])
-
- (define_insn "mips_dpsu_h_qbr"
-@@ -512,7 +512,7 @@
- UNSPEC_DPSU_H_QBR))]
- "ISA_HAS_DSP && !TARGET_64BIT"
- "dpsu.h.qbr\t%q0,%2,%3"
-- [(set_attr "type" "imadd")
-+ [(set_attr "type" "dspmac")
- (set_attr "mode" "SI")])
-
- ;; DPAQ*
-@@ -528,7 +528,7 @@
- UNSPEC_DPAQ_S_W_PH))])]
- "ISA_HAS_DSP && !TARGET_64BIT"
- "dpaq_s.w.ph\t%q0,%2,%3"
-- [(set_attr "type" "imadd")
-+ [(set_attr "type" "dspmac")
- (set_attr "mode" "SI")])
-
- ;; DPSQ*
-@@ -544,7 +544,7 @@
- UNSPEC_DPSQ_S_W_PH))])]
- "ISA_HAS_DSP && !TARGET_64BIT"
- "dpsq_s.w.ph\t%q0,%2,%3"
-- [(set_attr "type" "imadd")
-+ [(set_attr "type" "dspmac")
- (set_attr "mode" "SI")])
-
- ;; MULSAQ*
-@@ -560,7 +560,7 @@
- UNSPEC_MULSAQ_S_W_PH))])]
- "ISA_HAS_DSP && !TARGET_64BIT"
- "mulsaq_s.w.ph\t%q0,%2,%3"
-- [(set_attr "type" "imadd")
-+ [(set_attr "type" "dspmac")
- (set_attr "mode" "SI")])
-
- ;; DPAQ*
-@@ -576,7 +576,7 @@
- UNSPEC_DPAQ_SA_L_W))])]
- "ISA_HAS_DSP && !TARGET_64BIT"
- "dpaq_sa.l.w\t%q0,%2,%3"
-- [(set_attr "type" "imadd")
-+ [(set_attr "type" "dspmacsat")
- (set_attr "mode" "SI")])
-
- ;; DPSQ*
-@@ -592,7 +592,7 @@
- UNSPEC_DPSQ_SA_L_W))])]
- "ISA_HAS_DSP && !TARGET_64BIT"
- "dpsq_sa.l.w\t%q0,%2,%3"
-- [(set_attr "type" "imadd")
-+ [(set_attr "type" "dspmacsat")
- (set_attr "mode" "SI")])
-
- ;; MAQ*
-@@ -608,7 +608,7 @@
- UNSPEC_MAQ_S_W_PHL))])]
- "ISA_HAS_DSP && !TARGET_64BIT"
- "maq_s.w.phl\t%q0,%2,%3"
-- [(set_attr "type" "imadd")
-+ [(set_attr "type" "dspmac")
- (set_attr "mode" "SI")])
-
- (define_insn "mips_maq_s_w_phr"
-@@ -623,7 +623,7 @@
- UNSPEC_MAQ_S_W_PHR))])]
- "ISA_HAS_DSP && !TARGET_64BIT"
- "maq_s.w.phr\t%q0,%2,%3"
-- [(set_attr "type" "imadd")
-+ [(set_attr "type" "dspmac")
- (set_attr "mode" "SI")])
-
- ;; MAQ_SA*
-@@ -639,7 +639,7 @@
- UNSPEC_MAQ_SA_W_PHL))])]
- "ISA_HAS_DSP && !TARGET_64BIT"
- "maq_sa.w.phl\t%q0,%2,%3"
-- [(set_attr "type" "imadd")
-+ [(set_attr "type" "dspmacsat")
- (set_attr "mode" "SI")])
-
- (define_insn "mips_maq_sa_w_phr"
-@@ -654,7 +654,7 @@
- UNSPEC_MAQ_SA_W_PHR))])]
- "ISA_HAS_DSP && !TARGET_64BIT"
- "maq_sa.w.phr\t%q0,%2,%3"
-- [(set_attr "type" "imadd")
-+ [(set_attr "type" "dspmacsat")
- (set_attr "mode" "SI")])
-
- ;; Table 2-4. MIPS DSP ASE Instructions: General Bit/Manipulation
-@@ -665,7 +665,7 @@
- UNSPEC_BITREV))]
- "ISA_HAS_DSP"
- "bitrev\t%0,%1"
-- [(set_attr "type" "arith")
-+ [(set_attr "type" "dspalu")
- (set_attr "mode" "SI")])
-
- ;; INSV
-@@ -678,7 +678,7 @@
- UNSPEC_INSV))]
- "ISA_HAS_DSP"
- "insv\t%0,%2"
-- [(set_attr "type" "arith")
-+ [(set_attr "type" "dspalu")
- (set_attr "mode" "SI")])
-
- ;; REPL*
-@@ -696,7 +696,7 @@
- }
- return "replv.qb\t%0,%1";
- }
-- [(set_attr "type" "arith")
-+ [(set_attr "type" "dspalu")
- (set_attr "mode" "SI")])
-
- (define_insn "mips_repl_ph"
-@@ -707,7 +707,7 @@
- "@
- repl.ph\t%0,%1
- replv.ph\t%0,%1"
-- [(set_attr "type" "arith")
-+ [(set_attr "type" "dspalu")
- (set_attr "mode" "SI")])
-
- ;; Table 2-5. MIPS DSP ASE Instructions: Compare-Pick
-@@ -720,7 +720,7 @@
- UNSPEC_CMP_EQ))]
- "ISA_HAS_DSP"
- "cmp<DSPV:dspfmt1_1>.eq.<DSPV:dspfmt2>\t%0,%1"
-- [(set_attr "type" "arith")
-+ [(set_attr "type" "dspalu")
- (set_attr "mode" "SI")])
-
- (define_insn "mips_cmp<DSPV:dspfmt1_1>_lt_<DSPV:dspfmt2>"
-@@ -731,7 +731,7 @@
- UNSPEC_CMP_LT))]
- "ISA_HAS_DSP"
- "cmp<DSPV:dspfmt1_1>.lt.<DSPV:dspfmt2>\t%0,%1"
-- [(set_attr "type" "arith")
-+ [(set_attr "type" "dspalu")
- (set_attr "mode" "SI")])
-
- (define_insn "mips_cmp<DSPV:dspfmt1_1>_le_<DSPV:dspfmt2>"
-@@ -742,7 +742,7 @@
- UNSPEC_CMP_LE))]
- "ISA_HAS_DSP"
- "cmp<DSPV:dspfmt1_1>.le.<DSPV:dspfmt2>\t%0,%1"
-- [(set_attr "type" "arith")
-+ [(set_attr "type" "dspalu")
- (set_attr "mode" "SI")])
-
- (define_insn "mips_cmpgu_eq_qb"
-@@ -752,7 +752,7 @@
- UNSPEC_CMPGU_EQ_QB))]
- "ISA_HAS_DSP"
- "cmpgu.eq.qb\t%0,%1,%2"
-- [(set_attr "type" "arith")
-+ [(set_attr "type" "dspalu")
- (set_attr "mode" "SI")])
-
- (define_insn "mips_cmpgu_lt_qb"
-@@ -762,7 +762,7 @@
- UNSPEC_CMPGU_LT_QB))]
- "ISA_HAS_DSP"
- "cmpgu.lt.qb\t%0,%1,%2"
-- [(set_attr "type" "arith")
-+ [(set_attr "type" "dspalu")
- (set_attr "mode" "SI")])
-
- (define_insn "mips_cmpgu_le_qb"
-@@ -772,7 +772,7 @@
- UNSPEC_CMPGU_LE_QB))]
- "ISA_HAS_DSP"
- "cmpgu.le.qb\t%0,%1,%2"
-- [(set_attr "type" "arith")
-+ [(set_attr "type" "dspalu")
- (set_attr "mode" "SI")])
-
- ;; PICK*
-@@ -784,7 +784,7 @@
- UNSPEC_PICK))]
- "ISA_HAS_DSP"
- "pick.<DSPV:dspfmt2>\t%0,%1,%2"
-- [(set_attr "type" "arith")
-+ [(set_attr "type" "dspalu")
- (set_attr "mode" "SI")])
-
- ;; PACKRL*
-@@ -795,7 +795,7 @@
- UNSPEC_PACKRL_PH))]
- "ISA_HAS_DSP"
- "packrl.ph\t%0,%1,%2"
-- [(set_attr "type" "arith")
-+ [(set_attr "type" "dspalu")
- (set_attr "mode" "SI")])
-
- ;; Table 2-6. MIPS DSP ASE Instructions: Accumulator and DSPControl Access
-@@ -818,7 +818,7 @@
- }
- return "extrv.w\t%0,%q1,%2";
- }
-- [(set_attr "type" "mfhilo")
-+ [(set_attr "type" "accext")
- (set_attr "mode" "SI")])
-
- (define_insn "mips_extr_r_w"
-@@ -839,7 +839,7 @@
- }
- return "extrv_r.w\t%0,%q1,%2";
- }
-- [(set_attr "type" "mfhilo")
-+ [(set_attr "type" "accext")
- (set_attr "mode" "SI")])
-
- (define_insn "mips_extr_rs_w"
-@@ -860,7 +860,7 @@
- }
- return "extrv_rs.w\t%0,%q1,%2";
- }
-- [(set_attr "type" "mfhilo")
-+ [(set_attr "type" "accext")
- (set_attr "mode" "SI")])
-
- ;; EXTR*_S.H
-@@ -882,7 +882,7 @@
- }
- return "extrv_s.h\t%0,%q1,%2";
- }
-- [(set_attr "type" "mfhilo")
-+ [(set_attr "type" "accext")
- (set_attr "mode" "SI")])
-
- ;; EXTP*
-@@ -905,7 +905,7 @@
- }
- return "extpv\t%0,%q1,%2";
- }
-- [(set_attr "type" "mfhilo")
-+ [(set_attr "type" "accext")
- (set_attr "mode" "SI")])
-
- (define_insn "mips_extpdp"
-@@ -930,7 +930,7 @@
- }
- return "extpdpv\t%0,%q1,%2";
- }
-- [(set_attr "type" "mfhilo")
-+ [(set_attr "type" "accext")
- (set_attr "mode" "SI")])
-
- ;; SHILO*
-@@ -949,7 +949,7 @@
- }
- return "shilov\t%q0,%2";
- }
-- [(set_attr "type" "mfhilo")
-+ [(set_attr "type" "accmod")
- (set_attr "mode" "SI")])
-
- ;; MTHLIP*
-@@ -965,7 +965,7 @@
- (reg:CCDSP CCDSP_PO_REGNUM)] UNSPEC_MTHLIP))])]
- "ISA_HAS_DSP && !TARGET_64BIT"
- "mthlip\t%2,%q0"
-- [(set_attr "type" "mfhilo")
-+ [(set_attr "type" "accmod")
- (set_attr "mode" "SI")])
-
- ;; WRDSP
-@@ -987,7 +987,7 @@
- (unspec:CCDSP [(match_dup 0) (match_dup 1)] UNSPEC_WRDSP))])]
- "ISA_HAS_DSP"
- "wrdsp\t%0,%1"
-- [(set_attr "type" "arith")
-+ [(set_attr "type" "dspalu")
- (set_attr "mode" "SI")])
-
- ;; RDDSP
-@@ -1003,7 +1003,7 @@
- UNSPEC_RDDSP))]
- "ISA_HAS_DSP"
- "rddsp\t%0,%1"
-- [(set_attr "type" "arith")
-+ [(set_attr "type" "dspalu")
- (set_attr "mode" "SI")])
-
- ;; Table 2-7. MIPS DSP ASE Instructions: Indexed-Load
---- a/gcc/config/mips/mips-dspr2.md
-+++ b/gcc/config/mips/mips-dspr2.md
-@@ -9,7 +9,7 @@
- (unspec:CCDSP [(match_dup 1)] UNSPEC_ABSQ_S_QB))])]
- "ISA_HAS_DSPR2"
- "absq_s.qb\t%0,%z1"
-- [(set_attr "type" "arith")
-+ [(set_attr "type" "dspalusat")
- (set_attr "mode" "SI")])
-
- (define_insn "mips_addu_ph"
-@@ -21,7 +21,7 @@
- (unspec:CCDSP [(match_dup 1) (match_dup 2)] UNSPEC_ADDU_PH))])]
- "ISA_HAS_DSPR2"
- "addu.ph\t%0,%z1,%z2"
-- [(set_attr "type" "arith")
-+ [(set_attr "type" "dspalu")
- (set_attr "mode" "SI")])
-
- (define_insn "mips_addu_s_ph"
-@@ -34,7 +34,7 @@
- (unspec:CCDSP [(match_dup 1) (match_dup 2)] UNSPEC_ADDU_S_PH))])]
- "ISA_HAS_DSPR2"
- "addu_s.ph\t%0,%z1,%z2"
-- [(set_attr "type" "arith")
-+ [(set_attr "type" "dspalusat")
- (set_attr "mode" "SI")])
-
- (define_insn "mips_adduh_qb"
-@@ -44,7 +44,7 @@
- UNSPEC_ADDUH_QB))]
- "ISA_HAS_DSPR2"
- "adduh.qb\t%0,%z1,%z2"
-- [(set_attr "type" "arith")
-+ [(set_attr "type" "dspalu")
- (set_attr "mode" "SI")])
-
- (define_insn "mips_adduh_r_qb"
-@@ -54,7 +54,7 @@
- UNSPEC_ADDUH_R_QB))]
- "ISA_HAS_DSPR2"
- "adduh_r.qb\t%0,%z1,%z2"
-- [(set_attr "type" "arith")
-+ [(set_attr "type" "dspalusat")
- (set_attr "mode" "SI")])
-
- (define_insn "mips_append"
-@@ -69,7 +69,7 @@
- operands[2] = GEN_INT (INTVAL (operands[2]) & 31);
- return "append\t%0,%z2,%3";
- }
-- [(set_attr "type" "arith")
-+ [(set_attr "type" "dspalu")
- (set_attr "mode" "SI")])
-
- (define_insn "mips_balign"
-@@ -84,7 +84,7 @@
- operands[2] = GEN_INT (INTVAL (operands[2]) & 3);
- return "balign\t%0,%z2,%3";
- }
-- [(set_attr "type" "arith")
-+ [(set_attr "type" "dspalu")
- (set_attr "mode" "SI")])
-
- (define_insn "mips_cmpgdu_eq_qb"
-@@ -99,7 +99,7 @@
- UNSPEC_CMPGDU_EQ_QB))])]
- "ISA_HAS_DSPR2"
- "cmpgdu.eq.qb\t%0,%z1,%z2"
-- [(set_attr "type" "arith")
-+ [(set_attr "type" "dspalu")
- (set_attr "mode" "SI")])
-
- (define_insn "mips_cmpgdu_lt_qb"
-@@ -114,7 +114,7 @@
- UNSPEC_CMPGDU_LT_QB))])]
- "ISA_HAS_DSPR2"
- "cmpgdu.lt.qb\t%0,%z1,%z2"
-- [(set_attr "type" "arith")
-+ [(set_attr "type" "dspalu")
- (set_attr "mode" "SI")])
-
- (define_insn "mips_cmpgdu_le_qb"
-@@ -129,7 +129,7 @@
- UNSPEC_CMPGDU_LE_QB))])]
- "ISA_HAS_DSPR2"
- "cmpgdu.le.qb\t%0,%z1,%z2"
-- [(set_attr "type" "arith")
-+ [(set_attr "type" "dspalu")
- (set_attr "mode" "SI")])
-
- (define_insn "mips_dpa_w_ph"
-@@ -140,7 +140,7 @@
- UNSPEC_DPA_W_PH))]
- "ISA_HAS_DSPR2 && !TARGET_64BIT"
- "dpa.w.ph\t%q0,%z2,%z3"
-- [(set_attr "type" "imadd")
-+ [(set_attr "type" "dspmac")
- (set_attr "mode" "SI")])
-
- (define_insn "mips_dps_w_ph"
-@@ -151,7 +151,7 @@
- UNSPEC_DPS_W_PH))]
- "ISA_HAS_DSPR2 && !TARGET_64BIT"
- "dps.w.ph\t%q0,%z2,%z3"
-- [(set_attr "type" "imadd")
-+ [(set_attr "type" "dspmac")
- (set_attr "mode" "SI")])
-
- (define_expand "mips_madd<u>"
-@@ -247,7 +247,7 @@
- UNSPEC_MULSA_W_PH))]
- "ISA_HAS_DSPR2 && !TARGET_64BIT"
- "mulsa.w.ph\t%q0,%z2,%z3"
-- [(set_attr "type" "imadd")
-+ [(set_attr "type" "dspmac")
- (set_attr "mode" "SI")])
-
- (define_insn "mips_mult"
-@@ -277,7 +277,7 @@
- UNSPEC_PRECR_QB_PH))]
- "ISA_HAS_DSPR2"
- "precr.qb.ph\t%0,%z1,%z2"
-- [(set_attr "type" "arith")
-+ [(set_attr "type" "dspalu")
- (set_attr "mode" "SI")])
-
- (define_insn "mips_precr_sra_ph_w"
-@@ -292,7 +292,7 @@
- operands[2] = GEN_INT (INTVAL (operands[2]) & 31);
- return "precr_sra.ph.w\t%0,%z2,%3";
- }
-- [(set_attr "type" "arith")
-+ [(set_attr "type" "dspalu")
- (set_attr "mode" "SI")])
-
- (define_insn "mips_precr_sra_r_ph_w"
-@@ -307,7 +307,7 @@
- operands[2] = GEN_INT (INTVAL (operands[2]) & 31);
- return "precr_sra_r.ph.w\t%0,%z2,%3";
- }
-- [(set_attr "type" "arith")
-+ [(set_attr "type" "dspalu")
- (set_attr "mode" "SI")])
-
- (define_insn "mips_prepend"
-@@ -322,7 +322,7 @@
- operands[2] = GEN_INT (INTVAL (operands[2]) & 31);
- return "prepend\t%0,%z2,%3";
- }
-- [(set_attr "type" "arith")
-+ [(set_attr "type" "dspalu")
- (set_attr "mode" "SI")])
-
- (define_insn "mips_shra_qb"
-@@ -340,7 +340,7 @@
- }
- return "shrav.qb\t%0,%z1,%2";
- }
-- [(set_attr "type" "shift")
-+ [(set_attr "type" "dspalu")
- (set_attr "mode" "SI")])
-
-
-@@ -359,7 +359,7 @@
- }
- return "shrav_r.qb\t%0,%z1,%2";
- }
-- [(set_attr "type" "shift")
-+ [(set_attr "type" "dspalu")
- (set_attr "mode" "SI")])
-
- (define_insn "mips_shrl_ph"
-@@ -377,7 +377,7 @@
- }
- return "shrlv.ph\t%0,%z1,%2";
- }
-- [(set_attr "type" "shift")
-+ [(set_attr "type" "dspalu")
- (set_attr "mode" "SI")])
-
- (define_insn "mips_subu_ph"
-@@ -390,7 +390,7 @@
- (unspec:CCDSP [(match_dup 1) (match_dup 2)] UNSPEC_SUBU_PH))])]
- "ISA_HAS_DSPR2"
- "subu.ph\t%0,%z1,%z2"
-- [(set_attr "type" "arith")
-+ [(set_attr "type" "dspalu")
- (set_attr "mode" "SI")])
-
- (define_insn "mips_subu_s_ph"
-@@ -403,7 +403,7 @@
- (unspec:CCDSP [(match_dup 1) (match_dup 2)] UNSPEC_SUBU_S_PH))])]
- "ISA_HAS_DSPR2"
- "subu_s.ph\t%0,%z1,%z2"
-- [(set_attr "type" "arith")
-+ [(set_attr "type" "dspalusat")
- (set_attr "mode" "SI")])
-
- (define_insn "mips_subuh_qb"
-@@ -413,7 +413,7 @@
- UNSPEC_SUBUH_QB))]
- "ISA_HAS_DSPR2"
- "subuh.qb\t%0,%z1,%z2"
-- [(set_attr "type" "arith")
-+ [(set_attr "type" "dspalu")
- (set_attr "mode" "SI")])
-
- (define_insn "mips_subuh_r_qb"
-@@ -423,7 +423,7 @@
- UNSPEC_SUBUH_R_QB))]
- "ISA_HAS_DSPR2"
- "subuh_r.qb\t%0,%z1,%z2"
-- [(set_attr "type" "arith")
-+ [(set_attr "type" "dspalu")
- (set_attr "mode" "SI")])
-
- (define_insn "mips_addqh_ph"
-@@ -433,7 +433,7 @@
- UNSPEC_ADDQH_PH))]
- "ISA_HAS_DSPR2"
- "addqh.ph\t%0,%z1,%z2"
-- [(set_attr "type" "arith")
-+ [(set_attr "type" "dspalu")
- (set_attr "mode" "SI")])
-
- (define_insn "mips_addqh_r_ph"
-@@ -443,7 +443,7 @@
- UNSPEC_ADDQH_R_PH))]
- "ISA_HAS_DSPR2"
- "addqh_r.ph\t%0,%z1,%z2"
-- [(set_attr "type" "arith")
-+ [(set_attr "type" "dspalu")
- (set_attr "mode" "SI")])
-
- (define_insn "mips_addqh_w"
-@@ -453,7 +453,7 @@
- UNSPEC_ADDQH_W))]
- "ISA_HAS_DSPR2"
- "addqh.w\t%0,%z1,%z2"
-- [(set_attr "type" "arith")
-+ [(set_attr "type" "dspalu")
- (set_attr "mode" "SI")])
-
- (define_insn "mips_addqh_r_w"
-@@ -463,7 +463,7 @@
- UNSPEC_ADDQH_R_W))]
- "ISA_HAS_DSPR2"
- "addqh_r.w\t%0,%z1,%z2"
-- [(set_attr "type" "arith")
-+ [(set_attr "type" "dspalu")
- (set_attr "mode" "SI")])
-
- (define_insn "mips_subqh_ph"
-@@ -473,7 +473,7 @@
- UNSPEC_SUBQH_PH))]
- "ISA_HAS_DSPR2"
- "subqh.ph\t%0,%z1,%z2"
-- [(set_attr "type" "arith")
-+ [(set_attr "type" "dspalu")
- (set_attr "mode" "SI")])
-
- (define_insn "mips_subqh_r_ph"
-@@ -483,7 +483,7 @@
- UNSPEC_SUBQH_R_PH))]
- "ISA_HAS_DSPR2"
- "subqh_r.ph\t%0,%z1,%z2"
-- [(set_attr "type" "arith")
-+ [(set_attr "type" "dspalu")
- (set_attr "mode" "SI")])
-
- (define_insn "mips_subqh_w"
-@@ -493,7 +493,7 @@
- UNSPEC_SUBQH_W))]
- "ISA_HAS_DSPR2"
- "subqh.w\t%0,%z1,%z2"
-- [(set_attr "type" "arith")
-+ [(set_attr "type" "dspalu")
- (set_attr "mode" "SI")])
-
- (define_insn "mips_subqh_r_w"
-@@ -503,7 +503,7 @@
- UNSPEC_SUBQH_R_W))]
- "ISA_HAS_DSPR2"
- "subqh_r.w\t%0,%z1,%z2"
-- [(set_attr "type" "arith")
-+ [(set_attr "type" "dspalu")
- (set_attr "mode" "SI")])
-
- (define_insn "mips_dpax_w_ph"
-@@ -514,7 +514,7 @@
- UNSPEC_DPAX_W_PH))]
- "ISA_HAS_DSPR2 && !TARGET_64BIT"
- "dpax.w.ph\t%q0,%z2,%z3"
-- [(set_attr "type" "imadd")
-+ [(set_attr "type" "dspmac")
- (set_attr "mode" "SI")])
-
- (define_insn "mips_dpsx_w_ph"
-@@ -525,7 +525,7 @@
- UNSPEC_DPSX_W_PH))]
- "ISA_HAS_DSPR2 && !TARGET_64BIT"
- "dpsx.w.ph\t%q0,%z2,%z3"
-- [(set_attr "type" "imadd")
-+ [(set_attr "type" "dspmac")
- (set_attr "mode" "SI")])
-
- (define_insn "mips_dpaqx_s_w_ph"
-@@ -540,7 +540,7 @@
- UNSPEC_DPAQX_S_W_PH))])]
- "ISA_HAS_DSPR2 && !TARGET_64BIT"
- "dpaqx_s.w.ph\t%q0,%z2,%z3"
-- [(set_attr "type" "imadd")
-+ [(set_attr "type" "dspmac")
- (set_attr "mode" "SI")])
-
- (define_insn "mips_dpaqx_sa_w_ph"
-@@ -555,7 +555,7 @@
- UNSPEC_DPAQX_SA_W_PH))])]
- "ISA_HAS_DSPR2 && !TARGET_64BIT"
- "dpaqx_sa.w.ph\t%q0,%z2,%z3"
-- [(set_attr "type" "imadd")
-+ [(set_attr "type" "dspmacsat")
- (set_attr "mode" "SI")])
-
- (define_insn "mips_dpsqx_s_w_ph"
-@@ -570,7 +570,7 @@
- UNSPEC_DPSQX_S_W_PH))])]
- "ISA_HAS_DSPR2 && !TARGET_64BIT"
- "dpsqx_s.w.ph\t%q0,%z2,%z3"
-- [(set_attr "type" "imadd")
-+ [(set_attr "type" "dspmac")
- (set_attr "mode" "SI")])
-
- (define_insn "mips_dpsqx_sa_w_ph"
-@@ -585,5 +585,43 @@
- UNSPEC_DPSQX_SA_W_PH))])]
- "ISA_HAS_DSPR2 && !TARGET_64BIT"
- "dpsqx_sa.w.ph\t%q0,%z2,%z3"
-- [(set_attr "type" "imadd")
-+ [(set_attr "type" "dspmacsat")
-+ (set_attr "mode" "SI")])
-+
-+;; Convert mtlo $ac[1-3],$0 => mult $ac[1-3],$0,$0
-+;; mthi $ac[1-3],$0
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (const_int 0))
-+ (set (match_operand:SI 1 "register_operand" "")
-+ (const_int 0))]
-+ "ISA_HAS_DSPR2
-+ && !TARGET_MIPS16
-+ && !TARGET_64BIT
-+ && (((true_regnum (operands[0]) == AC1LO_REGNUM
-+ && true_regnum (operands[1]) == AC1HI_REGNUM)
-+ || (true_regnum (operands[0]) == AC1HI_REGNUM
-+ && true_regnum (operands[1]) == AC1LO_REGNUM))
-+ || ((true_regnum (operands[0]) == AC2LO_REGNUM
-+ && true_regnum (operands[1]) == AC2HI_REGNUM)
-+ || (true_regnum (operands[0]) == AC2HI_REGNUM
-+ && true_regnum (operands[1]) == AC2LO_REGNUM))
-+ || ((true_regnum (operands[0]) == AC3LO_REGNUM
-+ && true_regnum (operands[1]) == AC3HI_REGNUM)
-+ || (true_regnum (operands[0]) == AC3HI_REGNUM
-+ && true_regnum (operands[1]) == AC3LO_REGNUM)))"
-+ [(parallel [(set (match_dup 0) (const_int 0))
-+ (set (match_dup 1) (const_int 0))])]
-+)
-+
-+(define_insn "*mips_acc_init"
-+ [(parallel [(set (match_operand:SI 0 "register_operand" "=a")
-+ (const_int 0))
-+ (set (match_operand:SI 1 "register_operand" "=a")
-+ (const_int 0))])]
-+ "ISA_HAS_DSPR2
-+ && !TARGET_MIPS16
-+ && !TARGET_64BIT"
-+ "mult\t%q0,$0,$0\t\t# Clear ACC HI/LO"
-+ [(set_attr "type" "imul")
- (set_attr "mode" "SI")])
---- a/gcc/config/mips/mips-protos.h
-+++ b/gcc/config/mips/mips-protos.h
-@@ -261,6 +261,8 @@ extern void mips_print_operand_address (
- extern void mips_output_external (FILE *, tree, const char *);
- extern void mips_output_filename (FILE *, const char *);
- extern void mips_output_ascii (FILE *, const char *, size_t);
-+extern void octeon_output_shared_variable (FILE *, tree, const char *,
-+ unsigned HOST_WIDE_INT, int);
- extern void mips_output_aligned_decl_common (FILE *, tree, const char *,
- unsigned HOST_WIDE_INT,
- unsigned int);
-@@ -307,6 +309,8 @@ extern unsigned int mips_hard_regno_nreg
- extern bool mips_linked_madd_p (rtx, rtx);
- extern bool mips_store_data_bypass_p (rtx, rtx);
- extern rtx mips_prefetch_cookie (rtx, rtx);
-+extern int mips_mult_madd_chain_bypass_p (rtx, rtx);
-+extern int mips_dspalu_bypass_p (rtx, rtx);
-
- extern void irix_asm_output_align (FILE *, unsigned);
- extern const char *current_section_name (void);
-@@ -332,4 +336,6 @@ extern void mips_expand_atomic_qihi (uni
-
- extern void mips_expand_vector_init (rtx, rtx);
-
-+extern bool mips_epilogue_uses (unsigned int);
-+
- #endif /* ! GCC_MIPS_PROTOS_H */
---- a/gcc/config/mips/mips.c
-+++ b/gcc/config/mips/mips.c
-@@ -261,18 +261,29 @@ struct mips_frame_info GTY(()) {
- /* Likewise FPR X. */
- unsigned int fmask;
-
-- /* The number of GPRs and FPRs saved. */
-+ /* Likewise doubleword accumulator X ($acX). */
-+ unsigned int acc_mask;
-+
-+ /* The number of GPRs, FPRs, doubleword accumulators and COP0
-+ registers saved. */
- unsigned int num_gp;
- unsigned int num_fp;
-+ unsigned int num_acc;
-+ unsigned int num_cop0_regs;
-
-- /* The offset of the topmost GPR and FPR save slots from the top of
-- the frame, or zero if no such slots are needed. */
-+ /* The offset of the topmost GPR, FPR, accumulator and COP0-register
-+ save slots from the top of the frame, or zero if no such slots are
-+ needed. */
- HOST_WIDE_INT gp_save_offset;
- HOST_WIDE_INT fp_save_offset;
-+ HOST_WIDE_INT acc_save_offset;
-+ HOST_WIDE_INT cop0_save_offset;
-
- /* Likewise, but giving offsets from the bottom of the frame. */
- HOST_WIDE_INT gp_sp_offset;
- HOST_WIDE_INT fp_sp_offset;
-+ HOST_WIDE_INT acc_sp_offset;
-+ HOST_WIDE_INT cop0_sp_offset;
-
- /* The offset of arg_pointer_rtx from frame_pointer_rtx. */
- HOST_WIDE_INT arg_pointer_offset;
-@@ -310,6 +321,20 @@ struct machine_function GTY(()) {
- /* True if we have emitted an instruction to initialize
- mips16_gp_pseudo_rtx. */
- bool initialized_mips16_gp_pseudo_p;
-+
-+ /* True if this is an interrupt handler. */
-+ bool interrupt_handler_p;
-+
-+ /* True if this is an interrupt handler that uses shadow registers. */
-+ bool use_shadow_register_set_p;
-+
-+ /* True if this is an interrupt handler that should keep interrupts
-+ masked. */
-+ bool keep_interrupts_masked_p;
-+
-+ /* True if this is an interrupt handler that should use DERET
-+ instead of ERET. */
-+ bool use_debug_exception_return_p;
- };
-
- /* Information about a single argument. */
-@@ -542,9 +567,16 @@ const enum reg_class mips_regno_to_class
- ALL_REGS, ALL_REGS, ALL_REGS, ALL_REGS
- };
-
-+#ifdef CVMX_SHARED_BSS_FLAGS
-+static tree octeon_handle_cvmx_shared_attribute (tree *, tree, tree, int, bool *);
-+#endif
-+
- /* The value of TARGET_ATTRIBUTE_TABLE. */
- const struct attribute_spec mips_attribute_table[] = {
- /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
-+#ifdef CVMX_SHARED_BSS_FLAGS
-+ { "cvmx_shared", 0, 0, true, false, false, octeon_handle_cvmx_shared_attribute },
-+#endif
- { "long_call", 0, 0, false, true, true, NULL },
- { "far", 0, 0, false, true, true, NULL },
- { "near", 0, 0, false, true, true, NULL },
-@@ -554,6 +586,11 @@ const struct attribute_spec mips_attribu
- code generation but don't carry other semantics. */
- { "mips16", 0, 0, true, false, false, NULL },
- { "nomips16", 0, 0, true, false, false, NULL },
-+ /* Allow functions to be specified as interrupt handlers */
-+ { "interrupt", 0, 0, false, true, true, NULL },
-+ { "use_shadow_register_set", 0, 0, false, true, true, NULL },
-+ { "keep_interrupts_masked", 0, 0, false, true, true, NULL },
-+ { "use_debug_exception_return", 0, 0, false, true, true, NULL },
- { NULL, 0, 0, false, false, false, NULL }
- };
- \f
-@@ -659,6 +696,11 @@ static const struct mips_cpu_info mips_c
- { "74kx", PROCESSOR_74KF1_1, 33, 0 },
- { "74kf3_2", PROCESSOR_74KF3_2, 33, 0 },
-
-+ { "1004kc", PROCESSOR_24KC, 33, 0 }, /* 1004K with MT/DSP. */
-+ { "1004kf2_1", PROCESSOR_24KF2_1, 33, 0 },
-+ { "1004kf", PROCESSOR_24KF2_1, 33, 0 },
-+ { "1004kf1_1", PROCESSOR_24KF1_1, 33, 0 },
-+
- /* MIPS64 processors. */
- { "5kc", PROCESSOR_5KC, 64, 0 },
- { "5kf", PROCESSOR_5KF, 64, 0 },
-@@ -1064,13 +1106,7 @@ static const struct mips_rtx_cost_data m
- DEFAULT_COSTS
- },
- { /* XLR */
-- /* Need to replace first five with the costs of calling the appropriate
-- libgcc routine. */
-- COSTS_N_INSNS (256), /* fp_add */
-- COSTS_N_INSNS (256), /* fp_mult_sf */
-- COSTS_N_INSNS (256), /* fp_mult_df */
-- COSTS_N_INSNS (256), /* fp_div_sf */
-- COSTS_N_INSNS (256), /* fp_div_df */
-+ SOFT_FP_COSTS,
- COSTS_N_INSNS (8), /* int_mult_si */
- COSTS_N_INSNS (8), /* int_mult_di */
- COSTS_N_INSNS (72), /* int_div_si */
-@@ -1172,6 +1208,42 @@ mips_nomips16_decl_p (const_tree decl)
- return lookup_attribute ("nomips16", DECL_ATTRIBUTES (decl)) != NULL;
- }
-
-+/* Check if the interrupt attribute is set for a function. */
-+
-+static bool
-+mips_interrupt_type_p (tree type)
-+{
-+ return lookup_attribute ("interrupt", TYPE_ATTRIBUTES (type)) != NULL;
-+}
-+
-+/* Check if the attribute to use shadow register set is set for a function. */
-+
-+static bool
-+mips_use_shadow_register_set_p (tree type)
-+{
-+ return lookup_attribute ("use_shadow_register_set",
-+ TYPE_ATTRIBUTES (type)) != NULL;
-+}
-+
-+/* Check if the attribute to keep interrupts masked is set for a function. */
-+
-+static bool
-+mips_keep_interrupts_masked_p (tree type)
-+{
-+ return lookup_attribute ("keep_interrupts_masked",
-+ TYPE_ATTRIBUTES (type)) != NULL;
-+}
-+
-+/* Check if the attribute to use debug exception return is set for
-+ a function. */
-+
-+static bool
-+mips_use_debug_exception_return_p (tree type)
-+{
-+ return lookup_attribute ("use_debug_exception_return",
-+ TYPE_ATTRIBUTES (type)) != NULL;
-+}
-+
- /* Return true if function DECL is a MIPS16 function. Return the ambient
- setting if DECL is null. */
-
-@@ -2817,7 +2889,7 @@ bool
- mips_legitimize_address (rtx *xloc, enum machine_mode mode)
- {
- rtx base, addr;
-- HOST_WIDE_INT offset;
-+ HOST_WIDE_INT intval, high, offset;
-
- if (mips_tls_symbol_p (*xloc))
- {
-@@ -2842,6 +2914,32 @@ mips_legitimize_address (rtx *xloc, enum
- *xloc = mips_force_address (addr, mode);
- return true;
- }
-+
-+ /* Handle references to constant addresses by loading the high part
-+ into a register and using an offset for the low part. */
-+ if (GET_CODE (base) == CONST_INT)
-+ {
-+ intval = INTVAL (base);
-+ high = trunc_int_for_mode (CONST_HIGH_PART (intval), Pmode);
-+ offset = CONST_LOW_PART (intval);
-+ /* Ignore cases in which a positive address would be accessed by a
-+ negative offset from a negative address. The required wraparound
-+ does not occur for 32-bit addresses on 64-bit targets, and it is
-+ very unlikely that such an access would occur in real code anyway.
-+
-+ If the low offset is not legitimate for MODE, prefer to load
-+ the constant normally, instead of using mips_force_address on
-+ the legitimized address. The latter option would cause us to
-+ use (D)ADDIU unconditionally, but LUI/ORI is more efficient
-+ than LUI/ADDIU on some targets. */
-+ if ((intval < 0 || high > 0)
-+ && mips_valid_offset_p (GEN_INT (offset), mode))
-+ {
-+ base = mips_force_temporary (NULL, GEN_INT (high));
-+ *xloc = plus_constant (base, offset);
-+ return true;
-+ }
-+ }
- return false;
- }
-
-@@ -6210,6 +6308,11 @@ mips_function_ok_for_sibcall (tree decl,
- if (!TARGET_SIBCALLS)
- return false;
-
-+ /* Interrupt handlers need special epilogue code and therefore can't
-+ use sibcalls. */
-+ if (mips_interrupt_type_p (TREE_TYPE (current_function_decl)))
-+ return false;
-+
- /* We can't do a sibcall if the called function is a MIPS16 function
- because there is no direct "jx" instruction equivalent to "jalx" to
- switch the ISA mode. We only care about cases where the sibling
-@@ -6655,6 +6758,15 @@ mips_expand_ext_as_unaligned_load (rtx d
- if (!mips_get_unaligned_mem (&src, width, bitpos, &left, &right))
- return false;
-
-+ if (ISA_HAS_UL_US)
-+ {
-+ if (GET_MODE (dest) == DImode)
-+ emit_insn (gen_mov_uld (dest, src, left));
-+ else
-+ emit_insn (gen_mov_ulw (dest, src, left));
-+ return true;
-+ }
-+
- temp = gen_reg_rtx (GET_MODE (dest));
- if (GET_MODE (dest) == DImode)
- {
-@@ -6689,6 +6801,16 @@ mips_expand_ins_as_unaligned_store (rtx
-
- mode = mode_for_size (width, MODE_INT, 0);
- src = gen_lowpart (mode, src);
-+
-+ if (ISA_HAS_UL_US)
-+ {
-+ if (GET_MODE (src) == DImode)
-+ emit_insn (gen_mov_usd (dest, src, left));
-+ else
-+ emit_insn (gen_mov_usw (dest, src, left));
-+ return true;
-+ }
-+
- if (mode == DImode)
- {
- emit_insn (gen_mov_sdl (dest, src, left));
-@@ -7276,7 +7398,11 @@ mips_print_operand (FILE *file, rtx op,
- || (letter == 'L' && TARGET_BIG_ENDIAN)
- || letter == 'D')
- regno++;
-- fprintf (file, "%s", reg_names[regno]);
-+ /* We need to print $0 .. $31 for COP0 registers. */
-+ if (COP0_REG_P (regno))
-+ fprintf (file, "$%s", ®_names[regno][4]);
-+ else
-+ fprintf (file, "%s", reg_names[regno]);
- }
- break;
-
-@@ -7416,6 +7542,12 @@ mips_in_small_data_p (const_tree decl)
- if (TARGET_ABICALLS || TARGET_VXWORKS_RTP)
- return false;
-
-+#ifdef CVMX_SHARED_BSS_FLAGS
-+ if (TARGET_OCTEON && TREE_CODE (decl) == VAR_DECL
-+ && lookup_attribute ("cvmx_shared", DECL_ATTRIBUTES (decl)))
-+ return false;
-+#endif
-+
- if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl) != 0)
- {
- const char *name;
-@@ -7642,6 +7774,37 @@ mips_dwarf_register_span (rtx reg)
- return NULL_RTX;
- }
-
-+/* DSP ALU can bypass data with no delays for the following pairs. */
-+enum insn_code dspalu_bypass_table[][2] =
-+{
-+ {CODE_FOR_mips_addsc, CODE_FOR_mips_addwc},
-+ {CODE_FOR_mips_cmpu_eq_qb, CODE_FOR_mips_pick_qb},
-+ {CODE_FOR_mips_cmpu_lt_qb, CODE_FOR_mips_pick_qb},
-+ {CODE_FOR_mips_cmpu_le_qb, CODE_FOR_mips_pick_qb},
-+ {CODE_FOR_mips_cmp_eq_ph, CODE_FOR_mips_pick_ph},
-+ {CODE_FOR_mips_cmp_lt_ph, CODE_FOR_mips_pick_ph},
-+ {CODE_FOR_mips_cmp_le_ph, CODE_FOR_mips_pick_ph},
-+ {CODE_FOR_mips_wrdsp, CODE_FOR_mips_insv}
-+};
-+
-+int
-+mips_dspalu_bypass_p (rtx out_insn, rtx in_insn)
-+{
-+ int i;
-+ int num_bypass = (sizeof (dspalu_bypass_table)
-+ / (2 * sizeof (enum insn_code)));
-+ enum insn_code out_icode = INSN_CODE (out_insn);
-+ enum insn_code in_icode = INSN_CODE (in_insn);
-+
-+ for (i = 0; i < num_bypass; i++)
-+ {
-+ if (out_icode == dspalu_bypass_table[i][0]
-+ && in_icode == dspalu_bypass_table[i][1])
-+ return true;
-+ }
-+
-+ return false;
-+}
- /* Implement ASM_OUTPUT_ASCII. */
-
- void
-@@ -7866,11 +8029,19 @@ mips_file_start (void)
- "\t.previous\n", TARGET_LONG64 ? 64 : 32);
-
- #ifdef HAVE_AS_GNU_ATTRIBUTE
-+#ifdef TARGET_MIPS_SDEMTK
-+ fprintf (asm_out_file, "\t.gnu_attribute 4, %d\n",
-+ (!TARGET_NO_FLOAT
-+ ? (TARGET_HARD_FLOAT
-+ ? (TARGET_DOUBLE_FLOAT
-+ ? ((!TARGET_64BIT && TARGET_FLOAT64) ? 4 : 1) : 2) : 3) : 0));
-+#else
- fprintf (asm_out_file, "\t.gnu_attribute 4, %d\n",
- (TARGET_HARD_FLOAT_ABI
- ? (TARGET_DOUBLE_FLOAT
- ? ((!TARGET_64BIT && TARGET_FLOAT64) ? 4 : 1) : 2) : 3));
- #endif
-+#endif
- }
-
- /* If TARGET_ABICALLS, tell GAS to generate -KPIC code. */
-@@ -8483,12 +8654,53 @@ mips_global_pointer (void)
- return GLOBAL_POINTER_REGNUM;
- }
-
-+/* Return true if REGNO is a register that is ordinarily call-clobbered
-+ but must nevertheless be preserved by an interrupt handler. */
-+
-+static bool
-+mips_interrupt_extra_call_saved_reg_p (unsigned int regno)
-+{
-+ if (MD_REG_P (regno))
-+ return true;
-+
-+ if (TARGET_DSP && DSP_ACC_REG_P (regno))
-+ return true;
-+
-+ if (GP_REG_P (regno) && !cfun->machine->use_shadow_register_set_p)
-+ {
-+ /* $0 is hard-wired. */
-+ if (regno == GP_REG_FIRST)
-+ return false;
-+
-+ /* The interrupt handler can treat kernel registers as
-+ scratch registers. */
-+ if (KERNEL_REG_P (regno))
-+ return false;
-+
-+ /* The function will return the stack pointer to its original value
-+ anyway. */
-+ if (regno == STACK_POINTER_REGNUM)
-+ return false;
-+
-+ /* Otherwise, return true for registers that aren't ordinarily
-+ call-clobbered. */
-+ return call_really_used_regs[regno];
-+ }
-+
-+ return false;
-+}
-+
- /* Return true if the current function should treat register REGNO
- as call-saved. */
-
- static bool
- mips_cfun_call_saved_reg_p (unsigned int regno)
- {
-+ /* Interrupt handlers need to save extra registers. */
-+ if (cfun->machine->interrupt_handler_p
-+ && mips_interrupt_extra_call_saved_reg_p (regno))
-+ return true;
-+
- /* call_insns preserve $28 unless they explicitly say otherwise,
- so call_really_used_regs[] treats $28 as call-saved. However,
- we want the ABI property rather than the default call_insn
-@@ -8537,6 +8749,13 @@ mips_cfun_might_clobber_call_saved_reg_p
- if (regno == GP_REG_FIRST + 31 && mips16_cfun_returns_in_fpr_p ())
- return true;
-
-+ /* If REGNO is ordinarily call-clobbered, we must assume that any
-+ called function could modify it. */
-+ if (cfun->machine->interrupt_handler_p
-+ && !current_function_is_leaf
-+ && mips_interrupt_extra_call_saved_reg_p (regno))
-+ return true;
-+
- return false;
- }
-
-@@ -8592,6 +8811,14 @@ mips_save_reg_p (unsigned int regno)
- C | callee-allocated save area |
- | for register varargs |
- | |
-+ +-------------------------------+ <-- frame_pointer_rtx
-+ | | + cop0_sp_offset
-+ | COP0 reg save area | + UNITS_PER_WORD
-+ | |
-+ +-------------------------------+ <-- frame_pointer_rtx + acc_sp_offset
-+ | | + UNITS_PER_WORD
-+ | accumulator save area |
-+ | |
- +-------------------------------+ <-- frame_pointer_rtx + fp_sp_offset
- | | + UNITS_PER_HWFPVALUE
- | FPR save area |
-@@ -8635,6 +8862,28 @@ mips_compute_frame_info (void)
- HOST_WIDE_INT offset, size;
- unsigned int regno, i;
-
-+ /* Set this function's interrupt properties. */
-+ if (mips_interrupt_type_p (TREE_TYPE (current_function_decl)))
-+ {
-+ if (!ISA_MIPS32R2)
-+ error ("the %<interrupt%> attribute requires a MIPS32r2 processor");
-+ else if (TARGET_HARD_FLOAT)
-+ error ("the %<interrupt%> attribute requires %<-msoft-float%>");
-+ else if (TARGET_MIPS16)
-+ error ("interrupt handlers cannot be MIPS16 functions");
-+ else
-+ {
-+ cfun->machine->interrupt_handler_p = true;
-+ cfun->machine->use_shadow_register_set_p =
-+ mips_use_shadow_register_set_p (TREE_TYPE (current_function_decl));
-+ cfun->machine->keep_interrupts_masked_p =
-+ mips_keep_interrupts_masked_p (TREE_TYPE (current_function_decl));
-+ cfun->machine->use_debug_exception_return_p =
-+ mips_use_debug_exception_return_p (TREE_TYPE
-+ (current_function_decl));
-+ }
-+ }
-+
- frame = &cfun->machine->frame;
- memset (frame, 0, sizeof (*frame));
- size = get_frame_size ();
-@@ -8704,7 +8953,7 @@ mips_compute_frame_info (void)
- }
-
- /* Find out which FPRs we need to save. This loop must iterate over
-- the same space as its companion in mips_for_each_saved_reg. */
-+ the same space as its companion in mips_for_each_saved_gpr_and_fpr. */
- if (TARGET_HARD_FLOAT)
- for (regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno += MAX_FPRS_PER_FMT)
- if (mips_save_reg_p (regno))
-@@ -8720,6 +8969,47 @@ mips_compute_frame_info (void)
- frame->fp_sp_offset = offset - UNITS_PER_HWFPVALUE;
- }
-
-+ /* Add in space for the interrupt context information. */
-+ if (cfun->machine->interrupt_handler_p)
-+ {
-+ /* Check HI/LO. */
-+ if (mips_save_reg_p (LO_REGNUM) || mips_save_reg_p (HI_REGNUM))
-+ {
-+ frame->num_acc++;
-+ frame->acc_mask |= (1 << 0);
-+ }
-+
-+ /* Check accumulators 1, 2, 3. */
-+ for (i = DSP_ACC_REG_FIRST; i <= DSP_ACC_REG_LAST; i += 2)
-+ if (mips_save_reg_p (i) || mips_save_reg_p (i + 1))
-+ {
-+ frame->num_acc++;
-+ frame->acc_mask |= 1 << (((i - DSP_ACC_REG_FIRST) / 2) + 1);
-+ }
-+
-+ /* All interrupt context functions need space to preserve STATUS. */
-+ frame->num_cop0_regs++;
-+
-+ /* If we don't keep interrupts masked, we need to save EPC. */
-+ if (!cfun->machine->keep_interrupts_masked_p)
-+ frame->num_cop0_regs++;
-+ }
-+
-+ /* Move above the accumulator save area. */
-+ if (frame->num_acc > 0)
-+ {
-+ /* Each accumulator needs 2 words. */
-+ offset += frame->num_acc * 2 * UNITS_PER_WORD;
-+ frame->acc_sp_offset = offset - UNITS_PER_WORD;
-+ }
-+
-+ /* Move above the COP0 register save area. */
-+ if (frame->num_cop0_regs > 0)
-+ {
-+ offset += frame->num_cop0_regs * UNITS_PER_WORD;
-+ frame->cop0_sp_offset = offset - UNITS_PER_WORD;
-+ }
-+
- /* Move above the callee-allocated varargs save area. */
- offset += MIPS_STACK_ALIGN (cfun->machine->varargs_size);
- frame->arg_pointer_offset = offset;
-@@ -8733,6 +9023,10 @@ mips_compute_frame_info (void)
- frame->gp_save_offset = frame->gp_sp_offset - offset;
- if (frame->fp_sp_offset > 0)
- frame->fp_save_offset = frame->fp_sp_offset - offset;
-+ if (frame->acc_sp_offset > 0)
-+ frame->acc_save_offset = frame->acc_sp_offset - offset;
-+ if (frame->num_cop0_regs > 0)
-+ frame->cop0_save_offset = frame->cop0_sp_offset - offset;
-
- /* MIPS16 code offsets the frame pointer by the size of the outgoing
- arguments. This tends to increase the chances of using unextended
-@@ -8929,12 +9223,41 @@ mips_save_restore_reg (enum machine_mode
- fn (gen_rtx_REG (mode, regno), mem);
- }
-
-+/* Call FN for each accumlator that is saved by the current function.
-+ SP_OFFSET is the offset of the current stack pointer from the start
-+ of the frame. */
-+
-+static void
-+mips_for_each_saved_acc (HOST_WIDE_INT sp_offset, mips_save_restore_fn fn)
-+{
-+ HOST_WIDE_INT offset;
-+ int regno;
-+
-+ offset = cfun->machine->frame.acc_sp_offset - sp_offset;
-+ if (BITSET_P (cfun->machine->frame.acc_mask, 0))
-+ {
-+ mips_save_restore_reg (word_mode, LO_REGNUM, offset, fn);
-+ offset -= UNITS_PER_WORD;
-+ mips_save_restore_reg (word_mode, HI_REGNUM, offset, fn);
-+ offset -= UNITS_PER_WORD;
-+ }
-+
-+ for (regno = DSP_ACC_REG_FIRST; regno <= DSP_ACC_REG_LAST; regno++)
-+ if (BITSET_P (cfun->machine->frame.acc_mask,
-+ ((regno - DSP_ACC_REG_FIRST) / 2) + 1))
-+ {
-+ mips_save_restore_reg (word_mode, regno, offset, fn);
-+ offset -= UNITS_PER_WORD;
-+ }
-+}
-+
- /* Call FN for each register that is saved by the current function.
- SP_OFFSET is the offset of the current stack pointer from the start
- of the frame. */
-
- static void
--mips_for_each_saved_reg (HOST_WIDE_INT sp_offset, mips_save_restore_fn fn)
-+mips_for_each_saved_gpr_and_fpr (HOST_WIDE_INT sp_offset,
-+ mips_save_restore_fn fn)
- {
- enum machine_mode fpr_mode;
- HOST_WIDE_INT offset;
-@@ -9122,13 +9445,24 @@ mips_save_reg (rtx reg, rtx mem)
- }
- else
- {
-- if (TARGET_MIPS16
-- && REGNO (reg) != GP_REG_FIRST + 31
-- && !M16_REG_P (REGNO (reg)))
-- {
-- /* Save a non-MIPS16 register by moving it through a temporary.
-- We don't need to do this for $31 since there's a special
-- instruction for it. */
-+ if (REGNO (reg) == HI_REGNUM)
-+ {
-+ if (TARGET_64BIT)
-+ emit_insn (gen_mfhidi_ti (MIPS_PROLOGUE_TEMP (DImode),
-+ gen_rtx_REG (TImode, MD_REG_FIRST)));
-+ else
-+ emit_insn (gen_mfhisi_di (MIPS_PROLOGUE_TEMP (SImode),
-+ gen_rtx_REG (DImode, MD_REG_FIRST)));
-+ mips_emit_move (mem, MIPS_PROLOGUE_TEMP (GET_MODE (reg)));
-+ }
-+ else if ((TARGET_MIPS16
-+ && REGNO (reg) != GP_REG_FIRST + 31
-+ && !M16_REG_P (REGNO (reg)))
-+ || ACC_REG_P (REGNO (reg)))
-+ {
-+ /* If the register has no direct store instruction, move it
-+ through a temporary. Note that there's a special MIPS16
-+ instruction to save $31. */
- mips_emit_move (MIPS_PROLOGUE_TEMP (GET_MODE (reg)), reg);
- mips_emit_move (mem, MIPS_PROLOGUE_TEMP (GET_MODE (reg)));
- }
-@@ -9200,6 +9534,14 @@ mips_emit_loadgp (void)
- emit_insn (gen_loadgp_blockage ());
- }
-
-+/* A for_each_rtx callback. Stop the search if *X is a kernel register. */
-+
-+static int
-+mips_kernel_reg_p (rtx *x, void *data ATTRIBUTE_UNUSED)
-+{
-+ return GET_CODE (*x) == REG && KERNEL_REG_P (REGNO (*x));
-+}
-+
- /* Expand the "prologue" pattern. */
-
- void
-@@ -9219,7 +9561,8 @@ mips_expand_prologue (void)
- /* Save the registers. Allocate up to MIPS_MAX_FIRST_STACK_STEP
- bytes beforehand; this is enough to cover the register save area
- without going out of range. */
-- if ((frame->mask | frame->fmask) != 0)
-+ if (((frame->mask | frame->fmask | frame->acc_mask) != 0)
-+ || frame->num_cop0_regs > 0)
- {
- HOST_WIDE_INT step1;
-
-@@ -9250,12 +9593,97 @@ mips_expand_prologue (void)
- }
- else
- {
-- insn = gen_add3_insn (stack_pointer_rtx,
-- stack_pointer_rtx,
-- GEN_INT (-step1));
-- RTX_FRAME_RELATED_P (emit_insn (insn)) = 1;
-- size -= step1;
-- mips_for_each_saved_reg (size, mips_save_reg);
-+ if (cfun->machine->interrupt_handler_p)
-+ {
-+ HOST_WIDE_INT offset;
-+ rtx mem;
-+
-+ /* If this interrupt is using a shadow register set, we need to
-+ get the stack pointer from the previous register set. */
-+ if (cfun->machine->use_shadow_register_set_p)
-+ emit_insn (gen_mips_rdpgpr (stack_pointer_rtx,
-+ stack_pointer_rtx));
-+
-+ if (!cfun->machine->keep_interrupts_masked_p)
-+ {
-+ /* Move from COP0 Cause to K0. */
-+ emit_insn (gen_cop0_move (gen_rtx_REG (SImode, K0_REG_NUM),
-+ gen_rtx_REG (SImode,
-+ COP0_CAUSE_REG_NUM)));
-+ /* Move from COP0 EPC to K1. */
-+ emit_insn (gen_cop0_move (gen_rtx_REG (SImode, K1_REG_NUM),
-+ gen_rtx_REG (SImode,
-+ COP0_EPC_REG_NUM)));
-+ }
-+
-+ /* Allocate the first part of the frame. */
-+ insn = gen_add3_insn (stack_pointer_rtx, stack_pointer_rtx,
-+ GEN_INT (-step1));
-+ RTX_FRAME_RELATED_P (emit_insn (insn)) = 1;
-+ size -= step1;
-+
-+ /* Start at the uppermost location for saving. */
-+ offset = frame->cop0_sp_offset - size;
-+ if (!cfun->machine->keep_interrupts_masked_p)
-+ {
-+ /* Push EPC into its stack slot. */
-+ mem = gen_frame_mem (word_mode,
-+ plus_constant (stack_pointer_rtx,
-+ offset));
-+ mips_emit_move (mem, gen_rtx_REG (word_mode, K1_REG_NUM));
-+ offset -= UNITS_PER_WORD;
-+ }
-+
-+ /* Move from COP0 Status to K1. */
-+ emit_insn (gen_cop0_move (gen_rtx_REG (SImode, K1_REG_NUM),
-+ gen_rtx_REG (SImode,
-+ COP0_STATUS_REG_NUM)));
-+
-+ /* Right justify the RIPL in k0. */
-+ if (!cfun->machine->keep_interrupts_masked_p)
-+ emit_insn (gen_lshrsi3 (gen_rtx_REG (SImode, K0_REG_NUM),
-+ gen_rtx_REG (SImode, K0_REG_NUM),
-+ GEN_INT (CAUSE_IPL)));
-+
-+ /* Push Status into its stack slot. */
-+ mem = gen_frame_mem (word_mode,
-+ plus_constant (stack_pointer_rtx, offset));
-+ mips_emit_move (mem, gen_rtx_REG (word_mode, K1_REG_NUM));
-+ offset -= UNITS_PER_WORD;
-+
-+ /* Insert the RIPL into our copy of SR (k1) as the new IPL. */
-+ if (!cfun->machine->keep_interrupts_masked_p)
-+ emit_insn (gen_insvsi (gen_rtx_REG (SImode, K1_REG_NUM),
-+ GEN_INT (6),
-+ GEN_INT (SR_IPL),
-+ gen_rtx_REG (SImode, K0_REG_NUM)));
-+
-+ if (!cfun->machine->keep_interrupts_masked_p)
-+ /* Enable interrupts by clearing the KSU ERL and EXL bits.
-+ IE is already the correct value, so we don't have to do
-+ anything explicit. */
-+ emit_insn (gen_insvsi (gen_rtx_REG (SImode, K1_REG_NUM),
-+ GEN_INT (4),
-+ GEN_INT (SR_EXL),
-+ gen_rtx_REG (SImode, GP_REG_FIRST)));
-+ else
-+ /* Disable interrupts by clearing the KSU, ERL, EXL,
-+ and IE bits. */
-+ emit_insn (gen_insvsi (gen_rtx_REG (SImode, K1_REG_NUM),
-+ GEN_INT (5),
-+ GEN_INT (SR_IE),
-+ gen_rtx_REG (SImode, GP_REG_FIRST)));
-+ }
-+ else
-+ {
-+ insn = gen_add3_insn (stack_pointer_rtx,
-+ stack_pointer_rtx,
-+ GEN_INT (-step1));
-+ RTX_FRAME_RELATED_P (emit_insn (insn)) = 1;
-+ size -= step1;
-+ }
-+ mips_for_each_saved_acc (size, mips_save_reg);
-+ mips_for_each_saved_gpr_and_fpr (size, mips_save_reg);
- }
- }
-
-@@ -9340,6 +9768,20 @@ mips_expand_prologue (void)
- pic_offset_table_rtx);
- }
-
-+ /* We need to search back to the last use of K0 or K1. */
-+ if (cfun->machine->interrupt_handler_p)
-+ {
-+ for (insn = get_last_insn (); insn != NULL_RTX; insn = PREV_INSN (insn))
-+ if (INSN_P (insn)
-+ && for_each_rtx (&PATTERN (insn), mips_kernel_reg_p, NULL))
-+ break;
-+ /* Emit a move from K1 to COP0 Status after insn. */
-+ gcc_assert (insn != NULL_RTX);
-+ emit_insn_after (gen_cop0_move (gen_rtx_REG (SImode, COP0_STATUS_REG_NUM),
-+ gen_rtx_REG (SImode, K1_REG_NUM)),
-+ insn);
-+ }
-+
- /* If we are profiling, make sure no instructions are scheduled before
- the call to mcount. */
- if (crtl->profile)
-@@ -9356,7 +9798,20 @@ mips_restore_reg (rtx reg, rtx mem)
- if (TARGET_MIPS16 && REGNO (reg) == GP_REG_FIRST + 31)
- reg = gen_rtx_REG (GET_MODE (reg), GP_REG_FIRST + 7);
-
-- if (TARGET_MIPS16 && !M16_REG_P (REGNO (reg)))
-+ if (REGNO (reg) == HI_REGNUM)
-+ {
-+ mips_emit_move (MIPS_EPILOGUE_TEMP (GET_MODE (reg)), mem);
-+ if (TARGET_64BIT)
-+ emit_insn (gen_mthisi_di (gen_rtx_REG (TImode, MD_REG_FIRST),
-+ MIPS_EPILOGUE_TEMP (DImode),
-+ gen_rtx_REG (DImode, LO_REGNUM)));
-+ else
-+ emit_insn (gen_mthisi_di (gen_rtx_REG (DImode, MD_REG_FIRST),
-+ MIPS_EPILOGUE_TEMP (SImode),
-+ gen_rtx_REG (SImode, LO_REGNUM)));
-+ }
-+ else if ((TARGET_MIPS16 && !M16_REG_P (REGNO (reg)))
-+ || ACC_REG_P (REGNO (reg)))
- {
- /* Can't restore directly; move through a temporary. */
- mips_emit_move (MIPS_EPILOGUE_TEMP (GET_MODE (reg)), mem);
-@@ -9392,7 +9847,7 @@ mips_expand_epilogue (bool sibcall_p)
- {
- const struct mips_frame_info *frame;
- HOST_WIDE_INT step1, step2;
-- rtx base, target;
-+ rtx base, target, insn;
-
- if (!sibcall_p && mips_can_use_return_insn ())
- {
-@@ -9425,7 +9880,8 @@ mips_expand_epilogue (bool sibcall_p)
-
- /* If we need to restore registers, deallocate as much stack as
- possible in the second step without going out of range. */
-- if ((frame->mask | frame->fmask) != 0)
-+ if ((frame->mask | frame->fmask | frame->acc_mask) != 0
-+ || frame->num_cop0_regs > 0)
- {
- step2 = MIN (step1, MIPS_MAX_FIRST_STACK_STEP);
- step1 -= step2;
-@@ -9487,13 +9943,53 @@ mips_expand_epilogue (bool sibcall_p)
- else
- {
- /* Restore the registers. */
-- mips_for_each_saved_reg (frame->total_size - step2, mips_restore_reg);
-+ mips_for_each_saved_acc (frame->total_size - step2, mips_restore_reg);
-+ mips_for_each_saved_gpr_and_fpr (frame->total_size - step2,
-+ mips_restore_reg);
-
-- /* Deallocate the final bit of the frame. */
-- if (step2 > 0)
-- emit_insn (gen_add3_insn (stack_pointer_rtx,
-- stack_pointer_rtx,
-- GEN_INT (step2)));
-+ if (cfun->machine->interrupt_handler_p)
-+ {
-+ HOST_WIDE_INT offset;
-+ rtx mem;
-+
-+ offset = frame->cop0_sp_offset - (frame->total_size - step2);
-+ if (!cfun->machine->keep_interrupts_masked_p)
-+ {
-+ /* Restore the original EPC. */
-+ mem = gen_frame_mem (word_mode,
-+ plus_constant (stack_pointer_rtx, offset));
-+ mips_emit_move (gen_rtx_REG (word_mode, K0_REG_NUM), mem);
-+ offset -= UNITS_PER_WORD;
-+
-+ /* Move to COP0 EPC. */
-+ emit_insn (gen_cop0_move (gen_rtx_REG (SImode, COP0_EPC_REG_NUM),
-+ gen_rtx_REG (SImode, K0_REG_NUM)));
-+ }
-+
-+ /* Restore the original Status. */
-+ mem = gen_frame_mem (word_mode,
-+ plus_constant (stack_pointer_rtx, offset));
-+ mips_emit_move (gen_rtx_REG (word_mode, K0_REG_NUM), mem);
-+ offset -= UNITS_PER_WORD;
-+
-+ /* If we don't use shoadow register set, we need to update SP. */
-+ if (!cfun->machine->use_shadow_register_set_p && step2 > 0)
-+ emit_insn (gen_add3_insn (stack_pointer_rtx,
-+ stack_pointer_rtx,
-+ GEN_INT (step2)));
-+
-+ /* Move to COP0 Status. */
-+ emit_insn (gen_cop0_move (gen_rtx_REG (SImode, COP0_STATUS_REG_NUM),
-+ gen_rtx_REG (SImode, K0_REG_NUM)));
-+ }
-+ else
-+ {
-+ /* Deallocate the final bit of the frame. */
-+ if (step2 > 0)
-+ emit_insn (gen_add3_insn (stack_pointer_rtx,
-+ stack_pointer_rtx,
-+ GEN_INT (step2)));
-+ }
- }
-
- /* Add in the __builtin_eh_return stack adjustment. We need to
-@@ -9516,18 +10012,44 @@ mips_expand_epilogue (bool sibcall_p)
-
- if (!sibcall_p)
- {
-- unsigned int regno;
--
-- /* When generating MIPS16 code, the normal mips_for_each_saved_reg
-- path will restore the return address into $7 rather than $31. */
-- if (TARGET_MIPS16
-- && !GENERATE_MIPS16E_SAVE_RESTORE
-- && BITSET_P (frame->mask, 31))
-- regno = GP_REG_FIRST + 7;
-- else
-- regno = GP_REG_FIRST + 31;
- mips_expand_before_return ();
-- emit_jump_insn (gen_return_internal (gen_rtx_REG (Pmode, regno)));
-+ if (cfun->machine->interrupt_handler_p)
-+ {
-+ /* Interrupt handlers generate eret or deret. */
-+ if (cfun->machine->use_debug_exception_return_p)
-+ emit_jump_insn (gen_mips_deret ());
-+ else
-+ emit_jump_insn (gen_mips_eret ());
-+ }
-+ else
-+ {
-+ unsigned int regno;
-+
-+ /* When generating MIPS16 code, the normal
-+ mips_for_each_saved_gpr_and_fpr path will restore the return
-+ address into $7 rather than $31. */
-+ if (TARGET_MIPS16
-+ && !GENERATE_MIPS16E_SAVE_RESTORE
-+ && BITSET_P (frame->mask, 31))
-+ regno = GP_REG_FIRST + 7;
-+ else
-+ regno = GP_REG_FIRST + 31;
-+ emit_jump_insn (gen_return_internal (gen_rtx_REG (Pmode, regno)));
-+ }
-+ }
-+
-+ /* Search from the beginning to the first use of K0 or K1. */
-+ if (cfun->machine->interrupt_handler_p
-+ && !cfun->machine->keep_interrupts_masked_p)
-+ {
-+ for (insn = get_insns (); insn != NULL_RTX; insn = NEXT_INSN (insn))
-+ if (INSN_P (insn)
-+ && for_each_rtx (&PATTERN(insn), mips_kernel_reg_p, NULL))
-+ break;
-+ gcc_assert (insn != NULL_RTX);
-+ /* Insert disable interrupts before the first use of K0 or K1. */
-+ emit_insn_before (gen_mips_di (), insn);
-+ emit_insn_before (gen_mips_ehb (), insn);
- }
- }
- \f
-@@ -9538,6 +10060,10 @@ mips_expand_epilogue (bool sibcall_p)
- bool
- mips_can_use_return_insn (void)
- {
-+ /* Interrupt handlers need to go through the epilogue. */
-+ if (cfun->machine->interrupt_handler_p)
-+ return false;
-+
- if (!reload_completed)
- return false;
-
-@@ -10469,10 +10995,15 @@ mips_output_division (const char *divisi
- s = "bnez\t%2,1f\n\tbreak\t7\n1:";
- }
- else if (GENERATE_DIVIDE_TRAPS)
-- {
-- output_asm_insn (s, operands);
-- s = "teq\t%2,%.,7";
-- }
-+ {
-+ if (TUNE_74K)
-+ output_asm_insn ("teq\t%2,%.,7", operands);
-+ else
-+ {
-+ output_asm_insn (s, operands);
-+ s = "teq\t%2,%.,7";
-+ }
-+ }
- else
- {
- output_asm_insn ("%(bne\t%2,%.,1f", operands);
-@@ -10784,7 +11315,17 @@ mips_maybe_swap_ready (rtx *ready, int p
- ready[pos2] = temp;
- }
- }
--\f
-+
-+int
-+mips_mult_madd_chain_bypass_p (rtx out_insn ATTRIBUTE_UNUSED,
-+ rtx in_insn ATTRIBUTE_UNUSED)
-+{
-+ if (reload_completed)
-+ return false;
-+ else
-+ return true;
-+}
-+
- /* Used by TUNE_MACC_CHAINS to record the last scheduled instruction
- that may clobber hi or lo. */
- static rtx mips_macc_chains_last_hilo;
-@@ -13957,6 +14498,14 @@ mips_override_options (void)
- long as any indirect jumps use $25. */
- flag_pic = 1;
-
-+ /* For SDE, switch on ABICALLS mode if -fpic or -fpie were used, and the
-+ user hasn't explicitly disabled these modes. */
-+ if (TARGET_MIPS_SDE
-+ && (flag_pic || flag_pie) && !TARGET_ABICALLS
-+ && !((target_flags_explicit & MASK_ABICALLS))
-+ && mips_abi != ABI_EABI)
-+ target_flags |= MASK_ABICALLS;
-+
- /* -mvr4130-align is a "speed over size" optimization: it usually produces
- faster code, but at the expense of more nops. Enable it at -O3 and
- above. */
-@@ -14309,6 +14858,178 @@ mips_order_regs_for_local_alloc (void)
- reg_alloc_order[24] = 0;
- }
- }
-+
-+/* Implement EPILOGUE_USES. */
-+
-+bool
-+mips_epilogue_uses (unsigned int regno)
-+{
-+ /* Say that the epilogue uses the return address register. Note that
-+ in the case of sibcalls, the values "used by the epilogue" are
-+ considered live at the start of the called function. */
-+ if (regno == 31)
-+ return true;
-+
-+ /* If using a GOT, say that the epilogue also uses GOT_VERSION_REGNUM.
-+ See the comment above load_call<mode> for details. */
-+ if (TARGET_USE_GOT && (regno) == GOT_VERSION_REGNUM)
-+ return true;
-+
-+ /* An interrupt handler must preserve some registers that are
-+ ordinarily call-clobbered. */
-+ if (cfun->machine->interrupt_handler_p
-+ && mips_interrupt_extra_call_saved_reg_p (regno))
-+ return true;
-+
-+ return false;
-+}
-+\f
-+#ifdef CVMX_SHARED_BSS_FLAGS
-+/* Handle a "cvmx_shared" attribute; arguments as in
-+ struct attribute_spec.handler. */
-+
-+static tree
-+octeon_handle_cvmx_shared_attribute (tree *node, tree name,
-+ tree args ATTRIBUTE_UNUSED,
-+ int flags ATTRIBUTE_UNUSED,
-+ bool *no_add_attrs)
-+{
-+ if (TREE_CODE (*node) != VAR_DECL)
-+ {
-+ warning (OPT_Wattributes, "%qs attribute only applies to variables",
-+ IDENTIFIER_POINTER (name));
-+ *no_add_attrs = true;
-+ }
-+
-+ return NULL_TREE;
-+}
-+\f
-+/* Switch to the appropriate section for output of DECL.
-+ DECL is either a `VAR_DECL' node or a constant of some sort.
-+ RELOC indicates whether forming the initial value of DECL requires
-+ link-time relocations. */
-+
-+static section *
-+octeon_select_section (tree decl, int reloc, unsigned HOST_WIDE_INT align)
-+{
-+ if (decl && TREE_CODE (decl) == VAR_DECL
-+ && lookup_attribute ("cvmx_shared", DECL_ATTRIBUTES (decl)))
-+ {
-+ const char *sname = NULL;
-+ unsigned int flags = SECTION_WRITE;
-+
-+ switch (categorize_decl_for_section (decl, reloc))
-+ {
-+ case SECCAT_DATA:
-+ case SECCAT_SDATA:
-+ case SECCAT_RODATA:
-+ case SECCAT_SRODATA:
-+ case SECCAT_RODATA_MERGE_STR:
-+ case SECCAT_RODATA_MERGE_STR_INIT:
-+ case SECCAT_RODATA_MERGE_CONST:
-+ case SECCAT_DATA_REL:
-+ case SECCAT_DATA_REL_LOCAL:
-+ case SECCAT_DATA_REL_RO:
-+ case SECCAT_DATA_REL_RO_LOCAL:
-+ sname = ".cvmx_shared";
-+ break;
-+ case SECCAT_BSS:
-+ case SECCAT_SBSS:
-+ sname = ".cvmx_shared_bss";
-+ flags |= SECTION_BSS;
-+ break;
-+ case SECCAT_TEXT:
-+ case SECCAT_TDATA:
-+ case SECCAT_TBSS:
-+ break;
-+ }
-+ if (sname)
-+ {
-+ return get_section (sname, flags, decl);
-+ }
-+ }
-+ return default_elf_select_section (decl, reloc, align);
-+}
-+\f
-+/* Build up a unique section name, expressed as a
-+ STRING_CST node, and assign it to DECL_SECTION_NAME (decl).
-+ RELOC indicates whether the initial value of EXP requires
-+ link-time relocations. */
-+
-+static void
-+octeon_unique_section (tree decl, int reloc)
-+{
-+ if (decl && TREE_CODE (decl) == VAR_DECL
-+ && lookup_attribute ("cvmx_shared", DECL_ATTRIBUTES (decl)))
-+ {
-+ const char *sname = NULL;
-+
-+ if (! DECL_ONE_ONLY (decl))
-+ {
-+ section *sect;
-+ sect = octeon_select_section (decl, reloc, DECL_ALIGN (decl));
-+ DECL_SECTION_NAME (decl) = build_string (strlen (sect->named.name),
-+ sect->named.name);
-+ return;
-+ }
-+
-+ switch (categorize_decl_for_section (decl, reloc))
-+ {
-+ case SECCAT_BSS:
-+ case SECCAT_SBSS:
-+ sname = ".cvmx_shared_bss.linkonce.";
-+ break;
-+ case SECCAT_SDATA:
-+ case SECCAT_DATA:
-+ case SECCAT_DATA_REL:
-+ case SECCAT_DATA_REL_LOCAL:
-+ case SECCAT_DATA_REL_RO:
-+ case SECCAT_DATA_REL_RO_LOCAL:
-+ case SECCAT_RODATA:
-+ case SECCAT_SRODATA:
-+ case SECCAT_RODATA_MERGE_STR:
-+ case SECCAT_RODATA_MERGE_STR_INIT:
-+ case SECCAT_RODATA_MERGE_CONST:
-+ sname = ".cvmx_shared.linkonce.";
-+ break;
-+ case SECCAT_TEXT:
-+ case SECCAT_TDATA:
-+ case SECCAT_TBSS:
-+ break;
-+ }
-+ if (sname)
-+ {
-+ const char *name;
-+ size_t plen, nlen;
-+ char *string;
-+ plen = strlen (sname);
-+
-+ name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
-+ name = targetm.strip_name_encoding (name);
-+ nlen = strlen (name);
-+
-+ string = alloca (plen + nlen + 1);
-+ memcpy (string, sname, plen);
-+ memcpy (string + plen, name, nlen + 1);
-+ DECL_SECTION_NAME (decl) = build_string (nlen + plen, string);
-+ return;
-+ }
-+ }
-+ default_unique_section (decl, reloc);
-+}
-+\f
-+/* Emit an uninitialized cvmx_shared variable. */
-+void
-+octeon_output_shared_variable (FILE *stream, tree decl, const char *name,
-+ unsigned HOST_WIDE_INT size, int align)
-+{
-+ switch_to_section (get_section (".cvmx_shared_bss", CVMX_SHARED_BSS_FLAGS,
-+ NULL_TREE));
-+ ASM_OUTPUT_ALIGN (stream, floor_log2 (align / BITS_PER_UNIT));
-+ ASM_DECLARE_OBJECT_NAME (stream, name, decl);
-+ ASM_OUTPUT_SKIP (stream, size != 0 ? size : 1);
-+}
-+#endif
- \f
- /* Initialize the GCC target structure. */
- #undef TARGET_ASM_ALIGNED_HI_OP
---- a/gcc/config/mips/mips.h
-+++ b/gcc/config/mips/mips.h
-@@ -342,6 +342,9 @@ enum mips_code_readable_setting {
- #define TARGET_IRIX 0
- #define TARGET_IRIX6 0
-
-+/* SDE specific stuff. */
-+#define TARGET_MIPS_SDE 0
-+
- /* Define preprocessor macros for the -march and -mtune options.
- PREFIX is either _MIPS_ARCH or _MIPS_TUNE, INFO is the selected
- processor. If INFO's canonical name is "foo", define PREFIX to
-@@ -708,8 +711,9 @@ enum mips_code_readable_setting {
- |march=r10000|march=r12000|march=r14000|march=r16000:-mips4} \
- %{march=mips32|march=4kc|march=4km|march=4kp|march=4ksc:-mips32} \
- %{march=mips32r2|march=m4k|march=4ke*|march=4ksd|march=24k* \
-- |march=34k*|march=74k*: -mips32r2} \
-- %{march=mips64|march=5k*|march=20k*|march=sb1*|march=sr71000: -mips64} \
-+ |march=34k*|march=74k*|march=1004k*: -mips32r2} \
-+ %{march=mips64|march=5k*|march=20k*|march=sb1*|march=sr71000 \
-+ |march=xlr: -mips64} \
- %{march=mips64r2|march=octeon: -mips64r2} \
- %{!march=*: -" MULTILIB_ISA_DEFAULT "}}"
-
-@@ -720,7 +724,8 @@ enum mips_code_readable_setting {
- #define MIPS_ARCH_FLOAT_SPEC \
- "%{mhard-float|msoft-float|march=mips*:; \
- march=vr41*|march=m4k|march=4k*|march=24kc|march=24kec \
-- |march=34kc|march=74kc|march=5kc|march=octeon: -msoft-float; \
-+ |march=34kc|march=74kc|march=1004kc|march=5kc \
-+ |march=octeon|march=xlr: -msoft-float; \
- march=*: -mhard-float}"
-
- /* A spec condition that matches 32-bit options. It only works if
-@@ -731,8 +736,9 @@ enum mips_code_readable_setting {
-
- /* Support for a compile-time default CPU, et cetera. The rules are:
- --with-arch is ignored if -march is specified or a -mips is specified
-- (other than -mips16).
-- --with-tune is ignored if -mtune is specified.
-+ (other than -mips16); likewise --with-arch-32 and --with-arch-64.
-+ --with-tune is ignored if -mtune is specified; likewise
-+ --with-tune-32 and --with-tune-64.
- --with-abi is ignored if -mabi is specified.
- --with-float is ignored if -mhard-float or -msoft-float are
- specified.
-@@ -740,7 +746,11 @@ enum mips_code_readable_setting {
- specified. */
- #define OPTION_DEFAULT_SPECS \
- {"arch", "%{" MIPS_ARCH_OPTION_SPEC ":;: -march=%(VALUE)}" }, \
-+ {"arch_32", "%{!mabi=*|mabi=32:%{" MIPS_ARCH_OPTION_SPEC ":;: -march=%(VALUE)}}" }, \
-+ {"arch_64", "%{mabi=n32|mabi=64:%{" MIPS_ARCH_OPTION_SPEC ":;: -march=%(VALUE)}}" }, \
- {"tune", "%{!mtune=*:-mtune=%(VALUE)}" }, \
-+ {"tune_32", "%{!mabi=*|mabi=32:%{!mtune=*:-mtune=%(VALUE)}}" }, \
-+ {"tune_64", "%{mabi=n32|mabi=64:%{!mtune=*:-mtune=%(VALUE)}}" }, \
- {"abi", "%{!mabi=*:-mabi=%(VALUE)}" }, \
- {"float", "%{!msoft-float:%{!mhard-float:-m%(VALUE)-float}}" }, \
- {"divide", "%{!mdivide-traps:%{!mdivide-breaks:-mdivide-%(VALUE)}}" }, \
-@@ -750,7 +760,7 @@ enum mips_code_readable_setting {
-
- /* A spec that infers the -mdsp setting from an -march argument. */
- #define BASE_DRIVER_SELF_SPECS \
-- "%{!mno-dsp:%{march=24ke*|march=34k*|march=74k*: -mdsp}}"
-+ "%{!mno-dsp:%{march=24ke*|march=34k*|march=74k*|march=1004k*: -mdsp}}"
-
- #define DRIVER_SELF_SPECS BASE_DRIVER_SELF_SPECS
-
-@@ -1038,6 +1048,11 @@ enum mips_code_readable_setting {
- /* ISA includes the bbit* instructions. */
- #define ISA_HAS_BBIT (TARGET_OCTEON && !TARGET_MIPS16)
-
-+/* ISA has single-instruction unaligned load/store support. */
-+#define ISA_HAS_UL_US (TARGET_OCTEON \
-+ && TARGET_OCTEON_UNALIGNED \
-+ && !TARGET_MIPS16)
-+
- /* ISA includes the cins instruction. */
- #define ISA_HAS_CINS (TARGET_OCTEON && !TARGET_MIPS16)
-
-@@ -1055,6 +1070,7 @@ enum mips_code_readable_setting {
-
- /* The CACHE instruction is available. */
- #define ISA_HAS_CACHE (TARGET_CACHE_BUILTIN && !TARGET_MIPS16)
-+
- \f
- /* Add -G xx support. */
-
-@@ -1152,6 +1168,7 @@ enum mips_code_readable_setting {
- %{mshared} %{mno-shared} \
- %{msym32} %{mno-sym32} \
- %{mtune=*} %{v} \
-+%{mocteon-useun} %{mno-octeon-useun} \
- %(subtarget_asm_spec)"
-
- /* Extra switches sometimes passed to the linker. */
-@@ -1622,6 +1639,9 @@ enum mips_code_readable_setting {
- #define GP_REG_LAST 31
- #define GP_REG_NUM (GP_REG_LAST - GP_REG_FIRST + 1)
- #define GP_DBX_FIRST 0
-+#define K0_REG_NUM (GP_REG_FIRST + 26)
-+#define K1_REG_NUM (GP_REG_FIRST + 27)
-+#define KERNEL_REG_P(REGNO) (IN_RANGE (REGNO, K0_REG_NUM, K1_REG_NUM))
-
- #define FP_REG_FIRST 32
- #define FP_REG_LAST 63
-@@ -1649,6 +1669,10 @@ enum mips_code_readable_setting {
- #define COP0_REG_LAST 111
- #define COP0_REG_NUM (COP0_REG_LAST - COP0_REG_FIRST + 1)
-
-+#define COP0_STATUS_REG_NUM (COP0_REG_FIRST + 12)
-+#define COP0_CAUSE_REG_NUM (COP0_REG_FIRST + 13)
-+#define COP0_EPC_REG_NUM (COP0_REG_FIRST + 14)
-+
- #define COP2_REG_FIRST 112
- #define COP2_REG_LAST 143
- #define COP2_REG_NUM (COP2_REG_LAST - COP2_REG_FIRST + 1)
-@@ -1666,6 +1690,29 @@ enum mips_code_readable_setting {
- #define AT_REGNUM (GP_REG_FIRST + 1)
- #define HI_REGNUM (TARGET_BIG_ENDIAN ? MD_REG_FIRST : MD_REG_FIRST + 1)
- #define LO_REGNUM (TARGET_BIG_ENDIAN ? MD_REG_FIRST + 1 : MD_REG_FIRST)
-+#define AC1HI_REGNUM (TARGET_BIG_ENDIAN \
-+ ? DSP_ACC_REG_FIRST : DSP_ACC_REG_FIRST + 1)
-+#define AC1LO_REGNUM (TARGET_BIG_ENDIAN \
-+ ? DSP_ACC_REG_FIRST + 1 : DSP_ACC_REG_FIRST)
-+#define AC2HI_REGNUM (TARGET_BIG_ENDIAN \
-+ ? DSP_ACC_REG_FIRST + 2 : DSP_ACC_REG_FIRST + 3)
-+#define AC2LO_REGNUM (TARGET_BIG_ENDIAN \
-+ ? DSP_ACC_REG_FIRST + 3 : DSP_ACC_REG_FIRST + 2)
-+#define AC3HI_REGNUM (TARGET_BIG_ENDIAN \
-+ ? DSP_ACC_REG_FIRST + 4 : DSP_ACC_REG_FIRST + 5)
-+#define AC3LO_REGNUM (TARGET_BIG_ENDIAN \
-+ ? DSP_ACC_REG_FIRST + 5 : DSP_ACC_REG_FIRST + 4)
-+
-+/* A few bitfield locations for the coprocessor registers. */
-+/* Request Interrupt Priority Level is from bit 10 to bit 15 of
-+ the cause register for the EIC interrupt mode. */
-+#define CAUSE_IPL 10
-+/* Interrupt Priority Level is from bit 10 to bit 15 of the status register. */
-+#define SR_IPL 10
-+/* Exception Level is at bit 1 of the status register. */
-+#define SR_EXL 1
-+/* Interrupt Enable is at bit 0 of the status register. */
-+#define SR_IE 0
-
- /* FPSW_REGNUM is the single condition code used if !ISA_HAS_8CC.
- If ISA_HAS_8CC, it should not be used, and an arbitrary ST_REG
-@@ -1754,11 +1801,18 @@ enum mips_code_readable_setting {
- incoming arguments, the static chain pointer, or the frame pointer.
- The epilogue temporary mustn't conflict with the return registers,
- the PIC call register ($25), the frame pointer, the EH stack adjustment,
-- or the EH data registers. */
-+ or the EH data registers.
-+
-+ If we're generating interrupt handlers, we use K0 as a temporary register
-+ in prologue/epilogue code. */
-
- #define MIPS16_PIC_TEMP_REGNUM (GP_REG_FIRST + 2)
--#define MIPS_PROLOGUE_TEMP_REGNUM (GP_REG_FIRST + 3)
--#define MIPS_EPILOGUE_TEMP_REGNUM (GP_REG_FIRST + (TARGET_MIPS16 ? 6 : 8))
-+#define MIPS_PROLOGUE_TEMP_REGNUM \
-+ (cfun->machine->interrupt_handler_p ? K0_REG_NUM : GP_REG_FIRST + 3)
-+#define MIPS_EPILOGUE_TEMP_REGNUM \
-+ (cfun->machine->interrupt_handler_p \
-+ ? K0_REG_NUM \
-+ : GP_REG_FIRST + (TARGET_MIPS16 ? 6 : 8))
-
- #define MIPS16_PIC_TEMP gen_rtx_REG (Pmode, MIPS16_PIC_TEMP_REGNUM)
- #define MIPS_PROLOGUE_TEMP(MODE) gen_rtx_REG (MODE, MIPS_PROLOGUE_TEMP_REGNUM)
-@@ -2284,14 +2338,7 @@ typedef struct mips_args {
- (mips_abi == ABI_EABI && UNITS_PER_FPVALUE >= UNITS_PER_DOUBLE)
-
- \f
--/* Say that the epilogue uses the return address register. Note that
-- in the case of sibcalls, the values "used by the epilogue" are
-- considered live at the start of the called function.
--
-- If using a GOT, say that the epilogue also uses GOT_VERSION_REGNUM.
-- See the comment above load_call<mode> for details. */
--#define EPILOGUE_USES(REGNO) \
-- ((REGNO) == 31 || (TARGET_USE_GOT && (REGNO) == GOT_VERSION_REGNUM))
-+#define EPILOGUE_USES(REGNO) mips_epilogue_uses (REGNO)
-
- /* Treat LOC as a byte offset from the stack pointer and round it up
- to the next fully-aligned offset. */
---- a/gcc/config/mips/mips.md
-+++ b/gcc/config/mips/mips.md
-@@ -67,7 +67,16 @@
- (UNSPEC_SET_GOT_VERSION 46)
- (UNSPEC_UPDATE_GOT_VERSION 47)
- (UNSPEC_COPYGP 48)
-+ (UNSPEC_ERET 49)
-+ (UNSPEC_DERET 50)
-+ (UNSPEC_DI 51)
-+ (UNSPEC_EHB 52)
-+ (UNSPEC_RDPGPR 53)
-+ (UNSPEC_COP0 54)
-
-+ (UNSPEC_UNALIGNED_LOAD 60)
-+ (UNSPEC_UNALIGNED_STORE 61)
-+
- (UNSPEC_ADDRESS_FIRST 100)
-
- (TLS_GET_TP_REGNUM 3)
-@@ -372,6 +381,12 @@
- ;; frsqrt floating point reciprocal square root
- ;; frsqrt1 floating point reciprocal square root step1
- ;; frsqrt2 floating point reciprocal square root step2
-+;; dspmac DSP MAC instructions not saturating the accumulator
-+;; dspmacsat DSP MAC instructions that saturate the accumulator
-+;; accext DSP accumulator extract instructions
-+;; accmod DSP accumulator modify instructions
-+;; dspalu DSP ALU instructions not saturating the result
-+;; dspalusat DSP ALU instructions that saturate the result
- ;; multi multiword sequence (or user asm statements)
- ;; nop no operation
- ;; ghost an instruction that produces no real code
-@@ -380,7 +395,7 @@
- prefetch,prefetchx,condmove,mtc,mfc,mthilo,mfhilo,const,arith,logical,
- shift,slt,signext,clz,pop,trap,imul,imul3,imul3nc,imadd,idiv,idiv3,move,
- fmove,fadd,fmul,fmadd,fdiv,frdiv,frdiv1,frdiv2,fabs,fneg,fcmp,fcvt,fsqrt,
-- frsqrt,frsqrt1,frsqrt2,multi,nop,ghost"
-+ frsqrt,frsqrt1,frsqrt2,dspmac,dspmacsat,accext,accmod,dspalu,dspalusat,multi,nop,ghost"
- (cond [(eq_attr "jal" "!unset") (const_string "call")
- (eq_attr "got" "load") (const_string "load")
-
-@@ -3565,7 +3580,9 @@
- (unspec:GPR [(match_operand:BLK 1 "memory_operand" "m")
- (match_operand:QI 2 "memory_operand" "m")]
- UNSPEC_LOAD_LEFT))]
-- "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[1])"
-+ "!TARGET_MIPS16
-+ && !ISA_HAS_UL_US
-+ && mips_mem_fits_mode_p (<MODE>mode, operands[1])"
- "<load>l\t%0,%2"
- [(set_attr "move_type" "load")
- (set_attr "mode" "<MODE>")])
-@@ -3576,7 +3593,9 @@
- (match_operand:QI 2 "memory_operand" "m")
- (match_operand:GPR 3 "register_operand" "0")]
- UNSPEC_LOAD_RIGHT))]
-- "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[1])"
-+ "!TARGET_MIPS16
-+ && !ISA_HAS_UL_US
-+ && mips_mem_fits_mode_p (<MODE>mode, operands[1])"
- "<load>r\t%0,%2"
- [(set_attr "move_type" "load")
- (set_attr "mode" "<MODE>")])
-@@ -3586,7 +3605,9 @@
- (unspec:BLK [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
- (match_operand:QI 2 "memory_operand" "m")]
- UNSPEC_STORE_LEFT))]
-- "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[0])"
-+ "!TARGET_MIPS16
-+ && !ISA_HAS_UL_US
-+ && mips_mem_fits_mode_p (<MODE>mode, operands[0])"
- "<store>l\t%z1,%2"
- [(set_attr "move_type" "store")
- (set_attr "mode" "<MODE>")])
-@@ -3602,6 +3623,28 @@
- [(set_attr "move_type" "store")
- (set_attr "mode" "<MODE>")])
-
-+;; Unaligned load and store patterns.
-+
-+(define_insn "mov_u<load>"
-+ [(set (match_operand:GPR 0 "register_operand" "=d")
-+ (unspec:GPR [(match_operand:BLK 1 "memory_operand" "m")
-+ (match_operand:QI 2 "memory_operand" "m")]
-+ UNSPEC_UNALIGNED_LOAD))]
-+ "ISA_HAS_UL_US && mips_mem_fits_mode_p (<MODE>mode, operands[1])"
-+ "u<load>\t%0,%2"
-+ [(set_attr "type" "load")
-+ (set_attr "mode" "<MODE>")])
-+
-+(define_insn "mov_u<store>"
-+ [(set (match_operand:BLK 0 "memory_operand" "=m")
-+ (unspec:BLK [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
-+ (match_operand:QI 2 "memory_operand" "m")]
-+ UNSPEC_UNALIGNED_STORE))]
-+ "ISA_HAS_UL_US && mips_mem_fits_mode_p (<MODE>mode, operands[0])"
-+ "u<store>\t%z1,%2"
-+ [(set_attr "type" "store")
-+ (set_attr "mode" "<MODE>")])
-+
- ;; An instruction to calculate the high part of a 64-bit SYMBOL_ABSOLUTE.
- ;; The required value is:
- ;;
-@@ -5472,6 +5515,26 @@
- return "%*b\t%l0%/";
- else
- {
-+ if (final_sequence && (mips_abi == ABI_32 || mips_abi == ABI_O64))
-+ {
-+ /* If the delay slot contains a $gp restore, we need to
-+ do that first, because we need it for the load
-+ label. Other ABIs do not have caller-save $gp. */
-+ rtx next = NEXT_INSN (insn);
-+ if (INSN_P (next) && !INSN_DELETED_P (next))
-+ {
-+ rtx pat = PATTERN (next);
-+ if (GET_CODE (pat) == SET
-+ && REG_P (SET_DEST (pat))
-+ && REGNO (SET_DEST (pat)) == PIC_OFFSET_TABLE_REGNUM)
-+ {
-+ rtx ops[2];
-+ ops[0] = SET_DEST (pat);
-+ ops[1] = SET_SRC (pat);
-+ output_asm_insn (mips_output_move (ops[0], ops[1]), ops);
-+ }
-+ }
-+ }
- output_asm_insn (mips_output_load_label (), operands);
- return "%*jr\t%@%/%]";
- }
-@@ -5490,7 +5553,13 @@
- (lt (abs (minus (match_dup 0)
- (plus (pc) (const_int 4))))
- (const_int 131072)))
-- (const_int 4) (const_int 16)))])
-+ (const_int 4)
-+ (if_then_else
-+ ;; for these two ABIs we may need to move a restore of $gp
-+ (ior (eq (symbol_ref "mips_abi") (symbol_ref "ABI_32"))
-+ (eq (symbol_ref "mips_abi") (symbol_ref "ABI_O64")))
-+ (const_int 20)
-+ (const_int 16))))])
-
- ;; We need a different insn for the mips16, because a mips16 branch
- ;; does not have a delay slot.
-@@ -5679,6 +5748,60 @@
- [(set_attr "type" "jump")
- (set_attr "mode" "none")])
-
-+;; Exception return.
-+(define_insn "mips_eret"
-+ [(return)
-+ (unspec_volatile [(const_int 0)] UNSPEC_ERET)]
-+ ""
-+ "eret"
-+ [(set_attr "type" "trap")
-+ (set_attr "mode" "none")])
-+
-+;; Debug exception return.
-+(define_insn "mips_deret"
-+ [(return)
-+ (unspec_volatile [(const_int 0)] UNSPEC_DERET)]
-+ ""
-+ "deret"
-+ [(set_attr "type" "trap")
-+ (set_attr "mode" "none")])
-+
-+;; Disable interrupts.
-+(define_insn "mips_di"
-+ [(unspec_volatile [(const_int 0)] UNSPEC_DI)]
-+ ""
-+ "di"
-+ [(set_attr "type" "trap")
-+ (set_attr "mode" "none")])
-+
-+;; Execution hazard barrier.
-+(define_insn "mips_ehb"
-+ [(unspec_volatile [(const_int 0)] UNSPEC_EHB)]
-+ ""
-+ "ehb"
-+ [(set_attr "type" "trap")
-+ (set_attr "mode" "none")])
-+
-+;; Read GPR from previous shadow register set.
-+(define_insn "mips_rdpgpr"
-+ [(set (match_operand:SI 0 "register_operand" "=d")
-+ (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "d")]
-+ UNSPEC_RDPGPR))]
-+ ""
-+ "rdpgpr\t%0,%1"
-+ [(set_attr "type" "move")
-+ (set_attr "mode" "SI")])
-+
-+;; Move involving COP0 registers.
-+(define_insn "cop0_move"
-+ [(set (match_operand:SI 0 "register_operand" "=B,d")
-+ (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "d,B")]
-+ UNSPEC_COP0))]
-+ ""
-+{ return mips_output_move (operands[0], operands[1]); }
-+ [(set_attr "type" "mtc,mfc")
-+ (set_attr "mode" "SI")])
-+
- ;; This is used in compiling the unwind routines.
- (define_expand "eh_return"
- [(use (match_operand 0 "general_operand"))]
---- a/gcc/config/mips/mips.opt
-+++ b/gcc/config/mips/mips.opt
-@@ -184,6 +184,10 @@ mips16
- Target Report RejectNegative Mask(MIPS16)
- Generate MIPS16 code
-
-+mips16e
-+Target Report RejectNegative Mask(MIPS16) MaskExists
-+Deprecated; alias for -mips16
-+
- mips3d
- Target Report RejectNegative Mask(MIPS3D)
- Use MIPS-3D instructions
-@@ -236,6 +240,10 @@ mno-mips3d
- Target Report RejectNegative InverseMask(MIPS3D)
- Do not use MIPS-3D instructions
-
-+mocteon-useun
-+Target Report Mask(OCTEON_UNALIGNED)
-+Use Octeon-specific unaligned loads/stores for 32/64-bit data
-+
- mpaired-single
- Target Report Mask(PAIRED_SINGLE_FLOAT)
- Use paired-single floating-point instructions
---- /dev/null
-+++ b/gcc/config/mips/octeon-elf-unwind.h
-@@ -0,0 +1,57 @@
-+/* Stack unwinding support through the first exception frame.
-+ Copyright (C) 2007 Cavium Networks.
-+
-+This file is part of GCC.
-+
-+GCC is free software; you can redistribute it and/or modify
-+it under the terms of the GNU General Public License as published by
-+the Free Software Foundation; either version 2, or (at your option)
-+any later version.
-+
-+GCC is distributed in the hope that it will be useful,
-+but WITHOUT ANY WARRANTY; without even the implied warranty of
-+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+GNU General Public License for more details.
-+
-+You should have received a copy of the GNU General Public License
-+along with GCC; see the file COPYING. If not, write to
-+the Free Software Foundation, 51 Franklin Street, Fifth Floor,
-+Boston, MA 02110-1301, USA. */
-+
-+#define MD_FALLBACK_FRAME_STATE_FOR octeon_elf_fallback_frame_state
-+
-+/* Check whether this is the cvmx_interrupt_stage2 frame. If the
-+ function call was dispatched via k0 assume we are in
-+ cvmx_interrupt_stage2. In this case the sp in point to the saved
-+ register array. */
-+
-+static _Unwind_Reason_Code
-+octeon_elf_fallback_frame_state (struct _Unwind_Context *context,
-+ _Unwind_FrameState *fs)
-+{
-+ unsigned i;
-+ unsigned *pc = context->ra;
-+
-+ /* Look for "jalr k0". */
-+ if (pc[-2] != 0x0340f809)
-+ return _URC_END_OF_STACK;
-+
-+ for (i = 0; i < 32; i++)
-+ {
-+ fs->regs.reg[i].how = REG_SAVED_OFFSET;
-+ fs->regs.reg[i].loc.offset = 8 * i;
-+ }
-+
-+ /* Keep the next frame's sp. This way we have a CFA that points
-+ exactly to the register array. */
-+ fs->regs.cfa_how = CFA_REG_OFFSET;
-+ fs->regs.cfa_reg = STACK_POINTER_REGNUM;
-+ fs->regs.cfa_offset = 0;
-+
-+ /* DEPC is saved as the 35. register. */
-+ fs->regs.reg[DWARF_ALT_FRAME_RETURN_COLUMN].how = REG_SAVED_OFFSET;
-+ fs->regs.reg[DWARF_ALT_FRAME_RETURN_COLUMN].loc.offset = 8 * 35;
-+ fs->retaddr_column = DWARF_ALT_FRAME_RETURN_COLUMN;
-+
-+ return _URC_NO_REASON;
-+}
---- /dev/null
-+++ b/gcc/config/mips/octeon-elf.h
-@@ -0,0 +1,98 @@
-+/* Macros for mips*-octeon-elf target.
-+ Copyright (C) 2004, 2005, 2006 Cavium Networks.
-+
-+This file is part of GCC.
-+
-+GCC is free software; you can redistribute it and/or modify
-+it under the terms of the GNU General Public License as published by
-+the Free Software Foundation; either version 2, or (at your option)
-+any later version.
-+
-+GCC is distributed in the hope that it will be useful,
-+but WITHOUT ANY WARRANTY; without even the implied warranty of
-+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+GNU General Public License for more details.
-+
-+You should have received a copy of the GNU General Public License
-+along with GCC; see the file COPYING. If not, write to
-+the Free Software Foundation, 51 Franklin Street, Fifth Floor,
-+Boston, MA 02110-1301, USA. */
-+
-+/* Add MASK_SOFT_FLOAT and MASK_OCTEON_UNALIGNED. */
-+
-+#undef TARGET_DEFAULT
-+#define TARGET_DEFAULT (MASK_SOFT_FLOAT_ABI | MASK_OCTEON_UNALIGNED)
-+
-+/* Forward -m*octeon-useun. */
-+
-+#undef SUBTARGET_ASM_SPEC
-+#define SUBTARGET_ASM_SPEC "%{mno-octeon-useun} %{!mno-octeon-useun:-mocteon-useun}"
-+
-+/* Enable backtrace including on machine exceptions by default. */
-+
-+#undef SUBTARGET_CC1_SPEC
-+#define SUBTARGET_CC1_SPEC "%{!fno-asynchronous-unwind-tables:-fasynchronous-unwind-tables}"
-+
-+/* Without ASM_PREFERRED_EH_DATA_FORMAT, output_call_frame_info emits
-+ pointer-sized addresses for FDE addresses. For 64-bit targets, it does
-+ it without properly "switching over" to 64-bit as described in the DWARF3
-+ spec. GDB can fall back on .eh_frames and misinterpret FDE addresses.
-+ Instead let's be explicit and use augmentation to describe the encoding if
-+ pointer size is 64. */
-+
-+#undef ASM_PREFERRED_EH_DATA_FORMAT
-+#define ASM_PREFERRED_EH_DATA_FORMAT(CODE, GLOBAL) \
-+ ((CODE) == 1 && POINTER_SIZE == 64 \
-+ ? (ABI_HAS_64BIT_SYMBOLS ? DW_EH_PE_udata8 : DW_EH_PE_udata4) \
-+ : DW_EH_PE_absptr)
-+
-+/* Link to libc library. */
-+
-+#undef LIB_SPEC
-+#define LIB_SPEC "-lc"
-+
-+/* Link to startup file. */
-+
-+#undef STARTFILE_SPEC
-+#define STARTFILE_SPEC "crti%O%s crtbegin%O%s crt0%O%s"
-+
-+/* Default our test-only n64 configuration to -G0 since that is what
-+ the kernel uses. */
-+
-+#undef SUBTARGET_SELF_SPECS
-+#define SUBTARGET_SELF_SPECS \
-+"%{mabi=64:%{!G*: -G0}}"
-+
-+/* Pass linker emulation mode for N32. */
-+
-+#undef LINK_SPEC
-+#define LINK_SPEC "\
-+%(endian_spec) \
-+%{G*} %{mips1} %{mips2} %{mips3} %{mips4} %{mips32} %{mips32r2} %{mips64} \
-+%{mips64r2} %{bestGnum} %{shared} %{non_shared} \
-+%{mabi=n32:-melf32e%{!EL:b}%{EL:l}octeonn32} \
-+%{mabi=64:-melf64e%{!EL:b}%{EL:l}octeon}"
-+
-+/* Override because of N32. */
-+
-+#undef LOCAL_LABEL_PREFIX
-+#define LOCAL_LABEL_PREFIX ((mips_abi == ABI_N32) ? "." : "$")
-+
-+/* Append the core number to the GCOV filename FN. */
-+
-+#define GCOV_TARGET_SUFFIX_LENGTH 2
-+#define ADD_GCOV_TARGET_SUFFIX(FN) \
-+do \
-+ { \
-+ char *fn = FN; \
-+ int core; \
-+ char s[3]; \
-+ \
-+ asm ("rdhwr %0, $0" : "=r"(core)); \
-+ sprintf (s, "%d", core); \
-+ strcat (fn, s); \
-+ } \
-+while (0)
-+
-+/* Code to unwind through the exception frame. */
-+#define MD_UNWIND_SUPPORT "config/mips/octeon-elf-unwind.h"
---- /dev/null
-+++ b/gcc/config/mips/octeon.h
-@@ -0,0 +1,68 @@
-+/* Macros for mips*-octeon-* target.
-+ Copyright (C) 2004, 2005, 2006 Cavium Networks.
-+
-+This file is part of GCC.
-+
-+GCC is free software; you can redistribute it and/or modify
-+it under the terms of the GNU General Public License as published by
-+the Free Software Foundation; either version 2, or (at your option)
-+any later version.
-+
-+GCC is distributed in the hope that it will be useful,
-+but WITHOUT ANY WARRANTY; without even the implied warranty of
-+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+GNU General Public License for more details.
-+
-+You should have received a copy of the GNU General Public License
-+along with GCC; see the file COPYING. If not, write to
-+the Free Software Foundation, 51 Franklin Street, Fifth Floor,
-+Boston, MA 02110-1301, USA. */
-+
-+#define CVMX_SHARED_BSS_FLAGS (SECTION_WRITE | SECTION_BSS)
-+
-+#undef TARGET_ASM_SELECT_SECTION
-+#define TARGET_ASM_SELECT_SECTION octeon_select_section
-+
-+#undef TARGET_ASM_UNIQUE_SECTION
-+#define TARGET_ASM_UNIQUE_SECTION octeon_unique_section
-+
-+/* Implement ASM_OUTPUT_ALIGNED_DECL_LOCAL. This differs from the
-+ generic version only in the use of cvmx_shared attribute. */
-+
-+#undef ASM_OUTPUT_ALIGNED_DECL_LOCAL
-+#define ASM_OUTPUT_ALIGNED_DECL_LOCAL(STREAM, DECL, NAME, SIZE, ALIGN) \
-+ do \
-+ { \
-+ if ((DECL) && TREE_CODE ((DECL)) == VAR_DECL \
-+ && lookup_attribute ("cvmx_shared", DECL_ATTRIBUTES (DECL))) \
-+ { \
-+ fprintf ((STREAM), "%s", LOCAL_ASM_OP); \
-+ assemble_name ((STREAM), (NAME)); \
-+ fprintf ((STREAM), "\n"); \
-+ octeon_output_shared_variable ((STREAM), (DECL), (NAME), \
-+ (SIZE), (ALIGN)); \
-+ } \
-+ else \
-+ ASM_OUTPUT_ALIGNED_LOCAL (STREAM, NAME, SIZE, ALIGN); \
-+ } \
-+ while (0)
-+
-+\f
-+/* Implement ASM_OUTPUT_ALIGNED_DECL_COMMON. This differs from the mips
-+ version only in the use of cvmx_shared attribute. */
-+
-+#undef ASM_OUTPUT_ALIGNED_DECL_COMMON
-+#define ASM_OUTPUT_ALIGNED_DECL_COMMON(STREAM, DECL, NAME, SIZE, ALIGN) \
-+ { \
-+ if (TREE_CODE ((DECL)) == VAR_DECL \
-+ && lookup_attribute ("cvmx_shared", DECL_ATTRIBUTES ((DECL)))) \
-+ { \
-+ if (TREE_PUBLIC ((DECL)) && DECL_NAME ((DECL))) \
-+ targetm.asm_out.globalize_label (asm_out_file, (NAME)); \
-+ octeon_output_shared_variable ((STREAM), (DECL), (NAME), \
-+ (SIZE), (ALIGN)); \
-+ } \
-+ else \
-+ mips_output_aligned_decl_common ((STREAM), (DECL), (NAME), (SIZE), \
-+ (ALIGN)); \
-+ }
---- a/gcc/config/mips/predicates.md
-+++ b/gcc/config/mips/predicates.md
-@@ -211,6 +211,20 @@
- }
- })
-
-+(define_predicate "mask_low_and_shift_operator"
-+ (and (match_code "and")
-+ (match_test "GET_CODE (XEXP (op, 0)) == ASHIFT
-+ && GET_CODE (XEXP (op, 1)) == CONST_INT
-+ && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT"))
-+{
-+ int len;
-+
-+ len = mask_low_and_shift_len (GET_MODE (op),
-+ INTVAL (XEXP (XEXP (op, 0), 1)),
-+ INTVAL (XEXP (op, 1)));
-+ return 0 < len && len <= 32;
-+})
-+
- (define_predicate "consttable_operand"
- (match_test "CONSTANT_P (op)"))
-
---- a/gcc/config/mips/sde.h
-+++ b/gcc/config/mips/sde.h
-@@ -19,6 +19,9 @@ You should have received a copy of the G
- along with GCC; see the file COPYING3. If not see
- <http://www.gnu.org/licenses/>. */
-
-+#undef TARGET_MIPS_SDE
-+#define TARGET_MIPS_SDE 1
-+
- #undef DRIVER_SELF_SPECS
- #define DRIVER_SELF_SPECS \
- /* Make sure a -mips option is present. This helps us to pick \
-@@ -90,7 +93,8 @@ along with GCC; see the file COPYING3.
-
- /* Use $5 as a temporary for both MIPS16 and non-MIPS16. */
- #undef MIPS_EPILOGUE_TEMP_REGNUM
--#define MIPS_EPILOGUE_TEMP_REGNUM (GP_REG_FIRST + 5)
-+#define MIPS_EPILOGUE_TEMP_REGNUM \
-+ (cfun->machine->interrupt_handler_p ? K0_REG_NUM : GP_REG_FIRST + 5)
-
- /* Using long will always be right for size_t and ptrdiff_t, since
- sizeof(long) must equal sizeof(void *), following from the setting
---- a/gcc/config/mips/sdemtk.h
-+++ b/gcc/config/mips/sdemtk.h
-@@ -19,6 +19,8 @@ You should have received a copy of the G
- along with GCC; see the file COPYING3. If not see
- <http://www.gnu.org/licenses/>. */
-
-+#define TARGET_MIPS_SDEMTK 1
-+
- #define TARGET_OS_CPP_BUILTINS() \
- do \
- { \
-@@ -113,3 +115,12 @@ extern void mips_sync_icache (void *beg,
- /* ...nor does the call sequence preserve $31. */
- #undef MIPS_SAVE_REG_FOR_PROFILING_P
- #define MIPS_SAVE_REG_FOR_PROFILING_P(REGNO) ((REGNO) == GP_REG_FIRST + 31)
-+
-+/* From mips.h, with mno-float option added. */
-+
-+#undef MIPS_ARCH_FLOAT_SPEC
-+#define MIPS_ARCH_FLOAT_SPEC \
-+ "%{mhard-float|msoft-float|mno-float|march=mips*:; \
-+ march=vr41*|march=m4k|march=4k*|march=24kc|march=24kec \
-+ |march=34kc|march=74kc|march=1004kc|march=5kc|march=octeon|march=xlr: -msoft-float; \
-+ march=*: -mhard-float}"
---- /dev/null
-+++ b/gcc/config/mips/t-crtfm
-@@ -0,0 +1,9 @@
-+
-+EXTRA_MULTILIB_PARTS += crtfastmath.o
-+
-+EXTRA_PARTS += crtfastmath.o
-+
-+$(T)crtfastmath.o: $(srcdir)/config/mips/crtfastmath.c $(GCC_PASSES)
-+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) \
-+ -c -o $(T)crtfastmath.o $(srcdir)/config/mips/crtfastmath.c
-+
---- /dev/null
-+++ b/gcc/config/mips/t-octeon-elf
-@@ -0,0 +1,41 @@
-+# Don't let CTOR_LIST end up in sdata section.
-+
-+CRTSTUFF_T_CFLAGS = -G 0 -fno-asynchronous-unwind-tables
-+
-+# Assemble startup files.
-+
-+$(T)crti.o: $(srcdir)/config/mips/crti.asm $(GCC_PASSES)
-+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) \
-+ -c -o $(T)crti.o -x assembler-with-cpp $(srcdir)/config/mips/crti.asm
-+
-+$(T)crtn.o: $(srcdir)/config/mips/crtn.asm $(GCC_PASSES)
-+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) \
-+ -c -o $(T)crtn.o -x assembler-with-cpp $(srcdir)/config/mips/crtn.asm
-+
-+# N32 uses TFmode for long double.
-+
-+TPBIT = tp-bit.c
-+
-+tp-bit.c: $(srcdir)/config/fp-bit.c
-+ echo '#ifdef __MIPSEL__' > tp-bit.c
-+ echo '# define FLOAT_BIT_ORDER_MISMATCH' >> tp-bit.c
-+ echo '#endif' >> tp-bit.c
-+ echo '#if __LDBL_MANT_DIG__ == 113' >> tp-bit.c
-+ echo '#define QUIET_NAN_NEGATED' >> tp-bit.c
-+ echo '# define TFLOAT' >> tp-bit.c
-+ cat $(srcdir)/config/fp-bit.c >> tp-bit.c
-+ echo '#endif' >> tp-bit.c
-+
-+# We must build libgcc2.a with -G 0, in case the user wants to link
-+# without the $gp register.
-+
-+TARGET_LIBGCC2_CFLAGS = -G 0
-+
-+# Build both ABIs.
-+
-+MULTILIB_OPTIONS = mabi=n32/mabi=eabi/mabi=64
-+MULTILIB_DIRNAMES = n32 eabi n64
-+EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o crti.o crtn.o
-+
-+LIBGCC = stmp-multilib
-+INSTALL_LIBGCC = install-multilib
---- a/gcc/config/mips/xlr.md
-+++ b/gcc/config/mips/xlr.md
-@@ -1,5 +1,5 @@
- ;; DFA-based pipeline description for the XLR.
--;; Copyright (C) 2008 Free Software Foundation, Inc.
-+;; Copyright (C) 2008, 2009 Free Software Foundation, Inc.
- ;;
- ;; xlr.md Machine Description for the RMI XLR Microprocessor
- ;; This file is part of GCC.
-@@ -31,7 +31,7 @@
- ;; Integer arithmetic instructions.
- (define_insn_reservation "ir_xlr_alu" 1
- (and (eq_attr "cpu" "xlr")
-- (eq_attr "type" "arith,shift,clz,const,unknown,multi,nop,trap"))
-+ (eq_attr "type" "move,arith,shift,clz,logical,signext,const,unknown,multi,nop,trap"))
- "xlr_main_pipe")
-
- ;; Integer arithmetic instructions.
---- /dev/null
-+++ b/gcc/config/rs6000/e500mc.h
-@@ -0,0 +1,46 @@
-+/* Core target definitions for GNU compiler
-+ for IBM RS/6000 PowerPC targeted to embedded ELF systems.
-+ Copyright (C) 1995, 1996, 2000, 2003, 2004, 2007 Free Software Foundation, Inc.
-+ Contributed by Cygnus Support.
-+
-+ This file is part of GCC.
-+
-+ GCC is free software; you can redistribute it and/or modify it
-+ under the terms of the GNU General Public License as published
-+ by the Free Software Foundation; either version 3, or (at your
-+ option) any later version.
-+
-+ GCC is distributed in the hope that it will be useful, but WITHOUT
-+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
-+ License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with GCC; see the file COPYING3. If not see
-+ <http://www.gnu.org/licenses/>. */
-+
-+/* Add -meabi to target flags. */
-+#undef TARGET_DEFAULT
-+#define TARGET_DEFAULT (MASK_POWERPC | MASK_NEW_MNEMONICS | MASK_EABI)
-+
-+#undef TARGET_VERSION
-+#define TARGET_VERSION fprintf (stderr, " (PowerPC Embedded)");
-+
-+#undef TARGET_OS_CPP_BUILTINS
-+#define TARGET_OS_CPP_BUILTINS() \
-+ do \
-+ { \
-+ builtin_define_std ("PPC"); \
-+ builtin_define ("__embedded__"); \
-+ builtin_assert ("system=embedded"); \
-+ builtin_assert ("cpu=powerpc"); \
-+ builtin_assert ("machine=powerpc"); \
-+ TARGET_OS_SYSV_CPP_BUILTINS (); \
-+ } \
-+ while (0)
-+
-+#undef CC1_EXTRA_SPEC
-+#define CC1_EXTRA_SPEC "-maix-struct-return"
-+
-+#undef ASM_DEFAULT_SPEC
-+#define ASM_DEFAULT_SPEC "-mppc%{m64:64} -me500mc"
---- a/gcc/config/rs6000/eabi-ci.asm
-+++ b/gcc/config/rs6000/eabi-ci.asm
-@@ -98,6 +98,7 @@ __EH_FRAME_BEGIN__:
- /* Head of __init function used for static constructors. */
- .section ".init","ax"
- .align 2
-+FUNC_START(_init)
- FUNC_START(__init)
- stwu 1,-16(1)
- mflr 0
-@@ -106,6 +107,7 @@ FUNC_START(__init)
- /* Head of __fini function used for static destructors. */
- .section ".fini","ax"
- .align 2
-+FUNC_START(_fini)
- FUNC_START(__fini)
- stwu 1,-16(1)
- mflr 0
---- a/gcc/config/rs6000/eabi.asm
-+++ b/gcc/config/rs6000/eabi.asm
-@@ -230,7 +230,7 @@ FUNC_END(__eabi)
- r11 has the address of .LCTOC1 in it.
- r12 has the value to add to each pointer
- r13 .. r31 are unchanged */
--
-+#ifdef _RELOCATABLE
- FUNC_START(__eabi_convert)
- cmplw 1,3,4 /* any pointers to convert? */
- subf 5,3,4 /* calculate number of words to convert */
-@@ -285,5 +285,5 @@ FUNC_START(__eabi_uconvert)
- blr
-
- FUNC_END(__eabi_uconvert)
--
-+#endif
- #endif
---- a/gcc/config/rs6000/eabi.h
-+++ b/gcc/config/rs6000/eabi.h
-@@ -23,10 +23,6 @@
- #undef TARGET_DEFAULT
- #define TARGET_DEFAULT (MASK_POWERPC | MASK_NEW_MNEMONICS | MASK_EABI)
-
--/* Invoke an initializer function to set up the GOT. */
--#define NAME__MAIN "__eabi"
--#define INVOKE__main
--
- #undef TARGET_VERSION
- #define TARGET_VERSION fprintf (stderr, " (PowerPC Embedded)");
-
-@@ -42,3 +38,20 @@
- TARGET_OS_SYSV_CPP_BUILTINS (); \
- } \
- while (0)
-+
-+/* Add -te500v1 and -te500v2 options for convenience in generating
-+ multilibs. */
-+#undef CC1_EXTRA_SPEC
-+#define CC1_EXTRA_SPEC \
-+ "%{te500v1: -mcpu=8540 -mfloat-gprs=single -mspe=yes -mabi=spe} " \
-+ "%{te500v2: -mcpu=8548 -mfloat-gprs=double -mspe=yes -mabi=spe} " \
-+ "%{te600: -mcpu=7400 -maltivec -mabi=altivec}" \
-+ "%{te500mc: -mcpu=e500mc -maix-struct-return}"
-+
-+#undef ASM_DEFAULT_SPEC
-+#define ASM_DEFAULT_SPEC \
-+ "%{te500v1:-mppc -mspe -me500 ; \
-+ te500v2:-mppc -mspe -me500 ; \
-+ te600:-mppc -maltivec ; \
-+ te500mc:-mppc -me500mc ; \
-+ :-mppc%{m64:64}}"
---- a/gcc/config/rs6000/linux.h
-+++ b/gcc/config/rs6000/linux.h
-@@ -128,3 +128,29 @@
- #ifdef TARGET_DEFAULT_LONG_DOUBLE_128
- #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 128
- #endif
-+
-+/* Add -te500v1 and -te500v2 options for convenience in generating
-+ multilibs. */
-+#undef CC1_EXTRA_SPEC
-+#define CC1_EXTRA_SPEC \
-+ "%{te500v1: -mcpu=8540 -mfloat-gprs=single -mspe=yes -mabi=spe} " \
-+ "%{te500v2: -mcpu=8548 -mfloat-gprs=double -mspe=yes -mabi=spe} " \
-+ "%{te600: -mcpu=7400 -maltivec -mabi=altivec}" \
-+ "%{te500mc: -mcpu=e500mc}"
-+
-+#undef ASM_DEFAULT_SPEC
-+#define ASM_DEFAULT_SPEC \
-+ "%{te500v1:-mppc -mspe -me500 ; \
-+ te500v2:-mppc -mspe -me500 ; \
-+ te600:-mppc -maltivec ; \
-+ te500mc:-me500mc ; \
-+ :-mppc%{m64:64}}"
-+
-+/* The various C libraries each have their own subdirectory. */
-+#undef SYSROOT_SUFFIX_SPEC
-+#define SYSROOT_SUFFIX_SPEC \
-+ "%{msoft-float:/nof ; \
-+ te600:/te600 ; \
-+ te500v1:/te500v1 ; \
-+ te500v2:/te500v2 ; \
-+ te500mc:/te500mc}"
---- /dev/null
-+++ b/gcc/config/rs6000/option-defaults.h
-@@ -0,0 +1,64 @@
-+/* Definitions of default options for config/rs6000 configurations.
-+ Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-+ 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
-+ Free Software Foundation, Inc.
-+
-+ This file is part of GCC.
-+
-+ GCC is free software; you can redistribute it and/or modify it
-+ under the terms of the GNU General Public License as published
-+ by the Free Software Foundation; either version 3, or (at your
-+ option) any later version.
-+
-+ GCC is distributed in the hope that it will be useful, but WITHOUT
-+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
-+ License for more details.
-+
-+ Under Section 7 of GPL version 3, you are granted additional
-+ permissions described in the GCC Runtime Library Exception, version
-+ 3.1, as published by the Free Software Foundation.
-+
-+ You should have received a copy of the GNU General Public License and
-+ a copy of the GCC Runtime Library Exception along with this program;
-+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
-+ <http://www.gnu.org/licenses/>. */
-+
-+/* This header needs to be included after any other headers affecting
-+ TARGET_DEFAULT. */
-+
-+#if TARGET_AIX
-+#define OPT_64 "maix64"
-+#define OPT_32 "maix32"
-+#else
-+#define OPT_64 "m64"
-+#define OPT_32 "m32"
-+#endif
-+
-+#ifndef MASK_64BIT
-+#define MASK_64BIT 0
-+#endif
-+
-+#if TARGET_DEFAULT & MASK_64BIT
-+#define OPT_ARCH64 "!"OPT_32
-+#define OPT_ARCH32 OPT_32
-+#else
-+#define OPT_ARCH64 OPT_64
-+#define OPT_ARCH32 "!"OPT_64
-+#endif
-+
-+/* Support for a compile-time default CPU, et cetera. The rules are:
-+ --with-cpu is ignored if -mcpu is specified; likewise --with-cpu-32
-+ and --with-cpu-64.
-+ --with-tune is ignored if -mtune is specified; likewise --with-tune-32
-+ and --with-tune-64.
-+ --with-float is ignored if -mhard-float or -msoft-float are
-+ specified. */
-+#define OPTION_DEFAULT_SPECS \
-+ {"cpu", "%{mcpu=*|te500mc|te500v1|te500v2|te600:;:-mcpu=%(VALUE)}" }, \
-+ {"cpu_32", "%{" OPT_ARCH32 ":%{mcpu=*|te500mc|te500v1|te500v2|te600:;:-mcpu=%(VALUE)}}" }, \
-+ {"cpu_64", "%{" OPT_ARCH64 ":%{mcpu=*|te500mc|te500v1|te500v2|te600:;:-mcpu=%(VALUE)}}" }, \
-+ {"tune", "%{!mtune=*:-mtune=%(VALUE)}" }, \
-+ {"tune_32", "%{" OPT_ARCH32 ":%{!mtune=*:-mtune=%(VALUE)}}" }, \
-+ {"tune_64", "%{" OPT_ARCH64 ":%{!mtune=*:-mtune=%(VALUE)}}" }, \
-+ {"float", "%{!msoft-float:%{!mhard-float:-m%(VALUE)-float}}" }
---- a/gcc/config/rs6000/paired.md
-+++ b/gcc/config/rs6000/paired.md
-@@ -27,7 +27,7 @@
- (UNSPEC_EXTODD_V2SF 333)
- ])
-
--(define_insn "negv2sf2"
-+(define_insn "paired_negv2sf2"
- [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
- (neg:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "f")))]
- "TARGET_PAIRED_FLOAT"
-@@ -41,7 +41,7 @@
- "ps_rsqrte %0,%1"
- [(set_attr "type" "fp")])
-
--(define_insn "absv2sf2"
-+(define_insn "paired_absv2sf2"
- [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
- (abs:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "f")))]
- "TARGET_PAIRED_FLOAT"
-@@ -55,7 +55,7 @@
- "ps_nabs %0,%1"
- [(set_attr "type" "fp")])
-
--(define_insn "addv2sf3"
-+(define_insn "paired_addv2sf3"
- [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
- (plus:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "%f")
- (match_operand:V2SF 2 "gpc_reg_operand" "f")))]
-@@ -63,7 +63,7 @@
- "ps_add %0,%1,%2"
- [(set_attr "type" "fp")])
-
--(define_insn "subv2sf3"
-+(define_insn "paired_subv2sf3"
- [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
- (minus:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "f")
- (match_operand:V2SF 2 "gpc_reg_operand" "f")))]
-@@ -71,7 +71,7 @@
- "ps_sub %0,%1,%2"
- [(set_attr "type" "fp")])
-
--(define_insn "mulv2sf3"
-+(define_insn "paired_mulv2sf3"
- [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
- (mult:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "%f")
- (match_operand:V2SF 2 "gpc_reg_operand" "f")))]
-@@ -86,7 +86,7 @@
- "ps_res %0,%1"
- [(set_attr "type" "fp")])
-
--(define_insn "divv2sf3"
-+(define_insn "paired_divv2sf3"
- [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
- (div:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "f")
- (match_operand:V2SF 2 "gpc_reg_operand" "f")))]
---- a/gcc/config/rs6000/rs6000.c
-+++ b/gcc/config/rs6000/rs6000.c
-@@ -919,6 +919,7 @@ int easy_vector_constant (rtx, enum mach
- static bool rs6000_is_opaque_type (const_tree);
- static rtx rs6000_dwarf_register_span (rtx);
- static void rs6000_init_dwarf_reg_sizes_extra (tree);
-+static int rs6000_commutative_operand_precedence (const_rtx, int);
- static rtx rs6000_legitimize_tls_address (rtx, enum tls_model);
- static void rs6000_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
- static rtx rs6000_tls_get_addr (void);
-@@ -1194,6 +1195,10 @@ static const char alt_reg_names[][8] =
- #undef TARGET_VECTOR_OPAQUE_P
- #define TARGET_VECTOR_OPAQUE_P rs6000_is_opaque_type
-
-+#undef TARGET_COMMUTATIVE_OPERAND_PRECEDENCE
-+#define TARGET_COMMUTATIVE_OPERAND_PRECEDENCE \
-+ rs6000_commutative_operand_precedence
-+
- #undef TARGET_DWARF_REGISTER_SPAN
- #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
-
-@@ -4708,16 +4713,19 @@ rs6000_conditional_register_usage (void)
- if (TARGET_ALTIVEC)
- global_regs[VSCR_REGNO] = 1;
-
-- if (TARGET_ALTIVEC_ABI)
-- {
-- for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)
-- call_used_regs[i] = call_really_used_regs[i] = 1;
-+ /* If we are not using the AltiVec ABI, pretend that the normally
-+ call-saved registers are also call-used. We could use them
-+ normally if we saved and restored them in the prologue; that
-+ would require using the alignment padding around the register
-+ save area, and some care with unwinding information. */
-+ if (! TARGET_ALTIVEC_ABI)
-+ for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
-+ call_used_regs[i] = call_really_used_regs[i] = 1;
-
-- /* AIX reserves VR20:31 in non-extended ABI mode. */
-- if (TARGET_XCOFF)
-- for (i = FIRST_ALTIVEC_REGNO + 20; i < FIRST_ALTIVEC_REGNO + 32; ++i)
-- fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
-- }
-+ if (TARGET_ALTIVEC_ABI && TARGET_XCOFF)
-+ /* AIX reserves VR20:31 in non-extended ABI mode. */
-+ for (i = FIRST_ALTIVEC_REGNO + 20; i < FIRST_ALTIVEC_REGNO + 32; ++i)
-+ fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
- }
- \f
- /* Try to output insns to set TARGET equal to the constant C if it can
-@@ -7533,10 +7541,10 @@ static struct builtin_description bdesc_
- { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS },
- { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR },
-
-- { 0, CODE_FOR_divv2sf3, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3 },
-- { 0, CODE_FOR_addv2sf3, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3 },
-- { 0, CODE_FOR_subv2sf3, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3 },
-- { 0, CODE_FOR_mulv2sf3, "__builtin_paired_mulv2sf3", PAIRED_BUILTIN_MULV2SF3 },
-+ { 0, CODE_FOR_paired_divv2sf3, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3 },
-+ { 0, CODE_FOR_paired_addv2sf3, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3 },
-+ { 0, CODE_FOR_paired_subv2sf3, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3 },
-+ { 0, CODE_FOR_paired_mulv2sf3, "__builtin_paired_mulv2sf3", PAIRED_BUILTIN_MULV2SF3 },
- { 0, CODE_FOR_paired_muls0, "__builtin_paired_muls0", PAIRED_BUILTIN_MULS0 },
- { 0, CODE_FOR_paired_muls1, "__builtin_paired_muls1", PAIRED_BUILTIN_MULS1 },
- { 0, CODE_FOR_paired_merge00, "__builtin_paired_merge00", PAIRED_BUILTIN_MERGE00 },
-@@ -7545,10 +7553,10 @@ static struct builtin_description bdesc_
- { 0, CODE_FOR_paired_merge11, "__builtin_paired_merge11", PAIRED_BUILTIN_MERGE11 },
-
- /* Place holder, leave as first spe builtin. */
-- { 0, CODE_FOR_spe_evaddw, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
-- { 0, CODE_FOR_spe_evand, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
-+ { 0, CODE_FOR_addv2si3, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
-+ { 0, CODE_FOR_andv2si3, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
- { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC },
-- { 0, CODE_FOR_spe_evdivws, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
-+ { 0, CODE_FOR_divv2si3, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
- { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU },
- { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV },
- { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD },
-@@ -7824,7 +7832,7 @@ static struct builtin_description bdesc_
-
- /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
- end with SPE_BUILTIN_EVSUBFUSIAAW. */
-- { 0, CODE_FOR_spe_evabs, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
-+ { 0, CODE_FOR_absv2si2, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
- { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW },
- { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW },
- { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW },
-@@ -7856,9 +7864,9 @@ static struct builtin_description bdesc_
- /* Place-holder. Leave as last unary SPE builtin. */
- { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW },
-
-- { 0, CODE_FOR_absv2sf2, "__builtin_paired_absv2sf2", PAIRED_BUILTIN_ABSV2SF2 },
-+ { 0, CODE_FOR_paired_absv2sf2, "__builtin_paired_absv2sf2", PAIRED_BUILTIN_ABSV2SF2 },
- { 0, CODE_FOR_nabsv2sf2, "__builtin_paired_nabsv2sf2", PAIRED_BUILTIN_NABSV2SF2 },
-- { 0, CODE_FOR_negv2sf2, "__builtin_paired_negv2sf2", PAIRED_BUILTIN_NEGV2SF2 },
-+ { 0, CODE_FOR_paired_negv2sf2, "__builtin_paired_negv2sf2", PAIRED_BUILTIN_NEGV2SF2 },
- { 0, CODE_FOR_sqrtv2sf2, "__builtin_paired_sqrtv2sf2", PAIRED_BUILTIN_SQRTV2SF2 },
- { 0, CODE_FOR_resv2sf2, "__builtin_paired_resv2sf2", PAIRED_BUILTIN_RESV2SF2 }
- };
-@@ -9396,6 +9404,8 @@ build_opaque_vector_type (tree node, int
- static void
- rs6000_init_builtins (void)
- {
-+ tree tdecl;
-+
- V2SI_type_node = build_vector_type (intSI_type_node, 2);
- V2SF_type_node = build_vector_type (float_type_node, 2);
- V4HI_type_node = build_vector_type (intHI_type_node, 4);
-@@ -9433,60 +9443,75 @@ rs6000_init_builtins (void)
- float_type_internal_node = float_type_node;
- void_type_internal_node = void_type_node;
-
-- (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
-- get_identifier ("__bool char"),
-- bool_char_type_node));
-- (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
-- get_identifier ("__bool short"),
-- bool_short_type_node));
-- (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
-- get_identifier ("__bool int"),
-- bool_int_type_node));
-- (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
-- get_identifier ("__pixel"),
-- pixel_type_node));
-+ tdecl = build_decl (TYPE_DECL, get_identifier ("__bool char"),
-+ bool_char_type_node);
-+ TYPE_NAME (bool_char_type_node) = tdecl;
-+ (*lang_hooks.decls.pushdecl) (tdecl);
-+ tdecl = build_decl (TYPE_DECL, get_identifier ("__bool short"),
-+ bool_short_type_node);
-+ TYPE_NAME (bool_short_type_node) = tdecl;
-+ (*lang_hooks.decls.pushdecl) (tdecl);
-+ tdecl = build_decl (TYPE_DECL, get_identifier ("__bool int"),
-+ bool_int_type_node);
-+ TYPE_NAME (bool_int_type_node) = tdecl;
-+ (*lang_hooks.decls.pushdecl) (tdecl);
-+ tdecl = build_decl (TYPE_DECL, get_identifier ("__pixel"),
-+ pixel_type_node);
-+ TYPE_NAME (pixel_type_node) = tdecl;
-+ (*lang_hooks.decls.pushdecl) (tdecl);
-
- bool_V16QI_type_node = build_vector_type (bool_char_type_node, 16);
- bool_V8HI_type_node = build_vector_type (bool_short_type_node, 8);
- bool_V4SI_type_node = build_vector_type (bool_int_type_node, 4);
- pixel_V8HI_type_node = build_vector_type (pixel_type_node, 8);
-
-- (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
-- get_identifier ("__vector unsigned char"),
-- unsigned_V16QI_type_node));
-- (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
-- get_identifier ("__vector signed char"),
-- V16QI_type_node));
-- (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
-- get_identifier ("__vector __bool char"),
-- bool_V16QI_type_node));
--
-- (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
-- get_identifier ("__vector unsigned short"),
-- unsigned_V8HI_type_node));
-- (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
-- get_identifier ("__vector signed short"),
-- V8HI_type_node));
-- (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
-- get_identifier ("__vector __bool short"),
-- bool_V8HI_type_node));
--
-- (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
-- get_identifier ("__vector unsigned int"),
-- unsigned_V4SI_type_node));
-- (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
-- get_identifier ("__vector signed int"),
-- V4SI_type_node));
-- (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
-- get_identifier ("__vector __bool int"),
-- bool_V4SI_type_node));
--
-- (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
-- get_identifier ("__vector float"),
-- V4SF_type_node));
-- (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
-- get_identifier ("__vector __pixel"),
-- pixel_V8HI_type_node));
-+ tdecl = build_decl (TYPE_DECL, get_identifier ("__vector unsigned char"),
-+ unsigned_V16QI_type_node);
-+ TYPE_NAME (unsigned_V16QI_type_node) = tdecl;
-+ (*lang_hooks.decls.pushdecl) (tdecl);
-+ tdecl = build_decl (TYPE_DECL, get_identifier ("__vector signed char"),
-+ V16QI_type_node);
-+ TYPE_NAME (V16QI_type_node) = tdecl;
-+ (*lang_hooks.decls.pushdecl) (tdecl);
-+ tdecl = build_decl (TYPE_DECL, get_identifier ("__vector __bool char"),
-+ bool_V16QI_type_node);
-+ TYPE_NAME ( bool_V16QI_type_node) = tdecl;
-+ (*lang_hooks.decls.pushdecl) (tdecl);
-+
-+ tdecl = build_decl (TYPE_DECL, get_identifier ("__vector unsigned short"),
-+ unsigned_V8HI_type_node);
-+ TYPE_NAME (unsigned_V8HI_type_node) = tdecl;
-+ (*lang_hooks.decls.pushdecl) (tdecl);
-+ tdecl = build_decl (TYPE_DECL, get_identifier ("__vector signed short"),
-+ V8HI_type_node);
-+ TYPE_NAME (V8HI_type_node) = tdecl;
-+ (*lang_hooks.decls.pushdecl) (tdecl);
-+ tdecl = build_decl (TYPE_DECL, get_identifier ("__vector __bool short"),
-+ bool_V8HI_type_node);
-+ TYPE_NAME (bool_V8HI_type_node) = tdecl;
-+ (*lang_hooks.decls.pushdecl) (tdecl);
-+
-+ tdecl = build_decl (TYPE_DECL, get_identifier ("__vector unsigned int"),
-+ unsigned_V4SI_type_node);
-+ TYPE_NAME (unsigned_V4SI_type_node) = tdecl;
-+ (*lang_hooks.decls.pushdecl) (tdecl);
-+ tdecl = build_decl (TYPE_DECL, get_identifier ("__vector signed int"),
-+ V4SI_type_node);
-+ TYPE_NAME (V4SI_type_node) = tdecl;
-+ (*lang_hooks.decls.pushdecl) (tdecl);
-+ tdecl = build_decl (TYPE_DECL, get_identifier ("__vector __bool int"),
-+ bool_V4SI_type_node);
-+ TYPE_NAME (bool_V4SI_type_node) = tdecl;
-+ (*lang_hooks.decls.pushdecl) (tdecl);
-+
-+ tdecl = build_decl (TYPE_DECL, get_identifier ("__vector float"),
-+ V4SF_type_node);
-+ TYPE_NAME (V4SF_type_node) = tdecl;
-+ (*lang_hooks.decls.pushdecl) (tdecl);
-+ tdecl = build_decl (TYPE_DECL, get_identifier ("__vector __pixel"),
-+ pixel_V8HI_type_node);
-+ TYPE_NAME (pixel_V8HI_type_node) = tdecl;
-+ (*lang_hooks.decls.pushdecl) (tdecl);
-
- if (TARGET_PAIRED_FLOAT)
- paired_init_builtins ();
-@@ -15869,7 +15894,7 @@ static bool
- no_global_regs_above (int first, bool gpr)
- {
- int i;
-- for (i = first; i < gpr ? 32 : 64 ; i++)
-+ for (i = first; i < (gpr ? 32 : 64); i++)
- if (global_regs[i])
- return false;
- return true;
-@@ -15895,11 +15920,11 @@ rs6000_savres_routine_sym (rs6000_stack_
- int regno = gpr ? info->first_gp_reg_save : (info->first_fp_reg_save - 32);
- rtx sym;
- int select = ((savep ? 1 : 0) << 2
-- | (gpr
-+ | (TARGET_SPE_ABI
- /* On the SPE, we never have any FPRs, but we do have
- 32/64-bit versions of the routines. */
-- ? (TARGET_SPE_ABI && info->spe_64bit_regs_used ? 1 : 0)
-- : 0) << 1
-+ ? (info->spe_64bit_regs_used ? 1 : 0)
-+ : (gpr ? 1 : 0)) << 1
- | (exitp ? 1: 0));
-
- /* Don't generate bogus routine names. */
-@@ -15934,6 +15959,7 @@ rs6000_savres_routine_sym (rs6000_stack_
-
- sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select]
- = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
-+ SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_FUNCTION;
- }
-
- return sym;
-@@ -16124,6 +16150,14 @@ rs6000_savres_strategy (rs6000_stack_t *
- savres_gprs_inline = savres_gprs_inline || using_multiple_p;
- }
-
-+ /* Code intended for use in shared libraries cannot be reliably linked
-+ with out-of-line prologues and epilogues. */
-+ if (flag_pic)
-+ {
-+ savres_gprs_inline = 1;
-+ savres_fprs_inline = 1;
-+ }
-+
- return (using_multiple_p
- | (savres_fprs_inline << 1)
- | (savres_gprs_inline << 2));
-@@ -16148,7 +16182,7 @@ rs6000_emit_prologue (void)
- int using_store_multiple;
- int using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
- && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
-- && !call_used_regs[STATIC_CHAIN_REGNUM]);
-+ && call_used_regs[STATIC_CHAIN_REGNUM]);
- HOST_WIDE_INT sp_offset = 0;
-
- if (TARGET_FIX_AND_CONTINUE)
-@@ -16956,8 +16990,9 @@ rs6000_emit_epilogue (int sibcall)
- || (cfun->calls_alloca
- && !frame_pointer_needed));
- restore_lr = (info->lr_save_p
-- && restoring_GPRs_inline
-- && restoring_FPRs_inline);
-+ && (restoring_GPRs_inline
-+ || (restoring_FPRs_inline
-+ && info->first_fp_reg_save < 64)));
-
- if (WORLD_SAVE_P (info))
- {
-@@ -17229,7 +17264,7 @@ rs6000_emit_epilogue (int sibcall)
-
- /* Get the old lr if we saved it. If we are restoring registers
- out-of-line, then the out-of-line routines can do this for us. */
-- if (restore_lr)
-+ if (restore_lr && restoring_GPRs_inline)
- {
- rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
- info->lr_save_offset + sp_offset);
-@@ -17248,7 +17283,7 @@ rs6000_emit_epilogue (int sibcall)
- }
-
- /* Set LR here to try to overlap restores below. */
-- if (restore_lr)
-+ if (restore_lr && restoring_GPRs_inline)
- emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
- gen_rtx_REG (Pmode, 0));
-
-@@ -17428,6 +17463,18 @@ rs6000_emit_epilogue (int sibcall)
- }
- }
-
-+ if (restore_lr && !restoring_GPRs_inline)
-+ {
-+ rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
-+ info->lr_save_offset + sp_offset);
-+
-+ emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
-+ }
-+
-+ if (restore_lr && !restoring_GPRs_inline)
-+ emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
-+ gen_rtx_REG (Pmode, 0));
-+
- /* Restore fpr's if we need to do it without calling a function. */
- if (restoring_FPRs_inline)
- for (i = 0; i < 64 - info->first_fp_reg_save; i++)
-@@ -22195,6 +22242,30 @@ rs6000_memory_move_cost (enum machine_mo
- return 4 + rs6000_register_move_cost (mode, rclass, GENERAL_REGS);
- }
-
-+/* Return a value indicating whether OP, an operand of a commutative
-+ operation, is preferred as the first or second operand. The higher
-+ the value, the stronger the preference for being the first operand.
-+ We use negative values to indicate a preference for the first operand
-+ and positive values for the second operand.
-+ VALUE is the default precedence for OP; see rtlanal.c:
-+ commutative_operand_precendece. */
-+
-+static int
-+rs6000_commutative_operand_precedence (const_rtx op, int value)
-+{
-+ /* Prefer pointer objects over non pointer objects.
-+ For rationale see PR28690. */
-+ if (GET_RTX_CLASS (GET_CODE (op)) == RTX_OBJ
-+ && ((REG_P (op) && REG_POINTER (op))
-+ || (MEM_P (op) && MEM_POINTER (op))))
-+ /* value = -1 */;
-+ else
-+ /* value = -2 */
-+ --value;
-+
-+ return value;
-+}
-+
- /* Returns a code for a target-specific builtin that implements
- reciprocal of the function, or NULL_TREE if not available. */
-
-@@ -22718,12 +22789,16 @@ rs6000_is_opaque_type (const_tree type)
- static rtx
- rs6000_dwarf_register_span (rtx reg)
- {
-- unsigned regno;
-+ rtx parts[8];
-+ int i, words;
-+ unsigned regno = REGNO (reg);
-+ enum machine_mode mode = GET_MODE (reg);
-
- if (TARGET_SPE
-+ && regno < 32
- && (SPE_VECTOR_MODE (GET_MODE (reg))
-- || (TARGET_E500_DOUBLE
-- && (GET_MODE (reg) == DFmode || GET_MODE (reg) == DDmode))))
-+ || (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode)
-+ && mode != SFmode && mode != SDmode && mode != SCmode)))
- ;
- else
- return NULL_RTX;
-@@ -22733,15 +22808,23 @@ rs6000_dwarf_register_span (rtx reg)
- /* The duality of the SPE register size wreaks all kinds of havoc.
- This is a way of distinguishing r0 in 32-bits from r0 in
- 64-bits. */
-- return
-- gen_rtx_PARALLEL (VOIDmode,
-- BYTES_BIG_ENDIAN
-- ? gen_rtvec (2,
-- gen_rtx_REG (SImode, regno + 1200),
-- gen_rtx_REG (SImode, regno))
-- : gen_rtvec (2,
-- gen_rtx_REG (SImode, regno),
-- gen_rtx_REG (SImode, regno + 1200)));
-+ words = (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
-+ gcc_assert (words <= 4);
-+ for (i = 0; i < words; i++, regno++)
-+ {
-+ if (BYTES_BIG_ENDIAN)
-+ {
-+ parts[2 * i] = gen_rtx_REG (SImode, regno + 1200);
-+ parts[2 * i + 1] = gen_rtx_REG (SImode, regno);
-+ }
-+ else
-+ {
-+ parts[2 * i] = gen_rtx_REG (SImode, regno);
-+ parts[2 * i + 1] = gen_rtx_REG (SImode, regno + 1200);
-+ }
-+ }
-+
-+ return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (words * 2, parts));
- }
-
- /* Fill in sizes for SPE register high parts in table used by unwinder. */
---- a/gcc/config/rs6000/rs6000.h
-+++ b/gcc/config/rs6000/rs6000.h
-@@ -368,16 +368,6 @@ enum group_termination
- previous_group
- };
-
--/* Support for a compile-time default CPU, et cetera. The rules are:
-- --with-cpu is ignored if -mcpu is specified.
-- --with-tune is ignored if -mtune is specified.
-- --with-float is ignored if -mhard-float or -msoft-float are
-- specified. */
--#define OPTION_DEFAULT_SPECS \
-- {"cpu", "%{!mcpu=*:-mcpu=%(VALUE)}" }, \
-- {"tune", "%{!mtune=*:-mtune=%(VALUE)}" }, \
-- {"float", "%{!msoft-float:%{!mhard-float:-m%(VALUE)-float}}" }
--
- /* rs6000_select[0] is reserved for the default cpu defined via --with-cpu */
- struct rs6000_cpu_select
- {
-@@ -794,8 +784,8 @@ extern int rs6000_xilinx_fpu;
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
- 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, \
- /* AltiVec registers. */ \
-- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
-- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
-+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
-+ 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
- 1, 1 \
- , 1, 1, 1 \
- }
-@@ -813,8 +803,8 @@ extern int rs6000_xilinx_fpu;
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
- 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, \
- /* AltiVec registers. */ \
-- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
-- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
-+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
-+ 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
- 0, 0 \
- , 0, 0, 0 \
- }
---- a/gcc/config/rs6000/rs6000.md
-+++ b/gcc/config/rs6000/rs6000.md
-@@ -14703,9 +14703,9 @@
- [(match_parallel 0 "any_parallel_operand"
- [(clobber (reg:P 65))
- (use (match_operand:P 1 "symbol_ref_operand" "s"))
-- (use (match_operand:P 2 "gpc_reg_operand" "r"))
-- (set (match_operand:P 3 "memory_operand" "=m")
-- (match_operand:P 4 "gpc_reg_operand" "r"))])]
-+ (use (reg:P 11))
-+ (set (match_operand:P 2 "memory_operand" "=m")
-+ (match_operand:P 3 "gpc_reg_operand" "r"))])]
- ""
- "bl %z1"
- [(set_attr "type" "branch")
-@@ -14715,9 +14715,9 @@
- [(match_parallel 0 "any_parallel_operand"
- [(clobber (reg:P 65))
- (use (match_operand:P 1 "symbol_ref_operand" "s"))
-- (use (match_operand:P 2 "gpc_reg_operand" "r"))
-- (set (match_operand:DF 3 "memory_operand" "=m")
-- (match_operand:DF 4 "gpc_reg_operand" "f"))])]
-+ (use (reg:P 11))
-+ (set (match_operand:DF 2 "memory_operand" "=m")
-+ (match_operand:DF 3 "gpc_reg_operand" "f"))])]
- ""
- "bl %z1"
- [(set_attr "type" "branch")
-@@ -14810,9 +14810,9 @@
- [(match_parallel 0 "any_parallel_operand"
- [(clobber (match_operand:P 1 "register_operand" "=l"))
- (use (match_operand:P 2 "symbol_ref_operand" "s"))
-- (use (match_operand:P 3 "gpc_reg_operand" "r"))
-- (set (match_operand:P 4 "gpc_reg_operand" "=r")
-- (match_operand:P 5 "memory_operand" "m"))])]
-+ (use (reg:P 11))
-+ (set (match_operand:P 3 "gpc_reg_operand" "=r")
-+ (match_operand:P 4 "memory_operand" "m"))])]
- ""
- "bl %z2"
- [(set_attr "type" "branch")
-@@ -14823,9 +14823,9 @@
- [(return)
- (clobber (match_operand:P 1 "register_operand" "=l"))
- (use (match_operand:P 2 "symbol_ref_operand" "s"))
-- (use (match_operand:P 3 "gpc_reg_operand" "r"))
-- (set (match_operand:P 4 "gpc_reg_operand" "=r")
-- (match_operand:P 5 "memory_operand" "m"))])]
-+ (use (reg:P 11))
-+ (set (match_operand:P 3 "gpc_reg_operand" "=r")
-+ (match_operand:P 4 "memory_operand" "m"))])]
- ""
- "b %z2"
- [(set_attr "type" "branch")
-@@ -14836,9 +14836,9 @@
- [(return)
- (clobber (match_operand:P 1 "register_operand" "=l"))
- (use (match_operand:P 2 "symbol_ref_operand" "s"))
-- (use (match_operand:P 3 "gpc_reg_operand" "r"))
-- (set (match_operand:DF 4 "gpc_reg_operand" "=f")
-- (match_operand:DF 5 "memory_operand" "m"))])]
-+ (use (reg:P 11))
-+ (set (match_operand:DF 3 "gpc_reg_operand" "=f")
-+ (match_operand:DF 4 "memory_operand" "m"))])]
- ""
- "b %z2"
- [(set_attr "type" "branch")
-@@ -14889,6 +14889,120 @@
- }"
- [(set_attr "type" "load")])
- \f
-+;;; Expanders for vector insn patterns shared between the SPE and TARGET_PAIRED systems.
-+
-+(define_expand "absv2sf2"
-+ [(set (match_operand:V2SF 0 "gpc_reg_operand" "")
-+ (abs:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "")))]
-+ "TARGET_PAIRED_FLOAT || TARGET_SPE"
-+ "
-+{
-+ if (TARGET_SPE)
-+ {
-+ /* We need to make a note that we clobber SPEFSCR. */
-+ emit_insn (gen_rtx_SET (VOIDmode, operands[0],
-+ gen_rtx_ABS (V2SFmode, operands[1])));
-+ emit_insn (gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, SPEFSCR_REGNO)));
-+ DONE;
-+ }
-+}")
-+
-+(define_expand "negv2sf2"
-+ [(set (match_operand:V2SF 0 "gpc_reg_operand" "")
-+ (neg:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "")))]
-+ "TARGET_PAIRED_FLOAT || TARGET_SPE"
-+ "
-+{
-+ if (TARGET_SPE)
-+ {
-+ /* We need to make a note that we clobber SPEFSCR. */
-+ emit_insn (gen_rtx_SET (VOIDmode, operands[0],
-+ gen_rtx_NEG (V2SFmode, operands[1])));
-+ emit_insn (gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, SPEFSCR_REGNO)));
-+ DONE;
-+ }
-+}")
-+
-+(define_expand "addv2sf3"
-+ [(set (match_operand:V2SF 0 "gpc_reg_operand" "")
-+ (plus:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "")
-+ (match_operand:V2SF 2 "gpc_reg_operand" "")))]
-+ "TARGET_PAIRED_FLOAT || TARGET_SPE"
-+ "
-+{
-+ if (TARGET_SPE)
-+ {
-+ /* We need to make a note that we clobber SPEFSCR. */
-+ rtx par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (2));
-+
-+ XVECEXP (par, 0, 0) = gen_rtx_SET (VOIDmode, operands[0],
-+ gen_rtx_PLUS (V2SFmode, operands[1], operands[2]));
-+ XVECEXP (par, 0, 1) = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, SPEFSCR_REGNO));
-+ emit_insn (par);
-+ DONE;
-+ }
-+}")
-+
-+(define_expand "subv2sf3"
-+ [(set (match_operand:V2SF 0 "gpc_reg_operand" "")
-+ (minus:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "")
-+ (match_operand:V2SF 2 "gpc_reg_operand" "")))]
-+ "TARGET_PAIRED_FLOAT || TARGET_SPE"
-+ "
-+{
-+ if (TARGET_SPE)
-+ {
-+ /* We need to make a note that we clobber SPEFSCR. */
-+ rtx par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (2));
-+
-+ XVECEXP (par, 0, 0) = gen_rtx_SET (VOIDmode, operands[0],
-+ gen_rtx_MINUS (V2SFmode, operands[1], operands[2]));
-+ XVECEXP (par, 0, 1) = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, SPEFSCR_REGNO));
-+ emit_insn (par);
-+ DONE;
-+ }
-+}")
-+
-+(define_expand "mulv2sf3"
-+ [(set (match_operand:V2SF 0 "gpc_reg_operand" "")
-+ (mult:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "")
-+ (match_operand:V2SF 2 "gpc_reg_operand" "")))]
-+ "TARGET_PAIRED_FLOAT || TARGET_SPE"
-+ "
-+{
-+ if (TARGET_SPE)
-+ {
-+ /* We need to make a note that we clobber SPEFSCR. */
-+ rtx par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (2));
-+
-+ XVECEXP (par, 0, 0) = gen_rtx_SET (VOIDmode, operands[0],
-+ gen_rtx_MULT (V2SFmode, operands[1], operands[2]));
-+ XVECEXP (par, 0, 1) = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, SPEFSCR_REGNO));
-+ emit_insn (par);
-+ DONE;
-+ }
-+}")
-+
-+(define_expand "divv2sf3"
-+ [(set (match_operand:V2SF 0 "gpc_reg_operand" "")
-+ (div:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "")
-+ (match_operand:V2SF 2 "gpc_reg_operand" "")))]
-+ "TARGET_PAIRED_FLOAT || TARGET_SPE"
-+ "
-+{
-+ if (TARGET_SPE)
-+ {
-+ /* We need to make a note that we clobber SPEFSCR. */
-+ rtx par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (2));
-+
-+ XVECEXP (par, 0, 0) = gen_rtx_SET (VOIDmode, operands[0],
-+ gen_rtx_DIV (V2SFmode, operands[1], operands[2]));
-+ XVECEXP (par, 0, 1) = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, SPEFSCR_REGNO));
-+ emit_insn (par);
-+ DONE;
-+ }
-+}")
-+\f
-
- (include "sync.md")
- (include "altivec.md")
---- a/gcc/config/rs6000/spe.md
-+++ b/gcc/config/rs6000/spe.md
-@@ -164,7 +164,7 @@
-
- ;; SPE SIMD instructions
-
--(define_insn "spe_evabs"
-+(define_insn "absv2si2"
- [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
- (abs:V2SI (match_operand:V2SI 1 "gpc_reg_operand" "r")))]
- "TARGET_SPE"
-@@ -181,7 +181,7 @@
- [(set_attr "type" "vecsimple")
- (set_attr "length" "4")])
-
--(define_insn "spe_evand"
-+(define_insn "andv2si3"
- [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
- (and:V2SI (match_operand:V2SI 1 "gpc_reg_operand" "r")
- (match_operand:V2SI 2 "gpc_reg_operand" "r")))]
-@@ -1898,7 +1898,7 @@
- [(set_attr "type" "veccomplex")
- (set_attr "length" "4")])
-
--(define_insn "spe_evaddw"
-+(define_insn "addv2si3"
- [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
- (plus:V2SI (match_operand:V2SI 1 "gpc_reg_operand" "r")
- (match_operand:V2SI 2 "gpc_reg_operand" "r")))]
-@@ -2028,7 +2028,7 @@
- [(set_attr "type" "veccomplex")
- (set_attr "length" "4")])
-
--(define_insn "spe_evdivws"
-+(define_insn "divv2si3"
- [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
- (div:V2SI (match_operand:V2SI 1 "gpc_reg_operand" "r")
- (match_operand:V2SI 2 "gpc_reg_operand" "r")))
-@@ -3156,9 +3156,9 @@
- [(match_parallel 0 "any_parallel_operand"
- [(clobber (reg:P 65))
- (use (match_operand:P 1 "symbol_ref_operand" "s"))
-- (use (match_operand:P 2 "gpc_reg_operand" "r"))
-- (set (match_operand:V2SI 3 "memory_operand" "=m")
-- (match_operand:V2SI 4 "gpc_reg_operand" "r"))])]
-+ (use (reg:P 11))
-+ (set (match_operand:V2SI 2 "memory_operand" "=m")
-+ (match_operand:V2SI 3 "gpc_reg_operand" "r"))])]
- "TARGET_SPE_ABI"
- "bl %z1"
- [(set_attr "type" "branch")
-@@ -3168,9 +3168,9 @@
- [(match_parallel 0 "any_parallel_operand"
- [(clobber (reg:P 65))
- (use (match_operand:P 1 "symbol_ref_operand" "s"))
-- (use (match_operand:P 2 "gpc_reg_operand" "r"))
-- (set (match_operand:V2SI 3 "gpc_reg_operand" "=r")
-- (match_operand:V2SI 4 "memory_operand" "m"))])]
-+ (use (reg:P 11))
-+ (set (match_operand:V2SI 2 "gpc_reg_operand" "=r")
-+ (match_operand:V2SI 3 "memory_operand" "m"))])]
- "TARGET_SPE_ABI"
- "bl %z1"
- [(set_attr "type" "branch")
-@@ -3181,9 +3181,9 @@
- [(return)
- (clobber (reg:P 65))
- (use (match_operand:P 1 "symbol_ref_operand" "s"))
-- (use (match_operand:P 2 "gpc_reg_operand" "r"))
-- (set (match_operand:V2SI 3 "gpc_reg_operand" "=r")
-- (match_operand:V2SI 4 "memory_operand" "m"))])]
-+ (use (reg:P 11))
-+ (set (match_operand:V2SI 2 "gpc_reg_operand" "=r")
-+ (match_operand:V2SI 3 "memory_operand" "m"))])]
- "TARGET_SPE_ABI"
- "b %z1"
- [(set_attr "type" "branch")
---- a/gcc/config/rs6000/sysv4.h
-+++ b/gcc/config/rs6000/sysv4.h
-@@ -619,6 +619,9 @@ SVR4_ASM_SPEC \
- #define CC1_SECURE_PLT_DEFAULT_SPEC ""
- #endif
-
-+#undef CC1_EXTRA_SPEC
-+#define CC1_EXTRA_SPEC ""
-+
- /* Pass -G xxx to the compiler and set correct endian mode. */
- #define CC1_SPEC "%{G*} %(cc1_cpu) \
- %{mlittle|mlittle-endian: %(cc1_endian_little); \
-@@ -643,7 +646,7 @@ SVR4_ASM_SPEC \
- %{msdata: -msdata=default} \
- %{mno-sdata: -msdata=none} \
- %{!mbss-plt: %{!msecure-plt: %(cc1_secure_plt_default)}} \
--%{profile: -p}"
-+%{profile: -p}" CC1_EXTRA_SPEC
-
- /* Don't put -Y P,<path> for cross compilers. */
- #ifndef CROSS_DIRECTORY_STRUCTURE
-@@ -843,15 +846,15 @@ SVR4_ASM_SPEC \
- #define CPP_OS_MVME_SPEC ""
-
- /* PowerPC simulator based on netbsd system calls support. */
--#define LIB_SIM_SPEC "--start-group -lsim -lc --end-group"
-+#define LIB_SIM_SPEC LIB_DEFAULT_SPEC
-
--#define STARTFILE_SIM_SPEC "ecrti.o%s sim-crt0.o%s crtbegin.o%s"
-+#define STARTFILE_SIM_SPEC "ecrti.o%s crtbegin.o%s"
-
--#define ENDFILE_SIM_SPEC "crtend.o%s ecrtn.o%s"
-+#define ENDFILE_SIM_SPEC "crtend.o%s ecrtn.o%s -Tsim-hosted.ld"
-
- #define LINK_START_SIM_SPEC ""
-
--#define LINK_OS_SIM_SPEC "-m elf32ppcsim"
-+#define LINK_OS_SIM_SPEC ""
-
- #define CPP_OS_SIM_SPEC ""
-
---- /dev/null
-+++ b/gcc/config/rs6000/t-ppc-e500mc
-@@ -0,0 +1,12 @@
-+# Multilibs for powerpc embedded ELF targets.
-+
-+MULTILIB_OPTIONS =
-+
-+MULTILIB_DIRNAMES =
-+
-+MULTILIB_EXCEPTIONS =
-+
-+MULTILIB_EXTRA_OPTS = mno-eabi mstrict-align
-+
-+MULTILIB_MATCHES = ${MULTILIB_MATCHES_FLOAT} \
-+ ${MULTILIB_MATCHES_ENDIAN}
---- a/gcc/config/rs6000/t-ppccomm
-+++ b/gcc/config/rs6000/t-ppccomm
-@@ -3,10 +3,23 @@
- LIB2FUNCS_EXTRA += tramp.S $(srcdir)/config/rs6000/darwin-ldouble.c
-
- # These can't end up in shared libgcc
--LIB2FUNCS_STATIC_EXTRA = eabi.S
--
--eabi.S: $(srcdir)/config/rs6000/eabi.asm
-- cat $(srcdir)/config/rs6000/eabi.asm > eabi.S
-+LIB2FUNCS_STATIC_EXTRA = \
-+ crtsavfpr.S crtresfpr.S \
-+ crtsavgpr.S crtresgpr.S \
-+ crtresxfpr.S crtresxgpr.S \
-+ e500crtres32gpr.S \
-+ e500crtres64gpr.S \
-+ e500crtres64gprctr.S \
-+ e500crtrest32gpr.S \
-+ e500crtrest64gpr.S \
-+ e500crtresx32gpr.S \
-+ e500crtresx64gpr.S \
-+ e500crtsav32gpr.S \
-+ e500crtsav64gpr.S \
-+ e500crtsav64gprctr.S \
-+ e500crtsavg32gpr.S \
-+ e500crtsavg64gpr.S \
-+ e500crtsavg64gprctr.S
-
- tramp.S: $(srcdir)/config/rs6000/tramp.asm
- cat $(srcdir)/config/rs6000/tramp.asm > tramp.S
-@@ -36,6 +49,63 @@ ncrti.S: $(srcdir)/config/rs6000/sol-ci.
- ncrtn.S: $(srcdir)/config/rs6000/sol-cn.asm
- cat $(srcdir)/config/rs6000/sol-cn.asm >ncrtn.S
-
-+crtsavfpr.S: $(srcdir)/config/rs6000/crtsavfpr.asm
-+ cat $(srcdir)/config/rs6000/crtsavfpr.asm >crtsavfpr.S
-+
-+crtresfpr.S: $(srcdir)/config/rs6000/crtresfpr.asm
-+ cat $(srcdir)/config/rs6000/crtresfpr.asm >crtresfpr.S
-+
-+crtsavgpr.S: $(srcdir)/config/rs6000/crtsavgpr.asm
-+ cat $(srcdir)/config/rs6000/crtsavgpr.asm >crtsavgpr.S
-+
-+crtresgpr.S: $(srcdir)/config/rs6000/crtresgpr.asm
-+ cat $(srcdir)/config/rs6000/crtresgpr.asm >crtresgpr.S
-+
-+crtresxfpr.S: $(srcdir)/config/rs6000/crtresxfpr.asm
-+ cat $(srcdir)/config/rs6000/crtresxfpr.asm >crtresxfpr.S
-+
-+crtresxgpr.S: $(srcdir)/config/rs6000/crtresxgpr.asm
-+ cat $(srcdir)/config/rs6000/crtresxgpr.asm >crtresxgpr.S
-+
-+e500crtres32gpr.S: $(srcdir)/config/rs6000/e500crtres32gpr.asm
-+ cat $(srcdir)/config/rs6000/e500crtres32gpr.asm >e500crtres32gpr.S
-+
-+e500crtres64gpr.S: $(srcdir)/config/rs6000/e500crtres64gpr.asm
-+ cat $(srcdir)/config/rs6000/e500crtres64gpr.asm >e500crtres64gpr.S
-+
-+e500crtres64gprctr.S: $(srcdir)/config/rs6000/e500crtres64gprctr.asm
-+ cat $(srcdir)/config/rs6000/e500crtres64gprctr.asm >e500crtres64gprctr.S
-+
-+e500crtrest32gpr.S: $(srcdir)/config/rs6000/e500crtrest32gpr.asm
-+ cat $(srcdir)/config/rs6000/e500crtrest32gpr.asm >e500crtrest32gpr.S
-+
-+e500crtrest64gpr.S: $(srcdir)/config/rs6000/e500crtrest64gpr.asm
-+ cat $(srcdir)/config/rs6000/e500crtrest64gpr.asm >e500crtrest64gpr.S
-+
-+e500crtresx32gpr.S: $(srcdir)/config/rs6000/e500crtresx32gpr.asm
-+ cat $(srcdir)/config/rs6000/e500crtresx32gpr.asm >e500crtresx32gpr.S
-+
-+e500crtresx64gpr.S: $(srcdir)/config/rs6000/e500crtresx64gpr.asm
-+ cat $(srcdir)/config/rs6000/e500crtresx64gpr.asm >e500crtresx64gpr.S
-+
-+e500crtsav32gpr.S: $(srcdir)/config/rs6000/e500crtsav32gpr.asm
-+ cat $(srcdir)/config/rs6000/e500crtsav32gpr.asm >e500crtsav32gpr.S
-+
-+e500crtsav64gpr.S: $(srcdir)/config/rs6000/e500crtsav64gpr.asm
-+ cat $(srcdir)/config/rs6000/e500crtsav64gpr.asm >e500crtsav64gpr.S
-+
-+e500crtsav64gprctr.S: $(srcdir)/config/rs6000/e500crtsav64gprctr.asm
-+ cat $(srcdir)/config/rs6000/e500crtsav64gprctr.asm >e500crtsav64gprctr.S
-+
-+e500crtsavg32gpr.S: $(srcdir)/config/rs6000/e500crtsavg32gpr.asm
-+ cat $(srcdir)/config/rs6000/e500crtsavg32gpr.asm >e500crtsavg32gpr.S
-+
-+e500crtsavg64gpr.S: $(srcdir)/config/rs6000/e500crtsavg64gpr.asm
-+ cat $(srcdir)/config/rs6000/e500crtsavg64gpr.asm >e500crtsavg64gpr.S
-+
-+e500crtsavg64gprctr.S: $(srcdir)/config/rs6000/e500crtsavg64gprctr.asm
-+ cat $(srcdir)/config/rs6000/e500crtsavg64gprctr.asm >e500crtsavg64gprctr.S
-+
- # Build multiple copies of ?crt{i,n}.o, one for each target switch.
- $(T)ecrti$(objext): ecrti.S
- $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c ecrti.S -o $(T)ecrti$(objext)
-@@ -49,6 +119,63 @@ $(T)ncrti$(objext): ncrti.S
- $(T)ncrtn$(objext): ncrtn.S
- $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c ncrtn.S -o $(T)ncrtn$(objext)
-
-+$(T)crtsavfpr$(objext): crtsavfpr.S
-+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c crtsavfpr.S -o $(T)crtsavfpr$(objext)
-+
-+$(T)crtresfpr$(objext): crtresfpr.S
-+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c crtresfpr.S -o $(T)crtresfpr$(objext)
-+
-+$(T)crtsavgpr$(objext): crtsavgpr.S
-+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c crtsavgpr.S -o $(T)crtsavgpr$(objext)
-+
-+$(T)crtresgpr$(objext): crtresgpr.S
-+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c crtresgpr.S -o $(T)crtresgpr$(objext)
-+
-+$(T)crtresxfpr$(objext): crtresxfpr.S
-+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c crtresxfpr.S -o $(T)crtresxfpr$(objext)
-+
-+$(T)crtresxgpr$(objext): crtresxgpr.S
-+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c crtresxgpr.S -o $(T)crtresxgpr$(objext)
-+
-+$(T)e500crtres32gpr$(objext): e500crtres32gpr.S
-+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c e500crtres32gpr.S -o $(T)e500crtres32gpr$(objext)
-+
-+$(T)e500crtres64gpr$(objext): e500crtres64gpr.S
-+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c e500crtres64gpr.S -o $(T)e500crtres64gpr$(objext)
-+
-+$(T)e500crtres64gprctr$(objext): e500crtres64gprctr.S
-+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c e500crtres64gprctr.S -o $(T)e500crtres64gprctr$(objext)
-+
-+$(T)e500crtrest32gpr$(objext): e500crtrest32gpr.S
-+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c e500crtrest32gpr.S -o $(T)e500crtrest32gpr$(objext)
-+
-+$(T)e500crtrest64gpr$(objext): e500crtrest64gpr.S
-+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c e500crtrest64gpr.S -o $(T)e500crtrest64gpr$(objext)
-+
-+$(T)e500crtresx32gpr$(objext): e500crtresx32gpr.S
-+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c e500crtresx32gpr.S -o $(T)e500crtresx32gpr$(objext)
-+
-+$(T)e500crtresx64gpr$(objext): e500crtresx64gpr.S
-+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c e500crtresx64gpr.S -o $(T)e500crtresx64gpr$(objext)
-+
-+$(T)e500crtsav32gpr$(objext): e500crtsav32gpr.S
-+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c e500crtsav32gpr.S -o $(T)e500crtsav32gpr$(objext)
-+
-+$(T)e500crtsav64gpr$(objext): e500crtsav64gpr.S
-+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c e500crtsav64gpr.S -o $(T)e500crtsav64gpr$(objext)
-+
-+$(T)e500crtsav64gprctr$(objext): e500crtsav64gprctr.S
-+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c e500crtsav64gprctr.S -o $(T)e500crtsav64gprctr$(objext)
-+
-+$(T)e500crtsavg32gpr$(objext): e500crtsavg32gpr.S
-+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c e500crtsavg32gpr.S -o $(T)e500crtsavg32gpr$(objext)
-+
-+$(T)e500crtsavg64gpr$(objext): e500crtsavg64gpr.S
-+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c e500crtsavg64gpr.S -o $(T)e500crtsavg64gpr$(objext)
-+
-+$(T)e500crtsavg64gprctr$(objext): e500crtsavg64gprctr.S
-+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c e500crtsavg64gprctr.S -o $(T)e500crtsavg64gprctr$(objext)
-+
- # It is important that crtbegin.o, etc., aren't surprised by stuff in .sdata.
- CRTSTUFF_T_CFLAGS = -msdata=none
- # Make sure crt*.o are built with -fPIC even if configured with
---- a/gcc/config/sh/lib1funcs.asm
-+++ b/gcc/config/sh/lib1funcs.asm
-@@ -2080,8 +2080,9 @@ GLOBAL(ic_invalidate):
- GLOBAL(ic_invalidate):
- ocbwb @r4
- synco
-- rts
- icbi @r4
-+ rts
-+ nop
- ENDFUNC(GLOBAL(ic_invalidate))
- #elif defined(__SH4_SINGLE__) || defined(__SH4__) || defined(__SH4_SINGLE_ONLY__) || (defined(__SH4_NOFPU__) && !defined(__SH5__))
- /* For system code, we use ic_invalidate_line_i, but user code
-@@ -2147,8 +2148,10 @@ GLOBAL(ic_invalidate):
- GLOBAL(ic_invalidate_array):
- add r1,r4
- synco
-- rts
- icbi @r4
-+ rts
-+ nop
-+ .align 2
- .long 0
- ENDFUNC(GLOBAL(ic_invalidate_array))
- #elif defined(__SH4_SINGLE__) || defined(__SH4__) || defined(__SH4_SINGLE_ONLY__) || (defined(__SH4_NOFPU__) && !defined(__SH5__))
---- a/gcc/config/sh/linux-unwind.h
-+++ b/gcc/config/sh/linux-unwind.h
-@@ -24,7 +24,10 @@ see the files COPYING3 and COPYING.RUNTI
-
-
- /* Do code reading to identify a signal frame, and set the frame
-- state data appropriately. See unwind-dw2.c for the structs. */
-+ state data appropriately. See unwind-dw2.c for the structs.
-+ Don't use this at all if inhibit_libc is used. */
-+
-+#ifndef inhibit_libc
-
- #include <signal.h>
- #include <sys/ucontext.h>
-@@ -248,3 +251,5 @@ sh_fallback_frame_state (struct _Unwind_
- return _URC_NO_REASON;
- }
- #endif /* defined (__SH5__) */
-+
-+#endif /* inhibit_libc */
---- a/gcc/config/sh/sh.h
-+++ b/gcc/config/sh/sh.h
-@@ -712,8 +712,9 @@ do { \
- /* Never run scheduling before reload, since that can \
- break global alloc, and generates slower code anyway due \
- to the pressure on R0. */ \
-- /* Enable sched1 for SH4; ready queue will be reordered by \
-- the target hooks when pressure is high. We can not do this for \
-+ /* Enable sched1 for SH4 if the user explicitly requests. \
-+ When sched1 is enabled, the ready queue will be reordered by \
-+ the target hooks if pressure is high. We can not do this for \
- PIC, SH3 and lower as they give spill failures for R0. */ \
- if (!TARGET_HARD_SH4 || flag_pic) \
- flag_schedule_insns = 0; \
-@@ -728,6 +729,8 @@ do { \
- warning (0, "ignoring -fschedule-insns because of exception handling bug"); \
- flag_schedule_insns = 0; \
- } \
-+ else if (flag_schedule_insns == 2) \
-+ flag_schedule_insns = 0; \
- } \
- \
- if (align_loops == 0) \
---- a/gcc/config/sh/t-1e
-+++ /dev/null
-@@ -1 +0,0 @@
--MULTILIB_ENDIAN =
---- a/gcc/config/sh/t-linux
-+++ b/gcc/config/sh/t-linux
-@@ -4,6 +4,5 @@ LIB2FUNCS_EXTRA= $(srcdir)/config/sh/lin
-
- MULTILIB_DIRNAMES=
- MULTILIB_MATCHES =
--MULTILIB_EXCEPTIONS=
-
- EXTRA_MULTILIB_PARTS= crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o
---- a/gcc/config/sh/t-mlib-sh1
-+++ /dev/null
-@@ -1 +0,0 @@
--ML_sh1=m1/
---- a/gcc/config/sh/t-mlib-sh2
-+++ /dev/null
-@@ -1 +0,0 @@
--ML_sh2=m2/
---- a/gcc/config/sh/t-mlib-sh2a
-+++ /dev/null
-@@ -1 +0,0 @@
--ML_sh2a=m2a/
---- a/gcc/config/sh/t-mlib-sh2a-nofpu
-+++ /dev/null
-@@ -1 +0,0 @@
--ML_sh2a_nofpu=m2a-nofpu/
---- a/gcc/config/sh/t-mlib-sh2a-single
-+++ /dev/null
-@@ -1 +0,0 @@
--ML_sh2a_single=m2a-single/
---- a/gcc/config/sh/t-mlib-sh2a-single-only
-+++ /dev/null
-@@ -1 +0,0 @@
--ML_sh2a_single_only=m2a-single-only/
---- a/gcc/config/sh/t-mlib-sh2e
-+++ /dev/null
-@@ -1 +0,0 @@
--ML_sh2e=m2e/
---- a/gcc/config/sh/t-mlib-sh3
-+++ /dev/null
-@@ -1 +0,0 @@
--ML_sh3=m3/
---- a/gcc/config/sh/t-mlib-sh3e
-+++ /dev/null
-@@ -1 +0,0 @@
--ML_sh3e=m3e/
---- a/gcc/config/sh/t-mlib-sh4
-+++ /dev/null
-@@ -1 +0,0 @@
--ML_sh4=m4/
---- a/gcc/config/sh/t-mlib-sh4-nofpu
-+++ /dev/null
-@@ -1 +0,0 @@
--ML_sh4_nofpu=m4-nofpu/
---- a/gcc/config/sh/t-mlib-sh4-single
-+++ /dev/null
-@@ -1 +0,0 @@
--ML_sh4_single=m4-single/
---- a/gcc/config/sh/t-mlib-sh4-single-only
-+++ /dev/null
-@@ -1 +0,0 @@
--ML_sh4_single_only=m4-single-only/
---- a/gcc/config/sh/t-mlib-sh4a
-+++ /dev/null
-@@ -1 +0,0 @@
--ML_sh4a=m4a/
---- a/gcc/config/sh/t-mlib-sh4a-nofpu
-+++ /dev/null
-@@ -1 +0,0 @@
--ML_sh4a_nofpu=m4a-nofpu/
---- a/gcc/config/sh/t-mlib-sh4a-single
-+++ /dev/null
-@@ -1 +0,0 @@
--ML_sh4a_single=m4a-single/
---- a/gcc/config/sh/t-mlib-sh4a-single-only
-+++ /dev/null
-@@ -1 +0,0 @@
--ML_sh4a_single_only=m4a-single-only/
---- a/gcc/config/sh/t-mlib-sh4al
-+++ /dev/null
-@@ -1 +0,0 @@
--ML_sh4al=m4al/
---- a/gcc/config/sh/t-mlib-sh5-32media
-+++ /dev/null
-@@ -1 +0,0 @@
--ML_sh5_32media=m5-32media/
---- a/gcc/config/sh/t-mlib-sh5-32media-nofpu
-+++ /dev/null
-@@ -1 +0,0 @@
--ML_sh5_32media_nofpu=m5-32media-nofpu/
---- a/gcc/config/sh/t-mlib-sh5-64media
-+++ /dev/null
-@@ -1 +0,0 @@
--ML_sh5_64media=m5-64media/
---- a/gcc/config/sh/t-mlib-sh5-64media-nofpu
-+++ /dev/null
-@@ -1 +0,0 @@
--ML_sh5_64media_nofpu=m5-64media-nofpu/
---- a/gcc/config/sh/t-mlib-sh5-compact
-+++ /dev/null
-@@ -1 +0,0 @@
--ML_sh5_compact=m5-compact/
---- a/gcc/config/sh/t-mlib-sh5-compact-nofpu
-+++ /dev/null
-@@ -1 +0,0 @@
--ML_sh5_compact_nofpu=m5-compact-nofpu/
---- a/gcc/config/sh/t-sh
-+++ b/gcc/config/sh/t-sh
-@@ -27,10 +27,10 @@ fp-bit.c: $(srcdir)/config/fp-bit.c
- echo '#endif' >> fp-bit.c
- cat $(srcdir)/config/fp-bit.c >> fp-bit.c
-
--MULTILIB_ENDIAN = ml/mb
--MULTILIB_CPUS= $(ML_sh1)$(ML_sh2a)$(ML_sh2a_nofpu)$(ML_sh2a_single_only)$(ML_sh2a_single)$(ML_sh2e)$(ML_sh2)$(ML_sh3e)$(ML_sh3)$(ML_sh4_nofpu)$(ML_sh4_single_only)$(ML_sh4_single)$(ML_sh4)$(ML_sh4a_nofpu)$(ML_sh4a_single_only)$(ML_sh4a_single)$(ML_sh4a)$(ML_sh5_32media)$(ML_sh5_32media_nofpu)$(ML_sh5_compact)$(ML_sh5_compact_nofpu)$(ML_sh5_64media)$(ML_sh5_64media_nofpu)
-+DEFAULT_ENDIAN = $(word 1,$(TM_ENDIAN_CONFIG))
-+OTHER_ENDIAN = $(word 2,$(TM_ENDIAN_CONFIG))
-
--MULTILIB_OPTIONS= $(MULTILIB_ENDIAN) $(MULTILIB_CPUS:/=)
-+MULTILIB_OPTIONS= $(OTHER_ENDIAN) $(TM_MULTILIB_CONFIG)
- MULTILIB_DIRNAMES=
-
- # The separate entries for m2a-nofpu and m2a-single-only with
-@@ -58,7 +58,34 @@ MULTILIB_MATCHES = $(shell \
- done)
-
- # SH1 only supports big endian.
--MULTILIB_EXCEPTIONS = ml/m1 ml/m2a*
-+MULTILIB_EXCEPTIONS = ml/m1 ml/m2a* $(TM_MULTILIB_EXCEPTIONS_CONFIG)
-+
-+MULTILIB_OSDIRNAMES = \
-+ $(OTHER_ENDIAN)=!$(OTHER_ENDIAN) \
-+ m1=!m1 $(OTHER_ENDIAN)/m1=!$(OTHER_ENDIAN)/m1 \
-+ m2a=!m2a $(OTHER_ENDIAN)/m2a=!$(OTHER_ENDIAN)/m2a \
-+ m2a-nofpu=!m2a-nofpu $(OTHER_ENDIAN)/m2a-nofpu=!$(OTHER_ENDIAN)/m2a-nofpu \
-+ m2a-single-only=!m2a-single-only $(OTHER_ENDIAN)/m2a-single-only=!$(OTHER_ENDIAN)/m2a-single-only \
-+ m2a-single=!m2a-single $(OTHER_ENDIAN)/m2a-single=!$(OTHER_ENDIAN)/m2a-single \
-+ m2e=!m2e $(OTHER_ENDIAN)/m2e=!$(OTHER_ENDIAN)/m2e \
-+ m2=!m2 $(OTHER_ENDIAN)/m2=!$(OTHER_ENDIAN)/m2 \
-+ m3e=!m3e $(OTHER_ENDIAN)/m3e=!$(OTHER_ENDIAN)/m3e \
-+ m3=!m3 $(OTHER_ENDIAN)/m3=!$(OTHER_ENDIAN)/m3 \
-+ m4-nofpu=!m4-nofpu $(OTHER_ENDIAN)/m4-nofpu=!$(OTHER_ENDIAN)/m4-nofpu \
-+ m4-single-only=!m4-single-only $(OTHER_ENDIAN)/m4-single-only=!$(OTHER_ENDIAN)/m4-single-only \
-+ m4-single=!m4-single $(OTHER_ENDIAN)/m4-single=!$(OTHER_ENDIAN)/m4-single \
-+ m4=!m4 $(OTHER_ENDIAN)/m4=!$(OTHER_ENDIAN)/m4 \
-+ m4a-nofpu=!m4a-nofpu $(OTHER_ENDIAN)/m4a-nofpu=!$(OTHER_ENDIAN)/m4a-nofpu \
-+ m4a-single-only=!m4a-single-only $(OTHER_ENDIAN)/m4a-single-only=!$(OTHER_ENDIAN)/m4a-single-only \
-+ m4a-single=!m4a-single $(OTHER_ENDIAN)/m4a-single=!$(OTHER_ENDIAN)/m4a-single \
-+ m4a=!m4a $(OTHER_ENDIAN)/m4a=!$(OTHER_ENDIAN)/m4a \
-+ m4al=!m4al $(OTHER_ENDIAN)/m4al=!$(OTHER_ENDIAN)/m4al \
-+ m5-32media=!m5-32media $(OTHER_ENDIAN)/m5-32media=!$(OTHER_ENDIAN)/m5-32media \
-+ m5-32media-nofpu=!m5-32media-nofpu $(OTHER_ENDIAN)/m5-32media-nofpu=!$(OTHER_ENDIAN)/m5-32media-nofpu \
-+ m5-compact=!m5-compact $(OTHER_ENDIAN)/m5-compact=!$(OTHER_ENDIAN)/m5-compact \
-+ m5-compact-nofpu=!m5-compact-nofpu $(OTHER_ENDIAN)/m5-compact-nofpu=!$(OTHER_ENDIAN)/m5-compact-nofpu \
-+ m5-64media=!m5-64media $(OTHER_ENDIAN)/m5-64media=!$(OTHER_ENDIAN)/m5-64media \
-+ m5-64media-nofpu=!m5-64media-nofpu $(OTHER_ENDIAN)/m5-64media-nofpu=!$(OTHER_ENDIAN)/m5-64media-nofpu
-
- LIBGCC = stmp-multilib
- INSTALL_LIBGCC = install-multilib
---- a/gcc/config/sol2.h
-+++ b/gcc/config/sol2.h
-@@ -123,12 +123,12 @@ along with GCC; see the file COPYING3.
- %{YP,*} \
- %{R*} \
- %{compat-bsd: \
-- %{!YP,*:%{p|pg:-Y P,/usr/ucblib:/usr/ccs/lib/libp:/usr/lib/libp:/usr/ccs/lib:/usr/lib} \
-- %{!p:%{!pg:-Y P,/usr/ucblib:/usr/ccs/lib:/usr/lib}}} \
-- -R /usr/ucblib} \
-+ %{!YP,*:%{p|pg:-Y P,%R/usr/ucblib:%R/usr/ccs/lib/libp:%R/usr/lib/libp:%R/usr/ccs/lib:%R/usr/lib} \
-+ %{!p:%{!pg:-Y P,%R/usr/ucblib:%R/usr/ccs/lib:%R/usr/lib}}} \
-+ -R %R/usr/ucblib} \
- %{!compat-bsd: \
-- %{!YP,*:%{p|pg:-Y P,/usr/ccs/lib/libp:/usr/lib/libp:/usr/ccs/lib:/usr/lib} \
-- %{!p:%{!pg:-Y P,/usr/ccs/lib:/usr/lib}}}}"
-+ %{!YP,*:%{p|pg:-Y P,%R/usr/ccs/lib/libp:%R/usr/lib/libp:%R/usr/ccs/lib:%R/usr/lib} \
-+ %{!p:%{!pg:-Y P,%R/usr/ccs/lib:%R/usr/lib}}}}"
-
- #undef LINK_ARCH32_SPEC
- #define LINK_ARCH32_SPEC LINK_ARCH32_SPEC_BASE
---- a/gcc/config/sparc/linux64.h
-+++ b/gcc/config/sparc/linux64.h
-@@ -40,10 +40,15 @@ along with GCC; see the file COPYING3.
- in a Medium/Low code model environment. */
-
- #undef TARGET_DEFAULT
-+#ifdef BIARCH_32BIT_DEFAULT
-+#define TARGET_DEFAULT \
-+ (MASK_APP_REGS + MASK_FPU)
-+#else
- #define TARGET_DEFAULT \
- (MASK_V9 + MASK_PTR64 + MASK_64BIT /* + MASK_HARD_QUAD */ \
- + MASK_STACK_BIAS + MASK_APP_REGS + MASK_FPU + MASK_LONG_DOUBLE_128)
- #endif
-+#endif
-
- /* This must be v9a not just v9 because by default we enable
- -mvis. */
---- a/gcc/config/sparc/sol2-bi.h
-+++ b/gcc/config/sparc/sol2-bi.h
-@@ -172,12 +172,12 @@
- %{YP,*} \
- %{R*} \
- %{compat-bsd: \
-- %{!YP,*:%{p|pg:-Y P,/usr/ucblib/sparcv9:/usr/lib/libp/sparcv9:/usr/lib/sparcv9} \
-- %{!p:%{!pg:-Y P,/usr/ucblib/sparcv9:/usr/lib/sparcv9}}} \
-- -R /usr/ucblib/sparcv9} \
-+ %{!YP,*:%{p|pg:-Y P,%R/usr/ucblib/sparcv9:%R/usr/lib/libp/sparcv9:%R/usr/lib/sparcv9} \
-+ %{!p:%{!pg:-Y P,%R/usr/ucblib/sparcv9:%R/usr/lib/sparcv9}}} \
-+ -R %R/usr/ucblib/sparcv9} \
- %{!compat-bsd: \
-- %{!YP,*:%{p|pg:-Y P,/usr/lib/libp/sparcv9:/usr/lib/sparcv9} \
-- %{!p:%{!pg:-Y P,/usr/lib/sparcv9}}}}"
-+ %{!YP,*:%{p|pg:-Y P,%R/usr/lib/libp/sparcv9:%R/usr/lib/sparcv9} \
-+ %{!p:%{!pg:-Y P,%R/usr/lib/sparcv9}}}}"
-
- #define LINK_ARCH64_SPEC LINK_ARCH64_SPEC_BASE
-
---- a/gcc/config/sparc/sparc.c
-+++ b/gcc/config/sparc/sparc.c
-@@ -6104,7 +6104,7 @@ enum rtx_code
- sparc_emit_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison)
- {
- const char *qpfunc;
-- rtx slot0, slot1, result, tem, tem2;
-+ rtx slot0, slot1, result, tem, tem2, libfunc;
- enum machine_mode mode;
- enum rtx_code new_comparison;
-
-@@ -6167,7 +6167,8 @@ sparc_emit_float_lib_cmp (rtx x, rtx y,
- emit_move_insn (slot1, y);
- }
-
-- emit_library_call (gen_rtx_SYMBOL_REF (Pmode, qpfunc), LCT_NORMAL,
-+ libfunc = gen_rtx_SYMBOL_REF (Pmode, qpfunc);
-+ emit_library_call (libfunc, LCT_NORMAL,
- DImode, 2,
- XEXP (slot0, 0), Pmode,
- XEXP (slot1, 0), Pmode);
-@@ -6175,7 +6176,8 @@ sparc_emit_float_lib_cmp (rtx x, rtx y,
- }
- else
- {
-- emit_library_call (gen_rtx_SYMBOL_REF (Pmode, qpfunc), LCT_NORMAL,
-+ libfunc = gen_rtx_SYMBOL_REF (Pmode, qpfunc);
-+ emit_library_call (libfunc, LCT_NORMAL,
- SImode, 2,
- x, TFmode, y, TFmode);
- mode = SImode;
-@@ -6186,7 +6188,7 @@ sparc_emit_float_lib_cmp (rtx x, rtx y,
- register so reload doesn't clobber the value if it needs
- the return register for a spill reg. */
- result = gen_reg_rtx (mode);
-- emit_move_insn (result, hard_libcall_value (mode));
-+ emit_move_insn (result, hard_libcall_value (mode, libfunc));
-
- switch (comparison)
- {
---- a/gcc/config/spu/spu.h
-+++ b/gcc/config/spu/spu.h
-@@ -270,7 +270,8 @@ targetm.resolve_overloaded_builtin = spu
-
- #define DWARF_FRAME_RETURN_COLUMN DWARF_FRAME_REGNUM (LINK_REGISTER_REGNUM)
-
--#define ARG_POINTER_CFA_OFFSET(FNDECL) (-STACK_POINTER_OFFSET)
-+#define ARG_POINTER_CFA_OFFSET(FNDECL) \
-+ (crtl->args.pretend_args_size - STACK_POINTER_OFFSET)
-
- \f
- /* Stack Checking */
---- /dev/null
-+++ b/gcc/config/t-eglibc
-@@ -0,0 +1,25 @@
-+# multilibs -*- mode:Makefile -*-
-+
-+MULTILIB_EXCEPTIONS :=
-+MULTILIB_MATCHES :=
-+MULTILIB_ALIASES :=
-+
-+# For all items in EGLIBC_CONFIGS except for the last one
-+# do $1. For the last one do $2. The items are separated with ",".
-+EGLIBC_AWK = $(shell echo $(EGLIBC_CONFIGS) | $(AWK) \
-+ '{ \
-+ N=split ($$0, configs, ","); \
-+ for (i = 1; i < N; ++i) $1; \
-+ $2; \
-+ }')
-+
-+MULTILIB_OPTIONS := $(call EGLIBC_AWK, \
-+ printf ("feglibc=%s/", configs[i]), \
-+ printf ("feglibc=%s\n", configs[i]))
-+MULTILIB_DIRNAMES := $(call EGLIBC_AWK, \
-+ printf ("%s ", configs[i]), \
-+ printf ("%s\n", configs[i]))
-+MULTILIB_OSDIRNAMES := $(call EGLIBC_AWK, \
-+ printf ("feglibc.%s=!%s ", configs[i], configs[i]), \
-+ printf ("feglibc.%s=!%s\n", configs[i], configs[i]))
-+
---- a/gcc/configure
-+++ b/gcc/configure
-@@ -458,7 +458,7 @@ ac_includes_default="\
- # include <unistd.h>
- #endif"
-
--ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os target_noncanonical build_libsubdir build_subdir host_subdir target_subdir GENINSRC CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT GNATBIND ac_ct_GNATBIND GNATMAKE ac_ct_GNATMAKE NO_MINUS_C_MINUS_O OUTPUT_OPTION CPP EGREP loose_warn strict_warn warn_cflags nocommon_flag TREEBROWSER valgrind_path valgrind_path_defines valgrind_command coverage_flags enable_multilib enable_decimal_float enable_fixed_point enable_shared TARGET_SYSTEM_ROOT TARGET_SYSTEM_ROOT_DEFINE CROSS_SYSTEM_HEADER_DIR onestep PKGVERSION REPORT_BUGS_TO REPORT_BUGS_TEXI datarootdir docdir htmldir SET_MAKE AWK LN_S LN RANLIB ac_ct_RANLIB ranlib_flags INSTALL INSTALL_PROGRAM INSTALL_DATA make_compare_target have_mktemp_command MAKEINFO BUILD_INFO GENERATED_MANPAGES FLEX BISON NM AR COLLECT2_LIBS GNAT_LIBEXC LDEXP_LIB TARGET_GETGROUPS_T LIBICONV LTLIBICONV LIBICONV_DEP manext objext gthread_flags extra_modes_file extra_opt_files USE_NLS LIBINTL LIBINTL_DEP INCINTL XGETTEXT GMSGFMT POSUB CATALOGS DATADIRNAME INSTOBJEXT GENCAT CATOBJEXT CROSS ALL SYSTEM_HEADER_DIR inhibit_libc CC_FOR_BUILD BUILD_CFLAGS BUILD_LDFLAGS STMP_FIXINC STMP_FIXPROTO collect2 LIBTOOL SED FGREP GREP LD DUMPBIN ac_ct_DUMPBIN OBJDUMP ac_ct_OBJDUMP ac_ct_AR STRIP ac_ct_STRIP lt_ECHO DSYMUTIL ac_ct_DSYMUTIL NMEDIT ac_ct_NMEDIT LIPO ac_ct_LIPO OTOOL ac_ct_OTOOL OTOOL64 ac_ct_OTOOL64 objdir enable_fast_install gcc_cv_as ORIGINAL_AS_FOR_TARGET gcc_cv_ld ORIGINAL_LD_FOR_TARGET gcc_cv_nm ORIGINAL_NM_FOR_TARGET gcc_cv_objdump gcc_cv_readelf libgcc_visibility GGC zlibdir zlibinc MAINT gcc_tooldir dollar slibdir subdirs srcdir all_compilers all_gtfiles all_lang_makefrags all_lang_makefiles all_languages all_selected_languages build_exeext build_install_headers_dir build_xm_file_list build_xm_include_list build_xm_defines build_file_translate check_languages cpp_install_dir xmake_file tmake_file extra_gcc_objs extra_headers_list extra_objs extra_parts extra_passes extra_programs float_h_file gcc_config_arguments gcc_gxx_include_dir host_exeext host_xm_file_list host_xm_include_list host_xm_defines out_host_hook_obj install lang_opt_files lang_specs_files lang_tree_files local_prefix md_file objc_boehm_gc out_file out_object_file thread_file tm_file_list tm_include_list tm_defines tm_p_file_list tm_p_include_list xm_file_list xm_include_list xm_defines c_target_objs cxx_target_objs fortran_target_objs target_cpu_default GMPLIBS GMPINC PPLLIBS PPLINC CLOOGLIBS CLOOGINC LIBOBJS LTLIBOBJS'
-+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os target_noncanonical build_libsubdir build_subdir host_subdir target_subdir GENINSRC CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT GNATBIND ac_ct_GNATBIND GNATMAKE ac_ct_GNATMAKE NO_MINUS_C_MINUS_O OUTPUT_OPTION CPP EGREP loose_warn strict_warn warn_cflags nocommon_flag TREEBROWSER valgrind_path valgrind_path_defines valgrind_command coverage_flags enable_multilib enable_decimal_float enable_fixed_point enable_shared TARGET_SYSTEM_ROOT TARGET_SYSTEM_ROOT_DEFINE CROSS_SYSTEM_HEADER_DIR EGLIBC_CONFIGS CONFIGURE_SPECS onestep PKGVERSION REPORT_BUGS_TO REPORT_BUGS_TEXI datarootdir docdir htmldir SET_MAKE AWK LN_S LN RANLIB ac_ct_RANLIB ranlib_flags INSTALL INSTALL_PROGRAM INSTALL_DATA make_compare_target have_mktemp_command MAKEINFO BUILD_INFO GENERATED_MANPAGES FLEX BISON NM AR COLLECT2_LIBS GNAT_LIBEXC LDEXP_LIB TARGET_GETGROUPS_T LIBICONV LTLIBICONV LIBICONV_DEP manext objext gthread_flags extra_modes_file extra_opt_files USE_NLS LIBINTL LIBINTL_DEP INCINTL XGETTEXT GMSGFMT POSUB CATALOGS DATADIRNAME INSTOBJEXT GENCAT CATOBJEXT CROSS ALL SYSTEM_HEADER_DIR inhibit_libc CC_FOR_BUILD BUILD_CFLAGS BUILD_LDFLAGS STMP_FIXINC STMP_FIXPROTO collect2 LIBTOOL SED FGREP GREP LD DUMPBIN ac_ct_DUMPBIN OBJDUMP ac_ct_OBJDUMP ac_ct_AR STRIP ac_ct_STRIP lt_ECHO DSYMUTIL ac_ct_DSYMUTIL NMEDIT ac_ct_NMEDIT LIPO ac_ct_LIPO OTOOL ac_ct_OTOOL OTOOL64 ac_ct_OTOOL64 objdir enable_fast_install gcc_cv_as ORIGINAL_AS_FOR_TARGET gcc_cv_ld ORIGINAL_LD_FOR_TARGET gcc_cv_nm ORIGINAL_NM_FOR_TARGET gcc_cv_objdump gcc_cv_readelf libgcc_visibility GGC zlibdir zlibinc MAINT gcc_tooldir dollar slibdir subdirs srcdir all_compilers all_gtfiles all_lang_makefrags all_lang_makefiles all_languages all_selected_languages build_exeext build_install_headers_dir build_xm_file_list build_xm_include_list build_xm_defines build_file_translate check_languages cpp_install_dir xmake_file tmake_file TM_ENDIAN_CONFIG TM_MULTILIB_CONFIG TM_MULTILIB_EXCEPTIONS_CONFIG extra_gcc_objs extra_headers_list extra_objs extra_parts extra_passes extra_programs float_h_file gcc_config_arguments gcc_gxx_include_dir host_exeext host_xm_file_list host_xm_include_list host_xm_defines out_host_hook_obj install lang_opt_files lang_specs_files lang_tree_files local_prefix md_file objc_boehm_gc out_file out_object_file thread_file tm_file_list tm_include_list tm_defines tm_p_file_list tm_p_include_list xm_file_list xm_include_list xm_defines c_target_objs cxx_target_objs fortran_target_objs target_cpu_default GMPLIBS GMPINC PPLLIBS PPLINC CLOOGLIBS CLOOGINC LIBOBJS LTLIBOBJS'
- ac_subst_files='language_hooks'
- ac_pwd=`pwd`
-
-@@ -1084,6 +1084,8 @@ Optional Features:
- --enable-version-specific-runtime-libs
- specify that runtime libraries should be
- installed in a compiler-specific directory
-+ --enable-poison-system-directories
-+ warn for use of native system header directories
-
- Optional Packages:
- --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
-@@ -1105,8 +1107,12 @@ Optional Packages:
- --with-build-sysroot=sysroot
- use sysroot as the system root during the build
- --with-sysroot=DIR Search for usr/lib, usr/include, et al, within DIR.
-+ --with-eglibc-configs=CONFIGS
-+ build multilibs for these EGLIBC configurations
-+ --with-specs=SPECS add SPECS to driver command-line processing
- --with-pkgversion=PKG Use PKG in the version string in place of "GCC"
- --with-bugurl=URL Direct users to URL to report a bug
-+ --with-multilib-list Select multilibs (SH only)
- --with-gnu-ld assume the C compiler uses GNU ld default=no
- --with-libiconv-prefix[=DIR] search for libiconv in DIR/include and DIR/lib
- --without-libiconv-prefix don't search for libiconv in includedir and libdir
-@@ -8042,6 +8048,28 @@ fi;
-
-
-
-+
-+# Check whether --with-eglibc-configs or --without-eglibc-configs was given.
-+if test "${with_eglibc_configs+set}" = set; then
-+ withval="$with_eglibc_configs"
-+ EGLIBC_CONFIGS=$withval
-+else
-+ EGLIBC_CONFIGS=
-+
-+fi;
-+
-+
-+
-+# Check whether --with-specs or --without-specs was given.
-+if test "${with_specs+set}" = set; then
-+ withval="$with_specs"
-+ CONFIGURE_SPECS=$withval
-+else
-+ CONFIGURE_SPECS=
-+
-+fi;
-+
-+
- # Build with intermodule optimisations
- # Check whether --enable-intermodule or --disable-intermodule was given.
- if test "${enable_intermodule+set}" = set; then
-@@ -8137,6 +8165,15 @@ fi;
-
-
-
-+
-+# Check whether --with-multilib-list or --without-multilib-list was given.
-+if test "${with_multilib_list+set}" = set; then
-+ withval="$with_multilib_list"
-+ :
-+else
-+ with_multilib_list=default
-+fi;
-+
- # -------------------------
- # Checks for other programs
- # -------------------------
-@@ -14509,13 +14546,13 @@ if test "${lt_cv_nm_interface+set}" = se
- else
- lt_cv_nm_interface="BSD nm"
- echo "int some_variable = 0;" > conftest.$ac_ext
-- (eval echo "\"\$as_me:14512: $ac_compile\"" >&5)
-+ (eval echo "\"\$as_me:14621: $ac_compile\"" >&5)
- (eval "$ac_compile" 2>conftest.err)
- cat conftest.err >&5
-- (eval echo "\"\$as_me:14515: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
-+ (eval echo "\"\$as_me:14624: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
- (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
- cat conftest.err >&5
-- (eval echo "\"\$as_me:14518: output\"" >&5)
-+ (eval echo "\"\$as_me:14627: output\"" >&5)
- cat conftest.out >&5
- if $GREP 'External.*some_variable' conftest.out > /dev/null; then
- lt_cv_nm_interface="MS dumpbin"
-@@ -15672,7 +15709,7 @@ ia64-*-hpux*)
- ;;
- *-*-irix6*)
- # Find out which ABI we are using.
-- echo '#line 15675 "configure"' > conftest.$ac_ext
-+ echo '#line 15784 "configure"' > conftest.$ac_ext
- if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
-@@ -16971,11 +17008,11 @@ else
- -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
- -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
- -e 's:$: $lt_compiler_flag:'`
-- (eval echo "\"\$as_me:16974: $lt_compile\"" >&5)
-+ (eval echo "\"\$as_me:17083: $lt_compile\"" >&5)
- (eval "$lt_compile" 2>conftest.err)
- ac_status=$?
- cat conftest.err >&5
-- echo "$as_me:16978: \$? = $ac_status" >&5
-+ echo "$as_me:17087: \$? = $ac_status" >&5
- if (exit $ac_status) && test -s "$ac_outfile"; then
- # The compiler can only warn and ignore the option if not recognized
- # So say no if there are warnings other than the usual output.
-@@ -17310,11 +17347,11 @@ else
- -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
- -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
- -e 's:$: $lt_compiler_flag:'`
-- (eval echo "\"\$as_me:17313: $lt_compile\"" >&5)
-+ (eval echo "\"\$as_me:17422: $lt_compile\"" >&5)
- (eval "$lt_compile" 2>conftest.err)
- ac_status=$?
- cat conftest.err >&5
-- echo "$as_me:17317: \$? = $ac_status" >&5
-+ echo "$as_me:17426: \$? = $ac_status" >&5
- if (exit $ac_status) && test -s "$ac_outfile"; then
- # The compiler can only warn and ignore the option if not recognized
- # So say no if there are warnings other than the usual output.
-@@ -17415,11 +17452,11 @@ else
- -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
- -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
- -e 's:$: $lt_compiler_flag:'`
-- (eval echo "\"\$as_me:17418: $lt_compile\"" >&5)
-+ (eval echo "\"\$as_me:17527: $lt_compile\"" >&5)
- (eval "$lt_compile" 2>out/conftest.err)
- ac_status=$?
- cat out/conftest.err >&5
-- echo "$as_me:17422: \$? = $ac_status" >&5
-+ echo "$as_me:17531: \$? = $ac_status" >&5
- if (exit $ac_status) && test -s out/conftest2.$ac_objext
- then
- # The compiler can only warn and ignore the option if not recognized
-@@ -17470,11 +17507,11 @@ else
- -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
- -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
- -e 's:$: $lt_compiler_flag:'`
-- (eval echo "\"\$as_me:17473: $lt_compile\"" >&5)
-+ (eval echo "\"\$as_me:17582: $lt_compile\"" >&5)
- (eval "$lt_compile" 2>out/conftest.err)
- ac_status=$?
- cat out/conftest.err >&5
-- echo "$as_me:17477: \$? = $ac_status" >&5
-+ echo "$as_me:17586: \$? = $ac_status" >&5
- if (exit $ac_status) && test -s out/conftest2.$ac_objext
- then
- # The compiler can only warn and ignore the option if not recognized
-@@ -20282,7 +20319,7 @@ else
- lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
- lt_status=$lt_dlunknown
- cat > conftest.$ac_ext <<_LT_EOF
--#line 20285 "configure"
-+#line 20394 "configure"
- #include "confdefs.h"
-
- #if HAVE_DLFCN_H
-@@ -20378,7 +20415,7 @@ else
- lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
- lt_status=$lt_dlunknown
- cat > conftest.$ac_ext <<_LT_EOF
--#line 20381 "configure"
-+#line 20490 "configure"
- #include "confdefs.h"
-
- #if HAVE_DLFCN_H
-@@ -22144,6 +22181,22 @@ x:
- tls_first_minor=16
- tls_as_opt='-32 --fatal-warnings'
- ;;
-+ m68k-*-*)
-+ conftest_s='
-+ .section .tdata,"awT",@progbits
-+x:
-+ .word 2
-+ .text
-+foo:
-+ move.l x@TLSGD(%a5),%a0
-+ move.l x@TLSLDM(%a5),%a0
-+ move.l x@TLSLDO(%a5),%a0
-+ move.l x@TLSIE(%a5),%a0
-+ move.l x@TLSLE(%a5),%a0'
-+ tls_first_major=2
-+ tls_first_minor=19
-+ tls_as_opt='--fatal-warnings'
-+ ;;
- powerpc-*-*)
- conftest_s='
- .section ".tdata","awT",@progbits
-@@ -22775,6 +22828,44 @@ fi
- i[34567]86-*-* | x86_64-*-*)
- case $target_os in
- cygwin* | pe | mingw32*)
-+ # Recent binutils allows the three-operand form of ".comm" on PE. This
-+ # definition is used unconditionally to initialise the default state of
-+ # the target option variable that governs usage of the feature.
-+ echo "$as_me:$LINENO: checking assembler for .comm with alignment" >&5
-+echo $ECHO_N "checking assembler for .comm with alignment... $ECHO_C" >&6
-+if test "${gcc_cv_as_comm_has_align+set}" = set; then
-+ echo $ECHO_N "(cached) $ECHO_C" >&6
-+else
-+ gcc_cv_as_comm_has_align=no
-+ if test $in_tree_gas = yes; then
-+ if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 19 \) \* 1000 + 52`
-+ then gcc_cv_as_comm_has_align=yes
-+fi
-+ elif test x$gcc_cv_as != x; then
-+ echo '.comm foo,1,32' > conftest.s
-+ if { ac_try='$gcc_cv_as -o conftest.o conftest.s >&5'
-+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-+ (eval $ac_try) 2>&5
-+ ac_status=$?
-+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
-+ (exit $ac_status); }; }
-+ then
-+ gcc_cv_as_comm_has_align=yes
-+ else
-+ echo "configure: failed program was" >&5
-+ cat conftest.s >&5
-+ fi
-+ rm -f conftest.o conftest.s
-+ fi
-+fi
-+echo "$as_me:$LINENO: result: $gcc_cv_as_comm_has_align" >&5
-+echo "${ECHO_T}$gcc_cv_as_comm_has_align" >&6
-+
-+
-+cat >>confdefs.h <<_ACEOF
-+#define HAVE_GAS_ALIGNED_COMM `if test $gcc_cv_as_comm_has_align = yes; then echo 1; else echo 0; fi`
-+_ACEOF
-+
- # Used for DWARF 2 in PE
- echo "$as_me:$LINENO: checking assembler for .secrel32 relocs" >&5
- echo $ECHO_N "checking assembler for .secrel32 relocs... $ECHO_C" >&6
-@@ -24747,6 +24838,21 @@ else
- fi;
-
-
-+# Check whether --enable-poison-system-directories or --disable-poison-system-directories was given.
-+if test "${enable_poison_system_directories+set}" = set; then
-+ enableval="$enable_poison_system_directories"
-+
-+else
-+ enable_poison_system_directories=no
-+fi;
-+if test "x${enable_poison_system_directories}" = "xyes"; then
-+
-+cat >>confdefs.h <<\_ACEOF
-+#define ENABLE_POISON_SYSTEM_DIRECTORIES 1
-+_ACEOF
-+
-+fi
-+
- # Substitute configuration variables
-
-
-@@ -25523,6 +25629,8 @@ s,@enable_shared@,$enable_shared,;t t
- s,@TARGET_SYSTEM_ROOT@,$TARGET_SYSTEM_ROOT,;t t
- s,@TARGET_SYSTEM_ROOT_DEFINE@,$TARGET_SYSTEM_ROOT_DEFINE,;t t
- s,@CROSS_SYSTEM_HEADER_DIR@,$CROSS_SYSTEM_HEADER_DIR,;t t
-+s,@EGLIBC_CONFIGS@,$EGLIBC_CONFIGS,;t t
-+s,@CONFIGURE_SPECS@,$CONFIGURE_SPECS,;t t
- s,@onestep@,$onestep,;t t
- s,@PKGVERSION@,$PKGVERSION,;t t
- s,@REPORT_BUGS_TO@,$REPORT_BUGS_TO,;t t
-@@ -25642,6 +25750,9 @@ s,@check_languages@,$check_languages,;t
- s,@cpp_install_dir@,$cpp_install_dir,;t t
- s,@xmake_file@,$xmake_file,;t t
- s,@tmake_file@,$tmake_file,;t t
-+s,@TM_ENDIAN_CONFIG@,$TM_ENDIAN_CONFIG,;t t
-+s,@TM_MULTILIB_CONFIG@,$TM_MULTILIB_CONFIG,;t t
-+s,@TM_MULTILIB_EXCEPTIONS_CONFIG@,$TM_MULTILIB_EXCEPTIONS_CONFIG,;t t
- s,@extra_gcc_objs@,$extra_gcc_objs,;t t
- s,@extra_headers_list@,$extra_headers_list,;t t
- s,@extra_objs@,$extra_objs,;t t
---- a/gcc/configure.ac
-+++ b/gcc/configure.ac
-@@ -770,6 +770,22 @@ AC_SUBST(TARGET_SYSTEM_ROOT)
- AC_SUBST(TARGET_SYSTEM_ROOT_DEFINE)
- AC_SUBST(CROSS_SYSTEM_HEADER_DIR)
-
-+AC_ARG_WITH(eglibc-configs,
-+ [AS_HELP_STRING([--with-eglibc-configs=CONFIGS],
-+ [build multilibs for these EGLIBC configurations])],
-+ [EGLIBC_CONFIGS=$withval],
-+ [EGLIBC_CONFIGS=]
-+)
-+AC_SUBST(EGLIBC_CONFIGS)
-+
-+AC_ARG_WITH(specs,
-+ [AS_HELP_STRING([--with-specs=SPECS],
-+ [add SPECS to driver command-line processing])],
-+ [CONFIGURE_SPECS=$withval],
-+ [CONFIGURE_SPECS=]
-+)
-+AC_SUBST(CONFIGURE_SPECS)
-+
- # Build with intermodule optimisations
- AC_ARG_ENABLE(intermodule,
- [ --enable-intermodule build the compiler in one step],
-@@ -810,6 +826,11 @@ AC_SUBST(datarootdir)
- AC_SUBST(docdir)
- AC_SUBST(htmldir)
-
-+AC_ARG_WITH(multilib-list,
-+[ --with-multilib-list Select multilibs (SH only)],
-+:,
-+with_multilib_list=default)
-+
- # -------------------------
- # Checks for other programs
- # -------------------------
-@@ -2587,6 +2608,22 @@ x:
- tls_first_minor=16
- tls_as_opt='-32 --fatal-warnings'
- ;;
-+ m68k-*-*)
-+ conftest_s='
-+ .section .tdata,"awT",@progbits
-+x:
-+ .word 2
-+ .text
-+foo:
-+ move.l x@TLSGD(%a5),%a0
-+ move.l x@TLSLDM(%a5),%a0
-+ move.l x@TLSLDO(%a5),%a0
-+ move.l x@TLSIE(%a5),%a0
-+ move.l x@TLSLE(%a5),%a0'
-+ tls_first_major=2
-+ tls_first_minor=19
-+ tls_as_opt='--fatal-warnings'
-+ ;;
- powerpc-*-*)
- conftest_s='
- .section ".tdata","awT",@progbits
-@@ -2955,6 +2992,15 @@ changequote(,)dnl
- changequote([,])dnl
- case $target_os in
- cygwin* | pe | mingw32*)
-+ # Recent binutils allows the three-operand form of ".comm" on PE. This
-+ # definition is used unconditionally to initialise the default state of
-+ # the target option variable that governs usage of the feature.
-+ gcc_GAS_CHECK_FEATURE([.comm with alignment], gcc_cv_as_comm_has_align,
-+ [2,19,52],,[.comm foo,1,32])
-+ AC_DEFINE_UNQUOTED(HAVE_GAS_ALIGNED_COMM,
-+ [`if test $gcc_cv_as_comm_has_align = yes; then echo 1; else echo 0; fi`],
-+ [Define if your assembler supports specifying the alignment
-+ of objects allocated using the GAS .comm command.])
- # Used for DWARF 2 in PE
- gcc_GAS_CHECK_FEATURE([.secrel32 relocs],
- gcc_cv_as_ix86_pe_secrel32,
-@@ -3902,6 +3948,16 @@ htmldir="\${prefix}/$with_htmldir",
- htmldir='$(docdir)')
- AC_SUBST(htmldir)
-
-+AC_ARG_ENABLE([poison-system-directories],
-+ AS_HELP_STRING([--enable-poison-system-directories],
-+ [warn for use of native system header directories]),,
-+ [enable_poison_system_directories=no])
-+if test "x${enable_poison_system_directories}" = "xyes"; then
-+ AC_DEFINE([ENABLE_POISON_SYSTEM_DIRECTORIES],
-+ [1],
-+ [Define to warn for use of native system header directories])
-+fi
-+
- # Substitute configuration variables
- AC_SUBST(subdirs)
- AC_SUBST(srcdir)
-@@ -3921,6 +3977,9 @@ AC_SUBST(check_languages)
- AC_SUBST(cpp_install_dir)
- AC_SUBST(xmake_file)
- AC_SUBST(tmake_file)
-+AC_SUBST(TM_ENDIAN_CONFIG)
-+AC_SUBST(TM_MULTILIB_CONFIG)
-+AC_SUBST(TM_MULTILIB_EXCEPTIONS_CONFIG)
- AC_SUBST(extra_gcc_objs)
- AC_SUBST(extra_headers_list)
- AC_SUBST(extra_objs)
---- a/gcc/cp/class.c
-+++ b/gcc/cp/class.c
-@@ -6136,7 +6136,7 @@ resolve_address_of_overloaded_function (
- if (flags & tf_error)
- {
- error ("no matches converting function %qD to type %q#T",
-- DECL_NAME (OVL_FUNCTION (overload)),
-+ DECL_NAME (OVL_CURRENT (overload)),
- target_type);
-
- /* print_candidates expects a chain with the functions in
-@@ -6299,13 +6299,8 @@ instantiate_type (tree lhstype, tree rhs
- dependent on overload resolution. */
- gcc_assert (TREE_CODE (rhs) == ADDR_EXPR
- || TREE_CODE (rhs) == COMPONENT_REF
-- || TREE_CODE (rhs) == COMPOUND_EXPR
-- || really_overloaded_fn (rhs));
--
-- /* We don't overwrite rhs if it is an overloaded function.
-- Copying it would destroy the tree link. */
-- if (TREE_CODE (rhs) != OVERLOAD)
-- rhs = copy_node (rhs);
-+ || really_overloaded_fn (rhs)
-+ || (flag_ms_extensions && TREE_CODE (rhs) == FUNCTION_DECL));
-
- /* This should really only be used when attempting to distinguish
- what sort of a pointer to function we have. For now, any
-@@ -6357,19 +6352,6 @@ instantiate_type (tree lhstype, tree rhs
- /*explicit_targs=*/NULL_TREE,
- access_path);
-
-- case COMPOUND_EXPR:
-- TREE_OPERAND (rhs, 0)
-- = instantiate_type (lhstype, TREE_OPERAND (rhs, 0), flags);
-- if (TREE_OPERAND (rhs, 0) == error_mark_node)
-- return error_mark_node;
-- TREE_OPERAND (rhs, 1)
-- = instantiate_type (lhstype, TREE_OPERAND (rhs, 1), flags);
-- if (TREE_OPERAND (rhs, 1) == error_mark_node)
-- return error_mark_node;
--
-- TREE_TYPE (rhs) = lhstype;
-- return rhs;
--
- case ADDR_EXPR:
- {
- if (PTRMEM_OK_P (rhs))
---- a/gcc/cp/cp-tree.h
-+++ b/gcc/cp/cp-tree.h
-@@ -43,9 +43,6 @@ along with GCC; see the file COPYING3.
- #else
- #define ATTRIBUTE_GCC_CXXDIAG(m, n) ATTRIBUTE_NONNULL(m)
- #endif
--extern void cp_cpp_error (cpp_reader *, int,
-- const char *, va_list *)
-- ATTRIBUTE_GCC_CXXDIAG(3,0);
- #ifdef GCC_TOPLEV_H
- #error \
- In order for the format checking to accept the C++ front end diagnostic \
---- a/gcc/cp/cvt.c
-+++ b/gcc/cp/cvt.c
-@@ -581,6 +581,7 @@ ocp_convert (tree type, tree expr, int c
- tree e = expr;
- enum tree_code code = TREE_CODE (type);
- const char *invalid_conv_diag;
-+ tree e1;
-
- if (error_operand_p (e) || type == error_mark_node)
- return error_mark_node;
-@@ -629,6 +630,10 @@ ocp_convert (tree type, tree expr, int c
- }
- }
-
-+ e1 = targetm.convert_to_type (type, e);
-+ if (e1)
-+ return e1;
-+
- if (code == VOID_TYPE && (convtype & CONV_STATIC))
- {
- e = convert_to_void (e, /*implicit=*/NULL, tf_warning_or_error);
-@@ -1231,11 +1236,18 @@ build_expr_type_conversion (int desires,
- tree
- type_promotes_to (tree type)
- {
-+ tree promoted_type;
-+
- if (type == error_mark_node)
- return error_mark_node;
-
- type = TYPE_MAIN_VARIANT (type);
-
-+ /* Check for promotions of target-defined types first. */
-+ promoted_type = targetm.promoted_type (type);
-+ if (promoted_type)
-+ return promoted_type;
-+
- /* bool always promotes to int (not unsigned), even if it's the same
- size. */
- if (type == boolean_type_node)
---- a/gcc/cp/decl.c
-+++ b/gcc/cp/decl.c
-@@ -4508,7 +4508,7 @@ maybe_deduce_size_from_array_init (tree
-
- cp_apply_type_quals_to_decl (cp_type_quals (TREE_TYPE (decl)), decl);
-
-- layout_decl (decl, 0);
-+ relayout_decl (decl);
- }
- }
-
-@@ -7622,6 +7622,7 @@ grokdeclarator (const cp_declarator *dec
- bool type_was_error_mark_node = false;
- bool parameter_pack_p = declarator? declarator->parameter_pack_p : false;
- bool template_type_arg = false;
-+ const char *errmsg;
-
- signed_p = declspecs->specs[(int)ds_signed];
- unsigned_p = declspecs->specs[(int)ds_unsigned];
-@@ -8300,6 +8301,12 @@ grokdeclarator (const cp_declarator *dec
- decl, but to its return type. */
- type_quals = TYPE_UNQUALIFIED;
- }
-+ errmsg = targetm.invalid_return_type (type);
-+ if (errmsg)
-+ {
-+ error (errmsg);
-+ type = integer_type_node;
-+ }
-
- /* Error about some types functions can't return. */
-
-@@ -8842,8 +8849,13 @@ grokdeclarator (const cp_declarator *dec
-
- /* Replace the anonymous name with the real name everywhere. */
- for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
-- if (TYPE_NAME (t) == oldname)
-- TYPE_NAME (t) = decl;
-+ {
-+ if (ANON_AGGRNAME_P (TYPE_IDENTIFIER (t)))
-+ {
-+ debug_hooks->set_name (t, decl);
-+ TYPE_NAME (t) = decl;
-+ }
-+ }
-
- if (TYPE_LANG_SPECIFIC (type))
- TYPE_WAS_ANONYMOUS (type) = 1;
-@@ -9679,6 +9691,7 @@ grokparms (tree parmlist, tree *parms)
- tree type = NULL_TREE;
- tree init = TREE_PURPOSE (parm);
- tree decl = TREE_VALUE (parm);
-+ const char *errmsg;
-
- if (parm == void_list_node)
- break;
-@@ -9712,6 +9725,14 @@ grokparms (tree parmlist, tree *parms)
- init = NULL_TREE;
- }
-
-+ if (type != error_mark_node
-+ && (errmsg = targetm.invalid_parameter_type (type)))
-+ {
-+ error (errmsg);
-+ type = error_mark_node;
-+ TREE_TYPE (decl) = error_mark_node;
-+ }
-+
- if (type != error_mark_node)
- {
- if (deprecated_state != DEPRECATED_SUPPRESS)
---- a/gcc/cp/decl2.c
-+++ b/gcc/cp/decl2.c
-@@ -1724,6 +1724,10 @@ decl_needed_p (tree decl)
- || (DECL_ASSEMBLER_NAME_SET_P (decl)
- && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))))
- return true;
-+ /* Functions marked "dllexport" must be emitted so that they are
-+ visible to other DLLs. */
-+ if (lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl)))
-+ return true;
- /* Otherwise, DECL does not need to be emitted -- yet. A subsequent
- reference to DECL might cause it to be emitted later. */
- return false;
-@@ -3810,6 +3814,15 @@ mark_used (tree decl)
- }
-
- TREE_USED (decl) = 1;
-+ if (current_function_decl != NULL_TREE
-+ && (TREE_CODE (decl) == VAR_DECL
-+ || TREE_CODE (decl) == PARM_DECL
-+ || TREE_CODE (decl) == FUNCTION_DECL))
-+ {
-+ tree context = decl_function_context (decl);
-+ if (context != NULL_TREE && context != current_function_decl)
-+ DECL_NONLOCAL (decl) = 1;
-+ }
- if (DECL_CLONED_FUNCTION_P (decl))
- TREE_USED (DECL_CLONED_FUNCTION (decl)) = 1;
- if (TREE_CODE (decl) == FUNCTION_DECL
---- a/gcc/cp/error.c
-+++ b/gcc/cp/error.c
-@@ -2670,39 +2670,6 @@ cp_printer (pretty_printer *pp, text_inf
- #undef next_int
- }
- \f
--/* Callback from cpp_error for PFILE to print diagnostics arising from
-- interpreting strings. The diagnostic is of type LEVEL; MSG is the
-- translated message and AP the arguments. */
--
--void
--cp_cpp_error (cpp_reader *pfile ATTRIBUTE_UNUSED, int level,
-- const char *msg, va_list *ap)
--{
-- diagnostic_info diagnostic;
-- diagnostic_t dlevel;
-- switch (level)
-- {
-- case CPP_DL_WARNING:
-- case CPP_DL_WARNING_SYSHDR:
-- dlevel = DK_WARNING;
-- break;
-- case CPP_DL_PEDWARN:
-- dlevel = DK_PEDWARN;
-- break;
-- case CPP_DL_ERROR:
-- dlevel = DK_ERROR;
-- break;
-- case CPP_DL_ICE:
-- dlevel = DK_ICE;
-- break;
-- default:
-- gcc_unreachable ();
-- }
-- diagnostic_set_info_translated (&diagnostic, msg, ap,
-- input_location, dlevel);
-- report_diagnostic (&diagnostic);
--}
--
- /* Warn about the use of C++0x features when appropriate. */
- void
- maybe_warn_cpp0x (const char* str)
---- a/gcc/cp/except.c
-+++ b/gcc/cp/except.c
-@@ -146,14 +146,26 @@ eh_type_info (tree type)
- static tree
- build_eh_type_type (tree type)
- {
-- tree exp = eh_type_info (type);
-+ bool is_ref = TREE_CODE (type) == REFERENCE_TYPE;
-+ tree exp;
-+
-+ if (is_ref)
-+ type = TREE_TYPE (type);
-+
-+ exp = eh_type_info (type);
-
- if (!exp)
- return NULL;
-
- mark_used (exp);
-
-- return convert (ptr_type_node, build_address (exp));
-+ exp = build_address (exp);
-+
-+ if (is_ref)
-+ exp = targetm.cxx.ttype_ref_encode (exp);
-+
-+ exp = convert (ptr_type_node, exp);
-+ return exp;
- }
-
- tree
-@@ -495,6 +507,16 @@ expand_start_catch_block (tree decl)
- initialize_handler_parm (decl, exp);
- }
-
-+ /* Preserve the reference type on the exception, as this affects
-+ derived-to-base conversions in catch matching. Only do this when
-+ the ABI supports it, as originally this case was (incorrectly)
-+ treated just as catching a pointer-to-class by value. */
-+ if (targetm.cxx.ttype_ref_encode
-+ && decl && TREE_CODE (type) == POINTER_TYPE
-+ && CLASS_TYPE_P (TREE_TYPE (type))
-+ && TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE)
-+ type = build_reference_type (type);
-+
- return type;
- }
-
-@@ -538,10 +560,20 @@ finish_eh_spec_block (tree raw_raises, t
- raw_raises && TREE_VALUE (raw_raises);
- raw_raises = TREE_CHAIN (raw_raises))
- {
-- tree type = prepare_eh_type (TREE_VALUE (raw_raises));
-+ tree orig_type = TREE_VALUE (raw_raises);
-+ tree type = prepare_eh_type (orig_type);
- tree tinfo = eh_type_info (type);
-
- mark_used (tinfo);
-+ /* Preserve the reference type on the exception, as this affects
-+ derived-to-base conversions in catch matching. Only do this when
-+ the ABI supports it, as originally this case was (incorrectly)
-+ treated just as catching a pointer-to-class by value. */
-+ if (targetm.cxx.ttype_ref_encode
-+ && TREE_CODE (orig_type) == REFERENCE_TYPE
-+ && TREE_CODE (type) == POINTER_TYPE
-+ && CLASS_TYPE_P (TREE_TYPE (type)))
-+ type = build_reference_type (type);
- raises = tree_cons (NULL_TREE, type, raises);
- }
-
-@@ -956,24 +988,40 @@ nothrow_libfn_p (const_tree fn)
- static int
- can_convert_eh (tree to, tree from)
- {
-- to = non_reference (to);
-- from = non_reference (from);
-+ bool to_ref = TREE_CODE (to) == REFERENCE_TYPE;
-+ int depth = to_ref;
-+ bool outer_const = true;
-
-- if (TREE_CODE (to) == POINTER_TYPE && TREE_CODE (from) == POINTER_TYPE)
-+ if (to_ref)
-+ to = TREE_TYPE (to);
-+ from = non_reference (from);
-+
-+ while (TREE_CODE (to) == POINTER_TYPE && TREE_CODE (from) == POINTER_TYPE)
- {
-+ unsigned to_quals, from_quals;
-+
-+ depth++;
-+
- to = TREE_TYPE (to);
- from = TREE_TYPE (from);
-+ to_quals = TYPE_QUALS (to);
-+ from_quals = TYPE_QUALS (from);
-
-- if (! at_least_as_qualified_p (to, from))
-+ if ((from_quals & ~to_quals)
-+ || (!outer_const && to_quals & ~from_quals))
- return 0;
--
-- if (TREE_CODE (to) == VOID_TYPE)
-- return 1;
--
-- /* Else fall through. */
-+
-+ if (!(to_quals & TYPE_QUAL_CONST))
-+ outer_const = false;
- }
-
-- if (CLASS_TYPE_P (to) && CLASS_TYPE_P (from)
-+ if (same_type_ignoring_top_level_qualifiers_p (from, to))
-+ return 1;
-+
-+ if (depth == to_ref + 1 && TREE_CODE (to) == VOID_TYPE)
-+ return 1;
-+
-+ if (depth < 2 && CLASS_TYPE_P (to) && CLASS_TYPE_P (from)
- && PUBLICLY_UNIQUELY_DERIVED_P (to, from))
- return 1;
-
---- a/gcc/cp/parser.c
-+++ b/gcc/cp/parser.c
-@@ -309,8 +309,7 @@ cp_lexer_new_main (void)
-
- /* Subsequent preprocessor diagnostics should use compiler
- diagnostic functions to get the compiler source location. */
-- cpp_get_options (parse_in)->client_diagnostic = true;
-- cpp_get_callbacks (parse_in)->error = cp_cpp_error;
-+ done_lexing = true;
-
- gcc_assert (lexer->next_token->type != CPP_PURGED);
- return lexer;
---- a/gcc/cp/rtti.c
-+++ b/gcc/cp/rtti.c
-@@ -393,6 +393,7 @@ get_tinfo_decl (tree type)
- return d;
- }
-
-+ gcc_assert (TREE_CODE (type) != REFERENCE_TYPE);
- name = mangle_typeinfo_for_type (type);
-
- d = IDENTIFIER_GLOBAL_VALUE (name);
---- a/gcc/cp/semantics.c
-+++ b/gcc/cp/semantics.c
-@@ -1120,7 +1120,11 @@ finish_handler_parms (tree decl, tree ha
- type = expand_start_catch_block (decl);
- HANDLER_TYPE (handler) = type;
- if (!processing_template_decl && type)
-- mark_used (eh_type_info (type));
-+ {
-+ if (TREE_CODE (type) == REFERENCE_TYPE)
-+ type = TREE_TYPE (type);
-+ mark_used (eh_type_info (type));
-+ }
- }
-
- /* Finish a handler, which may be given by HANDLER. The BLOCKs are
-@@ -3242,8 +3246,10 @@ expand_or_defer_fn (tree fn)
-
- /* If the user wants us to keep all inline functions, then mark
- this function as needed so that finish_file will make sure to
-- output it later. */
-- if (flag_keep_inline_functions && DECL_DECLARED_INLINE_P (fn))
-+ output it later. Similarly, all dllexport'd functions must
-+ be emitted; there may be callers in other DLLs. */
-+ if ((flag_keep_inline_functions && DECL_DECLARED_INLINE_P (fn))
-+ || lookup_attribute ("dllexport", DECL_ATTRIBUTES (fn)))
- mark_needed (fn);
- }
-
---- a/gcc/cp/typeck.c
-+++ b/gcc/cp/typeck.c
-@@ -1707,10 +1707,14 @@ decay_conversion (tree exp)
- tree
- default_conversion (tree exp)
- {
-+ /* Check for target-specific promotions. */
-+ tree promoted_type = targetm.promoted_type (TREE_TYPE (exp));
-+ if (promoted_type)
-+ exp = cp_convert (promoted_type, exp);
- /* Perform the integral promotions first so that bitfield
- expressions (which may promote to "int", even if the bitfield is
- declared "unsigned") are promoted correctly. */
-- if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (TREE_TYPE (exp)))
-+ else if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (TREE_TYPE (exp)))
- exp = perform_integral_promotions (exp);
- /* Perform the other conversions. */
- exp = decay_conversion (exp);
-@@ -3389,6 +3393,25 @@ cp_build_binary_op (location_t location,
- return error_mark_node;
- }
-
-+ /* Issue warnings about peculiar, but valid, uses of NULL. */
-+ if ((orig_op0 == null_node || orig_op1 == null_node)
-+ /* It's reasonable to use pointer values as operands of &&
-+ and ||, so NULL is no exception. */
-+ && code != TRUTH_ANDIF_EXPR && code != TRUTH_ORIF_EXPR
-+ && ( /* Both are NULL (or 0) and the operation was not a
-+ comparison or a pointer subtraction. */
-+ (null_ptr_cst_p (orig_op0) && null_ptr_cst_p (orig_op1)
-+ && code != EQ_EXPR && code != NE_EXPR && code != MINUS_EXPR)
-+ /* Or if one of OP0 or OP1 is neither a pointer nor NULL. */
-+ || (!null_ptr_cst_p (orig_op0)
-+ && !TYPE_PTR_P (type0) && !TYPE_PTR_TO_MEMBER_P (type0))
-+ || (!null_ptr_cst_p (orig_op1)
-+ && !TYPE_PTR_P (type1) && !TYPE_PTR_TO_MEMBER_P (type1)))
-+ && (complain & tf_warning))
-+ /* Some sort of arithmetic operation involving NULL was
-+ performed. */
-+ warning (OPT_Wpointer_arith, "NULL used in arithmetic");
-+
- switch (code)
- {
- case MINUS_EXPR:
-@@ -3979,25 +4002,6 @@ cp_build_binary_op (location_t location,
- }
- }
-
-- /* Issue warnings about peculiar, but valid, uses of NULL. */
-- if ((orig_op0 == null_node || orig_op1 == null_node)
-- /* It's reasonable to use pointer values as operands of &&
-- and ||, so NULL is no exception. */
-- && code != TRUTH_ANDIF_EXPR && code != TRUTH_ORIF_EXPR
-- && ( /* Both are NULL (or 0) and the operation was not a comparison. */
-- (null_ptr_cst_p (orig_op0) && null_ptr_cst_p (orig_op1)
-- && code != EQ_EXPR && code != NE_EXPR)
-- /* Or if one of OP0 or OP1 is neither a pointer nor NULL. */
-- || (!null_ptr_cst_p (orig_op0) && TREE_CODE (TREE_TYPE (op0)) != POINTER_TYPE)
-- || (!null_ptr_cst_p (orig_op1) && TREE_CODE (TREE_TYPE (op1)) != POINTER_TYPE))
-- && (complain & tf_warning))
-- /* Some sort of arithmetic operation involving NULL was
-- performed. Note that pointer-difference and pointer-addition
-- have already been handled above, and so we don't end up here in
-- that case. */
-- warning (OPT_Wpointer_arith, "NULL used in arithmetic");
--
--
- /* If CONVERTED is zero, both args will be converted to type RESULT_TYPE.
- Then the expression will be built.
- It will be given type FINAL_TYPE if that is nonzero;
-@@ -5024,6 +5028,12 @@ cp_build_compound_expr (tree lhs, tree r
- return rhs;
- }
-
-+ if (type_unknown_p (rhs))
-+ {
-+ error ("no context to resolve type of %qE", rhs);
-+ return error_mark_node;
-+ }
-+
- return build2 (COMPOUND_EXPR, TREE_TYPE (rhs), lhs, rhs);
- }
-
---- a/gcc/cse.c
-+++ b/gcc/cse.c
-@@ -5754,6 +5754,11 @@ cse_process_notes_1 (rtx x, rtx object,
- validate_change (object, &XEXP (x, i),
- cse_process_notes (XEXP (x, i), object, changed), 0);
-
-+ /* Rebuild a PLUS expression in canonical form if the first operand
-+ ends up as a constant. */
-+ if (code == PLUS && GET_CODE (XEXP (x, 0)) == CONST_INT)
-+ return plus_constant (XEXP(x, 1), INTVAL (XEXP (x, 0)));
-+
- return x;
- }
-
---- a/gcc/dbxout.c
-+++ b/gcc/dbxout.c
-@@ -377,6 +377,7 @@ const struct gcc_debug_hooks dbx_debug_h
- dbxout_handle_pch, /* handle_pch */
- debug_nothing_rtx, /* var_location */
- debug_nothing_void, /* switch_text_section */
-+ debug_nothing_tree_tree, /* set_name */
- 0 /* start_end_main_source_file */
- };
- #endif /* DBX_DEBUGGING_INFO */
-@@ -410,6 +411,7 @@ const struct gcc_debug_hooks xcoff_debug
- dbxout_handle_pch, /* handle_pch */
- debug_nothing_rtx, /* var_location */
- debug_nothing_void, /* switch_text_section */
-+ debug_nothing_tree_tree, /* set_name */
- 0 /* start_end_main_source_file */
- };
- #endif /* XCOFF_DEBUGGING_INFO */
---- a/gcc/debug.c
-+++ b/gcc/debug.c
-@@ -51,6 +51,7 @@ const struct gcc_debug_hooks do_nothing_
- debug_nothing_int, /* handle_pch */
- debug_nothing_rtx, /* var_location */
- debug_nothing_void, /* switch_text_section */
-+ debug_nothing_tree_tree, /* set_name */
- 0 /* start_end_main_source_file */
- };
-
-@@ -68,6 +69,12 @@ debug_nothing_tree (tree decl ATTRIBUTE_
- }
-
- void
-+debug_nothing_tree_tree (tree t1 ATTRIBUTE_UNUSED,
-+ tree t2 ATTRIBUTE_UNUSED)
-+{
-+}
-+
-+void
- debug_nothing_tree_tree_tree_bool (tree t1 ATTRIBUTE_UNUSED,
- tree t2 ATTRIBUTE_UNUSED,
- tree t3 ATTRIBUTE_UNUSED,
---- a/gcc/debug.h
-+++ b/gcc/debug.h
-@@ -130,6 +130,10 @@ struct gcc_debug_hooks
- text sections. */
- void (* switch_text_section) (void);
-
-+ /* Called from grokdeclarator. Replaces the anonymous name with the
-+ type name. */
-+ void (* set_name) (tree, tree);
-+
- /* This is 1 if the debug writer wants to see start and end commands for the
- main source files, and 0 otherwise. */
- int start_end_main_source_file;
-@@ -144,6 +148,7 @@ extern void debug_nothing_int_charstar (
- extern void debug_nothing_int (unsigned int);
- extern void debug_nothing_int_int (unsigned int, unsigned int);
- extern void debug_nothing_tree (tree);
-+extern void debug_nothing_tree_tree (tree, tree);
- extern void debug_nothing_tree_int (tree, int);
- extern void debug_nothing_tree_tree_tree_bool (tree, tree, tree, bool);
- extern bool debug_true_const_tree (const_tree);
---- a/gcc/defaults.h
-+++ b/gcc/defaults.h
-@@ -902,7 +902,8 @@ see the files COPYING3 and COPYING.RUNTI
-
- /* On most machines, the CFA coincides with the first incoming parm. */
- #ifndef ARG_POINTER_CFA_OFFSET
--#define ARG_POINTER_CFA_OFFSET(FNDECL) FIRST_PARM_OFFSET (FNDECL)
-+#define ARG_POINTER_CFA_OFFSET(FNDECL) \
-+ (FIRST_PARM_OFFSET (FNDECL) + crtl->args.pretend_args_size)
- #endif
-
- /* On most machines, we use the CFA as DW_AT_frame_base. */
---- a/gcc/diagnostic.c
-+++ b/gcc/diagnostic.c
-@@ -126,6 +126,7 @@ diagnostic_set_info_translated (diagnost
- diagnostic->message.args_ptr = args;
- diagnostic->message.format_spec = msg;
- diagnostic->location = location;
-+ diagnostic->override_column = 0;
- diagnostic->kind = kind;
- diagnostic->option_index = 0;
- }
-@@ -153,6 +154,8 @@ diagnostic_build_prefix (diagnostic_info
- };
- const char *text = _(diagnostic_kind_text[diagnostic->kind]);
- expanded_location s = expand_location (diagnostic->location);
-+ if (diagnostic->override_column)
-+ s.column = diagnostic->override_column;
- gcc_assert (diagnostic->kind < DK_LAST_DIAGNOSTIC_KIND);
-
- return
---- a/gcc/diagnostic.h
-+++ b/gcc/diagnostic.h
-@@ -41,6 +41,7 @@ typedef struct diagnostic_info
- {
- text_info message;
- location_t location;
-+ unsigned int override_column;
- /* TREE_BLOCK if the diagnostic is to be reported in some inline
- function inlined into other function, otherwise NULL. */
- tree abstract_origin;
-@@ -185,6 +186,10 @@ extern diagnostic_context *global_dc;
-
- #define report_diagnostic(D) diagnostic_report_diagnostic (global_dc, D)
-
-+/* Override the column number to be used for reporting a
-+ diagnostic. */
-+#define diagnostic_override_column(DI, COL) (DI)->override_column = (COL)
-+
- /* Diagnostic related functions. */
- extern void diagnostic_initialize (diagnostic_context *);
- extern void diagnostic_report_current_module (diagnostic_context *);
---- a/gcc/dwarf2out.c
-+++ b/gcc/dwarf2out.c
-@@ -2486,6 +2486,12 @@ dwarf2out_frame_debug (rtx insn, bool af
- insn = PATTERN (insn);
-
- dwarf2out_frame_debug_expr (insn, label);
-+
-+ /* Check again. A parallel can save and update the same register.
-+ We could probably check just once, here, but this is safer than
-+ removing the check above. */
-+ if (clobbers_queued_reg_save (insn))
-+ flush_queued_reg_saves ();
- }
-
- #endif
-@@ -4611,6 +4617,7 @@ static void dwarf2out_imported_module_or
- static void dwarf2out_abstract_function (tree);
- static void dwarf2out_var_location (rtx);
- static void dwarf2out_begin_function (tree);
-+static void dwarf2out_set_name (tree, tree);
-
- /* The debug hooks structure. */
-
-@@ -4645,6 +4652,7 @@ const struct gcc_debug_hooks dwarf2_debu
- debug_nothing_int, /* handle_pch */
- dwarf2out_var_location,
- dwarf2out_switch_text_section,
-+ dwarf2out_set_name,
- 1 /* start_end_main_source_file */
- };
- #endif
-@@ -5989,12 +5997,9 @@ debug_str_eq (const void *x1, const void
- (const char *)x2) == 0;
- }
-
--/* Add a string attribute value to a DIE. */
--
--static inline void
--add_AT_string (dw_die_ref die, enum dwarf_attribute attr_kind, const char *str)
-+static struct indirect_string_node *
-+find_AT_string (const char *str)
- {
-- dw_attr_node attr;
- struct indirect_string_node *node;
- void **slot;
-
-@@ -6015,6 +6020,18 @@ add_AT_string (dw_die_ref die, enum dwar
- node = (struct indirect_string_node *) *slot;
-
- node->refcount++;
-+ return node;
-+}
-+
-+/* Add a string attribute value to a DIE. */
-+
-+static inline void
-+add_AT_string (dw_die_ref die, enum dwarf_attribute attr_kind, const char *str)
-+{
-+ dw_attr_node attr;
-+ struct indirect_string_node *node;
-+
-+ node = find_AT_string (str);
-
- attr.dw_attr = attr_kind;
- attr.dw_attr_val.val_class = dw_val_class_str;
-@@ -6651,6 +6668,8 @@ decl_loc_table_eq (const void *x, const
- static inline var_loc_list *
- lookup_decl_loc (const_tree decl)
- {
-+ if (!decl_loc_table)
-+ return NULL;
- return (var_loc_list *)
- htab_find_with_hash (decl_loc_table, decl, DECL_UID (decl));
- }
-@@ -13502,6 +13521,7 @@ dwarf2out_abstract_function (tree decl)
- tree save_fn;
- tree context;
- int was_abstract = DECL_ABSTRACT (decl);
-+ htab_t old_decl_loc_table;
-
- /* Make sure we have the actual abstract inline, not a clone. */
- decl = DECL_ORIGIN (decl);
-@@ -13511,6 +13531,12 @@ dwarf2out_abstract_function (tree decl)
- /* We've already generated the abstract instance. */
- return;
-
-+ /* We can be called while recursively when seeing block defining inlined subroutine
-+ DIE. Be sure to not clobber the outer location table nor use it or we would
-+ get locations in abstract instantces. */
-+ old_decl_loc_table = decl_loc_table;
-+ decl_loc_table = NULL;
-+
- /* Be sure we've emitted the in-class declaration DIE (if any) first, so
- we don't get confused by DECL_ABSTRACT. */
- if (debug_info_level > DINFO_LEVEL_TERSE)
-@@ -13532,6 +13558,7 @@ dwarf2out_abstract_function (tree decl)
- set_decl_abstract_flags (decl, 0);
-
- current_function_decl = save_fn;
-+ decl_loc_table = old_decl_loc_table;
- pop_cfun ();
- }
-
-@@ -15881,6 +15908,31 @@ maybe_emit_file (struct dwarf_file_data
- return fd->emitted_number;
- }
-
-+/* Replace DW_AT_name for the decl with name. */
-+
-+static void
-+dwarf2out_set_name (tree decl, tree name)
-+{
-+ dw_die_ref die;
-+ dw_attr_ref attr;
-+
-+ die = TYPE_SYMTAB_DIE (decl);
-+ if (!die)
-+ return;
-+
-+ attr = get_AT (die, DW_AT_name);
-+ if (attr)
-+ {
-+ struct indirect_string_node *node;
-+
-+ node = find_AT_string (dwarf2_name (name, 0));
-+ /* replace the string. */
-+ attr->dw_attr_val.v.val_str = node;
-+ }
-+
-+ else
-+ add_name_attribute (die, dwarf2_name (name, 0));
-+}
- /* Called by the final INSN scan whenever we see a var location. We
- use it to drop labels in the right places, and throw the location in
- our lookup table. */
---- a/gcc/except.c
-+++ b/gcc/except.c
-@@ -3567,6 +3567,12 @@ output_ttype (tree type, int tt_format,
- paths below go through assemble_integer, which would take
- care of this for us. */
- STRIP_NOPS (type);
-+ if (TREE_CODE (type) == POINTER_PLUS_EXPR)
-+ {
-+ gcc_assert (TREE_CODE (TREE_OPERAND (type, 1)) == INTEGER_CST);
-+ type = TREE_OPERAND (type, 0);
-+ STRIP_NOPS (type);
-+ }
- if (TREE_CODE (type) == ADDR_EXPR)
- {
- type = TREE_OPERAND (type, 0);
---- a/gcc/explow.c
-+++ b/gcc/explow.c
-@@ -1491,9 +1491,9 @@ hard_function_value (const_tree valtype,
- in which a scalar value of mode MODE was returned by a library call. */
-
- rtx
--hard_libcall_value (enum machine_mode mode)
-+hard_libcall_value (enum machine_mode mode, rtx fun)
- {
-- return LIBCALL_VALUE (mode);
-+ return targetm.calls.libcall_value (mode, fun);
- }
-
- /* Look up the tree code for a given rtx code
---- a/gcc/expmed.c
-+++ b/gcc/expmed.c
-@@ -103,7 +103,8 @@ static int add_cost[2][NUM_MACHINE_MODES
- static int neg_cost[2][NUM_MACHINE_MODES];
- static int shift_cost[2][NUM_MACHINE_MODES][MAX_BITS_PER_WORD];
- static int shiftadd_cost[2][NUM_MACHINE_MODES][MAX_BITS_PER_WORD];
--static int shiftsub_cost[2][NUM_MACHINE_MODES][MAX_BITS_PER_WORD];
-+static int shiftsub0_cost[2][NUM_MACHINE_MODES][MAX_BITS_PER_WORD];
-+static int shiftsub1_cost[2][NUM_MACHINE_MODES][MAX_BITS_PER_WORD];
- static int mul_cost[2][NUM_MACHINE_MODES];
- static int sdiv_cost[2][NUM_MACHINE_MODES];
- static int udiv_cost[2][NUM_MACHINE_MODES];
-@@ -130,7 +131,8 @@ init_expmed (void)
- struct rtx_def shift; rtunion shift_fld1;
- struct rtx_def shift_mult; rtunion shift_mult_fld1;
- struct rtx_def shift_add; rtunion shift_add_fld1;
-- struct rtx_def shift_sub; rtunion shift_sub_fld1;
-+ struct rtx_def shift_sub0; rtunion shift_sub0_fld1;
-+ struct rtx_def shift_sub1; rtunion shift_sub1_fld1;
- } all;
-
- rtx pow2[MAX_BITS_PER_WORD];
-@@ -201,9 +203,13 @@ init_expmed (void)
- XEXP (&all.shift_add, 0) = &all.shift_mult;
- XEXP (&all.shift_add, 1) = &all.reg;
-
-- PUT_CODE (&all.shift_sub, MINUS);
-- XEXP (&all.shift_sub, 0) = &all.shift_mult;
-- XEXP (&all.shift_sub, 1) = &all.reg;
-+ PUT_CODE (&all.shift_sub0, MINUS);
-+ XEXP (&all.shift_sub0, 0) = &all.shift_mult;
-+ XEXP (&all.shift_sub0, 1) = &all.reg;
-+
-+ PUT_CODE (&all.shift_sub1, MINUS);
-+ XEXP (&all.shift_sub1, 0) = &all.reg;
-+ XEXP (&all.shift_sub1, 1) = &all.shift_mult;
-
- for (speed = 0; speed < 2; speed++)
- {
-@@ -226,7 +232,8 @@ init_expmed (void)
- PUT_MODE (&all.shift, mode);
- PUT_MODE (&all.shift_mult, mode);
- PUT_MODE (&all.shift_add, mode);
-- PUT_MODE (&all.shift_sub, mode);
-+ PUT_MODE (&all.shift_sub0, mode);
-+ PUT_MODE (&all.shift_sub1, mode);
-
- add_cost[speed][mode] = rtx_cost (&all.plus, SET, speed);
- neg_cost[speed][mode] = rtx_cost (&all.neg, SET, speed);
-@@ -254,8 +261,8 @@ init_expmed (void)
- }
-
- shift_cost[speed][mode][0] = 0;
-- shiftadd_cost[speed][mode][0] = shiftsub_cost[speed][mode][0]
-- = add_cost[speed][mode];
-+ shiftadd_cost[speed][mode][0] = shiftsub0_cost[speed][mode][0]
-+ = shiftsub1_cost[speed][mode][0] = add_cost[speed][mode];
-
- n = MIN (MAX_BITS_PER_WORD, GET_MODE_BITSIZE (mode));
- for (m = 1; m < n; m++)
-@@ -265,7 +272,8 @@ init_expmed (void)
-
- shift_cost[speed][mode][m] = rtx_cost (&all.shift, SET, speed);
- shiftadd_cost[speed][mode][m] = rtx_cost (&all.shift_add, SET, speed);
-- shiftsub_cost[speed][mode][m] = rtx_cost (&all.shift_sub, SET, speed);
-+ shiftsub0_cost[speed][mode][m] = rtx_cost (&all.shift_sub0, SET, speed);
-+ shiftsub1_cost[speed][mode][m] = rtx_cost (&all.shift_sub1, SET, speed);
- }
- }
- }
-@@ -2397,6 +2405,7 @@ synth_mult (struct algorithm *alg_out, u
- struct mult_cost best_cost;
- struct mult_cost new_limit;
- int op_cost, op_latency;
-+ unsigned HOST_WIDE_INT orig_t = t;
- unsigned HOST_WIDE_INT q;
- int maxm = MIN (BITS_PER_WORD, GET_MODE_BITSIZE (mode));
- int hash_index;
-@@ -2542,6 +2551,38 @@ synth_mult (struct algorithm *alg_out, u
- best_alg->log[best_alg->ops] = m;
- best_alg->op[best_alg->ops] = alg_shift;
- }
-+
-+ /* See if treating ORIG_T as a signed number yields a better
-+ sequence. Try this sequence only for a negative ORIG_T
-+ as it would be useless for a non-negative ORIG_T. */
-+ if ((HOST_WIDE_INT) orig_t < 0)
-+ {
-+ /* Shift ORIG_T as follows because a right shift of a
-+ negative-valued signed type is implementation
-+ defined. */
-+ q = ~(~orig_t >> m);
-+ /* The function expand_shift will choose between a shift
-+ and a sequence of additions, so the observed cost is
-+ given as MIN (m * add_cost[speed][mode],
-+ shift_cost[speed][mode][m]). */
-+ op_cost = m * add_cost[speed][mode];
-+ if (shift_cost[speed][mode][m] < op_cost)
-+ op_cost = shift_cost[speed][mode][m];
-+ new_limit.cost = best_cost.cost - op_cost;
-+ new_limit.latency = best_cost.latency - op_cost;
-+ synth_mult (alg_in, q, &new_limit, mode);
-+
-+ alg_in->cost.cost += op_cost;
-+ alg_in->cost.latency += op_cost;
-+ if (CHEAPER_MULT_COST (&alg_in->cost, &best_cost))
-+ {
-+ struct algorithm *x;
-+ best_cost = alg_in->cost;
-+ x = alg_in, alg_in = best_alg, best_alg = x;
-+ best_alg->log[best_alg->ops] = m;
-+ best_alg->op[best_alg->ops] = alg_shift;
-+ }
-+ }
- }
- if (cache_hit)
- goto done;
-@@ -2604,6 +2645,29 @@ synth_mult (struct algorithm *alg_out, u
- best_alg->op[best_alg->ops] = alg_add_t_m2;
- }
- }
-+
-+ /* We may be able to calculate a * -7, a * -15, a * -31, etc
-+ quickly with a - a * n for some appropriate constant n. */
-+ m = exact_log2 (-orig_t + 1);
-+ if (m >= 0 && m < maxm)
-+ {
-+ op_cost = shiftsub1_cost[speed][mode][m];
-+ new_limit.cost = best_cost.cost - op_cost;
-+ new_limit.latency = best_cost.latency - op_cost;
-+ synth_mult (alg_in, (unsigned HOST_WIDE_INT) (-orig_t + 1) >> m, &new_limit, mode);
-+
-+ alg_in->cost.cost += op_cost;
-+ alg_in->cost.latency += op_cost;
-+ if (CHEAPER_MULT_COST (&alg_in->cost, &best_cost))
-+ {
-+ struct algorithm *x;
-+ best_cost = alg_in->cost;
-+ x = alg_in, alg_in = best_alg, best_alg = x;
-+ best_alg->log[best_alg->ops] = m;
-+ best_alg->op[best_alg->ops] = alg_sub_t_m2;
-+ }
-+ }
-+
- if (cache_hit)
- goto done;
- }
-@@ -2673,9 +2737,9 @@ synth_mult (struct algorithm *alg_out, u
- hardware the shift may be executed concurrently with the
- earlier steps in the algorithm. */
- op_cost = add_cost[speed][mode] + shift_cost[speed][mode][m];
-- if (shiftsub_cost[speed][mode][m] < op_cost)
-+ if (shiftsub0_cost[speed][mode][m] < op_cost)
- {
-- op_cost = shiftsub_cost[speed][mode][m];
-+ op_cost = shiftsub0_cost[speed][mode][m];
- op_latency = op_cost;
- }
- else
-@@ -2738,7 +2802,7 @@ synth_mult (struct algorithm *alg_out, u
- m = exact_log2 (q);
- if (m >= 0 && m < maxm)
- {
-- op_cost = shiftsub_cost[speed][mode][m];
-+ op_cost = shiftsub0_cost[speed][mode][m];
- new_limit.cost = best_cost.cost - op_cost;
- new_limit.latency = best_cost.latency - op_cost;
- synth_mult (alg_in, (t + 1) >> m, &new_limit, mode);
---- a/gcc/expr.c
-+++ b/gcc/expr.c
-@@ -4391,6 +4391,29 @@ expand_assignment (tree to, tree from, b
-
- /* Compute FROM and store the value in the rtx we got. */
-
-+ if (TREE_CODE (to) == MISALIGNED_INDIRECT_REF)
-+ {
-+ rtx insn;
-+ rtx from_rtx;
-+ enum insn_code icode;
-+ enum machine_mode mode = GET_MODE (to_rtx);
-+
-+ icode = optab_handler (movmisalign_optab, mode)->insn_code;
-+ gcc_assert (icode != CODE_FOR_nothing);
-+
-+ from_rtx = expand_expr (from, NULL_RTX, mode, EXPAND_NORMAL);
-+ insn = GEN_FCN (icode) (to_rtx, from_rtx);
-+ /* If that failed then force the source into a reg and try again. */
-+ if (!insn)
-+ {
-+ from_rtx = copy_to_mode_reg(mode, from_rtx);
-+ insn = GEN_FCN (icode) (to_rtx, from_rtx);
-+ gcc_assert(insn);
-+ }
-+ emit_insn (insn);
-+ return;
-+ }
-+
- push_temp_slots ();
- result = store_expr (from, to_rtx, 0, nontemporal);
- preserve_temp_slots (result);
-@@ -7291,6 +7314,19 @@ expand_expr_real_1 (tree exp, rtx target
- decl_rtl = DECL_RTL (exp);
- gcc_assert (decl_rtl);
- decl_rtl = copy_rtx (decl_rtl);
-+ /* Record writes to register variables. */
-+ if (modifier == EXPAND_WRITE && REG_P(decl_rtl)
-+ && REGNO(decl_rtl) < FIRST_PSEUDO_REGISTER)
-+ {
-+ int i = REGNO(decl_rtl);
-+ int nregs = hard_regno_nregs[i][GET_MODE(decl_rtl)];
-+ while (nregs)
-+ {
-+ SET_HARD_REG_BIT(crtl->asm_clobbers, i);
-+ i++;
-+ nregs--;
-+ }
-+ }
-
- /* Ensure variable marked as used even if it doesn't go through
- a parser. If it hasn't be used yet, write out an external
-@@ -7538,14 +7574,15 @@ expand_expr_real_1 (tree exp, rtx target
-
- /* Resolve the misalignment now, so that we don't have to remember
- to resolve it later. Of course, this only works for reads. */
-- /* ??? When we get around to supporting writes, we'll have to handle
-- this in store_expr directly. The vectorizer isn't generating
-- those yet, however. */
- if (code == MISALIGNED_INDIRECT_REF)
- {
- int icode;
- rtx reg, insn;
-
-+ /* For writes produce a MEM, and expand_assignment will DTRT. */
-+ if (modifier == EXPAND_WRITE)
-+ return temp;
-+
- gcc_assert (modifier == EXPAND_NORMAL
- || modifier == EXPAND_STACK_PARM);
-
---- a/gcc/expr.h
-+++ b/gcc/expr.h
-@@ -757,7 +757,7 @@ extern void probe_stack_range (HOST_WIDE
-
- /* Return an rtx that refers to the value returned by a library call
- in its original home. This becomes invalid if any more code is emitted. */
--extern rtx hard_libcall_value (enum machine_mode);
-+extern rtx hard_libcall_value (enum machine_mode, rtx);
-
- /* Return the mode desired by operand N of a particular bitfield
- insert/extract insn, or MAX_MACHINE_MODE if no such insn is
---- a/gcc/final.c
-+++ b/gcc/final.c
-@@ -891,6 +891,7 @@ shorten_branches (rtx first ATTRIBUTE_UN
- if (LABEL_P (insn))
- {
- rtx next;
-+ bool next_is_jumptable;
-
- /* Merge in alignments computed by compute_alignments. */
- log = LABEL_TO_ALIGNMENT (insn);
-@@ -900,31 +901,30 @@ shorten_branches (rtx first ATTRIBUTE_UN
- max_skip = LABEL_TO_MAX_SKIP (insn);
- }
-
-- log = LABEL_ALIGN (insn);
-- if (max_log < log)
-+ next = next_nonnote_insn (insn);
-+ next_is_jumptable = next && JUMP_TABLE_DATA_P (next);
-+ if (!next_is_jumptable)
- {
-- max_log = log;
-- max_skip = LABEL_ALIGN_MAX_SKIP;
-+ log = LABEL_ALIGN (insn);
-+ if (max_log < log)
-+ {
-+ max_log = log;
-+ max_skip = LABEL_ALIGN_MAX_SKIP;
-+ }
- }
-- next = next_nonnote_insn (insn);
- /* ADDR_VECs only take room if read-only data goes into the text
- section. */
-- if (JUMP_TABLES_IN_TEXT_SECTION
-- || readonly_data_section == text_section)
-- if (next && JUMP_P (next))
-- {
-- rtx nextbody = PATTERN (next);
-- if (GET_CODE (nextbody) == ADDR_VEC
-- || GET_CODE (nextbody) == ADDR_DIFF_VEC)
-- {
-- log = ADDR_VEC_ALIGN (next);
-- if (max_log < log)
-- {
-- max_log = log;
-- max_skip = LABEL_ALIGN_MAX_SKIP;
-- }
-- }
-- }
-+ if ((JUMP_TABLES_IN_TEXT_SECTION
-+ || readonly_data_section == text_section)
-+ && next_is_jumptable)
-+ {
-+ log = ADDR_VEC_ALIGN (next);
-+ if (max_log < log)
-+ {
-+ max_log = log;
-+ max_skip = LABEL_ALIGN_MAX_SKIP;
-+ }
-+ }
- LABEL_TO_ALIGNMENT (insn) = max_log;
- LABEL_TO_MAX_SKIP (insn) = max_skip;
- max_log = 0;
-@@ -2013,48 +2013,41 @@ final_scan_insn (rtx insn, FILE *file, i
- app_disable ();
-
- next = next_nonnote_insn (insn);
-- if (next != 0 && JUMP_P (next))
-+ /* If this label is followed by a jump-table, make sure we put
-+ the label in the read-only section. Also possibly write the
-+ label and jump table together. */
-+ if (next != 0 && JUMP_TABLE_DATA_P (next))
- {
-- rtx nextbody = PATTERN (next);
--
-- /* If this label is followed by a jump-table,
-- make sure we put the label in the read-only section. Also
-- possibly write the label and jump table together. */
--
-- if (GET_CODE (nextbody) == ADDR_VEC
-- || GET_CODE (nextbody) == ADDR_DIFF_VEC)
-- {
- #if defined(ASM_OUTPUT_ADDR_VEC) || defined(ASM_OUTPUT_ADDR_DIFF_VEC)
-- /* In this case, the case vector is being moved by the
-- target, so don't output the label at all. Leave that
-- to the back end macros. */
-+ /* In this case, the case vector is being moved by the
-+ target, so don't output the label at all. Leave that
-+ to the back end macros. */
- #else
-- if (! JUMP_TABLES_IN_TEXT_SECTION)
-- {
-- int log_align;
-+ if (! JUMP_TABLES_IN_TEXT_SECTION)
-+ {
-+ int log_align;
-
-- switch_to_section (targetm.asm_out.function_rodata_section
-- (current_function_decl));
-+ switch_to_section (targetm.asm_out.function_rodata_section
-+ (current_function_decl));
-
- #ifdef ADDR_VEC_ALIGN
-- log_align = ADDR_VEC_ALIGN (next);
-+ log_align = ADDR_VEC_ALIGN (next);
- #else
-- log_align = exact_log2 (BIGGEST_ALIGNMENT / BITS_PER_UNIT);
-+ log_align = exact_log2 (BIGGEST_ALIGNMENT / BITS_PER_UNIT);
- #endif
-- ASM_OUTPUT_ALIGN (file, log_align);
-- }
-- else
-- switch_to_section (current_function_section ());
-+ ASM_OUTPUT_ALIGN (file, log_align);
-+ }
-+ else
-+ switch_to_section (current_function_section ());
-
- #ifdef ASM_OUTPUT_CASE_LABEL
-- ASM_OUTPUT_CASE_LABEL (file, "L", CODE_LABEL_NUMBER (insn),
-- next);
-+ ASM_OUTPUT_CASE_LABEL (file, "L", CODE_LABEL_NUMBER (insn),
-+ next);
- #else
-- targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (insn));
-+ targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (insn));
- #endif
- #endif
-- break;
-- }
-+ break;
- }
- if (LABEL_ALT_ENTRY_P (insn))
- output_alternate_entry_point (file, insn);
---- a/gcc/fold-const.c
-+++ b/gcc/fold-const.c
-@@ -2293,7 +2293,24 @@ fold_convert_const_real_from_real (tree
- real_convert (&value, TYPE_MODE (type), &TREE_REAL_CST (arg1));
- t = build_real (type, value);
-
-- TREE_OVERFLOW (t) = TREE_OVERFLOW (arg1);
-+ /* If converting an infinity or NAN to a representation that doesn't
-+ have one, set the overflow bit so that we can produce some kind of
-+ error message at the appropriate point if necessary. It's not the
-+ most user-friendly message, but it's better than nothing. */
-+ if (REAL_VALUE_ISINF (TREE_REAL_CST (arg1))
-+ && !MODE_HAS_INFINITIES (TYPE_MODE (type)))
-+ TREE_OVERFLOW (t) = 1;
-+ else if (REAL_VALUE_ISNAN (TREE_REAL_CST (arg1))
-+ && !MODE_HAS_NANS (TYPE_MODE (type)))
-+ TREE_OVERFLOW (t) = 1;
-+ /* Regular overflow, conversion produced an infinity in a mode that
-+ can't represent them. */
-+ else if (!MODE_HAS_INFINITIES (TYPE_MODE (type))
-+ && REAL_VALUE_ISINF (value)
-+ && !REAL_VALUE_ISINF (TREE_REAL_CST (arg1)))
-+ TREE_OVERFLOW (t) = 1;
-+ else
-+ TREE_OVERFLOW (t) = TREE_OVERFLOW (arg1);
- return t;
- }
-
---- a/gcc/fortran/cpp.c
-+++ b/gcc/fortran/cpp.c
-@@ -137,6 +137,9 @@ static void cb_include (cpp_reader *, so
- static void cb_ident (cpp_reader *, source_location, const cpp_string *);
- static void cb_used_define (cpp_reader *, source_location, cpp_hashnode *);
- static void cb_used_undef (cpp_reader *, source_location, cpp_hashnode *);
-+static bool cb_cpp_error (cpp_reader *, int, location_t, unsigned int,
-+ const char *, va_list *)
-+ ATTRIBUTE_GCC_DIAG(5,0);
- void pp_dir_change (cpp_reader *, const char *);
-
- static int dump_macro (cpp_reader *, cpp_hashnode *, void *);
-@@ -452,7 +455,6 @@ gfc_cpp_post_options (void)
- cpp_option->cplusplus_comments = 0;
-
- cpp_option->pedantic = pedantic;
-- cpp_option->inhibit_warnings = inhibit_warnings;
-
- cpp_option->dollars_in_ident = gfc_option.flag_dollar_ok;
- cpp_option->discard_comments = gfc_cpp_option.discard_comments;
-@@ -465,9 +467,6 @@ gfc_cpp_post_options (void)
-
- cpp_post_options (cpp_in);
-
-- /* If an error has occurred in cpplib, note it so we fail immediately. */
-- errorcount += cpp_errors (cpp_in);
--
- gfc_cpp_register_include_paths ();
- }
-
-@@ -482,6 +481,7 @@ gfc_cpp_init_0 (void)
- cb->line_change = cb_line_change;
- cb->ident = cb_ident;
- cb->def_pragma = cb_def_pragma;
-+ cb->error = cb_cpp_error;
-
- if (gfc_cpp_option.dump_includes)
- cb->include = cb_include;
-@@ -961,6 +961,57 @@ cb_used_define (cpp_reader *pfile, sourc
- cpp_define_queue = q;
- }
-
-+/* Callback from cpp_error for PFILE to print diagnostics from the
-+ preprocessor. The diagnostic is of type LEVEL, at location
-+ LOCATION, with column number possibly overridden by COLUMN_OVERRIDE
-+ if not zero; MSG is the translated message and AP the arguments.
-+ Returns true if a diagnostic was emitted, false otherwise. */
-+
-+static bool
-+cb_cpp_error (cpp_reader *pfile ATTRIBUTE_UNUSED, int level,
-+ location_t location, unsigned int column_override,
-+ const char *msg, va_list *ap)
-+{
-+ diagnostic_info diagnostic;
-+ diagnostic_t dlevel;
-+ int save_warn_system_headers = warn_system_headers;
-+ bool ret;
-+
-+ switch (level)
-+ {
-+ case CPP_DL_WARNING_SYSHDR:
-+ warn_system_headers = 1;
-+ /* Fall through. */
-+ case CPP_DL_WARNING:
-+ dlevel = DK_WARNING;
-+ break;
-+ case CPP_DL_PEDWARN:
-+ dlevel = DK_PEDWARN;
-+ break;
-+ case CPP_DL_ERROR:
-+ dlevel = DK_ERROR;
-+ break;
-+ case CPP_DL_ICE:
-+ dlevel = DK_ICE;
-+ break;
-+ case CPP_DL_NOTE:
-+ dlevel = DK_NOTE;
-+ break;
-+ case CPP_DL_FATAL:
-+ dlevel = DK_FATAL;
-+ break;
-+ default:
-+ gcc_unreachable ();
-+ }
-+ diagnostic_set_info_translated (&diagnostic, msg, ap,
-+ location, dlevel);
-+ if (column_override)
-+ diagnostic_override_column (&diagnostic, column_override);
-+ ret = report_diagnostic (&diagnostic);
-+ if (level == CPP_DL_WARNING_SYSHDR)
-+ warn_system_headers = save_warn_system_headers;
-+ return ret;
-+}
-
- /* Callback called when -fworking-director and -E to emit working
- directory in cpp output file. */
---- a/gcc/function.c
-+++ b/gcc/function.c
-@@ -276,7 +276,10 @@ get_stack_local_alignment (tree type, en
- if (! type)
- type = lang_hooks.types.type_for_mode (mode, 0);
-
-- return STACK_SLOT_ALIGNMENT (type, mode, alignment);
-+ return alignment_for_aligned_arrays (type,
-+ STACK_SLOT_ALIGNMENT (type,
-+ mode,
-+ alignment));
- }
-
- /* Allocate a stack slot of SIZE bytes and return a MEM rtx for it
-@@ -5355,6 +5358,57 @@ current_function_assembler_name (void)
- {
- return IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (cfun->decl));
- }
-+
-+/* This function adjusts alignments as appropriate according to the
-+ setting of -falign-arrays. If that is specified then the minimum
-+ alignment for array variables is set to be the largest power of two
-+ less than or equal to their total storage size, or the biggest
-+ alignment used on the machine, whichever is smaller. */
-+
-+unsigned int
-+alignment_for_aligned_arrays (tree ty, unsigned int existing_alignment)
-+{
-+ unsigned int min_alignment;
-+ tree size;
-+
-+ /* Return the existing alignment if not using -falign-arrays or if
-+ the type is not an array type. */
-+ if (!flag_align_arrays || !ty || TREE_CODE (ty) != ARRAY_TYPE)
-+ return existing_alignment;
-+
-+ /* Extract the total storage size of the array in bits. */
-+ size = TYPE_SIZE (ty);
-+ gcc_assert (size);
-+
-+ /* At least for variable-length arrays, TREE_CODE (size) might not be an
-+ integer constant; check it now. If it is not, give the array at
-+ least BIGGEST_ALIGNMENT just to be safe. Furthermore, we assume that
-+ alignments always fit into a host integer. So if we can't fit the
-+ size of the array in bits into a host integer, it must also be large
-+ enough to deserve at least BIGGEST_ALIGNMENT (see below). */
-+ if (TREE_CODE (size) != INTEGER_CST || !host_integerp (size, 1))
-+ min_alignment = BIGGEST_ALIGNMENT;
-+ else
-+ {
-+ unsigned HOST_WIDE_INT bits = TREE_INT_CST_LOW (size);
-+ bits = (bits ? bits : 1);
-+
-+ /* An array with size greater than BIGGEST_ALIGNMENT is assigned
-+ at least that alignment. In all other cases the minimum
-+ alignment of the array is set to be the largest power of two
-+ less than or equal to the total storage size of the array.
-+ We assume that BIGGEST_ALIGNMENT fits in "unsigned int"; thus,
-+ the shift below will not overflow. */
-+ if (bits >= BIGGEST_ALIGNMENT)
-+ min_alignment = BIGGEST_ALIGNMENT;
-+ else
-+ min_alignment = 1 << (floor_log2 (bits));
-+ }
-+
-+ /* Having computed the minimum permissible alignment, enlarge it
-+ if EXISTING_ALIGNMENT is greater. */
-+ return MAX (min_alignment, existing_alignment);
-+}
- \f
-
- static unsigned int
---- a/gcc/function.h
-+++ b/gcc/function.h
-@@ -25,6 +25,7 @@ along with GCC; see the file COPYING3.
- #include "tree.h"
- #include "hashtab.h"
- #include "varray.h"
-+#include "hard-reg-set.h"
-
- /* Stack of pending (incomplete) sequences saved by `start_sequence'.
- Each element describes one pending sequence.
-@@ -441,6 +442,8 @@ struct rtl_data GTY(())
-
- /* True if dbr_schedule has already been called for this function. */
- bool dbr_scheduled_p;
-+
-+ HARD_REG_SET asm_clobbers;
- };
-
- #define return_label (crtl->x_return_label)
-@@ -709,4 +712,7 @@ extern bool reference_callee_copied (CUM
- extern void used_types_insert (tree);
-
- extern int get_next_funcdef_no (void);
-+
-+extern unsigned int alignment_for_aligned_arrays (tree, unsigned int);
-+
- #endif /* GCC_FUNCTION_H */
---- a/gcc/gcc.c
-+++ b/gcc/gcc.c
-@@ -229,6 +229,16 @@ static int combine_flag = 0;
-
- static int use_pipes;
-
-+/* Nonzero means that libgcc is being linked automatically by the
-+ compiler from its normal installed location; that is, neither -B,
-+ -nostdlib nor -nodefaultlibs was passed. */
-+
-+static int using_libgcc = 1;
-+
-+/* Nonzero means that the current spec is executing the linker. */
-+
-+static int executing_linker = 0;
-+
- /* The compiler version. */
-
- static const char *compiler_version;
-@@ -651,8 +661,32 @@ proper position among the other output f
-
- /* config.h can define SWITCHES_NEED_SPACES to control which options
- require spaces between the option and the argument. */
-+/* GCC Bugzilla PR11810 indicates that GCC does not correctly handle
-+ "-ofoo.o", in that it records "-ofoo.o" as a temporary file to
-+ delete, rather than "foo.o".
-+
-+ Unfortunately, Eclipse's makefile generators use the "-ofoo.o"
-+ form. See also CS Issue #3433. So, although most users probably
-+ use "-o foo.o", the "-ofoo.o" form is used in practice.
-+
-+ See this email thread for additional information:
-+
-+ http://gcc.gnu.org/ml/gcc/2008-07/msg00395.html
-+
-+ Therefore, we define SWITCHES_NEED_SPACES to include "o" by
-+ default. This causes "-ofoo.o" to be split into "-o foo.o" during
-+ the initial processing of the command-line, before being seen by
-+ the specs machinery.
-+
-+ A risk of this change is that tools which *require* the "-ofoo.o"
-+ form will no longer work. However, we know of no such tools, and
-+ they would not have worked with the "-o foo.o" form anyhow.
-+
-+ If this general strategy is acceptable upstream, the best approach
-+ might be simply to eliminate this macro, since the only definitions
-+ in target files are also to the value "o". */
- #ifndef SWITCHES_NEED_SPACES
--#define SWITCHES_NEED_SPACES ""
-+#define SWITCHES_NEED_SPACES "o"
- #endif
-
- /* config.h can define ENDFILE_SPEC to override the default crtn files. */
-@@ -728,6 +762,8 @@ proper position among the other output f
- %{!fsyntax-only:%{!c:%{!M:%{!MM:%{!E:%{!S:\
- %(linker) %l " LINK_PIE_SPEC "%X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} %{r}\
- %{s} %{t} %{u*} %{x} %{z} %{Z} %{!A:%{!nostdlib:%{!nostartfiles:%S}}}\
-+ %{Wno-poison-system-directories:--no-poison-system-directories}\
-+ %{Werror=poison-system-directories:--error-poison-system-directories}\
- %{static:} %{L*} %(mfwrap) %(link_libgcc) %o\
- %{fopenmp|ftree-parallelize-loops=*:%:include(libgomp.spec)%(link_gomp)} %(mflib)\
- %{fprofile-arcs|fprofile-generate|coverage:-lgcov}\
-@@ -882,7 +918,7 @@ static const char *const multilib_defaul
- #endif
-
- static const char *const driver_self_specs[] = {
-- DRIVER_SELF_SPECS, GOMP_SELF_SPECS
-+ DRIVER_SELF_SPECS, CONFIGURE_SPECS, GOMP_SELF_SPECS
- };
-
- #ifndef OPTION_DEFAULT_SPECS
-@@ -2853,6 +2889,29 @@ execute (void)
-
- gcc_assert (!processing_spec_function);
-
-+ if (executing_linker && using_libgcc)
-+ {
-+ const char *libgcc_a_filename;
-+
-+ /* Verify that the multilib being used is actually installed. */
-+ libgcc_a_filename = (gcc_exec_prefix
-+ ? gcc_exec_prefix
-+ : concat (standard_exec_prefix,
-+ machine_suffix, NULL));
-+ if (multilib_dir && strcmp (multilib_dir, ".") != 0)
-+ libgcc_a_filename = concat (libgcc_a_filename, multilib_dir,
-+ dir_separator_str, NULL);
-+ libgcc_a_filename = concat (libgcc_a_filename, "libgcc.a", NULL);
-+ if (access (libgcc_a_filename, R_OK) != 0)
-+ {
-+ if (errno == ENOENT)
-+ fatal ("selected multilib '%s' not installed",
-+ multilib_dir ? multilib_dir : ".");
-+ else
-+ pfatal_with_name (libgcc_a_filename);
-+ }
-+ }
-+
- if (wrapper_string)
- {
- string = find_a_file (&exec_prefixes, argbuf[0], X_OK, false);
-@@ -3688,6 +3747,16 @@ warranty; not even for MERCHANTABILITY o
- add_assembler_option ("--target-help", 13);
- add_linker_option ("--target-help", 13);
- }
-+ else if (! strcmp (argv[i], "-nodefaultlibs"))
-+ {
-+ using_libgcc = 0;
-+ n_switches++;
-+ }
-+ else if (! strcmp (argv[i], "-nostdlib"))
-+ {
-+ using_libgcc = 0;
-+ n_switches++;
-+ }
- else if (! strcmp (argv[i], "-pass-exit-codes"))
- {
- pass_exit_codes = 1;
-@@ -3905,6 +3974,7 @@ warranty; not even for MERCHANTABILITY o
- PREFIX_PRIORITY_B_OPT, 0, 0);
- add_prefix (&include_prefixes, value, NULL,
- PREFIX_PRIORITY_B_OPT, 0, 0);
-+ using_libgcc = 0;
- n_switches++;
- }
- break;
-@@ -4616,27 +4686,53 @@ do_self_spec (const char *spec)
-
- if (argbuf_index > 0)
- {
-- int i, first;
-+ int i, first, n;
-
- first = n_switches;
-- n_switches += argbuf_index;
-- switches = XRESIZEVEC (struct switchstr, switches, n_switches + 1);
-+ n = n_switches + argbuf_index;
-+ switches = XRESIZEVEC (struct switchstr, switches, n + 1);
-+ switches[n] = switches[first];
-
- switches[n_switches] = switches[first];
- for (i = 0; i < argbuf_index; i++)
- {
- struct switchstr *sw;
-+ const char *p = &argbuf[i][1];
-+ int c = *p;
-
- /* Each switch should start with '-'. */
- if (argbuf[i][0] != '-')
- fatal ("switch '%s' does not start with '-'", argbuf[i]);
-
-- sw = &switches[i + first];
-+ sw = &switches[n_switches];
- sw->part1 = &argbuf[i][1];
- sw->args = 0;
- sw->live_cond = 0;
- sw->validated = 0;
- sw->ordering = 0;
-+
-+ /* Deal with option arguments in separate argv elements. */
-+ if ((SWITCH_TAKES_ARG (c) > (p[1] != 0))
-+ || WORD_SWITCH_TAKES_ARG (p))
-+ {
-+ int j = 0;
-+ int n_args = WORD_SWITCH_TAKES_ARG (p);
-+
-+ if (n_args == 0)
-+ {
-+ /* Count only the option arguments in separate argv elements. */
-+ n_args = SWITCH_TAKES_ARG (c) - (p[1] != 0);
-+ }
-+ if (i + n_args >= argbuf_index)
-+ fatal ("argument to '-%s' is missing", p);
-+ switches[n_switches].args
-+ = XNEWVEC (const char *, n_args + 1);
-+ while (j < n_args)
-+ switches[n_switches].args[j++] = argbuf[++i];
-+ /* Null-terminate the vector. */
-+ switches[n_switches].args[j] = 0;
-+ }
-+ n_switches++;
- }
- }
- }
-@@ -6873,7 +6969,9 @@ main (int argc, char **argv)
- " to the linker.\n\n"));
- fflush (stdout);
- }
-+ executing_linker = 1;
- value = do_spec (link_command_spec);
-+ executing_linker = 0;
- if (value < 0)
- error_count = 1;
- linker_was_run = (tmp != execution_count);
---- a/gcc/gcse.c
-+++ b/gcc/gcse.c
-@@ -172,6 +172,7 @@ along with GCC; see the file COPYING3.
- #include "hashtab.h"
- #include "df.h"
- #include "dbgcnt.h"
-+#include "target.h"
-
- /* Propagate flow information through back edges and thus enable PRE's
- moving loop invariant calculations out of loops.
-@@ -1744,7 +1745,9 @@ hash_scan_set (rtx pat, rtx insn, struct
- REG_EQUIV notes and if the argument slot is used somewhere
- explicitly, it means address of parameter has been taken,
- so we should not extend the lifetime of the pseudo. */
-- && (note == NULL_RTX || ! MEM_P (XEXP (note, 0))))
-+ && (note == NULL_RTX || ! MEM_P (XEXP (note, 0)))
-+ && ! (targetm.cannot_copy_insn_p && INSN_P (insn)
-+ && targetm.cannot_copy_insn_p (insn)))
- {
- /* An expression is not anticipatable if its operands are
- modified before this insn or if this is not the only SET in
---- a/gcc/genautomata.c
-+++ b/gcc/genautomata.c
-@@ -1,5 +1,5 @@
- /* Pipeline hazard description translator.
-- Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008
-+ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009
- Free Software Foundation, Inc.
-
- Written by Vladimir Makarov <vmakarov@redhat.com>
-@@ -22,21 +22,25 @@ along with GCC; see the file COPYING3.
-
- /* References:
-
-- 1. Detecting pipeline structural hazards quickly. T. Proebsting,
-+ 1. The finite state automaton based pipeline hazard recognizer and
-+ instruction scheduler in GCC. V. Makarov. Proceedings of GCC
-+ summit, 2003.
-+
-+ 2. Detecting pipeline structural hazards quickly. T. Proebsting,
- C. Fraser. Proceedings of ACM SIGPLAN-SIGACT Symposium on
- Principles of Programming Languages, pages 280--286, 1994.
-
- This article is a good start point to understand usage of finite
- state automata for pipeline hazard recognizers. But I'd
-- recommend the 2nd article for more deep understanding.
-+ recommend the 1st and 3rd article for more deep understanding.
-
-- 2. Efficient Instruction Scheduling Using Finite State Automata:
-+ 3. Efficient Instruction Scheduling Using Finite State Automata:
- V. Bala and N. Rubin, Proceedings of MICRO-28. This is the best
- article about usage of finite state automata for pipeline hazard
- recognizers.
-
-- The current implementation is different from the 2nd article in the
-- following:
-+ The current implementation is described in the 1st article and it
-+ is different from the 3rd article in the following:
-
- 1. New operator `|' (alternative) is permitted in functional unit
- reservation which can be treated deterministically and
-@@ -463,7 +467,10 @@ struct insn_reserv_decl
- insn. */
- int insn_num;
- /* The following field value is list of bypasses in which given insn
-- is output insn. */
-+ is output insn. Bypasses with the same input insn stay one after
-+ another in the list in the same order as their occurrences in the
-+ description but the bypass without a guard stays always the last
-+ in a row of bypasses with the same input insn. */
- struct bypass_decl *bypass_list;
-
- /* The following fields are defined by automaton generator. */
-@@ -2367,18 +2374,67 @@ add_presence_absence (unit_set_el_t dest
- }
-
-
--/* The function searches for bypass with given IN_INSN_RESERV in given
-- BYPASS_LIST. */
--static struct bypass_decl *
--find_bypass (struct bypass_decl *bypass_list,
-- struct insn_reserv_decl *in_insn_reserv)
--{
-- struct bypass_decl *bypass;
--
-- for (bypass = bypass_list; bypass != NULL; bypass = bypass->next)
-- if (bypass->in_insn_reserv == in_insn_reserv)
-- break;
-- return bypass;
-+/* The function inserts BYPASS in the list of bypasses of the
-+ corresponding output insn. The order of bypasses in the list is
-+ decribed in a comment for member `bypass_list' (see above). If
-+ there is already the same bypass in the list the function reports
-+ this and does nothing. */
-+static void
-+insert_bypass (struct bypass_decl *bypass)
-+{
-+ struct bypass_decl *curr, *last;
-+ struct insn_reserv_decl *out_insn_reserv = bypass->out_insn_reserv;
-+ struct insn_reserv_decl *in_insn_reserv = bypass->in_insn_reserv;
-+
-+ for (curr = out_insn_reserv->bypass_list, last = NULL;
-+ curr != NULL;
-+ last = curr, curr = curr->next)
-+ if (curr->in_insn_reserv == in_insn_reserv)
-+ {
-+ if ((bypass->bypass_guard_name != NULL
-+ && curr->bypass_guard_name != NULL
-+ && ! strcmp (bypass->bypass_guard_name, curr->bypass_guard_name))
-+ || bypass->bypass_guard_name == curr->bypass_guard_name)
-+ {
-+ if (bypass->bypass_guard_name == NULL)
-+ {
-+ if (!w_flag)
-+ error ("the same bypass `%s - %s' is already defined",
-+ bypass->out_insn_name, bypass->in_insn_name);
-+ else
-+ warning (0, "the same bypass `%s - %s' is already defined",
-+ bypass->out_insn_name, bypass->in_insn_name);
-+ }
-+ else if (!w_flag)
-+ error ("the same bypass `%s - %s' (guard %s) is already defined",
-+ bypass->out_insn_name, bypass->in_insn_name,
-+ bypass->bypass_guard_name);
-+ else
-+ warning
-+ (0, "the same bypass `%s - %s' (guard %s) is already defined",
-+ bypass->out_insn_name, bypass->in_insn_name,
-+ bypass->bypass_guard_name);
-+ return;
-+ }
-+ if (curr->bypass_guard_name == NULL)
-+ break;
-+ if (curr->next == NULL || curr->next->in_insn_reserv != in_insn_reserv)
-+ {
-+ last = curr;
-+ break;
-+ }
-+
-+ }
-+ if (last == NULL)
-+ {
-+ bypass->next = out_insn_reserv->bypass_list;
-+ out_insn_reserv->bypass_list = bypass;
-+ }
-+ else
-+ {
-+ bypass->next = last->next;
-+ last->next = bypass;
-+ }
- }
-
- /* The function processes pipeline description declarations, checks
-@@ -2391,7 +2447,6 @@ process_decls (void)
- decl_t decl_in_table;
- decl_t out_insn_reserv;
- decl_t in_insn_reserv;
-- struct bypass_decl *bypass;
- int automaton_presence;
- int i;
-
-@@ -2514,36 +2569,7 @@ process_decls (void)
- = DECL_INSN_RESERV (out_insn_reserv);
- DECL_BYPASS (decl)->in_insn_reserv
- = DECL_INSN_RESERV (in_insn_reserv);
-- bypass
-- = find_bypass (DECL_INSN_RESERV (out_insn_reserv)->bypass_list,
-- DECL_BYPASS (decl)->in_insn_reserv);
-- if (bypass != NULL)
-- {
-- if (DECL_BYPASS (decl)->latency == bypass->latency)
-- {
-- if (!w_flag)
-- error
-- ("the same bypass `%s - %s' is already defined",
-- DECL_BYPASS (decl)->out_insn_name,
-- DECL_BYPASS (decl)->in_insn_name);
-- else
-- warning
-- (0, "the same bypass `%s - %s' is already defined",
-- DECL_BYPASS (decl)->out_insn_name,
-- DECL_BYPASS (decl)->in_insn_name);
-- }
-- else
-- error ("bypass `%s - %s' is already defined",
-- DECL_BYPASS (decl)->out_insn_name,
-- DECL_BYPASS (decl)->in_insn_name);
-- }
-- else
-- {
-- DECL_BYPASS (decl)->next
-- = DECL_INSN_RESERV (out_insn_reserv)->bypass_list;
-- DECL_INSN_RESERV (out_insn_reserv)->bypass_list
-- = DECL_BYPASS (decl);
-- }
-+ insert_bypass (DECL_BYPASS (decl));
- }
- }
- }
-@@ -8159,19 +8185,32 @@ output_internal_insn_latency_func (void)
- (advance_cycle_insn_decl)->insn_num));
- fprintf (output_file, " case %d:\n",
- bypass->in_insn_reserv->insn_num);
-- if (bypass->bypass_guard_name == NULL)
-- fprintf (output_file, " return %d;\n",
-- bypass->latency);
-- else
-+ for (;;)
- {
-- fprintf (output_file,
-- " if (%s (%s, %s))\n",
-- bypass->bypass_guard_name, INSN_PARAMETER_NAME,
-- INSN2_PARAMETER_NAME);
-- fprintf (output_file,
-- " return %d;\n break;\n",
-- bypass->latency);
-+ if (bypass->bypass_guard_name == NULL)
-+ {
-+ gcc_assert (bypass->next == NULL
-+ || (bypass->in_insn_reserv
-+ != bypass->next->in_insn_reserv));
-+ fprintf (output_file, " return %d;\n",
-+ bypass->latency);
-+ }
-+ else
-+ {
-+ fprintf (output_file,
-+ " if (%s (%s, %s))\n",
-+ bypass->bypass_guard_name, INSN_PARAMETER_NAME,
-+ INSN2_PARAMETER_NAME);
-+ fprintf (output_file, " return %d;\n",
-+ bypass->latency);
-+ }
-+ if (bypass->next == NULL
-+ || bypass->in_insn_reserv != bypass->next->in_insn_reserv)
-+ break;
-+ bypass = bypass->next;
- }
-+ if (bypass->bypass_guard_name != NULL)
-+ fprintf (output_file, " break;\n");
- }
- fputs (" }\n break;\n", output_file);
- }
---- a/gcc/gengtype-lex.l
-+++ b/gcc/gengtype-lex.l
-@@ -48,7 +48,7 @@ update_lineno (const char *l, size_t len
- ID [[:alpha:]_][[:alnum:]_]*
- WS [[:space:]]+
- HWS [ \t\r\v\f]*
--IWORD short|long|(un)?signed|char|int|HOST_WIDE_INT|HOST_WIDEST_INT|bool|size_t|BOOL_BITFIELD|CPPCHAR_SIGNED_T|ino_t|dev_t
-+IWORD short|long|(un)?signed|char|int|HOST_WIDE_INT|HOST_WIDEST_INT|bool|size_t|BOOL_BITFIELD|CPPCHAR_SIGNED_T|ino_t|dev_t|HARD_REG_SET
- ITYPE {IWORD}({WS}{IWORD})*
- EOID [^[:alnum:]_]
-
---- a/gcc/genmultilib
-+++ b/gcc/genmultilib
-@@ -73,6 +73,20 @@
- # the os directory names are used exclusively. Use the mapping when
- # there is no one-to-one equivalence between GCC levels and the OS.
-
-+# The optional eighth option is a list of multilib aliases. This takes the
-+# same form as the third argument. It specifies that the second multilib is
-+# a synonym for the first. This allows a suitable multilib to be selected
-+# for all option combinations while only building a subset of all possible
-+# multilibs.
-+# For example:
-+# genmultilib "mbig-endian mthumb" "eb thumb" "" "" "" "" "" \
-+# "mbig-endian=mbig-endian/mthumb" yes
-+# This produces:
-+# ". !mbig-endian !mthumb;",
-+# "be mbig-endian !mthumb;",
-+# "be mbig-endian mthumb;",
-+# "thumb !mbig-endian mthumb;",
-+
- # The last option should be "yes" if multilibs are enabled. If it is not
- # "yes", all GCC multilib dir names will be ".".
-
-@@ -121,7 +135,8 @@ exceptions=$4
- extra=$5
- exclusions=$6
- osdirnames=$7
--enable_multilib=$8
-+aliases=$8
-+enable_multilib=$9
-
- echo "static const char *const multilib_raw[] = {"
-
-@@ -129,6 +144,23 @@ mkdir tmpmultilib.$$ || exit 1
- # Use cd ./foo to avoid CDPATH output.
- cd ./tmpmultilib.$$ || exit 1
-
-+# Handle aliases
-+cat >tmpmultilib3 <<\EOF
-+#!/bin/sh
-+# Output a list of aliases (including the original name) for a multilib.
-+
-+echo $1
-+EOF
-+for a in ${aliases}; do
-+ l=`echo $a | sed -e 's/=.*$//' -e 's/?/=/g'`
-+ r=`echo $a | sed -e 's/^.*=//' -e 's/?/=/g'`
-+ echo "[ \$1 == /$l/ ] && echo /$r/" >>tmpmultilib3
-+
-+ # Also add the alias to the exclusion list
-+ exceptions="${exceptions} $r"
-+done
-+chmod +x tmpmultilib3
-+
- # What we want to do is select all combinations of the sets in
- # options. Each combination which includes a set of mutually
- # exclusive options must then be output multiple times, once for each
-@@ -195,6 +227,21 @@ EOF
- combinations=`./tmpmultilib2 ${combinations}`
- fi
-
-+# Check that all the aliases actually exist
-+for a in ${aliases}; do
-+ l=`echo $a | sed -e 's/=.*$//' -e 's/?/=/g'`
-+ for c in ${combinations}; do
-+ if [ "/$l/" = "$c" ]; then
-+ l=""
-+ break;
-+ fi
-+ done
-+ if [ -n "$l" ] ;then
-+ echo "Missing multilib $l for alias $a" 1>&2
-+ exit 1
-+ fi
-+done
-+
- # Construct a sed pattern which will convert option names to directory
- # names.
- todirnames=
-@@ -343,23 +390,25 @@ for combo in ${combinations}; do
- fi
- fi
-
-- # Look through the options. We must output each option that is
-- # present, and negate each option that is not present.
-- optout=
-- for set in ${options}; do
-- setopts=`echo ${set} | sed -e 's_[/|]_ _g'`
-- for opt in ${setopts}; do
-- if expr "${combo} " : ".*/${opt}/.*" > /dev/null; then
-- optout="${optout} ${opt}"
-- else
-- optout="${optout} !${opt}"
-- fi
-+ for optcombo in `./tmpmultilib3 ${combo}`; do
-+ # Look through the options. We must output each option that is
-+ # present, and negate each option that is not present.
-+ optout=
-+ for set in ${options}; do
-+ setopts=`echo ${set} | sed -e 's_[/|]_ _g'`
-+ for opt in ${setopts}; do
-+ if expr "${optcombo} " : ".*/${opt}/.*" > /dev/null; then
-+ optout="${optout} ${opt}"
-+ else
-+ optout="${optout} !${opt}"
-+ fi
-+ done
- done
-- done
-- optout=`echo ${optout} | sed -e 's/^ //'`
-+ optout=`echo ${optout} | sed -e 's/^ //'`
-
-- # Output the line with all appropriate matches.
-- dirout="${dirout}" optout="${optout}" ./tmpmultilib2
-+ # Output the line with all appropriate matches.
-+ dirout="${dirout}" optout="${optout}" ./tmpmultilib2
-+ done
- done
-
- # Terminate the list of string.
---- a/gcc/haifa-sched.c
-+++ b/gcc/haifa-sched.c
-@@ -1990,6 +1990,23 @@ move_insn (rtx insn, rtx last, rtx nt)
- SCHED_GROUP_P (insn) = 0;
- }
-
-+/* Return true if scheduling INSN will finish current clock cycle. */
-+static bool
-+insn_finishes_cycle_p (rtx insn)
-+{
-+ if (SCHED_GROUP_P (insn))
-+ /* After issuing INSN, rest of the sched_group will be forced to issue
-+ in order. Don't make any plans for the rest of cycle. */
-+ return true;
-+
-+ /* Finishing the block will, apparently, finish the cycle. */
-+ if (current_sched_info->insn_finishes_block_p
-+ && current_sched_info->insn_finishes_block_p (insn))
-+ return true;
-+
-+ return false;
-+}
-+
- /* The following structure describe an entry of the stack of choices. */
- struct choice_entry
- {
-@@ -2168,7 +2185,10 @@ max_issue (struct ready_list *ready, int
- delay = state_transition (state, insn);
- if (delay < 0)
- {
-- if (state_dead_lock_p (state))
-+ if (state_dead_lock_p (state)
-+ || insn_finishes_cycle_p (insn))
-+ /* We won't issue any more instructions in the next
-+ choice_state. */
- top->rest = 0;
- else
- top->rest--;
---- a/gcc/hooks.c
-+++ b/gcc/hooks.c
-@@ -335,3 +335,10 @@ hook_constcharptr_int_const_tree_const_t
- {
- return NULL;
- }
-+
-+/* Generic hook that takes a const_tree and returns NULL_TREE. */
-+tree
-+hook_tree_const_tree_null (const_tree t ATTRIBUTE_UNUSED)
-+{
-+ return NULL;
-+}
---- a/gcc/hooks.h
-+++ b/gcc/hooks.h
-@@ -64,6 +64,8 @@ extern int hook_int_rtx_bool_0 (rtx, boo
- extern int hook_int_size_t_constcharptr_int_0 (size_t, const char *, int);
- extern int hook_int_void_no_regs (void);
-
-+extern tree hook_tree_const_tree_null (const_tree);
-+
- extern tree hook_tree_tree_tree_null (tree, tree);
- extern tree hook_tree_tree_tree_tree_null (tree, tree, tree);
- extern tree hook_tree_tree_tree_tree_3rd_identity (tree, tree, tree);
---- a/gcc/incpath.c
-+++ b/gcc/incpath.c
-@@ -30,6 +30,8 @@
- #include "intl.h"
- #include "incpath.h"
- #include "cppdefault.h"
-+#include "flags.h"
-+#include "toplev.h"
-
- /* Microsoft Windows does not natively support inodes.
- VMS has non-numeric inodes. */
-@@ -353,6 +355,24 @@ merge_include_chains (const char *sysroo
- }
- fprintf (stderr, _("End of search list.\n"));
- }
-+
-+#ifdef ENABLE_POISON_SYSTEM_DIRECTORIES
-+ if (flag_poison_system_directories)
-+ {
-+ struct cpp_dir *p;
-+
-+ for (p = heads[QUOTE]; p; p = p->next)
-+ {
-+ if ((!strncmp (p->name, "/usr/include", 12))
-+ || (!strncmp (p->name, "/usr/local/include", 18))
-+ || (!strncmp (p->name, "/usr/X11R6/include", 18)))
-+ warning (OPT_Wpoison_system_directories,
-+ "include location \"%s\" is unsafe for "
-+ "cross-compilation",
-+ p->name);
-+ }
-+ }
-+#endif
- }
-
- /* Use given -I paths for #include "..." but not #include <...>, and
---- a/gcc/ira-costs.c
-+++ b/gcc/ira-costs.c
-@@ -706,11 +706,11 @@ record_reg_classes (int n_alts, int n_op
-
- /* Wrapper around REGNO_OK_FOR_INDEX_P, to allow pseudo registers. */
- static inline bool
--ok_for_index_p_nonstrict (rtx reg)
-+ok_for_index_p_nonstrict (rtx reg, enum machine_mode mode)
- {
- unsigned regno = REGNO (reg);
-
-- return regno >= FIRST_PSEUDO_REGISTER || REGNO_OK_FOR_INDEX_P (regno);
-+ return regno >= FIRST_PSEUDO_REGISTER || ok_for_index_p_1 (regno, mode);
- }
-
- /* A version of regno_ok_for_base_p for use here, when all
-@@ -748,7 +748,7 @@ record_address_regs (enum machine_mode m
- enum reg_class rclass;
-
- if (context == 1)
-- rclass = INDEX_REG_CLASS;
-+ rclass = index_reg_class (mode);
- else
- rclass = base_reg_class (mode, outer_code, index_code);
-
-@@ -795,7 +795,8 @@ record_address_regs (enum machine_mode m
- just record registers in any non-constant operands. We
- assume here, as well as in the tests below, that all
- addresses are in canonical form. */
-- else if (INDEX_REG_CLASS == base_reg_class (VOIDmode, PLUS, SCRATCH))
-+ else if (index_reg_class (mode)
-+ == base_reg_class (mode, PLUS, SCRATCH))
- {
- record_address_regs (mode, arg0, context, PLUS, code1, scale);
- if (! CONSTANT_P (arg1))
-@@ -816,7 +817,7 @@ record_address_regs (enum machine_mode m
- else if (code0 == REG && code1 == REG
- && REGNO (arg0) < FIRST_PSEUDO_REGISTER
- && (ok_for_base_p_nonstrict (arg0, mode, PLUS, REG)
-- || ok_for_index_p_nonstrict (arg0)))
-+ || ok_for_index_p_nonstrict (arg0, mode)))
- record_address_regs (mode, arg1,
- ok_for_base_p_nonstrict (arg0, mode, PLUS, REG)
- ? 1 : 0,
-@@ -824,7 +825,7 @@ record_address_regs (enum machine_mode m
- else if (code0 == REG && code1 == REG
- && REGNO (arg1) < FIRST_PSEUDO_REGISTER
- && (ok_for_base_p_nonstrict (arg1, mode, PLUS, REG)
-- || ok_for_index_p_nonstrict (arg1)))
-+ || ok_for_index_p_nonstrict (arg1, mode)))
- record_address_regs (mode, arg0,
- ok_for_base_p_nonstrict (arg1, mode, PLUS, REG)
- ? 1 : 0,
---- a/gcc/ira.c
-+++ b/gcc/ira.c
-@@ -1349,14 +1349,12 @@ insn_contains_asm (rtx insn)
- return for_each_rtx (&insn, insn_contains_asm_1, NULL);
- }
-
--/* Set up regs_asm_clobbered. */
-+/* Add register clobbers from asm statements. */
- static void
--compute_regs_asm_clobbered (char *regs_asm_clobbered)
-+compute_regs_asm_clobbered (void)
- {
- basic_block bb;
-
-- memset (regs_asm_clobbered, 0, sizeof (char) * FIRST_PSEUDO_REGISTER);
--
- FOR_EACH_BB (bb)
- {
- rtx insn;
-@@ -1377,7 +1375,7 @@ compute_regs_asm_clobbered (char *regs_a
- + hard_regno_nregs[dregno][mode] - 1;
-
- for (i = dregno; i <= end; ++i)
-- regs_asm_clobbered[i] = 1;
-+ SET_HARD_REG_BIT(crtl->asm_clobbers, i);
- }
- }
- }
-@@ -1415,7 +1413,8 @@ setup_eliminable_regset (void)
- COPY_HARD_REG_SET (ira_no_alloc_regs, no_unit_alloc_regs);
- CLEAR_HARD_REG_SET (eliminable_regset);
-
-- compute_regs_asm_clobbered (regs_asm_clobbered);
-+ compute_regs_asm_clobbered ();
-+
- /* Build the regset of all eliminable registers and show we can't
- use those that we already know won't be eliminated. */
- #ifdef ELIMINABLE_REGS
-@@ -1425,7 +1424,7 @@ setup_eliminable_regset (void)
- = (! CAN_ELIMINATE (eliminables[i].from, eliminables[i].to)
- || (eliminables[i].to == STACK_POINTER_REGNUM && need_fp));
-
-- if (! regs_asm_clobbered[eliminables[i].from])
-+ if (!TEST_HARD_REG_BIT (crtl->asm_clobbers, eliminables[i].from))
- {
- SET_HARD_REG_BIT (eliminable_regset, eliminables[i].from);
-
-@@ -1439,7 +1438,7 @@ setup_eliminable_regset (void)
- df_set_regs_ever_live (eliminables[i].from, true);
- }
- #if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
-- if (! regs_asm_clobbered[HARD_FRAME_POINTER_REGNUM])
-+ if (!TEST_HARD_REG_BIT (crtl->asm_clobbers, HARD_FRAME_POINTER_REGNUM))
- {
- SET_HARD_REG_BIT (eliminable_regset, HARD_FRAME_POINTER_REGNUM);
- if (need_fp)
-@@ -1453,7 +1452,7 @@ setup_eliminable_regset (void)
- #endif
-
- #else
-- if (! regs_asm_clobbered[FRAME_POINTER_REGNUM])
-+ if (!TEST_HARD_REG_BIT (crtl->asm_clobbers, HARD_FRAME_POINTER_REGNUM))
- {
- SET_HARD_REG_BIT (eliminable_regset, FRAME_POINTER_REGNUM);
- if (need_fp)
---- a/gcc/modulo-sched.c
-+++ b/gcc/modulo-sched.c
-@@ -270,6 +270,7 @@ static struct haifa_sched_info sms_sched
- NULL,
- sms_print_insn,
- NULL,
-+ NULL, /* insn_finishes_block_p */
- NULL, NULL,
- NULL, NULL,
- 0, 0,
---- a/gcc/optabs.c
-+++ b/gcc/optabs.c
-@@ -3300,7 +3300,8 @@ expand_unop (enum machine_mode mode, opt
- if (unoptab == ffs_optab || unoptab == clz_optab || unoptab == ctz_optab
- || unoptab == popcount_optab || unoptab == parity_optab)
- outmode
-- = GET_MODE (hard_libcall_value (TYPE_MODE (integer_type_node)));
-+ = GET_MODE (hard_libcall_value (TYPE_MODE (integer_type_node),
-+ optab_libfunc (unoptab, mode)));
-
- start_sequence ();
-
-@@ -4357,10 +4358,12 @@ prepare_float_lib_cmp (rtx *px, rtx *py,
- mode != VOIDmode;
- mode = GET_MODE_WIDER_MODE (mode))
- {
-- if ((libfunc = optab_libfunc (code_to_optab[comparison], mode)))
-+ if (code_to_optab[comparison]
-+ && (libfunc = optab_libfunc (code_to_optab[comparison], mode)))
- break;
-
-- if ((libfunc = optab_libfunc (code_to_optab[swapped] , mode)))
-+ if (code_to_optab[swapped]
-+ && (libfunc = optab_libfunc (code_to_optab[swapped], mode)))
- {
- rtx tmp;
- tmp = x; x = y; y = tmp;
-@@ -4368,7 +4371,8 @@ prepare_float_lib_cmp (rtx *px, rtx *py,
- break;
- }
-
-- if ((libfunc = optab_libfunc (code_to_optab[reversed], mode))
-+ if (code_to_optab[reversed]
-+ && (libfunc = optab_libfunc (code_to_optab[reversed], mode))
- && FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, reversed))
- {
- comparison = reversed;
---- a/gcc/opts.c
-+++ b/gcc/opts.c
-@@ -906,7 +906,7 @@ decode_options (unsigned int argc, const
- flag_tree_vrp = opt2;
- flag_tree_builtin_call_dce = opt2;
- flag_tree_pre = opt2;
-- flag_tree_switch_conversion = 1;
-+ flag_tree_switch_conversion = opt2;
- flag_ipa_cp = opt2;
-
- /* Allow more virtual operators to increase alias precision. */
-@@ -930,6 +930,7 @@ decode_options (unsigned int argc, const
- flag_gcse_after_reload = opt3;
- flag_tree_vectorize = opt3;
- flag_ipa_cp_clone = opt3;
-+ flag_tree_pre_partial_partial = opt3;
- if (flag_ipa_cp_clone)
- flag_ipa_cp = 1;
-
-@@ -953,10 +954,13 @@ decode_options (unsigned int argc, const
- being declared inline. */
- flag_inline_functions = 1;
-
-- /* Basic optimization options. */
-- optimize_size = 1;
-+ /* Basic optimization options at -Os are almost the same as -O2. The
-+ only difference is that we disable PRE, because it sometimes still
-+ increases code size. If the user want to run PRE with -Os, he/she
-+ will have to indicate so explicitly. */
- if (optimize > 2)
- optimize = 2;
-+ flag_tree_pre = 0;
-
- /* We want to crossjump as much as possible. */
- set_param_value ("min-crossjump-insns", 1);
-@@ -2062,6 +2066,10 @@ common_handle_option (size_t scode, cons
- /* These are no-ops, preserved for backward compatibility. */
- break;
-
-+ case OPT_feglibc_:
-+ /* This is a no-op at the moment. */
-+ break;
-+
- default:
- /* If the flag was handled in a standard way, assume the lack of
- processing here is intentional. */
---- a/gcc/passes.c
-+++ b/gcc/passes.c
-@@ -591,6 +591,7 @@ init_optimization_passes (void)
- NEXT_PASS (pass_rename_ssa_copies);
- NEXT_PASS (pass_complete_unrolli);
- NEXT_PASS (pass_ccp);
-+ NEXT_PASS (pass_promote_indices);
- NEXT_PASS (pass_forwprop);
- /* Ideally the function call conditional
- dead code elimination phase can be delayed
-@@ -605,6 +606,7 @@ init_optimization_passes (void)
- alias information also rewrites no longer addressed
- locals into SSA form if possible. */
- NEXT_PASS (pass_build_alias);
-+ NEXT_PASS (pass_remove_local_statics);
- NEXT_PASS (pass_return_slot);
- NEXT_PASS (pass_phiprop);
- NEXT_PASS (pass_fre);
---- a/gcc/pointer-set.c
-+++ b/gcc/pointer-set.c
-@@ -181,6 +181,23 @@ void pointer_set_traverse (const struct
- break;
- }
-
-+/* Return the number of elements in PSET. */
-+
-+size_t
-+pointer_set_n_elements (struct pointer_set_t *pset)
-+{
-+ return pset->n_elements;
-+}
-+
-+/* Remove all entries from PSET. */
-+
-+void
-+pointer_set_clear (struct pointer_set_t *pset)
-+{
-+ pset->n_elements = 0;
-+ memset (pset->slots, 0, sizeof (pset->slots[0]) * pset->n_slots);
-+}
-+
- \f
- /* A pointer map is represented the same way as a pointer_set, so
- the hash code is based on the address of the key, rather than
-@@ -301,3 +318,20 @@ void pointer_map_traverse (const struct
- if (pmap->keys[i] && !fn (pmap->keys[i], &pmap->values[i], data))
- break;
- }
-+
-+/* Return the number of elements in PMAP. */
-+
-+size_t
-+pointer_map_n_elements (struct pointer_map_t *pmap)
-+{
-+ return pmap->n_elements;
-+}
-+
-+/* Remove all entries from PMAP. */
-+
-+void pointer_map_clear (struct pointer_map_t *pmap)
-+{
-+ pmap->n_elements = 0;
-+ memset (pmap->keys, 0, sizeof (pmap->keys[0]) * pmap->n_slots);
-+ memset (pmap->values, 0, sizeof (pmap->values[0]) * pmap->n_slots);
-+}
---- a/gcc/pointer-set.h
-+++ b/gcc/pointer-set.h
-@@ -29,6 +29,8 @@ int pointer_set_insert (struct pointer_s
- void pointer_set_traverse (const struct pointer_set_t *,
- bool (*) (const void *, void *),
- void *);
-+size_t pointer_set_n_elements (struct pointer_set_t *);
-+void pointer_set_clear (struct pointer_set_t *);
-
- struct pointer_map_t;
- struct pointer_map_t *pointer_map_create (void);
-@@ -38,5 +40,7 @@ void **pointer_map_contains (const struc
- void **pointer_map_insert (struct pointer_map_t *pmap, const void *p);
- void pointer_map_traverse (const struct pointer_map_t *,
- bool (*) (const void *, void **, void *), void *);
-+size_t pointer_map_n_elements (struct pointer_map_t *);
-+void pointer_map_clear (struct pointer_map_t *);
-
- #endif /* POINTER_SET_H */
---- a/gcc/postreload.c
-+++ b/gcc/postreload.c
-@@ -46,6 +46,7 @@ along with GCC; see the file COPYING3.
- #include "tree.h"
- #include "timevar.h"
- #include "tree-pass.h"
-+#include "addresses.h"
- #include "df.h"
- #include "dbgcnt.h"
-
-@@ -708,17 +709,19 @@ reload_combine (void)
- int last_label_ruid;
- int min_labelno, n_labels;
- HARD_REG_SET ever_live_at_start, *label_live;
-+ enum reg_class index_regs;
-
- /* If reg+reg can be used in offsetable memory addresses, the main chunk of
- reload has already used it where appropriate, so there is no use in
- trying to generate it now. */
-- if (double_reg_address_ok && INDEX_REG_CLASS != NO_REGS)
-+ index_regs = index_reg_class (VOIDmode);
-+ if (double_reg_address_ok && index_regs != NO_REGS)
- return;
-
- /* To avoid wasting too much time later searching for an index register,
- determine the minimum and maximum index register numbers. */
- for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
-- if (TEST_HARD_REG_BIT (reg_class_contents[INDEX_REG_CLASS], r))
-+ if (TEST_HARD_REG_BIT (reg_class_contents[index_regs], r))
- {
- if (first_index_reg == -1)
- first_index_reg = r;
-@@ -826,8 +829,8 @@ reload_combine (void)
- substitute uses of REG (typically in MEMs) with.
- First check REG and BASE for being index registers;
- we can use them even if they are not dead. */
-- if (TEST_HARD_REG_BIT (reg_class_contents[INDEX_REG_CLASS], regno)
-- || TEST_HARD_REG_BIT (reg_class_contents[INDEX_REG_CLASS],
-+ if (TEST_HARD_REG_BIT (reg_class_contents[index_regs], regno)
-+ || TEST_HARD_REG_BIT (reg_class_contents[index_regs],
- REGNO (base)))
- {
- const_reg = reg;
-@@ -841,8 +844,7 @@ reload_combine (void)
- two registers. */
- for (i = first_index_reg; i <= last_index_reg; i++)
- {
-- if (TEST_HARD_REG_BIT (reg_class_contents[INDEX_REG_CLASS],
-- i)
-+ if (TEST_HARD_REG_BIT (reg_class_contents[index_regs], i)
- && reg_state[i].use_index == RELOAD_COMBINE_MAX_USES
- && reg_state[i].store_ruid <= reg_state[regno].use_ruid
- && hard_regno_nregs[i][GET_MODE (reg)] == 1)
---- a/gcc/real.c
-+++ b/gcc/real.c
-@@ -4576,6 +4576,167 @@ const struct real_format decimal_quad_fo
- false
- };
- \f
-+/* Encode half-precision floats. This routine is used both for the IEEE
-+ ARM alternative encodings. */
-+static void
-+encode_ieee_half (const struct real_format *fmt, long *buf,
-+ const REAL_VALUE_TYPE *r)
-+{
-+ unsigned long image, sig, exp;
-+ unsigned long sign = r->sign;
-+ bool denormal = (r->sig[SIGSZ-1] & SIG_MSB) == 0;
-+
-+ image = sign << 15;
-+ sig = (r->sig[SIGSZ-1] >> (HOST_BITS_PER_LONG - 11)) & 0x3ff;
-+
-+ switch (r->cl)
-+ {
-+ case rvc_zero:
-+ break;
-+
-+ case rvc_inf:
-+ if (fmt->has_inf)
-+ image |= 31 << 10;
-+ else
-+ image |= 0x7fff;
-+ break;
-+
-+ case rvc_nan:
-+ if (fmt->has_nans)
-+ {
-+ if (r->canonical)
-+ sig = (fmt->canonical_nan_lsbs_set ? (1 << 9) - 1 : 0);
-+ if (r->signalling == fmt->qnan_msb_set)
-+ sig &= ~(1 << 9);
-+ else
-+ sig |= 1 << 9;
-+ if (sig == 0)
-+ sig = 1 << 8;
-+
-+ image |= 31 << 10;
-+ image |= sig;
-+ }
-+ else
-+ image |= 0x3ff;
-+ break;
-+
-+ case rvc_normal:
-+ /* Recall that IEEE numbers are interpreted as 1.F x 2**exp,
-+ whereas the intermediate representation is 0.F x 2**exp.
-+ Which means we're off by one. */
-+ if (denormal)
-+ exp = 0;
-+ else
-+ exp = REAL_EXP (r) + 15 - 1;
-+ image |= exp << 10;
-+ image |= sig;
-+ break;
-+
-+ default:
-+ gcc_unreachable ();
-+ }
-+
-+ buf[0] = image;
-+}
-+
-+/* Decode half-precision floats. This routine is used both for the IEEE
-+ ARM alternative encodings. */
-+static void
-+decode_ieee_half (const struct real_format *fmt, REAL_VALUE_TYPE *r,
-+ const long *buf)
-+{
-+ unsigned long image = buf[0] & 0xffff;
-+ bool sign = (image >> 15) & 1;
-+ int exp = (image >> 10) & 0x1f;
-+
-+ memset (r, 0, sizeof (*r));
-+ image <<= HOST_BITS_PER_LONG - 11;
-+ image &= ~SIG_MSB;
-+
-+ if (exp == 0)
-+ {
-+ if (image && fmt->has_denorm)
-+ {
-+ r->cl = rvc_normal;
-+ r->sign = sign;
-+ SET_REAL_EXP (r, -14);
-+ r->sig[SIGSZ-1] = image << 1;
-+ normalize (r);
-+ }
-+ else if (fmt->has_signed_zero)
-+ r->sign = sign;
-+ }
-+ else if (exp == 31 && (fmt->has_nans || fmt->has_inf))
-+ {
-+ if (image)
-+ {
-+ r->cl = rvc_nan;
-+ r->sign = sign;
-+ r->signalling = (((image >> (HOST_BITS_PER_LONG - 2)) & 1)
-+ ^ fmt->qnan_msb_set);
-+ r->sig[SIGSZ-1] = image;
-+ }
-+ else
-+ {
-+ r->cl = rvc_inf;
-+ r->sign = sign;
-+ }
-+ }
-+ else
-+ {
-+ r->cl = rvc_normal;
-+ r->sign = sign;
-+ SET_REAL_EXP (r, exp - 15 + 1);
-+ r->sig[SIGSZ-1] = image | SIG_MSB;
-+ }
-+}
-+
-+/* Half-precision format, as specified in IEEE 754R. */
-+const struct real_format ieee_half_format =
-+ {
-+ encode_ieee_half,
-+ decode_ieee_half,
-+ 2,
-+ 11,
-+ 11,
-+ -13,
-+ 16,
-+ 15,
-+ 15,
-+ false,
-+ true,
-+ true,
-+ true,
-+ true,
-+ true,
-+ true,
-+ false
-+ };
-+
-+/* ARM's alternative half-precision format, similar to IEEE but with
-+ no reserved exponent value for NaNs and infinities; rather, it just
-+ extends the range of exponents by one. */
-+const struct real_format arm_half_format =
-+ {
-+ encode_ieee_half,
-+ decode_ieee_half,
-+ 2,
-+ 11,
-+ 11,
-+ -13,
-+ 17,
-+ 15,
-+ 15,
-+ false,
-+ true,
-+ false,
-+ false,
-+ true,
-+ true,
-+ false,
-+ false
-+ };
-+\f
- /* A synthetic "format" for internal arithmetic. It's the size of the
- internal significand minus the two bits needed for proper rounding.
- The encode and decode routines exist only to satisfy our paranoia
---- a/gcc/real.h
-+++ b/gcc/real.h
-@@ -304,6 +304,8 @@ extern const struct real_format real_int
- extern const struct real_format decimal_single_format;
- extern const struct real_format decimal_double_format;
- extern const struct real_format decimal_quad_format;
-+extern const struct real_format ieee_half_format;
-+extern const struct real_format arm_half_format;
-
-
- /* ====================================================================== */
---- a/gcc/regrename.c
-+++ b/gcc/regrename.c
-@@ -567,14 +567,14 @@ scan_rtx_address (rtx insn, rtx *loc, en
- int index_op;
- unsigned regno0 = REGNO (op0), regno1 = REGNO (op1);
-
-- if (REGNO_OK_FOR_INDEX_P (regno1)
-+ if (regno_ok_for_index_p (regno1, mode)
- && regno_ok_for_base_p (regno0, mode, PLUS, REG))
- index_op = 1;
-- else if (REGNO_OK_FOR_INDEX_P (regno0)
-+ else if (regno_ok_for_index_p (regno0, mode)
- && regno_ok_for_base_p (regno1, mode, PLUS, REG))
- index_op = 0;
- else if (regno_ok_for_base_p (regno0, mode, PLUS, REG)
-- || REGNO_OK_FOR_INDEX_P (regno1))
-+ || regno_ok_for_index_p (regno1, mode))
- index_op = 1;
- else if (regno_ok_for_base_p (regno1, mode, PLUS, REG))
- index_op = 0;
-@@ -599,7 +599,7 @@ scan_rtx_address (rtx insn, rtx *loc, en
- }
-
- if (locI)
-- scan_rtx_address (insn, locI, INDEX_REG_CLASS, action, mode);
-+ scan_rtx_address (insn, locI, index_reg_class (mode), action, mode);
- if (locB)
- scan_rtx_address (insn, locB, base_reg_class (mode, PLUS, index_code),
- action, mode);
-@@ -1488,14 +1488,14 @@ replace_oldest_value_addr (rtx *loc, enu
- int index_op;
- unsigned regno0 = REGNO (op0), regno1 = REGNO (op1);
-
-- if (REGNO_OK_FOR_INDEX_P (regno1)
-+ if (regno_ok_for_index_p (regno1, mode)
- && regno_ok_for_base_p (regno0, mode, PLUS, REG))
- index_op = 1;
-- else if (REGNO_OK_FOR_INDEX_P (regno0)
-+ else if (regno_ok_for_index_p (regno0, mode)
- && regno_ok_for_base_p (regno1, mode, PLUS, REG))
- index_op = 0;
- else if (regno_ok_for_base_p (regno0, mode, PLUS, REG)
-- || REGNO_OK_FOR_INDEX_P (regno1))
-+ || regno_ok_for_index_p (regno1, mode))
- index_op = 1;
- else if (regno_ok_for_base_p (regno1, mode, PLUS, REG))
- index_op = 0;
-@@ -1520,8 +1520,8 @@ replace_oldest_value_addr (rtx *loc, enu
- }
-
- if (locI)
-- changed |= replace_oldest_value_addr (locI, INDEX_REG_CLASS, mode,
-- insn, vd);
-+ changed |= replace_oldest_value_addr (locI, index_reg_class (mode),
-+ mode, insn, vd);
- if (locB)
- changed |= replace_oldest_value_addr (locB,
- base_reg_class (mode, PLUS,
---- a/gcc/reload.c
-+++ b/gcc/reload.c
-@@ -5046,7 +5046,7 @@ find_reloads_address (enum machine_mode
- loc = &XEXP (*loc, 0);
- }
-
-- if (double_reg_address_ok)
-+ if (double_reg_address_ok && index_reg_class (mode) != NO_REGS)
- {
- /* Unshare the sum as well. */
- *loc = ad = copy_rtx (ad);
-@@ -5054,8 +5054,8 @@ find_reloads_address (enum machine_mode
- /* Reload the displacement into an index reg.
- We assume the frame pointer or arg pointer is a base reg. */
- find_reloads_address_part (XEXP (ad, 1), &XEXP (ad, 1),
-- INDEX_REG_CLASS, GET_MODE (ad), opnum,
-- type, ind_levels);
-+ index_reg_class (mode), GET_MODE (ad),
-+ opnum, type, ind_levels);
- return 0;
- }
- else
-@@ -5448,13 +5448,13 @@ find_reloads_address_1 (enum machine_mod
- #define REG_OK_FOR_CONTEXT(CONTEXT, REGNO, MODE, OUTER, INDEX) \
- ((CONTEXT) == 0 \
- ? regno_ok_for_base_p (REGNO, MODE, OUTER, INDEX) \
-- : REGNO_OK_FOR_INDEX_P (REGNO))
-+ : regno_ok_for_index_p (REGNO, MODE))
-
- enum reg_class context_reg_class;
- RTX_CODE code = GET_CODE (x);
-
- if (context == 1)
-- context_reg_class = INDEX_REG_CLASS;
-+ context_reg_class = index_reg_class (mode);
- else
- context_reg_class = base_reg_class (mode, outer_code, index_code);
-
-@@ -5546,17 +5546,17 @@ find_reloads_address_1 (enum machine_mod
-
- else if (code0 == REG && code1 == REG)
- {
-- if (REGNO_OK_FOR_INDEX_P (REGNO (op1))
-+ if (regno_ok_for_index_p (REGNO (op1), mode)
- && regno_ok_for_base_p (REGNO (op0), mode, PLUS, REG))
- return 0;
-- else if (REGNO_OK_FOR_INDEX_P (REGNO (op0))
-+ else if (regno_ok_for_index_p (REGNO (op0), mode)
- && regno_ok_for_base_p (REGNO (op1), mode, PLUS, REG))
- return 0;
- else if (regno_ok_for_base_p (REGNO (op0), mode, PLUS, REG))
- find_reloads_address_1 (mode, orig_op1, 1, PLUS, SCRATCH,
- &XEXP (x, 1), opnum, type, ind_levels,
- insn);
-- else if (REGNO_OK_FOR_INDEX_P (REGNO (op1)))
-+ else if (regno_ok_for_index_p (REGNO (op1), mode))
- find_reloads_address_1 (mode, orig_op0, 0, PLUS, REG,
- &XEXP (x, 0), opnum, type, ind_levels,
- insn);
-@@ -5564,7 +5564,7 @@ find_reloads_address_1 (enum machine_mod
- find_reloads_address_1 (mode, orig_op0, 1, PLUS, SCRATCH,
- &XEXP (x, 0), opnum, type, ind_levels,
- insn);
-- else if (REGNO_OK_FOR_INDEX_P (REGNO (op0)))
-+ else if (regno_ok_for_index_p (REGNO (op0), mode))
- find_reloads_address_1 (mode, orig_op1, 0, PLUS, REG,
- &XEXP (x, 1), opnum, type, ind_levels,
- insn);
-@@ -5634,7 +5634,7 @@ find_reloads_address_1 (enum machine_mod
- need to live longer than a TYPE reload normally would, so be
- conservative and class it as RELOAD_OTHER. */
- if ((REG_P (XEXP (op1, 1))
-- && !REGNO_OK_FOR_INDEX_P (REGNO (XEXP (op1, 1))))
-+ && !regno_ok_for_index_p (REGNO (XEXP (op1, 1)), mode))
- || GET_CODE (XEXP (op1, 1)) == PLUS)
- find_reloads_address_1 (mode, XEXP (op1, 1), 1, code, SCRATCH,
- &XEXP (op1, 1), opnum, RELOAD_OTHER,
-@@ -6131,18 +6131,26 @@ find_reloads_subreg_address (rtx x, int
- /* For some processors an address may be valid in the
- original mode but not in a smaller mode. For
- example, ARM accepts a scaled index register in
-- SImode but not in HImode. Similarly, the address may
-- have been valid before the subreg offset was added,
-- but not afterwards. find_reloads_address
-- assumes that we pass it a valid address, and doesn't
-- force a reload. This will probably be fine if
-- find_reloads_address finds some reloads. But if it
-- doesn't find any, then we may have just converted a
-- valid address into an invalid one. Check for that
-- here. */
-+ SImode but not in HImode. Note that this is only
-+ a problem if the address in reg_equiv_mem is already
-+ invalid in the new mode; other cases would be fixed
-+ by find_reloads_address as usual.
-+
-+ ??? We attempt to handle such cases here by doing an
-+ additional reload of the full address after the
-+ usual processing by find_reloads_address. Note that
-+ this may not work in the general case, but it seems
-+ to cover the cases where this situation currently
-+ occurs. A more general fix might be to reload the
-+ *value* instead of the address, but this would not
-+ be expected by the callers of this routine as-is.
-+
-+ If find_reloads_address already completed replaced
-+ the address, there is nothing further to do. */
- if (reloaded == 0
-- && !strict_memory_address_p (GET_MODE (tem),
-- XEXP (tem, 0)))
-+ && reg_equiv_mem[regno] != 0
-+ && !strict_memory_address_p (GET_MODE (x),
-+ XEXP (reg_equiv_mem[regno], 0)))
- push_reload (XEXP (tem, 0), NULL_RTX, &XEXP (tem, 0), (rtx*) 0,
- base_reg_class (GET_MODE (tem), MEM, SCRATCH),
- GET_MODE (XEXP (tem, 0)), VOIDmode, 0, 0,
---- a/gcc/rtl.def
-+++ b/gcc/rtl.def
-@@ -1088,7 +1088,11 @@ DEF_RTL_EXPR(FINAL_ABSENCE_SET, "final_a
- guard for the bypass. The function will get the two insns as
- parameters. If the function returns zero the bypass will be
- ignored for this case. Additional guard is necessary to recognize
-- complicated bypasses, e.g. when consumer is load address. */
-+ complicated bypasses, e.g. when consumer is load address. If there
-+ are more one bypass with the same output and input insns, the
-+ chosen bypass is the first bypass with a guard in description whose
-+ guard function returns nonzero. If there is no such bypass, then
-+ bypass without the guard function is chosen. */
- DEF_RTL_EXPR(DEFINE_BYPASS, "define_bypass", "issS", RTX_EXTRA)
-
- /* (define_automaton string) describes names of automata generated and
---- a/gcc/rtlanal.c
-+++ b/gcc/rtlanal.c
-@@ -2913,62 +2913,78 @@ int
- commutative_operand_precedence (rtx op)
- {
- enum rtx_code code = GET_CODE (op);
-+ int value;
-
- /* Constants always come the second operand. Prefer "nice" constants. */
- if (code == CONST_INT)
-- return -8;
-- if (code == CONST_DOUBLE)
-- return -7;
-- if (code == CONST_FIXED)
-- return -7;
-- op = avoid_constant_pool_reference (op);
-- code = GET_CODE (op);
--
-- switch (GET_RTX_CLASS (code))
-- {
-- case RTX_CONST_OBJ:
-- if (code == CONST_INT)
-- return -6;
-- if (code == CONST_DOUBLE)
-- return -5;
-- if (code == CONST_FIXED)
-- return -5;
-- return -4;
--
-- case RTX_EXTRA:
-- /* SUBREGs of objects should come second. */
-- if (code == SUBREG && OBJECT_P (SUBREG_REG (op)))
-- return -3;
-- return 0;
-+ value = -8;
-+ else if (code == CONST_DOUBLE)
-+ value = -7;
-+ else if (code == CONST_FIXED)
-+ value = -7;
-+ else
-+ {
-+ op = avoid_constant_pool_reference (op);
-+ code = GET_CODE (op);
-+
-+ switch (GET_RTX_CLASS (code))
-+ {
-+ case RTX_CONST_OBJ:
-+ if (code == CONST_INT)
-+ value = -6;
-+ else if (code == CONST_DOUBLE)
-+ value = -5;
-+ else if (code == CONST_FIXED)
-+ value = -5;
-+ else
-+ value = -4;
-+ break;
-+
-+ case RTX_EXTRA:
-+ /* SUBREGs of objects should come second. */
-+ if (code == SUBREG && OBJECT_P (SUBREG_REG (op)))
-+ value = -3;
-+ else
-+ value = 0;
-+ break;
-+
-+ case RTX_OBJ:
-+ /* Complex expressions should be the first, so decrease priority
-+ of objects. */
-+ value = -1;
-+ break;
-
-- case RTX_OBJ:
-- /* Complex expressions should be the first, so decrease priority
-- of objects. Prefer pointer objects over non pointer objects. */
-- if ((REG_P (op) && REG_POINTER (op))
-- || (MEM_P (op) && MEM_POINTER (op)))
-- return -1;
-- return -2;
--
-- case RTX_COMM_ARITH:
-- /* Prefer operands that are themselves commutative to be first.
-- This helps to make things linear. In particular,
-- (and (and (reg) (reg)) (not (reg))) is canonical. */
-- return 4;
--
-- case RTX_BIN_ARITH:
-- /* If only one operand is a binary expression, it will be the first
-- operand. In particular, (plus (minus (reg) (reg)) (neg (reg)))
-- is canonical, although it will usually be further simplified. */
-- return 2;
-+ case RTX_COMM_ARITH:
-+ /* Prefer operands that are themselves commutative to be first.
-+ This helps to make things linear. In particular,
-+ (and (and (reg) (reg)) (not (reg))) is canonical. */
-+ value = 4;
-+ break;
-+
-+ case RTX_BIN_ARITH:
-+ /* If only one operand is a binary expression, it will be the first
-+ operand. In particular, (plus (minus (reg) (reg)) (neg (reg)))
-+ is canonical, although it will usually be further simplified. */
-+ value = 2;
-+ break;
-
-- case RTX_UNARY:
-- /* Then prefer NEG and NOT. */
-- if (code == NEG || code == NOT)
-- return 1;
-+ case RTX_UNARY:
-+ /* Then prefer NEG and NOT. */
-+ if (code == NEG || code == NOT)
-+ value = 1;
-+ else
-+ value = 0;
-+ break;
-
-- default:
-- return 0;
-+ default:
-+ value = 0;
-+ }
- }
-+
-+ if (targetm.commutative_operand_precedence)
-+ value = targetm.commutative_operand_precedence (op, value);
-+
-+ return value;
- }
-
- /* Return 1 iff it is necessary to swap operands of commutative operation
---- a/gcc/sched-ebb.c
-+++ b/gcc/sched-ebb.c
-@@ -286,6 +286,7 @@ static struct haifa_sched_info ebb_sched
- rank,
- ebb_print_insn,
- ebb_contributes_to_priority,
-+ NULL, /* insn_finishes_block_p */
-
- NULL, NULL,
- NULL, NULL,
---- a/gcc/sched-int.h
-+++ b/gcc/sched-int.h
-@@ -558,6 +558,10 @@ struct haifa_sched_info
- calculations. */
- int (*contributes_to_priority) (rtx, rtx);
-
-+ /* Return true if scheduling insn (passed as the parameter) will trigger
-+ finish of scheduling current block. */
-+ bool (*insn_finishes_block_p) (rtx);
-+
- /* The boundaries of the set of insns to be scheduled. */
- rtx prev_head, next_tail;
-
---- a/gcc/sched-rgn.c
-+++ b/gcc/sched-rgn.c
-@@ -2338,6 +2338,19 @@ static const struct sched_deps_info_def
- 0, 0, 0
- };
-
-+/* Return true if scheduling INSN will trigger finish of scheduling
-+ current block. */
-+static bool
-+rgn_insn_finishes_block_p (rtx insn)
-+{
-+ if (INSN_BB (insn) == target_bb
-+ && sched_target_n_insns + 1 == target_n_insns)
-+ /* INSN is the last not-scheduled instruction in the current block. */
-+ return true;
-+
-+ return false;
-+}
-+
- /* Used in schedule_insns to initialize current_sched_info for scheduling
- regions (or single basic blocks). */
-
-@@ -2350,6 +2363,7 @@ static const struct haifa_sched_info rgn
- rgn_rank,
- rgn_print_insn,
- contributes_to_priority,
-+ rgn_insn_finishes_block_p,
-
- NULL, NULL,
- NULL, NULL,
---- a/gcc/sdbout.c
-+++ b/gcc/sdbout.c
-@@ -338,6 +338,7 @@ const struct gcc_debug_hooks sdb_debug_h
- debug_nothing_int, /* handle_pch */
- debug_nothing_rtx, /* var_location */
- debug_nothing_void, /* switch_text_section */
-+ debug_nothing_tree_tree, /* set_name */
- 0 /* start_end_main_source_file */
- };
-
---- a/gcc/sel-sched-ir.c
-+++ b/gcc/sel-sched-ir.c
-@@ -5431,6 +5431,7 @@ static struct haifa_sched_info sched_sel
- NULL, /* rgn_rank */
- sel_print_insn, /* rgn_print_insn */
- contributes_to_priority,
-+ NULL, /* insn_finishes_block_p */
-
- NULL, NULL,
- NULL, NULL,
---- a/gcc/target-def.h
-+++ b/gcc/target-def.h
-@@ -84,7 +84,7 @@
- #define TARGET_ASM_INTERNAL_LABEL default_internal_label
- #endif
-
--#ifndef TARGET_ARM_TTYPE
-+#ifndef TARGET_ASM_TTYPE
- #define TARGET_ASM_TTYPE hook_bool_rtx_false
- #endif
-
-@@ -208,6 +208,10 @@
- #define TARGET_EXTRA_LIVE_ON_ENTRY hook_void_bitmap
- #endif
-
-+#ifndef TARGET_WARN_FUNC_RESULT
-+#define TARGET_WARN_FUNC_RESULT hook_bool_void_true
-+#endif
-+
- #ifndef TARGET_ASM_FILE_START_APP_OFF
- #define TARGET_ASM_FILE_START_APP_OFF false
- #endif
-@@ -383,6 +387,9 @@
- #define TARGET_VECTOR_ALIGNMENT_REACHABLE \
- default_builtin_vector_alignment_reachable
- #define TARGET_VECTORIZE_BUILTIN_VEC_PERM 0
-+#define TARGET_VECTOR_MIN_ALIGNMENT \
-+ default_vector_min_alignment
-+#define TARGET_VECTOR_ALWAYS_MISALIGN hook_bool_const_tree_false
-
- #define TARGET_VECTORIZE \
- { \
-@@ -393,7 +400,9 @@
- TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD, \
- TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST, \
- TARGET_VECTOR_ALIGNMENT_REACHABLE, \
-- TARGET_VECTORIZE_BUILTIN_VEC_PERM \
-+ TARGET_VECTORIZE_BUILTIN_VEC_PERM, \
-+ TARGET_VECTOR_MIN_ALIGNMENT, \
-+ TARGET_VECTOR_ALWAYS_MISALIGN, \
- }
-
- #define TARGET_DEFAULT_TARGET_FLAGS 0
-@@ -504,6 +513,7 @@
- #define TARGET_ALLOCATE_INITIAL_VALUE NULL
-
- #define TARGET_UNSPEC_MAY_TRAP_P default_unspec_may_trap_p
-+#define TARGET_COMMUTATIVE_OPERAND_PRECEDENCE NULL
-
- #ifndef TARGET_SET_CURRENT_FUNCTION
- #define TARGET_SET_CURRENT_FUNCTION hook_void_tree
-@@ -532,6 +542,10 @@
- #define TARGET_INVALID_CONVERSION hook_constcharptr_const_tree_const_tree_null
- #define TARGET_INVALID_UNARY_OP hook_constcharptr_int_const_tree_null
- #define TARGET_INVALID_BINARY_OP hook_constcharptr_int_const_tree_const_tree_null
-+#define TARGET_INVALID_PARAMETER_TYPE hook_constcharptr_const_tree_null
-+#define TARGET_INVALID_RETURN_TYPE hook_constcharptr_const_tree_null
-+#define TARGET_PROMOTED_TYPE hook_tree_const_tree_null
-+#define TARGET_CONVERT_TO_TYPE hook_tree_tree_tree_null
-
- #define TARGET_FIXED_CONDITION_CODE_REGS hook_bool_uintp_uintp_false
-
-@@ -590,6 +604,7 @@
- #define TARGET_ARG_PARTIAL_BYTES hook_int_CUMULATIVE_ARGS_mode_tree_bool_0
-
- #define TARGET_FUNCTION_VALUE default_function_value
-+#define TARGET_LIBCALL_VALUE default_libcall_value
- #define TARGET_INTERNAL_ARG_POINTER default_internal_arg_pointer
- #define TARGET_UPDATE_STACK_BOUNDARY NULL
- #define TARGET_GET_DRAP_RTX NULL
-@@ -613,6 +628,7 @@
- TARGET_ARG_PARTIAL_BYTES, \
- TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN, \
- TARGET_FUNCTION_VALUE, \
-+ TARGET_LIBCALL_VALUE, \
- TARGET_INTERNAL_ARG_POINTER, \
- TARGET_UPDATE_STACK_BOUNDARY, \
- TARGET_GET_DRAP_RTX, \
-@@ -716,6 +732,11 @@
- #define TARGET_CXX_ADJUST_CLASS_AT_DEFINITION hook_void_tree
- #endif
-
-+
-+#ifndef TARGET_CXX_TTYPE_REF_ENCODE
-+#define TARGET_CXX_TTYPE_REF_ENCODE NULL
-+#endif
-+
- #define TARGET_CXX \
- { \
- TARGET_CXX_GUARD_TYPE, \
-@@ -730,7 +751,8 @@
- TARGET_CXX_LIBRARY_RTTI_COMDAT, \
- TARGET_CXX_USE_AEABI_ATEXIT, \
- TARGET_CXX_USE_ATEXIT_FOR_CXA_ATEXIT, \
-- TARGET_CXX_ADJUST_CLASS_AT_DEFINITION \
-+ TARGET_CXX_ADJUST_CLASS_AT_DEFINITION, \
-+ TARGET_CXX_TTYPE_REF_ENCODE \
- }
-
- /* EMUTLS specific */
-@@ -886,6 +908,7 @@
- TARGET_ADDRESS_COST, \
- TARGET_ALLOCATE_INITIAL_VALUE, \
- TARGET_UNSPEC_MAY_TRAP_P, \
-+ TARGET_COMMUTATIVE_OPERAND_PRECEDENCE, \
- TARGET_DWARF_REGISTER_SPAN, \
- TARGET_INIT_DWARF_REG_SIZES_EXTRA, \
- TARGET_FIXED_CONDITION_CODE_REGS, \
-@@ -913,6 +936,10 @@
- TARGET_INVALID_CONVERSION, \
- TARGET_INVALID_UNARY_OP, \
- TARGET_INVALID_BINARY_OP, \
-+ TARGET_INVALID_PARAMETER_TYPE, \
-+ TARGET_INVALID_RETURN_TYPE, \
-+ TARGET_PROMOTED_TYPE, \
-+ TARGET_CONVERT_TO_TYPE, \
- TARGET_IRA_COVER_CLASSES, \
- TARGET_SECONDARY_RELOAD, \
- TARGET_EXPAND_TO_RTL_HOOK, \
-@@ -923,6 +950,7 @@
- TARGET_EMUTLS, \
- TARGET_OPTION_HOOKS, \
- TARGET_EXTRA_LIVE_ON_ENTRY, \
-+ TARGET_WARN_FUNC_RESULT, \
- TARGET_UNWIND_TABLES_DEFAULT, \
- TARGET_HAVE_NAMED_SECTIONS, \
- TARGET_HAVE_SWITCHABLE_BSS_SECTIONS, \
---- a/gcc/target.h
-+++ b/gcc/target.h
-@@ -473,7 +473,16 @@ struct gcc_target
-
- /* Target builtin that implements vector permute. */
- tree (* builtin_vec_perm) (tree, tree*);
--} vectorize;
-+
-+ /* Return the minimum alignment required to load or store a
-+ vector of the given type, which may be less than the
-+ natural alignment of the type. */
-+ int (* vector_min_alignment) (const_tree);
-+
-+ /* Return true if "movmisalign" patterns should be used for all
-+ loads/stores from data arrays. */
-+ bool (* always_misalign) (const_tree);
-+ } vectorize;
-
- /* The initial value of target_flags. */
- int default_target_flags;
-@@ -694,6 +703,10 @@ struct gcc_target
- FLAGS has the same meaning as in rtlanal.c: may_trap_p_1. */
- int (* unspec_may_trap_p) (const_rtx x, unsigned flags);
-
-+ /* Return a value indicating whether an operand of a commutative
-+ operation is preferred as the first or second operand. */
-+ int (* commutative_operand_precedence) (const_rtx, int);
-+
- /* Given a register, this hook should return a parallel of registers
- to represent where to find the register pieces. Define this hook
- if the register and its mode are represented in Dwarf in
-@@ -870,6 +883,10 @@ struct gcc_target
- rtx (*function_value) (const_tree ret_type, const_tree fn_decl_or_type,
- bool outgoing);
-
-+ /* Return the rtx for the result of a libcall of mode MODE,
-+ calling the function FN_NAME. */
-+ rtx (*libcall_value) (enum machine_mode, rtx);
-+
- /* Return an rtx for the argument pointer incoming to the
- current function. */
- rtx (*internal_arg_pointer) (void);
-@@ -899,6 +916,24 @@ struct gcc_target
- is not permitted on TYPE1 and TYPE2, NULL otherwise. */
- const char *(*invalid_binary_op) (int op, const_tree type1, const_tree type2);
-
-+ /* Return the diagnostic message string if TYPE is not valid as a
-+ function parameter type, NULL otherwise. */
-+ const char *(*invalid_parameter_type) (const_tree type);
-+
-+ /* Return the diagnostic message string if TYPE is not valid as a
-+ function return type, NULL otherwise. */
-+ const char *(*invalid_return_type) (const_tree type);
-+
-+ /* If values of TYPE are promoted to some other type when used in
-+ expressions (analogous to the integer promotions), return that type,
-+ or NULL_TREE otherwise. */
-+ tree (*promoted_type) (const_tree type);
-+
-+ /* Convert EXPR to TYPE, if target-specific types with special conversion
-+ rules are involved. Return the converted expression, or NULL to apply
-+ the standard conversion rules. */
-+ tree (*convert_to_type) (tree type, tree expr);
-+
- /* Return the array of IRA cover classes for the current target. */
- const enum reg_class *(*ira_cover_classes) (void);
-
-@@ -977,6 +1012,11 @@ struct gcc_target
- class (eg, tweak visibility or perform any other required
- target modifications). */
- void (*adjust_class_at_definition) (tree type);
-+ /* Encode a reference type info, used for catching pointer
-+ references. The provided expression will be the address of the
-+ type info object of the type to which a reference is being
-+ caught. */
-+ tree (* ttype_ref_encode) (tree);
- } cxx;
-
- /* Functions and data for emulated TLS support. */
-@@ -1040,6 +1080,10 @@ struct gcc_target
- bits in the bitmap passed in. */
- void (*live_on_entry) (bitmap);
-
-+ /* Return false if warnings about missing return statements or suspect
-+ noreturn attributes should be suppressed for the current function. */
-+ bool (*warn_func_result) (void);
-+
- /* True if unwinding tables should be generated by default. */
- bool unwind_tables_default;
-
---- a/gcc/targhooks.c
-+++ b/gcc/targhooks.c
-@@ -441,6 +441,15 @@ hook_invalid_arg_for_unprototyped_fn (
- return NULL;
- }
-
-+tree
-+hook_cxx_ttype_ref_in_bit0 (tree exp)
-+{
-+ exp = convert (build_pointer_type (char_type_node), exp);
-+ exp = pointer_int_sum (PLUS_EXPR, exp, integer_one_node);
-+
-+ return exp;
-+}
-+
- /* Initialize the stack protection decls. */
-
- /* Stack protection related decls living in libgcc. */
-@@ -561,6 +570,12 @@ default_function_value (const_tree ret_t
- }
-
- rtx
-+default_libcall_value (enum machine_mode mode, rtx fun ATTRIBUTE_UNUSED)
-+{
-+ return LIBCALL_VALUE (mode);
-+}
-+
-+rtx
- default_internal_arg_pointer (void)
- {
- /* If the reg that the virtual arg pointer will be translated into is
-@@ -712,6 +727,12 @@ default_builtin_vector_alignment_reachab
- return true;
- }
-
-+int
-+default_vector_min_alignment (const_tree type)
-+{
-+ return TYPE_ALIGN_UNIT (type);
-+}
-+
- bool
- default_hard_regno_scratch_ok (unsigned int regno ATTRIBUTE_UNUSED)
- {
---- a/gcc/targhooks.h
-+++ b/gcc/targhooks.h
-@@ -48,6 +48,7 @@ extern enum machine_mode default_mode_fo
-
- extern tree default_cxx_guard_type (void);
- extern tree default_cxx_get_cookie_size (tree);
-+extern tree hook_cxx_ttype_ref_in_bit0 (tree);
-
- extern bool hook_pass_by_reference_must_pass_in_stack
- (CUMULATIVE_ARGS *, enum machine_mode mode, const_tree, bool);
-@@ -71,6 +72,8 @@ extern tree default_builtin_reciprocal (
-
- extern bool default_builtin_vector_alignment_reachable (const_tree, bool);
-
-+extern int default_vector_min_alignment (const_tree);
-+
- /* These are here, and not in hooks.[ch], because not all users of
- hooks.h include tm.h, and thus we don't have CUMULATIVE_ARGS. */
-
-@@ -87,6 +90,7 @@ extern const char *hook_invalid_arg_for_
- (const_tree, const_tree, const_tree);
- extern bool hook_bool_const_rtx_commutative_p (const_rtx, int);
- extern rtx default_function_value (const_tree, const_tree, bool);
-+extern rtx default_libcall_value (enum machine_mode, rtx);
- extern rtx default_internal_arg_pointer (void);
- #ifdef IRA_COVER_CLASSES
- extern const enum reg_class *default_ira_cover_classes (void);
---- a/gcc/testsuite/g++.dg/abi/mangle-neon.C
-+++ b/gcc/testsuite/g++.dg/abi/mangle-neon.C
-@@ -2,7 +2,7 @@
-
- // { dg-do compile }
- // { dg-require-effective-target arm_neon_ok }
--// { dg-options "-mfpu=neon -mfloat-abi=softfp" }
-+// { dg-add-options arm_neon }
-
- #include <arm_neon.h>
-
---- /dev/null
-+++ b/gcc/testsuite/g++.dg/eh/ref1.C
-@@ -0,0 +1,61 @@
-+// { dg-do run { xfail { ! arm-*-*eabi } } }
-+
-+// catching a pointer to class by reference prohibits derived->base
-+// transformation. The generic C++ ABI gets this wrong. ARM EABI
-+// gets this right, except for exception specifications where a bug is
-+// acknowledged.
-+
-+#include <stdio.h>
-+
-+struct A {};
-+
-+struct B : A {};
-+
-+int Foo ()
-+{
-+ B b;
-+
-+ try
-+ {
-+ throw &b;
-+ }
-+ catch (A *&a) // { dg-bogus "earlier handler" "" { xfail { ! arm-*-*eabi } } }
-+ {
-+ printf ("fail, caught A*&%p\n", a);
-+ return 1;
-+ }
-+ catch (B *&b) // { dg-bogus "will be caught" "" { xfail { ! arm-*-*eabi } } }
-+ {
-+ printf ("pass, caught B*&%p\n", b);
-+ }
-+ catch (...)
-+ {
-+ printf ("fail, caught ...");
-+ return 2;
-+ }
-+ try
-+ {
-+ throw &b;
-+ }
-+ catch (A *a) // { dg-warning "by earlier handler" }
-+ {
-+ printf ("pass, caught A*%p\n", a);
-+ }
-+ catch (B *b) // { dg-warning "will be caught" }
-+ {
-+ printf ("fail, caught B*%p\n", b);
-+ return 3;
-+ }
-+ catch (...)
-+ {
-+ printf ("fail, caught ...");
-+ return 4;
-+ }
-+ return 0;
-+}
-+
-+
-+int main ()
-+{
-+ return Foo ();
-+}
---- /dev/null
-+++ b/gcc/testsuite/g++.dg/eh/ref2.C
-@@ -0,0 +1,70 @@
-+// { dg-do run { xfail { ! arm-*-*eabi } } }
-+
-+// catching a pointer to class by reference prohibits derived->base
-+// transformation. The generic C++ ABI gets this wrong. ARM EABI
-+// gets this right, except for exception specifications where a bug is
-+// acknowledged.
-+
-+#include <stdio.h>
-+#include <exception>
-+#include <stdlib.h>
-+
-+struct A {};
-+
-+struct B : A {};
-+
-+B b;
-+
-+void One () throw (A *&)
-+{
-+ throw &b;
-+}
-+
-+void Two () throw (A *&, B *&)
-+{
-+ throw &b;
-+}
-+
-+void Three () throw (A *)
-+{
-+ throw &b;
-+}
-+
-+int Foo (void (*fn)())
-+{
-+ try
-+ {
-+ fn ();
-+ }
-+ catch (B *b)
-+ {
-+ printf ("pass, caught B*%p\n", b);
-+ }
-+ catch (...)
-+ {
-+ printf ("fail, caught ...");
-+ return 1;
-+ }
-+ return 0;
-+}
-+
-+void handler ()
-+{
-+ printf ("pass, got unexpected exception\n");
-+ exit (0);
-+}
-+
-+int main ()
-+{
-+ if (Foo (&Three))
-+ return 1;
-+
-+ if (Foo (&Two))
-+ return 2;
-+
-+ std::set_unexpected (handler);
-+ if (Foo (&One))
-+ return 3;
-+ printf ("fail, did not get unexpected exception\n");
-+ return 4;
-+}
---- /dev/null
-+++ b/gcc/testsuite/g++.dg/ext/altivec-17.C
-@@ -0,0 +1,16 @@
-+// { dg-do compile { target powerpc*-*-* } }
-+// { dg-require-effective-target powerpc_altivec_ok }
-+// { dg-options "-maltivec" }
-+
-+// Make sure that bool vectors have distinct names to int vectors
-+
-+#define vector__ __attribute__((altivec (vector__)))
-+#define bool__ __attribute__((altivec(bool__)))
-+
-+typedef vector__ unsigned int simd_type;
-+typedef vector__ bool__ int bool_simd_type;
-+
-+void Foo (bool_simd_type const &a)
-+{
-+ simd_type const &v = a; // { dg-error "'const unsigned int __vector__&' from expression of type 'const __bool int __vector__'" }
-+}
---- /dev/null
-+++ b/gcc/testsuite/g++.dg/ext/arm-fp16/arm-fp16-ops-1.C
-@@ -0,0 +1,5 @@
-+/* Test various operators on __fp16 and mixed __fp16/float operands. */
-+/* { dg-do run { target arm*-*-* } } */
-+/* { dg-options "-mfp16-format=ieee" } */
-+
-+#include "arm-fp16-ops.h"
---- /dev/null
-+++ b/gcc/testsuite/g++.dg/ext/arm-fp16/arm-fp16-ops-2.C
-@@ -0,0 +1,5 @@
-+/* Test various operators on __fp16 and mixed __fp16/float operands. */
-+/* { dg-do run { target arm*-*-* } } */
-+/* { dg-options "-mfp16-format=ieee -ffast-math" } */
-+
-+#include "arm-fp16-ops.h"
---- /dev/null
-+++ b/gcc/testsuite/g++.dg/ext/arm-fp16/arm-fp16-ops-3.C
-@@ -0,0 +1,5 @@
-+/* Test various operators on __fp16 and mixed __fp16/float operands. */
-+/* { dg-do run { target arm*-*-* } } */
-+/* { dg-options "-mfp16-format=alternative" } */
-+
-+#include "arm-fp16-ops.h"
---- /dev/null
-+++ b/gcc/testsuite/g++.dg/ext/arm-fp16/arm-fp16-ops-4.C
-@@ -0,0 +1,5 @@
-+/* Test various operators on __fp16 and mixed __fp16/float operands. */
-+/* { dg-do run { target arm*-*-* } } */
-+/* { dg-options "-mfp16-format=alternative -ffast-math" } */
-+
-+#include "arm-fp16-ops.h"
---- /dev/null
-+++ b/gcc/testsuite/g++.dg/ext/arm-fp16/arm-fp16-ops-5.C
-@@ -0,0 +1,15 @@
-+/* Test various operators on __fp16 and mixed __fp16/float operands. */
-+/* { dg-do compile { target arm*-*-* } } */
-+/* { dg-require-effective-target arm_neon_fp16_ok } */
-+/* { dg-options "-mfp16-format=ieee" } */
-+/* { dg-add-options arm_neon_fp16 } */
-+
-+#include "arm-fp16-ops.h"
-+
-+/* We've specified options for hardware float, including fp16 support, so
-+ we should not see any calls to libfuncs here. */
-+/* { dg-final { scan-assembler-not "\tbl\t__.*hf2" } } */
-+/* { dg-final { scan-assembler-not "\tbl\t__.*hf3" } } */
-+/* { dg-final { scan-assembler-not "\tbl\t__gnu_h\[a-z\]*_ieee" } } */
-+/* { dg-final { scan-assembler-not "\tbl\t__gnu_h2f_ieee" } } */
-+/* { dg-final { scan-assembler-not "\tbl\t__gnu_f2h_ieee" } } */
---- /dev/null
-+++ b/gcc/testsuite/g++.dg/ext/arm-fp16/arm-fp16-ops-6.C
-@@ -0,0 +1,15 @@
-+/* Test various operators on __fp16 and mixed __fp16/float operands. */
-+/* { dg-do compile { target arm*-*-* } } */
-+/* { dg-require-effective-target arm_neon_fp16_ok } */
-+/* { dg-options "-mfp16-format=ieee -ffast-math" } */
-+/* { dg-add-options arm_neon_fp16 } */
-+
-+#include "arm-fp16-ops.h"
-+
-+/* We've specified options for hardware float, including fp16 support, so
-+ we should not see any calls to libfuncs here. */
-+/* { dg-final { scan-assembler-not "\tbl\t__.*hf2" } } */
-+/* { dg-final { scan-assembler-not "\tbl\t__.*hf3" } } */
-+/* { dg-final { scan-assembler-not "\tbl\t__gnu_h\[a-z\]*_ieee" } } */
-+/* { dg-final { scan-assembler-not "\tbl\t__gnu_h2f_ieee" } } */
-+/* { dg-final { scan-assembler-not "\tbl\t__gnu_f2h_ieee" } } */
---- /dev/null
-+++ b/gcc/testsuite/g++.dg/ext/arm-fp16/arm-fp16-ops-7.C
-@@ -0,0 +1,13 @@
-+/* Test various operators on __fp16 and mixed __fp16/float operands. */
-+/* { dg-do compile { target arm*-*-* } } */
-+/* { dg-require-effective-target arm_neon_ok } */
-+/* { dg-options "-mfp16-format=ieee" } */
-+/* { dg-add-options arm_neon } */
-+
-+#include "arm-fp16-ops.h"
-+
-+/* We've specified options for hardware float, so we should not see any
-+ calls to libfuncs here except for those to the conversion functions. */
-+/* { dg-final { scan-assembler-not "\tbl\t__.*hf2" } } */
-+/* { dg-final { scan-assembler-not "\tbl\t__.*hf3" } } */
-+/* { dg-final { scan-assembler-not "\tbl\t__gnu_h\[a-z\]*_ieee" } } */
---- /dev/null
-+++ b/gcc/testsuite/g++.dg/ext/arm-fp16/arm-fp16-ops-8.C
-@@ -0,0 +1,13 @@
-+/* Test various operators on __fp16 and mixed __fp16/float operands. */
-+/* { dg-do compile { target arm*-*-* } } */
-+/* { dg-require-effective-target arm_neon_ok } */
-+/* { dg-options "-mfp16-format=ieee -ffast-math" } */
-+/* { dg-add-options arm_neon } */
-+
-+#include "arm-fp16-ops.h"
-+
-+/* We've specified options for hardware float, so we should not see any
-+ calls to libfuncs here except for those to the conversion functions. */
-+/* { dg-final { scan-assembler-not "\tbl\t__.*hf2" } } */
-+/* { dg-final { scan-assembler-not "\tbl\t__.*hf3" } } */
-+/* { dg-final { scan-assembler-not "\tbl\t__gnu_h\[a-z\]*_ieee" } } */
---- /dev/null
-+++ b/gcc/testsuite/g++.dg/ext/arm-fp16/arm-fp16-ops.h
-@@ -0,0 +1,135 @@
-+/* Test various operators on __fp16 and mixed __fp16/float operands. */
-+
-+#include <assert.h>
-+
-+#define CHECK(e,r) assert ((e) == r)
-+#define CHECK2(e,r) (assert ((e) == r), temp = (e), assert (temp == r))
-+#define TEST(e) assert (e)
-+#define TESTNOT(e) assert (!(e))
-+
-+volatile __fp16 h0 = 0.0;
-+volatile __fp16 h1 = 1.0;
-+volatile __fp16 h42 = 42.0;
-+volatile __fp16 hm2 = -2.0;
-+volatile __fp16 temp;
-+
-+volatile float f0 = 0.0;
-+volatile float f1 = 1.0;
-+volatile float f42 = 42.0;
-+volatile float fm2 = -2.0;
-+
-+int main (void)
-+{
-+ TEST (h1);
-+ TESTNOT (h0);
-+ TEST (!h0);
-+ TESTNOT (!h1);
-+
-+ CHECK2 (-h1, -1.0);
-+ CHECK2 (+h1, 1.0);
-+
-+ CHECK (h1++, 1.0);
-+ CHECK (h1, 2.0);
-+ CHECK (++h1, 3.0);
-+ CHECK (h1, 3.0);
-+
-+ CHECK (--h1, 2.0);
-+ CHECK (h1, 2.0);
-+ CHECK (h1--, 2.0);
-+ CHECK (h1, 1.0);
-+
-+ CHECK2 (h42 * hm2, -84.0);
-+ CHECK2 (h42 * (__fp16) -2.0, -84.0);
-+ CHECK2 (h42 * fm2, -84.0);
-+ CHECK2 (f42 * hm2, -84.0);
-+
-+ CHECK2 (h42 / hm2, -21.0);
-+ CHECK2 (h42 / (__fp16) -2.0, -21.0);
-+ CHECK2 (h42 / fm2, -21.0);
-+ CHECK2 (f42 / hm2, -21.0);
-+
-+ CHECK2 (hm2 + h42, 40.0);
-+ CHECK2 ((__fp16)-2.0 + h42, 40.0);
-+ CHECK2 (hm2 + f42, 40.0);
-+ CHECK2 (fm2 + h42, 40.0);
-+
-+ CHECK2 (hm2 - h42, -44.0);
-+ CHECK2 ((__fp16)-2.0 - h42, -44.0);
-+ CHECK2 (hm2 - f42, -44.0);
-+ CHECK2 (fm2 - h42, -44.0);
-+
-+ TEST (hm2 < h42);
-+ TEST (hm2 < (__fp16)42.0);
-+ TEST (hm2 < f42);
-+ TEST (fm2 < h42);
-+
-+ TEST (h42 > hm2);
-+ TEST ((__fp16)42.0 > hm2);
-+ TEST (h42 > fm2);
-+ TEST (f42 > hm2);
-+
-+ TEST (hm2 <= h42);
-+ TEST (hm2 <= (__fp16)42.0);
-+ TEST (hm2 <= f42);
-+ TEST (fm2 <= h42);
-+
-+ TEST (h42 >= hm2);
-+ TEST (h42 >= (__fp16)-2.0);
-+ TEST (h42 >= fm2);
-+ TEST (f42 >= hm2);
-+
-+ TESTNOT (h1 == hm2);
-+ TEST (h1 == h1);
-+ TEST (h1 == (__fp16)1.0);
-+ TEST (h1 == f1);
-+ TEST (f1 == h1);
-+
-+ TEST (h1 != hm2);
-+ TESTNOT (h1 != h1);
-+ TESTNOT (h1 != (__fp16)1.0);
-+ TESTNOT (h1 != f1);
-+ TESTNOT (f1 != h1);
-+
-+ CHECK2 ((h1 ? hm2 : h42), -2.0);
-+ CHECK2 ((h0 ? hm2 : h42), 42.0);
-+
-+ CHECK (h0 = h42, 42.0);
-+ CHECK (h0, 42.0);
-+ CHECK (h0 = (__fp16)-2.0, -2.0);
-+ CHECK (h0, -2.0);
-+ CHECK (h0 = f0, 0.0);
-+ CHECK (h0, 0.0);
-+
-+ CHECK (h0 += h1, 1.0);
-+ CHECK (h0, 1.0);
-+ CHECK (h0 += (__fp16)1.0, 2.0);
-+ CHECK (h0, 2.0);
-+ CHECK (h0 += fm2, 0.0);
-+ CHECK (h0, 0.0);
-+
-+ CHECK (h0 -= h1, -1.0);
-+ CHECK (h0, -1.0);
-+ CHECK (h0 -= (__fp16)1.0, -2.0);
-+ CHECK (h0, -2.0);
-+ CHECK (h0 -= fm2, 0.0);
-+ CHECK (h0, 0.0);
-+
-+ h0 = hm2;
-+ CHECK (h0 *= hm2, 4.0);
-+ CHECK (h0, 4.0);
-+ CHECK (h0 *= (__fp16)-2.0, -8.0);
-+ CHECK (h0, -8.0);
-+ CHECK (h0 *= fm2, 16.0);
-+ CHECK (h0, 16.0);
-+
-+ CHECK (h0 /= hm2, -8.0);
-+ CHECK (h0, -8.0);
-+ CHECK (h0 /= (__fp16)-2.0, 4.0);
-+ CHECK (h0, 4.0);
-+ CHECK (h0 /= fm2, -2.0);
-+ CHECK (h0, -2.0);
-+
-+ CHECK ((h0, h1), 1.0);
-+
-+ return 0;
-+}
---- /dev/null
-+++ b/gcc/testsuite/g++.dg/ext/arm-fp16/fp16-mangle-1.C
-@@ -0,0 +1,14 @@
-+/* { dg-do compile { target arm*-*-* } } */
-+/* { dg-options "-mfp16-format=ieee" } */
-+
-+/* Test mangling */
-+
-+/* { dg-final { scan-assembler "\t.global\t_Z1fPDh" } } */
-+void f (__fp16 *x) { }
-+
-+/* { dg-final { scan-assembler "\t.global\t_Z1gPDhS_" } } */
-+void g (__fp16 *x, __fp16 *y) { }
-+
-+/* { dg-final { scan-assembler "\t.global\t_ZN1SIDhDhE1iE" } } */
-+template <typename T, typename U> struct S { static int i; };
-+template <> int S<__fp16, __fp16>::i = 3;
---- /dev/null
-+++ b/gcc/testsuite/g++.dg/ext/arm-fp16/fp16-overload-1.C
-@@ -0,0 +1,16 @@
-+/* { dg-do compile { target arm*-*-* } } */
-+/* { dg-options "-mfp16-format=ieee" } */
-+
-+/* __fp16 values are autoconverted to float and should therefore be treated
-+ * just like float for overloading purposes. */
-+
-+extern int frobnify (float x);
-+extern int frobnify (double x);
-+
-+int g (void)
-+{
-+ return frobnify ((__fp16)1.0);
-+}
-+
-+/* { dg-final { scan-assembler "_Z8frobnifyf" } } */
-+/* { dg-final { scan-assembler-not " _Z8frobnifyd" } } */
---- /dev/null
-+++ b/gcc/testsuite/g++.dg/ext/arm-fp16/fp16-param-1.C
-@@ -0,0 +1,10 @@
-+/* { dg-do compile { target arm*-*-* } } */
-+/* { dg-options "-mfp16-format=ieee" } */
-+
-+/* Functions cannot have parameters of type __fp16. */
-+extern void f (__fp16); /* { dg-error "parameters cannot have __fp16 type" } */
-+extern void (*pf) (__fp16); /* { dg-error "parameters cannot have __fp16 type" } */
-+
-+/* These should be OK. */
-+extern void g (__fp16 *);
-+extern void (*pg) (__fp16 *);
---- /dev/null
-+++ b/gcc/testsuite/g++.dg/ext/arm-fp16/fp16-return-1.C
-@@ -0,0 +1,10 @@
-+/* { dg-do compile { target arm*-*-* } } */
-+/* { dg-options "-mfp16-format=ieee" } */
-+
-+/* Functions cannot return type __fp16. */
-+extern __fp16 f (void); /* { dg-error "cannot return __fp16" } */
-+extern __fp16 (*pf) (void); /* { dg-error "cannot return __fp16" } */
-+
-+/* These should be OK. */
-+extern __fp16 *g (void);
-+extern __fp16 *(*pg) (void);
---- /dev/null
-+++ b/gcc/testsuite/g++.dg/ext/dllexport2.C
-@@ -0,0 +1,52 @@
-+// { dg-do link }
-+// { dg-require-dll "" }
-+// { dg-additional-sources "dllexport2a.cc" }
-+// { dg-options "-O2" }
-+
-+/* Test that inline functions declared "dllexport" appear in object
-+ files, even if they are not called.
-+
-+ This behavior is required by the ARM C++ ABI:
-+
-+ Exporting a function that can be inlined should force the
-+ creation and export of an out-of-line copy of it.
-+
-+ and should presumably also apply.
-+
-+ Visual Studio 2005 also honors that rule. */
-+
-+__declspec(dllexport) inline void i1() {}
-+
-+__declspec(dllexport) extern inline void e1() {}
-+
-+/* It is invalid to declare the function inline after its definition. */
-+#if 0
-+__declspec(dllexport) void i2() {}
-+inline void i2();
-+
-+__declspec(dllexport) extern void e2() {}
-+inline void e2();
-+#endif
-+
-+__declspec(dllexport) inline void i3() {}
-+void i3();
-+
-+__declspec(dllexport) inline void e3() {}
-+extern void e3();
-+
-+__declspec(dllexport) void i4();
-+inline void i4() {};
-+
-+__declspec(dllexport) extern void e4();
-+inline void e4() {};
-+
-+__declspec(dllexport) inline void i5();
-+void i5() {};
-+
-+__declspec(dllexport) inline void e5();
-+extern void e5() {};
-+
-+/* Make sure that just declaring the function -- without defining it
-+ -- does not cause errors. */
-+__declspec(dllexport) inline void i6();
-+__declspec(dllexport) extern inline void e6();
---- /dev/null
-+++ b/gcc/testsuite/g++.dg/ext/dllexport2a.cc
-@@ -0,0 +1,21 @@
-+extern void i1();
-+extern void i3();
-+extern void i4();
-+extern void i5();
-+
-+extern void e1();
-+extern void e3();
-+extern void e4();
-+extern void e5();
-+
-+int main () {
-+ i1();
-+ i3();
-+ i4();
-+ i5();
-+
-+ e1();
-+ e3();
-+ e4();
-+ e5();
-+}
---- /dev/null
-+++ b/gcc/testsuite/g++.dg/ext/ms-1.C
-@@ -0,0 +1,17 @@
-+
-+// MS allows more things to be pointers to member functions
-+// { dg-options "-fms-extensions" }
-+
-+struct X
-+{
-+ void Foo (X *);
-+ void Bar ();
-+};
-+
-+void Quux (void (X::*) ());
-+
-+void X::Foo (X *ptr) // { dg-message "candidates" }
-+{
-+ Quux (Foo); // { dg-error "no matches" }
-+ Quux (Bar);
-+}
---- a/gcc/testsuite/g++.dg/init/ref15.C
-+++ b/gcc/testsuite/g++.dg/init/ref15.C
-@@ -1,6 +1,8 @@
- // PR c++/20416. We correctly constructed the temporary S in foo(),
- // but incorrectly destroyed it every time foo() was called.
--// { dg-do run }
-+// When using a wrapped target, there is no way to override the exit
-+// code after returning from main.
-+// { dg-do run { target unwrapped } }
- extern "C" void abort (void);
- extern "C" void _exit (int);
-
---- /dev/null
-+++ b/gcc/testsuite/g++.dg/opt/alias5.C
-@@ -0,0 +1,24 @@
-+// { dg-options "-O2" }
-+// ICE in struct-alias
-+
-+typedef int (*PFN)(void);
-+int f (void);
-+struct Container
-+{
-+ PFN ptr;
-+};
-+
-+inline PFN Get (struct Container *tpl)
-+{
-+ return tpl->ptr;
-+}
-+void Other (PFN);
-+
-+inline void Foo (PFN pfn)
-+{
-+ Other (Get ((struct Container *)&pfn));
-+}
-+void Bar (void)
-+{
-+ Foo (f);
-+}
---- /dev/null
-+++ b/gcc/testsuite/g++.dg/other/arm-neon-1.C
-@@ -0,0 +1,18 @@
-+/* Basic smoke test for arm_neon.h */
-+
-+/* { dg-do assemble } */
-+/* { dg-require-effective-target arm_neon_ok } */
-+/* { dg-add-options arm_neon } */
-+
-+#include "arm_neon.h"
-+
-+float a[4];
-+
-+void test(void)
-+{
-+ float32x2x2_t v;
-+ float32x2_t res;
-+ v = vld2_f32(a);
-+ res = vadd_f32(v.val[0], v.val[1]);
-+ vst1_f32(a, res);
-+}
---- /dev/null
-+++ b/gcc/testsuite/g++.dg/other/armv7m-1.C
-@@ -0,0 +1,69 @@
-+/* { dg-do run { target arm*-*-* } } */
-+/* Test Armv7m interrupt routines. */
-+#include <stdlib.h>
-+
-+#ifdef __ARM_ARCH_7M__
-+void __attribute__((interrupt))
-+foo(void)
-+{
-+ long long n;
-+ long p;
-+ asm volatile ("" : "=r" (p) : "0" (&n));
-+ if (p & 4)
-+ abort ();
-+ return;
-+}
-+
-+void __attribute__((interrupt))
-+bar(void)
-+{
-+ throw 42;
-+}
-+
-+int main()
-+{
-+ int a;
-+ int before;
-+ int after;
-+ volatile register int sp asm("sp");
-+
-+ asm volatile ("mov %0, sp\n"
-+ "blx %2\n"
-+ "mov %1, sp\n"
-+ : "=&r" (before), "=r" (after) : "r" (foo)
-+ : "memory", "cc", "r0", "r1", "r2", "r3", "ip", "lr");
-+ if (before != after)
-+ abort();
-+ asm volatile ("mov %0, sp\n"
-+ "sub sp, sp, #4\n"
-+ "blx %2\n"
-+ "add sp, sp, #4\n"
-+ "mov %1, sp\n"
-+ : "=&r" (before), "=r" (after) : "r" (foo)
-+ : "memory", "cc", "r0", "r1", "r2", "r3", "ip", "lr");
-+ if (before != after)
-+ abort();
-+ before = sp;
-+ try
-+ {
-+ bar();
-+ }
-+ catch (int i)
-+ {
-+ if (i != 42)
-+ abort();
-+ }
-+ catch (...)
-+ {
-+ abort();
-+ }
-+ if (before != sp)
-+ abort();
-+ exit(0);
-+}
-+#else
-+int main()
-+{
-+ exit (0);
-+}
-+#endif
---- /dev/null
-+++ b/gcc/testsuite/g++.dg/remove-local-statics-1.C
-@@ -0,0 +1,21 @@
-+/* Verify that we do not eliminate a static variable in
-+ main::Local::Foo. */
-+
-+/* { dg-do compile } */
-+/* { dg-options "-O2 -fremove-local-statics" } */
-+/* { dg-final { scan-assembler "thestatic" } } */
-+
-+int
-+main (void)
-+{
-+ static int thestatic = 0;
-+ struct Local {
-+ __attribute__((__noinline__))
-+ static void Foo () { thestatic = 1; }
-+ };
-+
-+ thestatic = 2;
-+ Local::Foo();
-+
-+ return thestatic++;
-+}
---- /dev/null
-+++ b/gcc/testsuite/g++.dg/remove-local-statics-2.C
-@@ -0,0 +1,21 @@
-+/* Verify that we do not eliminate a static variable in
-+ main due to its use in Local::Foo. */
-+
-+/* { dg-do compile } */
-+/* { dg-options "-O2 -fremove-local-statics" } */
-+/* { dg-final { scan-assembler "thestatic" } } */
-+
-+int
-+main (void)
-+{
-+ static int thestatic = 0;
-+ struct Local {
-+ __attribute__((__noinline__))
-+ static int Foo () { return thestatic; }
-+ };
-+
-+ thestatic = 2;
-+ thestatic = Local::Foo();
-+
-+ return thestatic++;
-+}
---- a/gcc/testsuite/g++.dg/template/overload9.C
-+++ b/gcc/testsuite/g++.dg/template/overload9.C
-@@ -7,12 +7,12 @@ template <typename T> A<T>& operator<<(A
- template <typename T>
- struct A
- {
-- A<T>& operator<<(A<T>& (*)(A<T>&)); // { dg-message "candidate" }
-+ A<T>& operator<<(A<T>& (*)(A<T>&));
- };
-
- template <typename T> A<T>& foo(A<T>&);
- extern A<char> c;
-
- int main () {
-- c << (1, foo); // { dg-error "no match" }
-+ c << (1, foo); // { dg-error "no context" }
- }
---- a/gcc/testsuite/g++.dg/torture/pr36191.C
-+++ b/gcc/testsuite/g++.dg/torture/pr36191.C
-@@ -1,6 +1,7 @@
- // PR c++/36191
- // { dg-do compile }
- // { dg-options "-fnon-call-exceptions" }
-+// { dg-skip-if "Frame pointer required for unwind tables" { sh*-*-* } "-fomit-frame-pointer" "" }
-
- __complex__ double
- foo (__complex__ double x, double y)
---- /dev/null
-+++ b/gcc/testsuite/g++.dg/tree-ssa/sink-1.C
-@@ -0,0 +1,50 @@
-+/* { dg-do run } */
-+/* { dg-options "-O1" } */
-+
-+class A {
-+ public:
-+ A() {}
-+ virtual ~A() {}
-+ void * dostuff();
-+
-+ virtual int dovirtual() = 0;
-+};
-+
-+
-+class B : public A {
-+ public:
-+ B() {}
-+ int dovirtual() { return 0;}
-+ virtual ~B() {};
-+};
-+
-+class C : public B {
-+ public:
-+ C() {}
-+ virtual ~C() {};
-+};
-+
-+void* A::dostuff()
-+{
-+ return (void*)dovirtual();
-+}
-+
-+/* tree-ssa-sink was sinking the inlined destructor for STUFF out of
-+ the first inner block and into the second one, where it was ending up
-+ after the inlined constructor for STUFF2. This is bad because
-+ cfgexpand aliases STUFF and STUFF2 to the same storage at -O1
-+ (i.e., without -fstrict-aliasing), with the result that STUFF2's
-+ vtable was getting trashed. */
-+
-+int main() {
-+ {
-+ B stuff;
-+ stuff.dostuff();
-+ }
-+ {
-+ C stuff2;
-+ stuff2.dostuff();
-+ }
-+ return 0;
-+}
-+
---- a/gcc/testsuite/g++.dg/vect/vect.exp
-+++ b/gcc/testsuite/g++.dg/vect/vect.exp
-@@ -105,7 +105,7 @@ if [istarget "powerpc-*paired*"] {
- } elseif [istarget "ia64-*-*"] {
- set dg-do-what-default run
- } elseif [is-effective-target arm_neon_ok] {
-- lappend DEFAULT_VECTCFLAGS "-mfpu=neon" "-mfloat-abi=softfp"
-+ eval lappend DEFAULT_VECTCFLAGS [add_options_for_arm_neon ""]
- if [is-effective-target arm_neon_hw] {
- set dg-do-what-default run
- } else {
---- a/gcc/testsuite/g++.dg/warn/null4.C
-+++ b/gcc/testsuite/g++.dg/warn/null4.C
-@@ -11,9 +11,22 @@ int foo (void)
- if (NULL < NULL) return -1; // { dg-warning "NULL used in arithmetic" }
- if (NULL >= 0) return -1; // { dg-warning "NULL used in arithmetic" }
- if (NULL <= 0) return -1; // { dg-warning "NULL used in arithmetic" }
-+ // Adding to the NULL pointer, which has no specific type, should
-+ // result in a warning; the type of the resulting expression is
-+ // actually "int", not a pointer type.
-+ if (NULL + 1) return -1; // { dg-warning "NULL used in arithmetic" }
-+ if (1 + NULL) return -1; // { dg-warning "NULL used in arithmetic" }
- return 0;
- }
-
-+int *ip;
-+
-+struct S {};
-+typedef int S::*SPD;
-+typedef void (S::*SPF)(void);
-+SPD spd;
-+SPF spf;
-+
- int bar (void)
- {
- if (NULL) return -1;
-@@ -25,5 +38,18 @@ int bar (void)
- if (NULL != NULL) return -1;
- if (NULL == 0) return -1;
- if (NULL != 0) return -1;
-+ // Subtraction of pointers is vaild, so using NULL is OK.
-+ if (ip - NULL) return -1;
-+ if (NULL - NULL) return -1;
-+ // Comparing NULL with a pointer-to-member is OK.
-+ if (NULL == spd) return -1;
-+ if (spd == NULL) return -1;
-+ if (NULL != spd) return -1;
-+ if (spd != NULL) return -1;
-+ if (NULL == spf) return -1;
-+ if (spf == NULL) return -1;
-+ if (NULL != spf) return -1;
-+ if (spf != NULL) return -1;
-+
- return 0;
- }
---- a/gcc/testsuite/g++.old-deja/g++.other/overload11.C
-+++ b/gcc/testsuite/g++.old-deja/g++.other/overload11.C
-@@ -54,11 +54,10 @@ int main (int argc, char **argv)
-
- ptr = (ovl); // ok
- ptr = (&ovl); // ok
-- // 13.4 indicates these are ok.
-- ptr = (0, ovl); // ok { dg-bogus "" "" { xfail *-*-* } }
-- ptr = (0, &ovl); // ok { dg-bogus "" "" { xfail *-*-* } }
-- ptr = (argc ? ovl : ovl); // ok { dg-bogus "" "" { xfail *-*-* } }
-- ptr = (argc ? &ovl : &ovl);// ok { dg-bogus "" "" { xfail *-*-* } }
-+ ptr = (0, ovl); // ok { dg-error "no context" }
-+ ptr = (0, &ovl); // ok { dg-error "no context" }
-+ ptr = (argc ? ovl : ovl); // ok { dg-error "no context" }
-+ ptr = (argc ? &ovl : &ovl);// ok { dg-error "no context" }
-
- vptr = (ovl); // { dg-error "" } no matching candidates
- vptr = (&ovl); // { dg-error "" } no matching candidates
---- /dev/null
-+++ b/gcc/testsuite/gcc.c-torture/execute/990208-1.x
-@@ -0,0 +1,12 @@
-+
-+# On ARM, with -Os, some of the functions that this test
-+# expects to be inlined are not inlined for code size
-+# reasons. This is not a bug, it's intentional,
-+# so stop this test from running.
-+set torture_eval_before_compile {
-+ if { [istarget "arm-*-*"] && [string match {*-Os*} "$option"] } {
-+ continue
-+ }
-+}
-+
-+return 0
-\ No newline at end of file
---- /dev/null
-+++ b/gcc/testsuite/gcc.c-torture/execute/bcp-1.x
-@@ -0,0 +1,12 @@
-+
-+# On ARM, with -Os, some of the functions that this test
-+# expects to be inlined are not inlined for code size
-+# reasons. This is not a bug, it's intentional,
-+# so stop this test from running.
-+set torture_eval_before_compile {
-+ if { [istarget "arm-*-*"] && [string match {*-Os*} "$option"] } {
-+ continue
-+ }
-+}
-+
-+return 0
-\ No newline at end of file
---- a/gcc/testsuite/gcc.c-torture/execute/ieee/ieee.exp
-+++ b/gcc/testsuite/gcc.c-torture/execute/ieee/ieee.exp
-@@ -54,6 +54,9 @@ if { [istarget "alpha*-*-*"]
- || [istarget "sh*-*-*"] } then {
- lappend additional_flags "-mieee"
- }
-+if [istarget "mips*-sde-*"] then {
-+ lappend additional_flags "-Wl,--defsym=__cs3_mips_float_type=2" "-lcs3-mips-cp1" "-lcs3-mips-fpemu"
-+}
-
- # load support procs
- load_lib c-torture.exp
---- a/gcc/testsuite/gcc.dg/builtin-redefine.c
-+++ b/gcc/testsuite/gcc.dg/builtin-redefine.c
-@@ -28,7 +28,7 @@
- #define __TIME__ "X" /* Re-define while defined. */
-
- #define __TIME__ "Y" /* { dg-warning "\"__TIME__\" redefined" } */
--/* { dg-warning "previous definition" "" { target *-*-* } 28 } */
-+/* { dg-message "previous definition" "" { target *-*-* } 28 } */
-
- #undef __TIME__ /* Undefine while defined. */
-
-@@ -39,7 +39,7 @@
- #define __DATE__ "X" /* Re-define while defined. */
-
- #define __DATE__ "Y" /* { dg-warning "\"__DATE__\" redefined" } */
--/* { dg-warning "previous definition" "" { target *-*-* } 39 } */
-+/* { dg-message "previous definition" "" { target *-*-* } 39 } */
-
- #undef __DATE__ /* Undefine while defined. */
-
-@@ -48,7 +48,7 @@
- #define __TIMESTAMP__ "X" /* Re-define while defined. */
-
- #define __TIMESTAMP__ "Y" /* { dg-warning "\"__TIMESTAMP__\" redefined" } */
--/* { dg-warning "previous definition" "" { target *-*-* } 48 } */
-+/* { dg-message "previous definition" "" { target *-*-* } 48 } */
-
- #undef __TIMESTAMP__ /* Undefine while defined. */
-
---- a/gcc/testsuite/gcc.dg/compat/struct-layout-1_generate.c
-+++ b/gcc/testsuite/gcc.dg/compat/struct-layout-1_generate.c
-@@ -46,7 +46,7 @@ const char *dg_options[] = {
- "/* { dg-options \"%s-I%s\" } */\n",
- "/* { dg-options \"%s-I%s -Wno-abi\" } */\n",
- "/* { dg-options \"%s-I%s -mno-mmx -Wno-abi\" { target i?86-*-* x86_64-*-* } } */\n",
--"/* { dg-options \"%s-I%s -fno-common\" { target hppa*-*-hpux* powerpc*-*-darwin* *-*-mingw32* *-*-cygwin* } } */\n",
-+"/* { dg-options \"%s-I%s -fno-common\" { target hppa*-*-hpux* powerpc*-*-darwin* } } */\n",
- "/* { dg-options \"%s-I%s -mno-mmx -fno-common -Wno-abi\" { target i?86-*-darwin* x86_64-*-darwin* } } */\n",
- "/* { dg-options \"%s-I%s -mno-base-addresses\" { target mmix-*-* } } */\n",
- "/* { dg-options \"%s-I%s -mlongcalls -mtext-section-literals\" { target xtensa*-*-* } } */\n"
---- a/gcc/testsuite/gcc.dg/cpp/Wvariadic-1.c
-+++ b/gcc/testsuite/gcc.dg/cpp/Wvariadic-1.c
-@@ -4,3 +4,4 @@
- #define f(x,...) /* { dg-error "variadic" } */
- #define g(x,y...) /* { dg-error "variadic" } */
- int not_empty;
-+/* { dg-message "warnings being treated as errors" "" { target *-*-* } 0 } */
---- a/gcc/testsuite/gcc.dg/cpp/Wvariadic-3.c
-+++ b/gcc/testsuite/gcc.dg/cpp/Wvariadic-3.c
-@@ -4,3 +4,4 @@
- #define f(x,...)
- #define g(x,y...) /* { dg-error "variadic" } */
- int not_empty;
-+/* { dg-message "warnings being treated as errors" "" { target *-*-* } 0 } */
---- a/gcc/testsuite/gcc.dg/cpp/include2.c
-+++ b/gcc/testsuite/gcc.dg/cpp/include2.c
-@@ -8,9 +8,8 @@
- /* Source: Neil Booth, 4 Nov 2000. */
-
- #include <silly\>> /* { dg-error "extra tokens" "" } */
--#include "silly\"" /* { dg-error "extra tokens" "" } */
-
- /* These error is No such file or directory, just once. However, this
- message is locale-dependent, so don't test for it. */
- /* { dg-error "silly" "" { target *-*-* } 10 } */
--/* { dg-error "missing" "" { target *-*-* } 11 } */
-+/* { dg-message "terminated" "" { target *-*-* } 0 } */
---- /dev/null
-+++ b/gcc/testsuite/gcc.dg/cpp/include2a.c
-@@ -0,0 +1,16 @@
-+/* Copyright (C) 2000 Free Software Foundation, Inc. */
-+
-+/* { dg-do preprocess } */
-+
-+/* Tests that #include does not allow the terminating '>' or '"' to be
-+ escaped, as per the standard. */
-+
-+/* Source: Neil Booth, 4 Nov 2000. */
-+
-+#include "silly\"" /* { dg-error "extra tokens" "" } */
-+
-+/* These error is No such file or directory, just once. However, this
-+ message is locale-dependent, so don't test for it. */
-+/* { dg-error "silly" "" { target *-*-* } 10 } */
-+/* { dg-error "missing" "" { target *-*-* } 10 } */
-+/* { dg-message "terminated" "" { target *-*-* } 0 } */
---- /dev/null
-+++ b/gcc/testsuite/gcc.dg/cpp/missing-header-1.c
-@@ -0,0 +1,9 @@
-+/* Test that missing headers are fatal errors. PR 15638. */
-+/* { dg-do compile } */
-+/* { dg-options "" } */
-+
-+#include "nonexistent.h" /* { dg-error "nonexistent.h" } */
-+/* { dg-message "terminated" "" { target *-*-* } 0 } */
-+
-+/* This declaration should not receive any diagnostic. */
-+foo bar;
---- /dev/null
-+++ b/gcc/testsuite/gcc.dg/cpp/missing-header-MD.c
-@@ -0,0 +1,6 @@
-+/* Test that missing user headers are fatal errors with -MD. */
-+/* { dg-do compile } */
-+/* { dg-options "-MD" } */
-+
-+#include "nonexistent.h" /* { dg-error "nonexistent.h" } */
-+/* { dg-message "terminated" "" { target *-*-* } 0 } */
---- /dev/null
-+++ b/gcc/testsuite/gcc.dg/cpp/missing-header-MMD.c
-@@ -0,0 +1,6 @@
-+/* Test that missing user headers are fatal errors with -MMD. */
-+/* { dg-do compile } */
-+/* { dg-options "-MMD" } */
-+
-+#include "nonexistent.h" /* { dg-error "nonexistent.h" } */
-+/* { dg-message "terminated" "" { target *-*-* } 0 } */
---- /dev/null
-+++ b/gcc/testsuite/gcc.dg/cpp/missing-sysheader-MD.c
-@@ -0,0 +1,6 @@
-+/* Test that missing system headers are fatal errors with -MD. */
-+/* { dg-do compile } */
-+/* { dg-options "-MD" } */
-+
-+#include <nonexistent.h> /* { dg-error "nonexistent.h" } */
-+/* { dg-message "terminated" "" { target *-*-* } 0 } */
---- /dev/null
-+++ b/gcc/testsuite/gcc.dg/cpp/missing-sysheader-MMD.c
-@@ -0,0 +1,6 @@
-+/* Test that missing system headers are fatal errors with -MMD. */
-+/* { dg-do compile } */
-+/* { dg-options "-MMD" } */
-+
-+#include <nonexistent.h> /* { dg-error "nonexistent.h" } */
-+/* { dg-message "terminated" "" { target *-*-* } 0 } */
---- a/gcc/testsuite/gcc.dg/cpp/redef2.c
-+++ b/gcc/testsuite/gcc.dg/cpp/redef2.c
-@@ -23,9 +23,9 @@
- { dg-warning "redefined" "redef ro" { target *-*-* } 12 }
- { dg-warning "redefined" "redef va" { target *-*-* } 15 }
-
-- { dg-warning "previous" "prev def mac" { target *-*-* } 6 }
-- { dg-warning "previous" "prev def mac" { target *-*-* } 7 }
-- { dg-warning "previous" "prev def mac" { target *-*-* } 8 }
-- { dg-warning "previous" "prev def ro" { target *-*-* } 11 }
-- { dg-warning "previous" "prev def va" { target *-*-* } 14 }
-+ { dg-message "previous" "prev def mac" { target *-*-* } 6 }
-+ { dg-message "previous" "prev def mac" { target *-*-* } 7 }
-+ { dg-message "previous" "prev def mac" { target *-*-* } 8 }
-+ { dg-message "previous" "prev def ro" { target *-*-* } 11 }
-+ { dg-message "previous" "prev def va" { target *-*-* } 14 }
- */
---- a/gcc/testsuite/gcc.dg/cpp/redef3.c
-+++ b/gcc/testsuite/gcc.dg/cpp/redef3.c
-@@ -15,7 +15,7 @@
- { dg-warning "redefined" "redef B" { target *-*-* } 9 }
- { dg-warning "redefined" "redef D" { target *-*-* } 11 }
- { dg-warning "redefined" "redef E" { target *-*-* } 12 }
-- { dg-warning "previous" "prev def A" { target *-*-* } 6 }
-- { dg-warning "previous" "prev def B" { target *-*-* } 8 }
-- { dg-warning "previous" "prev def D/E" { target *-*-* } 0 }
-+ { dg-message "previous" "prev def A" { target *-*-* } 6 }
-+ { dg-message "previous" "prev def B" { target *-*-* } 8 }
-+ { dg-message "previous" "prev def D/E" { target *-*-* } 0 }
- */
---- a/gcc/testsuite/gcc.dg/cpp/trad/redef2.c
-+++ b/gcc/testsuite/gcc.dg/cpp/trad/redef2.c
-@@ -2,31 +2,31 @@
-
- /* { dg-do preprocess } */
-
--#define foo bar /* { dg-warning "previous def" "foo prev def" } */
-+#define foo bar /* { dg-message "previous def" "foo prev def" } */
- #define foo barr /* { dg-warning "redefined" "foo redefined" } */
-
- #undef foo
--#define foo bar /* { dg-warning "previous def" "foo prev def 2" } */
-+#define foo bar /* { dg-message "previous def" "foo prev def 2" } */
- #define foo() bar /* { dg-warning "redefined" "foo redefined 2" } */
-
- #undef foo
--#define foo() bar /* { dg-warning "previous def" "foo prev def" } */
-+#define foo() bar /* { dg-message "previous def" "foo prev def" } */
- #define foo() barr /* { dg-warning "redefined" "foo redefined" } */
-
--#define quux(thud) a thud b /* { dg-warning "previous def" "quux prev def" } */
-+#define quux(thud) a thud b /* { dg-message "previous def" "quux prev def" } */
- #define quux(thu) a thud b /* { dg-warning "redefined" "quux redefined" } */
-
--#define bar(x, y) x+y /* { dg-warning "previous def" "bar prev def" } */
-+#define bar(x, y) x+y /* { dg-message "previous def" "bar prev def" } */
- #define bar(x, y) x+x /* { dg-warning "redefined" "bar redefined" } */
-
--#define bat(x, y) x+y /* { dg-warning "previous def" "bat prev def" } */
-+#define bat(x, y) x+y /* { dg-message "previous def" "bat prev def" } */
- #define bat(x, y) x+ y /* { dg-warning "redefined" "bat redefined" } */
-
--#define baz(x, y) x+y /* { dg-warning "previous def" "baz prev def" } */
-+#define baz(x, y) x+y /* { dg-message "previous def" "baz prev def" } */
- #define baz(x, y) x +y /* { dg-warning "redefined" "baz redefined" } */
-
--#define f(x, y) "x y" /* { dg-warning "previous def" "f prev def" } */
-+#define f(x, y) "x y" /* { dg-message "previous def" "f prev def" } */
- #define f(x, y) "x y" /* { dg-warning "redefined" "f redefined" } */
-
--#define g(x, y) 'x' /* { dg-warning "previous def" "g prev def" } */
-+#define g(x, y) 'x' /* { dg-message "previous def" "g prev def" } */
- #define g(x, y) ' x' /* { dg-warning "redefined" "g redefined" } */
---- a/gcc/testsuite/gcc.dg/dll-4.c
-+++ b/gcc/testsuite/gcc.dg/dll-4.c
-@@ -11,5 +11,6 @@ int foo2 = 5; /* { dg-warning "redeclare
- int f () { return foo1 + foo2; }
-
- /* FIXME: We should scan the output of nm for this case. */
--/* { dg-final { scan-assembler "(foo2:.*\.comm\[ \t_\]*foo1)" } } */
-+/* { dg-final { scan-assembler "(foo2:)" } } */
-+/* { dg-final { scan-assembler "(\.comm\[ \t_\]*foo1)" } } */
- /* { dg-final { scan-assembler-not "(__imp_|_imp__)" } } */
---- /dev/null
-+++ b/gcc/testsuite/gcc.dg/dll-6.c
-@@ -0,0 +1,52 @@
-+/* { dg-do link } */
-+/* { dg-require-dll "" } */
-+/* { dg-additional-sources "dll-6a.c" } */
-+/* { dg-options "-w -O2 -std=gnu89" } */
-+
-+/* Test that inline functions declared "dllexport" appear in object
-+ files, even if they are not called.
-+
-+ This behavior is required by the ARM C++ ABI:
-+
-+ Exporting a function that can be inlined should force the
-+ creation and export of an out-of-line copy of it.
-+
-+ and should presumably also apply.
-+
-+ Visual Studio 2005 also honors that rule. */
-+
-+__declspec(dllexport) inline void i1() {}
-+
-+__declspec(dllexport) extern inline void e1() {}
-+
-+/* It is invalid to declare the function inline after its definition. */
-+#if 0
-+__declspec(dllexport) void i2() {}
-+inline void i2();
-+
-+__declspec(dllexport) extern void e2() {}
-+inline void e2();
-+#endif
-+
-+__declspec(dllexport) inline void i3() {}
-+void i3();
-+
-+__declspec(dllexport) inline void e3() {}
-+extern void e3();
-+
-+__declspec(dllexport) void i4();
-+inline void i4() {};
-+
-+__declspec(dllexport) extern void e4();
-+inline void e4() {};
-+
-+__declspec(dllexport) inline void i5();
-+void i5() {};
-+
-+__declspec(dllexport) inline void e5();
-+extern void e5() {};
-+
-+/* Make sure that just declaring the function -- without defining it
-+ -- does not cause errors. */
-+__declspec(dllexport) inline void i6();
-+__declspec(dllexport) extern inline void e6();
---- /dev/null
-+++ b/gcc/testsuite/gcc.dg/dll-6a.c
-@@ -0,0 +1,21 @@
-+extern void i1();
-+extern void i3();
-+extern void i4();
-+extern void i5();
-+
-+extern void e1();
-+extern void e3();
-+extern void e4();
-+extern void e5();
-+
-+int main () {
-+ i1();
-+ i3();
-+ i4();
-+ i5();
-+
-+ e1();
-+ e3();
-+ e4();
-+ e5();
-+}
---- /dev/null
-+++ b/gcc/testsuite/gcc.dg/dll-7.c
-@@ -0,0 +1,52 @@
-+/* { dg-do link } */
-+/* { dg-require-dll "" } */
-+/* { dg-additional-sources "dll-7a.c" } */
-+/* { dg-options "-w -O2 -std=gnu99" } */
-+
-+/* Test that inline functions declared "dllexport" appear in object
-+ files, even if they are not called.
-+
-+ This behavior is required by the ARM C++ ABI:
-+
-+ Exporting a function that can be inlined should force the
-+ creation and export of an out-of-line copy of it.
-+
-+ and should presumably also apply.
-+
-+ Visual Studio 2005 also honors that rule. */
-+
-+__declspec(dllexport) inline void i1() {}
-+
-+__declspec(dllexport) extern inline void e1() {}
-+
-+/* It is invalid to declare the function inline after its definition. */
-+#if 0
-+__declspec(dllexport) void i2() {}
-+inline void i2();
-+
-+__declspec(dllexport) extern void e2() {}
-+inline void e2();
-+#endif
-+
-+__declspec(dllexport) inline void i3() {}
-+void i3();
-+
-+__declspec(dllexport) inline void e3() {}
-+extern void e3();
-+
-+__declspec(dllexport) void i4();
-+inline void i4() {};
-+
-+__declspec(dllexport) extern void e4();
-+inline void e4() {};
-+
-+__declspec(dllexport) inline void i5();
-+void i5() {};
-+
-+__declspec(dllexport) inline void e5();
-+extern void e5() {};
-+
-+/* Make sure that just declaring the function -- without defining it
-+ -- does not cause errors. */
-+__declspec(dllexport) inline void i6();
-+__declspec(dllexport) extern inline void e6();
---- /dev/null
-+++ b/gcc/testsuite/gcc.dg/dll-7a.c
-@@ -0,0 +1,21 @@
-+extern void i1();
-+extern void i3();
-+extern void i4();
-+extern void i5();
-+
-+extern void e1();
-+extern void e3();
-+extern void e4();
-+extern void e5();
-+
-+int main () {
-+ i1();
-+ i3();
-+ i4();
-+ i5();
-+
-+ e1();
-+ e3();
-+ e4();
-+ e5();
-+}
---- /dev/null
-+++ b/gcc/testsuite/gcc.dg/falign-labels-1.c
-@@ -0,0 +1,39 @@
-+/* { dg-do run } */
-+/* { dg-options "-falign-labels=8" { target { ! { m68k*-*-* || fido*-*-* } } } } */
-+
-+/* On ARMv7-A CPUs, this test resulted in incorrect code generation.
-+ The code generated for the switch statement expected the jump table
-+ to immediately follow the jump instruction, but -falign-labels
-+ caused the label preceding the table to be aligned. */
-+/* M68K and fido only support -falign-labels argument <= 2. */
-+
-+volatile int x;
-+
-+int main(void)
-+{
-+ int y;
-+
-+ x = 0;
-+
-+ switch(x)
-+ {
-+ case 0:
-+ y = 2 * x;
-+ break;
-+ case 1:
-+ y = -3 * x;
-+ break;
-+ case 2:
-+ y = x + 5;
-+ break;
-+ case 3:
-+ y = x - 7;
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ x = y;
-+
-+ return 0;
-+}
---- a/gcc/testsuite/gcc.dg/fltconst-1.c
-+++ b/gcc/testsuite/gcc.dg/fltconst-1.c
-@@ -1,5 +1,5 @@
- /* { dg-do compile } */
--/* { dg-options "-std=gnu99" } */
-+/* { dg-options "-std=gnu99 -fshow-column" } */
-
- double a = 1.ld; /* { dg-error "12:invalid suffix" } */
- double b = 1.fd; /* { dg-error "12:invalid suffix" } */
---- /dev/null
-+++ b/gcc/testsuite/gcc.dg/m68k-fp-1.c
-@@ -0,0 +1,13 @@
-+/* ColdFire has restricted addressing modes for float operands. */
-+/* { dg-do compile { target m68k-*-* } } */
-+/* { dg-options "-O0 -mcpu=547x -mhard-float" } */
-+
-+double Foo (unsigned a)
-+{
-+ unsigned local_data[16384] __attribute__((unused));
-+ double d;
-+
-+ d = a;
-+
-+ return d;
-+}
---- a/gcc/testsuite/gcc.dg/pch/counter-2.c
-+++ b/gcc/testsuite/gcc.dg/pch/counter-2.c
-@@ -10,6 +10,7 @@
- #include "counter-2.h" /* { dg-warning "not used because `__COUNTER__' is invalid" } */
- /* { dg-error "counter-2.h: No such file or directory" "no such file" { target *-*-* } 10 } */
- /* { dg-error "one or more PCH files were found, but they were invalid" "invalid files" { target *-*-* } 10 } */
-+/* { dg-message "terminated" "" { target *-*-* } 0 } */
-
- int main(void)
- {
---- a/gcc/testsuite/gcc.dg/pch/valid-1.c
-+++ b/gcc/testsuite/gcc.dg/pch/valid-1.c
-@@ -3,5 +3,6 @@
- #include "valid-1.h"/* { dg-warning "created with -gnone, but used with -g" } */
- /* { dg-error "No such file" "no such file" { target *-*-* } 3 } */
- /* { dg-error "they were invalid" "invalid files" { target *-*-* } 3 } */
-+/* { dg-message "terminated" "" { target *-*-* } 0 } */
-
- int x;
---- a/gcc/testsuite/gcc.dg/pch/valid-2.c
-+++ b/gcc/testsuite/gcc.dg/pch/valid-2.c
-@@ -3,4 +3,5 @@
- #include "valid-2.h" /* { dg-warning "settings for -fexceptions do not match" } */
- /* { dg-error "No such file" "no such file" { target *-*-* } 3 } */
- /* { dg-error "they were invalid" "invalid files" { target *-*-* } 3 } */
-+/* { dg-message "terminated" "" { target *-*-* } 0 } */
- int x;
---- a/gcc/testsuite/gcc.dg/pch/warn-1.c
-+++ b/gcc/testsuite/gcc.dg/pch/warn-1.c
-@@ -5,6 +5,7 @@
- #include "warn-1.h"/* { dg-warning "not used because .DEFINED_VALUE. is defined" } */
- /* { dg-error "No such file" "no such file" { target *-*-* } 5 } */
- /* { dg-error "they were invalid" "invalid files" { target *-*-* } 5 } */
-+/* { dg-message "terminated" "" { target *-*-* } 0 } */
-
-
- int main(void)
---- a/gcc/testsuite/gcc.dg/pr34263.c
-+++ b/gcc/testsuite/gcc.dg/pr34263.c
-@@ -1,5 +1,5 @@
- /* { dg-do run } */
--/* { dg-options "-O2 -fdump-tree-optimized" } */
-+/* { dg-options "-O2 -fdump-tree-optimized -fno-unroll-loops" } */
- /* Same test as 990128-1.c. */
-
- extern int printf (const char *,...);
---- a/gcc/testsuite/gcc.dg/pragma-isr-trapa2.c
-+++ b/gcc/testsuite/gcc.dg/pragma-isr-trapa2.c
-@@ -1,4 +1,6 @@
- /* { dg-do compile { target { { sh-*-* sh4*-*-* } && nonpic } } } */
-+/* { dg-skip-if "FPU Required" { "sh*-*-*" } { "-m*nofpu*" } { "" } } */
-+/* { dg-skip-if "FPU Required" { "sh*-*-*" } { "-m4al*" } { "" } } */
- /* { dg-options "-O -m4" } */
-
- extern void foo ();
---- a/gcc/testsuite/gcc.dg/profile-dir-1.c
-+++ b/gcc/testsuite/gcc.dg/profile-dir-1.c
-@@ -1,5 +1,6 @@
- /* { dg-do compile } */
- /* { dg-options "-O -fprofile-generate=. -fdump-tree-tree_profile" } */
-+/* { dg-require-host-local "" } */
- /* { dg-final { scan-tree-dump " ./profile-dir-1.gcda" "tree_profile" } } */
-
- int
---- a/gcc/testsuite/gcc.dg/profile-dir-2.c
-+++ b/gcc/testsuite/gcc.dg/profile-dir-2.c
-@@ -1,5 +1,6 @@
- /* { dg-do compile } */
- /* { dg-options "-O -fprofile-generate -fdump-tree-tree_profile" } */
-+/* { dg-require-host-local "" } */
- /* { dg-final { scan-tree-dump "/profile-dir-2.gcda" "tree_profile" } } */
-
- int
---- a/gcc/testsuite/gcc.dg/profile-dir-3.c
-+++ b/gcc/testsuite/gcc.dg/profile-dir-3.c
-@@ -1,5 +1,6 @@
- /* { dg-do compile } */
- /* { dg-options "-O -fprofile-generate -fprofile-dir=. -fdump-tree-tree_profile" } */
-+/* { dg-require-host-local "" } */
- /* { dg-final { scan-tree-dump " ./profile-dir-3.gcda" "tree_profile" } } */
-
- int
---- /dev/null
-+++ b/gcc/testsuite/gcc.dg/promote-short-1.c
-@@ -0,0 +1,15 @@
-+/* Verify that we promote a short loop index variable. */
-+
-+/* { dg-do compile } */
-+/* { dg-options "-O2 -fpromote-loop-indices -fdump-tree-promoteshort" } */
-+/* { dg-final { scan-tree-dump-times "Promoting 1 variables" 1 "promoteshort" } } */
-+/* { dg-final { cleanup-tree-dump "promoteshort" } } */
-+
-+void
-+test1 (short n, int *x)
-+{
-+ short i;
-+
-+ for (i = 0; i < n; i++)
-+ x[i] = 0;
-+}
---- /dev/null
-+++ b/gcc/testsuite/gcc.dg/promote-short-10.c
-@@ -0,0 +1,20 @@
-+/* Verify that we do not promote a short loop index variable when its
-+ address is taken. */
-+
-+/* { dg-do compile } */
-+/* { dg-options "-O2 -fpromote-loop-indices -fdump-tree-promoteshort" } */
-+/* { dg-final { scan-tree-dump-times "Found 0 candidates" 1 "promoteshort" } } */
-+/* { dg-final { cleanup-tree-dump "promoteshort" } } */
-+
-+extern void outside (short *);
-+
-+void
-+test1 (int n, int *x)
-+{
-+ short i;
-+
-+ for (i = 0; i < n; i++)
-+ {
-+ outside (&i);
-+ }
-+}
---- /dev/null
-+++ b/gcc/testsuite/gcc.dg/promote-short-2.c
-@@ -0,0 +1,16 @@
-+/* Verify that we do not promote a short loop index variable when it is
-+ being stored to memory. */
-+
-+/* { dg-do compile } */
-+/* { dg-options "-O2 -fpromote-loop-indices -fdump-tree-promoteshort" } */
-+/* { dg-final { scan-tree-dump-times "Promoting 0 variables" 1 "promoteshort" } } */
-+/* { dg-final { cleanup-tree-dump "promoteshort" } } */
-+
-+void
-+test1 (short n, short *x)
-+{
-+ short i;
-+
-+ for (i = 0; i < n; i++)
-+ x[i] = i;
-+}
---- /dev/null
-+++ b/gcc/testsuite/gcc.dg/promote-short-3.c
-@@ -0,0 +1,18 @@
-+/* Verify that we do not promote a short loop index variable when it is
-+ being passed as a function parameter. */
-+
-+/* { dg-do compile } */
-+/* { dg-options "-O2 -fpromote-loop-indices -fdump-tree-promoteshort" } */
-+/* { dg-final { scan-tree-dump-times "Promoting 0 variables" 1 "promoteshort" { xfail m68k*-*-* fido*-*-* i?86-*-* x86_64-*-* mips*-*-* sh*-*-* } } } */
-+/* { dg-final { cleanup-tree-dump "promoteshort" } } */
-+
-+extern void outside (short);
-+
-+void
-+test1 (short n)
-+{
-+ short i;
-+
-+ for (i = 0; i < n; i++)
-+ outside (i);
-+}
---- /dev/null
-+++ b/gcc/testsuite/gcc.dg/promote-short-4.c
-@@ -0,0 +1,19 @@
-+/* Verify that we do not promote a short loop index variable when it is
-+ modified within the loop. */
-+
-+/* { dg-do compile } */
-+/* { dg-options "-O2 -fpromote-loop-indices -fdump-tree-promoteshort" } */
-+/* { dg-final { scan-tree-dump-times "Promoting 0 variables" 1 "promoteshort" } } */
-+/* { dg-final { cleanup-tree-dump "promoteshort" } } */
-+
-+void
-+test1 (short n, int *x)
-+{
-+ short i;
-+
-+ for (i = 0; i < n; i++)
-+ {
-+ i++;
-+ x[i] = 0;
-+ }
-+}
---- /dev/null
-+++ b/gcc/testsuite/gcc.dg/promote-short-5.c
-@@ -0,0 +1,18 @@
-+/* Verify that we do not promote a short loop index variable when it has
-+ a non-unit-increment. */
-+
-+/* { dg-do compile } */
-+/* { dg-options "-O2 -fpromote-loop-indices -fdump-tree-promoteshort" } */
-+/* { dg-final { scan-tree-dump-times "Promoting 0 variables" 1 "promoteshort" } } */
-+/* { dg-final { cleanup-tree-dump "promoteshort" } } */
-+
-+void
-+test1 (short n, int *x)
-+{
-+ short i;
-+
-+ for (i = 0; i < n; i+=2)
-+ {
-+ x[i] = 0;
-+ }
-+}
---- /dev/null
-+++ b/gcc/testsuite/gcc.dg/promote-short-6.c
-@@ -0,0 +1,18 @@
-+/* Verify that we do promote a short loop index variable when it has
-+ a non-unit-increment and -funsafe-loop-optimizations is in effect. */
-+
-+/* { dg-do compile } */
-+/* { dg-options "-O2 -fpromote-loop-indices -funsafe-loop-optimizations -fdump-tree-promoteshort" } */
-+/* { dg-final { scan-tree-dump-times "Promoting 1 variables" 1 "promoteshort" } } */
-+/* { dg-final { cleanup-tree-dump "promoteshort" } } */
-+
-+void
-+test1 (short n, int *x)
-+{
-+ short i;
-+
-+ for (i = 0; i < n; i+=2)
-+ {
-+ x[i] = 0;
-+ }
-+}
---- /dev/null
-+++ b/gcc/testsuite/gcc.dg/promote-short-7.c
-@@ -0,0 +1,18 @@
-+/* Verify that we do not promote a short loop index variable when the
-+ loop in which it is used has a bound of wider type. */
-+
-+/* { dg-do compile } */
-+/* { dg-options "-O2 -fpromote-loop-indices -fdump-tree-promoteshort" } */
-+/* { dg-final { scan-tree-dump-times "Promoting 0 variables" 1 "promoteshort" } } */
-+/* { dg-final { cleanup-tree-dump "promoteshort" } } */
-+
-+void
-+test1 (int n, int *x)
-+{
-+ short i;
-+
-+ for (i = 0; i < n; i++)
-+ {
-+ x[i] = 0;
-+ }
-+}
---- /dev/null
-+++ b/gcc/testsuite/gcc.dg/promote-short-8.c
-@@ -0,0 +1,19 @@
-+/* Verify that we do promote a short loop index variable when the loop
-+ in which it is used has a bound of wider type and
-+ -funsafe-loop-optimizations is in effect. */
-+
-+/* { dg-do compile } */
-+/* { dg-options "-O2 -fpromote-loop-indices -funsafe-loop-optimizations -fdump-tree-promoteshort" } */
-+/* { dg-final { scan-tree-dump-times "Promoting 1 variables" 1 "promoteshort" } } */
-+/* { dg-final { cleanup-tree-dump "promoteshort" } } */
-+
-+void
-+test1 (int n, int *x)
-+{
-+ short i;
-+
-+ for (i = 0; i < n; i++)
-+ {
-+ x[i] = 0;
-+ }
-+}
---- /dev/null
-+++ b/gcc/testsuite/gcc.dg/promote-short-9.c
-@@ -0,0 +1,15 @@
-+/* -fpromote-loop-indices used to ICE on this. */
-+
-+/* { dg-do compile } */
-+/* { dg-options "-O2 -fpromote-loop-indices" } */
-+
-+char
-+lookup (char *haystack, char *needle)
-+{
-+ char x;
-+
-+ for (x = haystack[-2]; x < *needle; x++)
-+ haystack[x] = needle[x];
-+
-+ return 1;
-+}
---- /dev/null
-+++ b/gcc/testsuite/gcc.dg/remove-local-statics-1.c
-@@ -0,0 +1,16 @@
-+/* Verify that we eliminate a static local variable where its uses
-+ are dominated by a def. */
-+
-+/* { dg-do compile } */
-+/* { dg-options "-O2 -fremove-local-statics" } */
-+/* { dg-final { scan-assembler-not "thestatic" } } */
-+
-+int
-+test1 (int x)
-+{
-+ static int thestatic;
-+
-+ thestatic = x;
-+
-+ return thestatic + x;
-+}
---- /dev/null
-+++ b/gcc/testsuite/gcc.dg/remove-local-statics-10.c
-@@ -0,0 +1,32 @@
-+/* Verify that we do not eliminate a static local variable when it is
-+ live on return from a function call that recursively calls the
-+ function in which the variable is defined. */
-+
-+/* { dg-do compile } */
-+/* { dg-options "-O2 -fremove-local-statics" } */
-+/* { dg-final { scan-assembler "thestatic" } } */
-+
-+int
-+test2 (int x)
-+{
-+ if (x < 0)
-+ return 0;
-+ else
-+ return test1 (x - 1);
-+}
-+
-+int
-+test1 (int x)
-+{
-+ static int thestatic;
-+ int y;
-+
-+ thestatic = x;
-+
-+ y = test2 (x - 1);
-+
-+ y += thestatic;
-+
-+ return y + x;
-+}
-+
---- /dev/null
-+++ b/gcc/testsuite/gcc.dg/remove-local-statics-11.c
-@@ -0,0 +1,16 @@
-+/* Verify that we do not eliminate a static local variable when its
-+ address is taken. */
-+
-+/* { dg-do compile } */
-+/* { dg-options "-O2 -fremove-local-statics" } */
-+/* { dg-final { scan-assembler "thestatic" } } */
-+
-+int *
-+test1 (int x)
-+{
-+ static int thestatic;
-+
-+ thestatic = x;
-+
-+ return &thestatic + x;
-+}
---- /dev/null
-+++ b/gcc/testsuite/gcc.dg/remove-local-statics-12.c
-@@ -0,0 +1,20 @@
-+/* Verify that we do not eliminate a static variable when it is declared
-+ in a function that has nested functions. */
-+
-+/* { dg-do compile } */
-+/* { dg-options "-O2 -fremove-local-statics" } */
-+/* { dg-final { scan-assembler "thestatic" } } */
-+
-+int test1 (int x)
-+{
-+ static int thestatic;
-+
-+ int nested_test1 (int x)
-+ {
-+ return x + thestatic;
-+ }
-+
-+ thestatic = x;
-+
-+ return thestatic + x + nested_test1 (x);
-+}
---- /dev/null
-+++ b/gcc/testsuite/gcc.dg/remove-local-statics-13.c
-@@ -0,0 +1,24 @@
-+/* We used to ICE on this test, because the call to BAR appeared to
-+ define both static variables in FOO. Verify that we no longer do
-+ this. */
-+
-+/* { dg-do compile } */
-+/* { dg-options "-O2 -fremove-local-statics" } */
-+/* { dg-final { scan-assembler "static1" } } */
-+/* { dg-final { scan-assembler-not "static2" } } */
-+
-+int foo(int i) {
-+ static int static1 = 0;
-+ static int static2;
-+
-+ if (static2 = bar(i))
-+ static1 = 1;
-+ static2 = static1 + 30;
-+
-+ return static1 + static2;
-+}
-+
-+int bar(int i) {
-+ if (i) { foo(i-1); return 0; }
-+ return 1;
-+}
---- /dev/null
-+++ b/gcc/testsuite/gcc.dg/remove-local-statics-14.c
-@@ -0,0 +1,29 @@
-+/* Verify that we do eliminate a static local variable whose last use is
-+ in a statement containing a call expression. */
-+
-+/* { dg-do compile } */
-+/* { dg-options "-O2 -fremove-local-statics" } */
-+/* { dg-final { scan-assembler-not "thestatic" } } */
-+
-+int
-+test2 (int x)
-+{
-+ if (x < 0)
-+ return 0;
-+ else
-+ return test1 (x - 1);
-+}
-+
-+int
-+test1 (int x)
-+{
-+ static int thestatic;
-+ int y;
-+
-+ thestatic = x;
-+
-+ y = test2 (thestatic - 1);
-+
-+ return y + x;
-+}
-+
---- /dev/null
-+++ b/gcc/testsuite/gcc.dg/remove-local-statics-15.c
-@@ -0,0 +1,17 @@
-+/* Verify that we do not consider an array variable for local static
-+ elimination. */
-+
-+/* { dg-do compile } */
-+/* { dg-options "-O2 -fremove-local-statics -fdump-tree-remlocstatic-details" } */
-+
-+int foo (void)
-+{
-+ static int a[1];
-+
-+ a[0] = 0;
-+
-+ return a[0];
-+}
-+
-+/* { dg-final { scan-tree-dump-times "static variables to consider" 0 "remlocstatic" } } */
-+/* { dg-final { cleanup-tree-dump "remlocstatic" } } */
---- /dev/null
-+++ b/gcc/testsuite/gcc.dg/remove-local-statics-16.c
-@@ -0,0 +1,20 @@
-+/* Verify that we do not consider an structure variable for local static
-+ elimination. */
-+
-+/* { dg-do compile } */
-+/* { dg-options "-O2 -fremove-local-statics -fdump-tree-remlocstatic-details" } */
-+
-+int foo (void)
-+{
-+ static struct {
-+ int x;
-+ int y;
-+ } a;
-+
-+ a.x = 0;
-+
-+ return a.y;
-+}
-+
-+/* { dg-final { scan-tree-dump-times "static variables to consider" 0 "remlocstatic" } } */
-+/* { dg-final { cleanup-tree-dump "remlocstatic" } } */
---- /dev/null
-+++ b/gcc/testsuite/gcc.dg/remove-local-statics-17.c
-@@ -0,0 +1,19 @@
-+/* Verify that we do not eliminate a static variable that is "defined"
-+ by an asm that clobbers memory. */
-+
-+/* { dg-do compile } */
-+/* { dg-options "-O2 -fremove-local-statics -fdump-tree-remlocstatic-details" } */
-+
-+int foo (void)
-+{
-+ static int foo = 0;
-+
-+ __asm__ __volatile__ ("bogus" : : : "memory");
-+
-+ foo++;
-+
-+ return foo;
-+}
-+
-+/* { dg-final { scan-tree-dump-times "static variables to consider" 0 "remlocstatic" } } */
-+/* { dg-final { cleanup-tree-dump "remlocstatic" } } */
---- /dev/null
-+++ b/gcc/testsuite/gcc.dg/remove-local-statics-2.c
-@@ -0,0 +1,19 @@
-+/* Verify that we do not eliminate a static local variable when its uses
-+ are not dominated by a def. */
-+
-+/* { dg-do compile } */
-+/* { dg-options "-O2 -fremove-local-statics" } */
-+/* { dg-final { scan-assembler "first_time" } } */
-+
-+int
-+test1 (int x)
-+{
-+ static int first_time;
-+
-+ if (x == 1)
-+ first_time = 1;
-+ else if (x > 0)
-+ first_time = 2;
-+
-+ return first_time + x;
-+}
---- /dev/null
-+++ b/gcc/testsuite/gcc.dg/remove-local-statics-3.c
-@@ -0,0 +1,16 @@
-+/* Verify that we do not eliminate a static local variable whose uses
-+ are dominated by a def when the variable is volatile. */
-+
-+/* { dg-do compile } */
-+/* { dg-options "-O2 -fremove-local-statics" } */
-+/* { dg-final { scan-assembler "thestatic" } } */
-+
-+int
-+test1 (int x)
-+{
-+ static volatile int thestatic;
-+
-+ thestatic = x;
-+
-+ return thestatic + x;
-+}
---- /dev/null
-+++ b/gcc/testsuite/gcc.dg/remove-local-statics-4.c
-@@ -0,0 +1,15 @@
-+/* Verify that we don't eliminate a global static variable. */
-+
-+/* { dg-do compile } */
-+/* { dg-options "-O2 -fremove-local-statics" } */
-+/* { dg-final { scan-assembler "global_static" } } */
-+
-+static int global_static;
-+
-+int
-+test1 (int x)
-+{
-+ global_static = x;
-+
-+ return global_static + x;
-+}
---- /dev/null
-+++ b/gcc/testsuite/gcc.dg/remove-local-statics-5.c
-@@ -0,0 +1,24 @@
-+/* Verify that we do not eliminate a static local variable whose uses
-+ are dominated by a def when the function calls setjmp. */
-+
-+/* { dg-do compile } */
-+/* { dg-options "-O2 -fremove-local-statics" } */
-+/* { dg-final { scan-assembler "thestatic" } } */
-+
-+#include <setjmp.h>
-+
-+int
-+foo (int x)
-+{
-+ static int thestatic;
-+ int retval;
-+ jmp_buf env;
-+
-+ thestatic = x;
-+
-+ retval = thestatic + x;
-+
-+ setjmp (env);
-+
-+ return retval;
-+}
---- /dev/null
-+++ b/gcc/testsuite/gcc.dg/remove-local-statics-6.c
-@@ -0,0 +1,16 @@
-+/* Verify that we do not eliminate a static local variable whose uses
-+ are dominated by a def when the variable is addressed. */
-+
-+/* { dg-do compile } */
-+/* { dg-options "-O2 -fremove-local-statics" } */
-+/* { dg-final { scan-assembler "thestatic" } } */
-+
-+int *
-+test1 (int x)
-+{
-+ static int thestatic;
-+
-+ thestatic = x;
-+
-+ return &thestatic + x;
-+}
---- /dev/null
-+++ b/gcc/testsuite/gcc.dg/remove-local-statics-7.c
-@@ -0,0 +1,21 @@
-+/* Verify that we eliminate a static local variable where it is defined
-+ along all paths leading to a use.
-+
-+ XFAIL'd because our analysis is currently too weak. */
-+
-+/* { dg-do compile } */
-+/* { dg-options "-O2 -fremove-local-statics" } */
-+/* { dg-final { scan-assembler-not "thestatic" } } */
-+
-+int
-+test1 (int x)
-+{
-+ static int thestatic;
-+
-+ if (x < 0)
-+ thestatic = x;
-+ else
-+ thestatic = -x;
-+
-+ return thestatic + x;
-+}
---- /dev/null
-+++ b/gcc/testsuite/gcc.dg/remove-local-statics-8.c
-@@ -0,0 +1,33 @@
-+/* Verify that we eliminate a static local variable when it is dead on
-+ return from a function call that recursively calls the function in
-+ which the variable is defined. */
-+
-+/* { dg-do compile } */
-+/* { dg-options "-O2 -fremove-local-statics" } */
-+/* { dg-final { scan-assembler-not "thestatic" } } */
-+
-+int test1 (int);
-+int test2 (int);
-+
-+int
-+test2 (int x)
-+{
-+ if (x < 0)
-+ return 0;
-+ else
-+ return test1 (x - 1);
-+}
-+
-+int
-+test1 (int x)
-+{
-+ static int thestatic;
-+ int y;
-+
-+ thestatic = x;
-+
-+ y = thestatic;
-+
-+ return y + x + test1 (x - 1) + test2 (x - 1);
-+}
-+
---- /dev/null
-+++ b/gcc/testsuite/gcc.dg/remove-local-statics-9.c
-@@ -0,0 +1,34 @@
-+/* Verify that we eliminate a static local variable when it is live
-+ on return from a function call that does not recursively call the
-+ function in which the variable is defined. */
-+
-+/* XFAIL'd because we don't utilize the callgraph properly. */
-+
-+/* { dg-do compile } */
-+/* { dg-options "-O2 -fremove-local-statics" } */
-+/* { dg-final { scan-assembler-not "thestatic" { xfail *-*-* } } } */
-+
-+static int
-+test2 (int x)
-+{
-+ if (x < 0)
-+ return 0;
-+ else
-+ return x + test2 (x - 1);
-+}
-+
-+int
-+test1 (int x)
-+{
-+ static int thestatic;
-+ int y;
-+
-+ thestatic = x;
-+
-+ y = test2 (x - 1);
-+
-+ y += thestatic;
-+
-+ return y + x;
-+}
-+
---- /dev/null
-+++ b/gcc/testsuite/gcc.dg/torture/arm-fp16-compile-assign.c
-@@ -0,0 +1,29 @@
-+/* { dg-do compile { target arm*-*-* } } */
-+/* { dg-options "-mfp16-format=ieee" } */
-+
-+/* Test basic assignments and conversions for __fp16. */
-+
-+__fp16 h0 = -1.0;
-+__fp16 h1 = 0.0;
-+__fp16 h2 = 1234.0;
-+__fp16 h3 = 42.0;
-+float f1 = 2.0;
-+float f2 = -999.9;
-+
-+void f (__fp16 *p)
-+{
-+ __fp16 t;
-+
-+ h0 = 1.0;
-+ h1 = h2;
-+ h2 = f1;
-+ f2 = h2;
-+
-+ t = *p;
-+ *p = h3;
-+ h3 = t;
-+}
-+
-+/* Make sure we are not falling through to undefined libcalls. */
-+/* { dg-final { scan-assembler-not "__truncsfhf" } } */
-+/* { dg-final { scan-assembler-not "__extendhfsf" } } */
---- /dev/null
-+++ b/gcc/testsuite/gcc.dg/torture/arm-fp16-compile-convert.c
-@@ -0,0 +1,41 @@
-+/* { dg-do compile { target arm*-*-* } } */
-+/* { dg-options "-mfp16-format=ieee" } */
-+
-+/* Test basic assignments and conversions for __fp16. */
-+
-+__fp16 h1 = 0.0;
-+__fp16 h2 = 1234.0;
-+char c1 = 1;
-+char c2 = 2;
-+short s1 = 10;
-+short s2 = 20;
-+int i1 = -100;
-+int i2 = -200;
-+long long l1 = 1000.0;
-+long long l2 = 2000.0;
-+double d1 = -10000.0;
-+double d2 = -20000.0;
-+
-+void f (void)
-+{
-+ c1 = h1;
-+ h2 = c2;
-+
-+ h1 = s1;
-+ s2 = h2;
-+
-+ i1 = h1;
-+ h2 = i2;
-+
-+ h1 = l1;
-+ l2 = h2;
-+
-+ d1 = h1;
-+ h2 = d2;
-+}
-+
-+/* Make sure we are not falling through to undefined libcalls. */
-+/* { dg-final { scan-assembler-not "__float.ihf" } } */
-+/* { dg-final { scan-assembler-not "__fixhf.i" } } */
-+/* { dg-final { scan-assembler-not "__trunc.fhf" } } */
-+/* { dg-final { scan-assembler-not "__extendhf.f" } } */
---- /dev/null
-+++ b/gcc/testsuite/gcc.dg/torture/arm-fp16-int-convert-alt.c
-@@ -0,0 +1,17 @@
-+/* Test floating-point conversions. Standard types and __fp16. */
-+/* { dg-do run { target arm*-*-* } } */
-+/* { dg-options "-mfp16-format=alternative" } */
-+
-+#include "fp-int-convert.h"
-+#define FP16_MANT_DIG 11
-+
-+int
-+main (void)
-+{
-+ TEST_I_F(signed char, unsigned char, float, FP16_MANT_DIG);
-+ TEST_I_F(signed short, unsigned short, float, FP16_MANT_DIG);
-+ TEST_I_F(signed int, unsigned int, float, FP16_MANT_DIG);
-+ TEST_I_F(signed long, unsigned long, float, FP16_MANT_DIG);
-+ TEST_I_F(signed long long, unsigned long long, float, FP16_MANT_DIG);
-+ exit (0);
-+}
---- /dev/null
-+++ b/gcc/testsuite/gcc.dg/torture/arm-fp16-int-convert-ieee.c
-@@ -0,0 +1,17 @@
-+/* Test floating-point conversions. Standard types and __fp16. */
-+/* { dg-do run { target arm*-*-* } } */
-+/* { dg-options "-mfp16-format=ieee" } */
-+
-+#include "fp-int-convert.h"
-+#define FP16_MANT_DIG 11
-+
-+int
-+main (void)
-+{
-+ TEST_I_F(signed char, unsigned char, float, FP16_MANT_DIG);
-+ TEST_I_F(signed short, unsigned short, float, FP16_MANT_DIG);
-+ TEST_I_F(signed int, unsigned int, float, FP16_MANT_DIG);
-+ TEST_I_F(signed long, unsigned long, float, FP16_MANT_DIG);
-+ TEST_I_F(signed long long, unsigned long long, float, FP16_MANT_DIG);
-+ exit (0);
-+}
---- /dev/null
-+++ b/gcc/testsuite/gcc.dg/torture/arm-fp16-ops-1.c
-@@ -0,0 +1,5 @@
-+/* Test various operators on __fp16 and mixed __fp16/float operands. */
-+/* { dg-do run { target arm*-*-* } } */
-+/* { dg-options "-mfp16-format=ieee" } */
-+
-+#include "arm-fp16-ops.h"
---- /dev/null
-+++ b/gcc/testsuite/gcc.dg/torture/arm-fp16-ops-2.c
-@@ -0,0 +1,5 @@
-+/* Test various operators on __fp16 and mixed __fp16/float operands. */
-+/* { dg-do run { target arm*-*-* } } */
-+/* { dg-options "-mfp16-format=ieee -ffast-math" } */
-+
-+#include "arm-fp16-ops.h"
---- /dev/null
-+++ b/gcc/testsuite/gcc.dg/torture/arm-fp16-ops-3.c
-@@ -0,0 +1,5 @@
-+/* Test various operators on __fp16 and mixed __fp16/float operands. */
-+/* { dg-do run { target arm*-*-* } } */
-+/* { dg-options "-mfp16-format=alternative" } */
-+
-+#include "arm-fp16-ops.h"
---- /dev/null
-+++ b/gcc/testsuite/gcc.dg/torture/arm-fp16-ops-4.c
-@@ -0,0 +1,5 @@
-+/* Test various operators on __fp16 and mixed __fp16/float operands. */
-+/* { dg-do run { target arm*-*-* } } */
-+/* { dg-options "-mfp16-format=alternative -ffast-math" } */
-+
-+#include "arm-fp16-ops.h"
---- /dev/null
-+++ b/gcc/testsuite/gcc.dg/torture/arm-fp16-ops-5.c
-@@ -0,0 +1,15 @@
-+/* Test various operators on __fp16 and mixed __fp16/float operands. */
-+/* { dg-do compile { target arm*-*-* } } */
-+/* { dg-require-effective-target arm_neon_fp16_ok } */
-+/* { dg-options "-mfp16-format=ieee" } */
-+/* { dg-add-options arm_neon_fp16 } */
-+
-+#include "arm-fp16-ops.h"
-+
-+/* We've specified options for hardware float, including fp16 support, so
-+ we should not see any calls to libfuncs here. */
-+/* { dg-final { scan-assembler-not "\tbl\t__.*hf2" } } */
-+/* { dg-final { scan-assembler-not "\tbl\t__.*hf3" } } */
-+/* { dg-final { scan-assembler-not "\tbl\t__gnu_h\[a-z\]*_ieee" } } */
-+/* { dg-final { scan-assembler-not "\tbl\t__gnu_h2f_ieee" } } */
-+/* { dg-final { scan-assembler-not "\tbl\t__gnu_f2h_ieee" } } */
---- /dev/null
-+++ b/gcc/testsuite/gcc.dg/torture/arm-fp16-ops-6.c
-@@ -0,0 +1,15 @@
-+/* Test various operators on __fp16 and mixed __fp16/float operands. */
-+/* { dg-do compile { target arm*-*-* } } */
-+/* { dg-require-effective-target arm_neon_fp16_ok } */
-+/* { dg-options "-mfp16-format=ieee -ffast-math" } */
-+/* { dg-add-options arm_neon_fp16 } */
-+
-+#include "arm-fp16-ops.h"
-+
-+/* We've specified options for hardware float, including fp16 support, so
-+ we should not see any calls to libfuncs here. */
-+/* { dg-final { scan-assembler-not "\tbl\t__.*hf2" } } */
-+/* { dg-final { scan-assembler-not "\tbl\t__.*hf3" } } */
-+/* { dg-final { scan-assembler-not "\tbl\t__gnu_h\[a-z\]*_ieee" } } */
-+/* { dg-final { scan-assembler-not "\tbl\t__gnu_h2f_ieee" } } */
-+/* { dg-final { scan-assembler-not "\tbl\t__gnu_f2h_ieee" } } */
---- /dev/null
-+++ b/gcc/testsuite/gcc.dg/torture/arm-fp16-ops-7.c
-@@ -0,0 +1,13 @@
-+/* Test various operators on __fp16 and mixed __fp16/float operands. */
-+/* { dg-do compile { target arm*-*-* } } */
-+/* { dg-require-effective-target arm_neon_ok } */
-+/* { dg-options "-mfp16-format=ieee" } */
-+/* { dg-add-options arm_neon } */
-+
-+#include "arm-fp16-ops.h"
-+
-+/* We've specified options for hardware float, so we should not see any
-+ calls to libfuncs here except for those to the conversion functions. */
-+/* { dg-final { scan-assembler-not "\tbl\t__.*hf2" } } */
-+/* { dg-final { scan-assembler-not "\tbl\t__.*hf3" } } */
-+/* { dg-final { scan-assembler-not "\tbl\t__gnu_h\[a-z\]*_ieee" } } */
---- /dev/null
-+++ b/gcc/testsuite/gcc.dg/torture/arm-fp16-ops-8.c
-@@ -0,0 +1,13 @@
-+/* Test various operators on __fp16 and mixed __fp16/float operands. */
-+/* { dg-do compile { target arm*-*-* } } */
-+/* { dg-require-effective-target arm_neon_ok } */
-+/* { dg-options "-mfp16-format=ieee -ffast-math" } */
-+/* { dg-add-options arm_neon } */
-+
-+#include "arm-fp16-ops.h"
-+
-+/* We've specified options for hardware float, so we should not see any
-+ calls to libfuncs here except for those to the conversion functions. */
-+/* { dg-final { scan-assembler-not "\tbl\t__.*hf2" } } */
-+/* { dg-final { scan-assembler-not "\tbl\t__.*hf3" } } */
-+/* { dg-final { scan-assembler-not "\tbl\t__gnu_h\[a-z\]*_ieee" } } */
---- /dev/null
-+++ b/gcc/testsuite/gcc.dg/torture/arm-fp16-ops.h
-@@ -0,0 +1,135 @@
-+/* Test various operators on __fp16 and mixed __fp16/float operands. */
-+
-+#include <assert.h>
-+
-+#define CHECK(e,r) assert ((e) == r)
-+#define CHECK2(e,r) (assert ((e) == r), temp = (e), assert (temp == r))
-+#define TEST(e) assert (e)
-+#define TESTNOT(e) assert (!(e))
-+
-+volatile __fp16 h0 = 0.0;
-+volatile __fp16 h1 = 1.0;
-+volatile __fp16 h42 = 42.0;
-+volatile __fp16 hm2 = -2.0;
-+volatile __fp16 temp;
-+
-+volatile float f0 = 0.0;
-+volatile float f1 = 1.0;
-+volatile float f42 = 42.0;
-+volatile float fm2 = -2.0;
-+
-+int main (void)
-+{
-+ TEST (h1);
-+ TESTNOT (h0);
-+ TEST (!h0);
-+ TESTNOT (!h1);
-+
-+ CHECK2 (-h1, -1.0);
-+ CHECK2 (+h1, 1.0);
-+
-+ CHECK (h1++, 1.0);
-+ CHECK (h1, 2.0);
-+ CHECK (++h1, 3.0);
-+ CHECK (h1, 3.0);
-+
-+ CHECK (--h1, 2.0);
-+ CHECK (h1, 2.0);
-+ CHECK (h1--, 2.0);
-+ CHECK (h1, 1.0);
-+
-+ CHECK2 (h42 * hm2, -84.0);
-+ CHECK2 (h42 * (__fp16) -2.0, -84.0);
-+ CHECK2 (h42 * fm2, -84.0);
-+ CHECK2 (f42 * hm2, -84.0);
-+
-+ CHECK2 (h42 / hm2, -21.0);
-+ CHECK2 (h42 / (__fp16) -2.0, -21.0);
-+ CHECK2 (h42 / fm2, -21.0);
-+ CHECK2 (f42 / hm2, -21.0);
-+
-+ CHECK2 (hm2 + h42, 40.0);
-+ CHECK2 ((__fp16)-2.0 + h42, 40.0);
-+ CHECK2 (hm2 + f42, 40.0);
-+ CHECK2 (fm2 + h42, 40.0);
-+
-+ CHECK2 (hm2 - h42, -44.0);
-+ CHECK2 ((__fp16)-2.0 - h42, -44.0);
-+ CHECK2 (hm2 - f42, -44.0);
-+ CHECK2 (fm2 - h42, -44.0);
-+
-+ TEST (hm2 < h42);
-+ TEST (hm2 < (__fp16)42.0);
-+ TEST (hm2 < f42);
-+ TEST (fm2 < h42);
-+
-+ TEST (h42 > hm2);
-+ TEST ((__fp16)42.0 > hm2);
-+ TEST (h42 > fm2);
-+ TEST (f42 > hm2);
-+
-+ TEST (hm2 <= h42);
-+ TEST (hm2 <= (__fp16)42.0);
-+ TEST (hm2 <= f42);
-+ TEST (fm2 <= h42);
-+
-+ TEST (h42 >= hm2);
-+ TEST (h42 >= (__fp16)-2.0);
-+ TEST (h42 >= fm2);
-+ TEST (f42 >= hm2);
-+
-+ TESTNOT (h1 == hm2);
-+ TEST (h1 == h1);
-+ TEST (h1 == (__fp16)1.0);
-+ TEST (h1 == f1);
-+ TEST (f1 == h1);
-+
-+ TEST (h1 != hm2);
-+ TESTNOT (h1 != h1);
-+ TESTNOT (h1 != (__fp16)1.0);
-+ TESTNOT (h1 != f1);
-+ TESTNOT (f1 != h1);
-+
-+ CHECK2 ((h1 ? hm2 : h42), -2.0);
-+ CHECK2 ((h0 ? hm2 : h42), 42.0);
-+
-+ CHECK (h0 = h42, 42.0);
-+ CHECK (h0, 42.0);
-+ CHECK (h0 = (__fp16)-2.0, -2.0);
-+ CHECK (h0, -2.0);
-+ CHECK (h0 = f0, 0.0);
-+ CHECK (h0, 0.0);
-+
-+ CHECK (h0 += h1, 1.0);
-+ CHECK (h0, 1.0);
-+ CHECK (h0 += (__fp16)1.0, 2.0);
-+ CHECK (h0, 2.0);
-+ CHECK (h0 += fm2, 0.0);
-+ CHECK (h0, 0.0);
-+
-+ CHECK (h0 -= h1, -1.0);
-+ CHECK (h0, -1.0);
-+ CHECK (h0 -= (__fp16)1.0, -2.0);
-+ CHECK (h0, -2.0);
-+ CHECK (h0 -= fm2, 0.0);
-+ CHECK (h0, 0.0);
-+
-+ h0 = hm2;
-+ CHECK (h0 *= hm2, 4.0);
-+ CHECK (h0, 4.0);
-+ CHECK (h0 *= (__fp16)-2.0, -8.0);
-+ CHECK (h0, -8.0);
-+ CHECK (h0 *= fm2, 16.0);
-+ CHECK (h0, 16.0);
-+
-+ CHECK (h0 /= hm2, -8.0);
-+ CHECK (h0, -8.0);
-+ CHECK (h0 /= (__fp16)-2.0, 4.0);
-+ CHECK (h0, 4.0);
-+ CHECK (h0 /= fm2, -2.0);
-+ CHECK (h0, -2.0);
-+
-+ CHECK ((h0, h1), 1.0);
-+
-+ return 0;
-+}
---- a/gcc/testsuite/gcc.dg/torture/type-generic-1.c
-+++ b/gcc/testsuite/gcc.dg/torture/type-generic-1.c
-@@ -3,6 +3,7 @@
-
- /* { dg-do run } */
- /* { dg-options "-mieee" { target alpha*-*-* sh*-*-* } } */
-+/* { dg-options "-Wl,--defsym=__cs3_mips_float_type=2 -lcs3-mips-cp1 -lcs3-mips-fpemu" { target mips*-*sde*-* } } */
- /* { dg-skip-if "No Inf/NaN support" { spu-*-* } } */
-
- #include "../tg-tests.h"
---- a/gcc/testsuite/gcc.dg/tree-ssa/pr21559.c
-+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr21559.c
-@@ -1,5 +1,5 @@
- /* { dg-do compile } */
--/* { dg-options "-O2 -fdump-tree-vrp1-details" } */
-+/* { dg-options "-O2 -fdump-tree-vrp1-details -fno-remove-local-statics" } */
-
- static int blocksize = 4096;
-
---- a/gcc/testsuite/gcc.dg/tree-ssa/prefetch-7.c
-+++ b/gcc/testsuite/gcc.dg/tree-ssa/prefetch-7.c
-@@ -1,5 +1,6 @@
- /* { dg-do compile { target i?86-*-* x86_64-*-* } } */
- /* { dg-require-effective-target ilp32 } */
-+/* { dg-skip-if "" { i?86-*-* x86_64-*-* } { "-march=*" } { "-march=athlon" } } */
- /* { dg-options "-O2 -fprefetch-loop-arrays -march=athlon -msse2 -mfpmath=sse --param simultaneous-prefetches=100 --param max-unrolled-insns=1 -fdump-tree-aprefetch-details -fdump-tree-final_cleanup" } */
-
- #define K 1000000
---- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-6.c
-+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-6.c
-@@ -1,5 +1,5 @@
- /* { dg-do compile } */
--/* { dg-options "-O2 -fdump-tree-dse1" } */
-+/* { dg-options "-O2 -fdump-tree-dse1 -fno-remove-local-statics" } */
-
- int foo11 (int c)
- {
---- /dev/null
-+++ b/gcc/testsuite/gcc.dg/vect/aligned-section-anchors-nest-1.c
-@@ -0,0 +1,34 @@
-+/* { dg-do compile } */
-+/* { dg-require-effective-target section_anchors } */
-+/* { dg-require-effective-target vect_int } */
-+
-+#include <stdarg.h>
-+#include "tree-vect.h"
-+
-+#define N 32
-+
-+static int a[N][N];
-+static int b[N][N];
-+static int c[N][N];
-+
-+void clobber(int *);
-+
-+int *foo(void)
-+{
-+ int i;
-+ int j;
-+
-+ clobber (&a[0][0]);
-+ clobber (&b[0][0]);
-+ clobber (&c[0][0]);
-+
-+ for (i = 0; i < N; i++) {
-+ for (j = 0; j < N; j++) {
-+ c[j][i] += a[j][i] + c[j][i];
-+ }
-+ }
-+ return &c[0][0];
-+}
-+
-+/* { dg-final { scan-ipa-dump-times "Increasing alignment of decl" 3 "increase_alignment" } } */
-+/* { dg-final { cleanup-ipa-dump "increase_alignment" } } */
---- a/gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-31.c
-+++ b/gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-31.c
-@@ -88,5 +88,5 @@ int main (void)
-
- /* { dg-final { scan-tree-dump-times "vectorized 4 loops" 1 "vect" } } */
- /* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" } } */
--/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 2 "vect" } } */
-+/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 2 "vect" { target { ! vect_element_align } } } } */
- /* { dg-final { cleanup-tree-dump "vect" } } */
---- a/gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-64.c
-+++ b/gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-64.c
-@@ -84,5 +84,5 @@ int main (void)
-
- /* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" } } */
- /* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" } } */
--/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 2 "vect" } } */
-+/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 2 "vect" { target { ! vect_element_align } } } } */
- /* { dg-final { cleanup-tree-dump "vect" } } */
---- a/gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-66.c
-+++ b/gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-66.c
-@@ -79,5 +79,5 @@ int main (void)
-
- /* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" } } */
- /* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" } } */
--/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" } } */
-+/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { target { ! vect_element_align } } } } */
- /* { dg-final { cleanup-tree-dump "vect" } } */
---- a/gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-68.c
-+++ b/gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-68.c
-@@ -88,5 +88,5 @@ int main (void)
-
- /* { dg-final { scan-tree-dump-times "vectorized 4 loops" 1 "vect" } } */
- /* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" } } */
--/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 2 "vect" } } */
-+/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 2 "vect" { target { ! vect_element_align } } } } */
- /* { dg-final { cleanup-tree-dump "vect" } } */
---- a/gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-69.c
-+++ b/gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-69.c
-@@ -114,7 +114,7 @@ int main (void)
-
- /* { dg-final { scan-tree-dump-times "vectorized 4 loops" 1 "vect" } } */
- /* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" } } */
--/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 2 "vect" { xfail {! vector_alignment_reachable} } } } */
-+/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 2 "vect" { xfail { vect_element_align || {! vector_alignment_reachable} } } } } */
- /* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 1 "vect" { target {! vector_alignment_reachable} } } } */
--/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { target {! vector_alignment_reachable} } } } */
-+/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { target { { ! vector_alignment_reachable } && { ! vect_element_align } } } } } */
- /* { dg-final { cleanup-tree-dump "vect" } } */
---- a/gcc/testsuite/gcc.dg/vect/section-anchors-vect-69.c
-+++ b/gcc/testsuite/gcc.dg/vect/section-anchors-vect-69.c
-@@ -115,6 +115,6 @@ int main (void)
- /* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" } } */
- /* Alignment forced using versioning until the pass that increases alignment
- is extended to handle structs. */
--/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 4 "vect" { target {vect_int && vector_alignment_reachable } } } } */
-+/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 4 "vect" { target { {vect_int && vector_alignment_reachable } && { ! vect_element_align } } } } } */
- /* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 4 "vect" { target {vect_int && {! vector_alignment_reachable} } } } } */
- /* { dg-final { cleanup-tree-dump "vect" } } */
---- a/gcc/testsuite/gcc.dg/vect/slp-25.c
-+++ b/gcc/testsuite/gcc.dg/vect/slp-25.c
-@@ -56,5 +56,5 @@ int main (void)
-
- /* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" } } */
- /* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" } } */
--/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 2 "vect" { xfail vect_no_align } } } */
-+/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 2 "vect" { xfail { vect_no_align || vect_element_align } } } } */
- /* { dg-final { cleanup-tree-dump "vect" } } */
---- a/gcc/testsuite/gcc.dg/vect/vect-109.c
-+++ b/gcc/testsuite/gcc.dg/vect/vect-109.c
-@@ -73,6 +73,6 @@ int main (void)
- }
-
- /* { dg-final { scan-tree-dump-times "vectorized 0 loops" 2 "vect" } } */
--/* { dg-final { scan-tree-dump-times "not vectorized: unsupported unaligned store" 2 "vect" } } */
-+/* { dg-final { scan-tree-dump-times "not vectorized: unsupported unaligned store" 2 "vect" { target { ! vect_element_align } } } } */
- /* { dg-final { cleanup-tree-dump "vect" } } */
-
---- a/gcc/testsuite/gcc.dg/vect/vect-26.c
-+++ b/gcc/testsuite/gcc.dg/vect/vect-26.c
-@@ -37,5 +37,5 @@ int main (void)
-
- /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
- /* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" } } */
--/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" } } */
-+/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { target { ! vect_element_align } } } } */
- /* { dg-final { cleanup-tree-dump "vect" } } */
---- a/gcc/testsuite/gcc.dg/vect/vect-27.c
-+++ b/gcc/testsuite/gcc.dg/vect/vect-27.c
-@@ -45,6 +45,6 @@ int main (void)
- /* The initialization induction loop (with aligned access) is also vectorized. */
- /* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" { xfail vect_no_align } } } */
- /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_no_align } } } */
--/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail vect_no_align } } } */
--/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 0 "vect" } } */
-+/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail { vect_no_align || vect_element_align } } } } */
-+/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 0 "vect" { target { ! vect_element_align } } } } */
- /* { dg-final { cleanup-tree-dump "vect" } } */
---- a/gcc/testsuite/gcc.dg/vect/vect-28.c
-+++ b/gcc/testsuite/gcc.dg/vect/vect-28.c
-@@ -40,6 +40,6 @@ int main (void)
-
- /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
- /* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" } } */
--/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { target vector_alignment_reachable } } } */
-+/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { target { vector_alignment_reachable && { ! vect_element_align } } } } } */
- /* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 1 "vect" { target { ! vector_alignment_reachable } } } } */
- /* { dg-final { cleanup-tree-dump "vect" } } */
---- a/gcc/testsuite/gcc.dg/vect/vect-29.c
-+++ b/gcc/testsuite/gcc.dg/vect/vect-29.c
-@@ -50,7 +50,7 @@ int main (void)
-
- /* The initialization induction loop (with aligned access) is also vectorized. */
- /* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" } } */
--/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail vect_no_align } } } */
--/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 0 "vect" } } */
-+/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail { vect_no_align || vect_element_align } } } } */
-+/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 0 "vect" { target { ! vect_element_align } } } } */
- /* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 1 "vect" {target vect_no_align } } } */
- /* { dg-final { cleanup-tree-dump "vect" } } */
---- a/gcc/testsuite/gcc.dg/vect/vect-33.c
-+++ b/gcc/testsuite/gcc.dg/vect/vect-33.c
-@@ -39,6 +39,6 @@ int main (void)
-
- /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
- /* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" } } */
--/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { target vector_alignment_reachable } } } */
-+/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { target { vector_alignment_reachable && { ! vect_element_align } } } } } */
- /* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 1 "vect" { target { ! vector_alignment_reachable } } } } */
- /* { dg-final { cleanup-tree-dump "vect" } } */
---- a/gcc/testsuite/gcc.dg/vect/vect-42.c
-+++ b/gcc/testsuite/gcc.dg/vect/vect-42.c
-@@ -57,6 +57,6 @@ int main (void)
-
- /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
- /* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 1 "vect" { target { vect_no_align || { ! vector_alignment_reachable } } } } } */
--/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { xfail { vect_no_align || { ! vector_alignment_reachable } } } } } */
--/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { xfail {vect_no_align || { ! vector_alignment_reachable } } } } } */
-+/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { xfail { { vect_no_align || vect_element_align } || { ! vector_alignment_reachable } } } } } */
-+/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { xfail { { vect_no_align || vect_element_align } || { ! vector_alignment_reachable } } } } } */
- /* { dg-final { cleanup-tree-dump "vect" } } */
---- a/gcc/testsuite/gcc.dg/vect/vect-44.c
-+++ b/gcc/testsuite/gcc.dg/vect/vect-44.c
-@@ -65,8 +65,8 @@ int main (void)
- two loads to be aligned). */
-
- /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
--/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { xfail vect_no_align } } } */
--/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { xfail { vect_no_align || {! vector_alignment_reachable} } } } } */
-+/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { xfail { vect_no_align || vect_element_align } } } } */
-+/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { xfail { { vect_no_align || vect_element_align } || {! vector_alignment_reachable} } } } } */
- /* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 3 "vect" { target vect_no_align } } } */
- /* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 1 "vect" { target { {! vector_alignment_reachable} && {! vect_no_align} } } } } */
- /* { dg-final { cleanup-tree-dump "vect" } } */
---- a/gcc/testsuite/gcc.dg/vect/vect-48.c
-+++ b/gcc/testsuite/gcc.dg/vect/vect-48.c
-@@ -54,7 +54,7 @@ int main (void)
- (The store is aligned). */
-
- /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
--/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { xfail vect_no_align } } } */
--/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 0 "vect" } } */
-+/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { xfail { vect_no_align || vect_element_align } } } } */
-+/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 0 "vect" { target { ! vect_element_align } } } } */
- /* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 2 "vect" { target vect_no_align } } } */
- /* { dg-final { cleanup-tree-dump "vect" } } */
---- a/gcc/testsuite/gcc.dg/vect/vect-50.c
-+++ b/gcc/testsuite/gcc.dg/vect/vect-50.c
-@@ -61,8 +61,8 @@ int main (void)
- two loads to be aligned). */
-
- /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
--/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { xfail vect_no_align } } } */
--/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { xfail { vect_no_align || {! vector_alignment_reachable} } } } } */
-+/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { xfail { vect_no_align || vect_element_align } } } } */
-+/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { xfail { { vect_no_align || vect_element_align } || {! vector_alignment_reachable} } } } } */
- /* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 3 "vect" { target vect_no_align } } } */
- /* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 1 "vect" { target { {! vector_alignment_reachable} && {! vect_no_align} } } } } */
- /* { dg-final { cleanup-tree-dump "vect" } } */
---- a/gcc/testsuite/gcc.dg/vect/vect-52.c
-+++ b/gcc/testsuite/gcc.dg/vect/vect-52.c
-@@ -55,7 +55,7 @@ int main (void)
- (The store is aligned). */
-
- /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
--/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { xfail vect_no_align } } } */
--/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 0 "vect" } } */
-+/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { xfail { vect_no_align || vect_element_align } } } } */
-+/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 0 "vect" { target { ! vect_element_align } } } } */
- /* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 2 "vect" { target vect_no_align } } } */
- /* { dg-final { cleanup-tree-dump "vect" } } */
---- a/gcc/testsuite/gcc.dg/vect/vect-54.c
-+++ b/gcc/testsuite/gcc.dg/vect/vect-54.c
-@@ -59,5 +59,5 @@ int main (void)
-
- /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
- /* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" } } */
--/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" } } */
-+/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { target { ! vect_element_align } } } } */
- /* { dg-final { cleanup-tree-dump "vect" } } */
---- a/gcc/testsuite/gcc.dg/vect/vect-56.c
-+++ b/gcc/testsuite/gcc.dg/vect/vect-56.c
-@@ -67,6 +67,6 @@ int main (void)
- }
-
- /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail vect_no_align } } } */
--/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { xfail vect_no_align } } } */
--/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 0 "vect" } } */
-+/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { xfail { vect_no_align || vect_element_align } } } } */
-+/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 0 "vect" { target { ! vect_element_align } } } } */
- /* { dg-final { cleanup-tree-dump "vect" } } */
---- a/gcc/testsuite/gcc.dg/vect/vect-58.c
-+++ b/gcc/testsuite/gcc.dg/vect/vect-58.c
-@@ -58,5 +58,5 @@ int main (void)
-
- /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
- /* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" } } */
--/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" } } */
-+/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { target { ! vect_element_align } } } } */
- /* { dg-final { cleanup-tree-dump "vect" } } */
---- a/gcc/testsuite/gcc.dg/vect/vect-60.c
-+++ b/gcc/testsuite/gcc.dg/vect/vect-60.c
-@@ -68,6 +68,6 @@ int main (void)
- }
-
- /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail vect_no_align } } } */
--/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { xfail vect_no_align } } } */
--/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 0 "vect" } } */
-+/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { xfail { vect_no_align || vect_element_align } } } } */
-+/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 0 "vect" { target { ! vect_element_align } } } } */
- /* { dg-final { cleanup-tree-dump "vect" } } */
---- a/gcc/testsuite/gcc.dg/vect/vect-70.c
-+++ b/gcc/testsuite/gcc.dg/vect/vect-70.c
-@@ -64,6 +64,6 @@ int main (void)
-
- /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
- /* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" } } */
--/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" {target vector_alignment_reachable } } } */
-+/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" {target { vector_alignment_reachable && { ! vect_element_align } } } } } */
- /* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 1 "vect" {target {! vector_alignment_reachable} } } } */
- /* { dg-final { cleanup-tree-dump "vect" } } */
---- a/gcc/testsuite/gcc.dg/vect/vect-72.c
-+++ b/gcc/testsuite/gcc.dg/vect/vect-72.c
-@@ -46,6 +46,6 @@ int main (void)
- }
-
- /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail vect_no_align } } } */
--/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail vect_no_align } } } */
--/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 0 "vect" } } */
-+/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail { vect_no_align || vect_element_align } } } } */
-+/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 0 "vect" { target { ! vect_element_align } } } } */
- /* { dg-final { cleanup-tree-dump "vect" } } */
---- a/gcc/testsuite/gcc.dg/vect/vect-75.c
-+++ b/gcc/testsuite/gcc.dg/vect/vect-75.c
-@@ -45,5 +45,5 @@ int main (void)
-
- /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
- /* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 1 "vect" { target vect_no_align } } } */
--/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail vect_no_align } } } */
-+/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail { vect_no_align || vect_element_align } } } } */
- /* { dg-final { cleanup-tree-dump "vect" } } */
---- a/gcc/testsuite/gcc.dg/vect/vect-87.c
-+++ b/gcc/testsuite/gcc.dg/vect/vect-87.c
-@@ -51,6 +51,6 @@ int main (void)
- /* Fails for targets that don't vectorize PLUS (e.g alpha). */
- /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
- /* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" } } */
--/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" {target vector_alignment_reachable } } } */
-+/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" {target { vector_alignment_reachable && { ! vect_element_align } } } } } */
- /* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 1 "vect" {target {! vector_alignment_reachable} } } } */
- /* { dg-final { cleanup-tree-dump "vect" } } */
---- a/gcc/testsuite/gcc.dg/vect/vect-88.c
-+++ b/gcc/testsuite/gcc.dg/vect/vect-88.c
-@@ -51,6 +51,6 @@ int main (void)
- /* Fails for targets that don't vectorize PLUS (e.g alpha). */
- /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
- /* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" } } */
--/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" {target vector_alignment_reachable } } } */
-+/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" {target { vector_alignment_reachable && { ! vect_element_align } } } } } */
- /* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 1 "vect" {target {! vector_alignment_reachable} } } } */
- /* { dg-final { cleanup-tree-dump "vect" } } */
---- a/gcc/testsuite/gcc.dg/vect/vect-89.c
-+++ b/gcc/testsuite/gcc.dg/vect/vect-89.c
-@@ -46,5 +46,5 @@ int main (void)
-
- /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
- /* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" } } */
--/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" } } */
-+/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { target { ! vect_element_align } } } } */
- /* { dg-final { cleanup-tree-dump "vect" } } */
---- a/gcc/testsuite/gcc.dg/vect/vect-91.c
-+++ b/gcc/testsuite/gcc.dg/vect/vect-91.c
-@@ -59,6 +59,6 @@ main3 ()
-
- /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 3 "vect" { xfail vect_no_int_add } } } */
- /* { dg-final { scan-tree-dump-times "accesses have the same alignment." 3 "vect" } } */
--/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 3 "vect" {target vector_alignment_reachable } } } */
-+/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 3 "vect" {target { vector_alignment_reachable && { ! vect_element_align } } } } } */
- /* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 3 "vect" {target {! vector_alignment_reachable} } } } */
- /* { dg-final { cleanup-tree-dump "vect" } } */
---- a/gcc/testsuite/gcc.dg/vect/vect-92.c
-+++ b/gcc/testsuite/gcc.dg/vect/vect-92.c
-@@ -92,5 +92,5 @@ int main (void)
-
- /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 3 "vect" } } */
- /* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" } } */
--/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 3 "vect" } } */
-+/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 3 "vect" { target { ! vect_element_align } } } } */
- /* { dg-final { cleanup-tree-dump "vect" } } */
---- a/gcc/testsuite/gcc.dg/vect/vect-93.c
-+++ b/gcc/testsuite/gcc.dg/vect/vect-93.c
-@@ -72,7 +72,7 @@ int main (void)
- /* main && main1 together: */
- /* { dg-final { scan-tree-dump-times "vectorized 2 loops" 2 "vect" { target powerpc*-*-* i?86-*-* x86_64-*-* } } } */
- /* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 2 "vect" { target { vect_no_align && {! vector_alignment_reachable} } } } } */
--/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 3 "vect" { xfail { vect_no_align || {! vector_alignment_reachable} } } } } */
-+/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 3 "vect" { xfail { { vect_no_align || vect_element_align } || {! vector_alignment_reachable} } } } } */
-
- /* in main1: */
- /* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" { target !powerpc*-*-* !i?86-*-* !x86_64-*-* } } } */
-@@ -80,6 +80,6 @@ int main (void)
-
- /* in main: */
- /* { dg-final { scan-tree-dump-times "vectorized 0 loops" 1 "vect" { target vect_no_align } } } */
--/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail vect_no_align } } } */
-+/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail { vect_no_align || vect_element_align } } } } */
-
- /* { dg-final { cleanup-tree-dump "vect" } } */
---- a/gcc/testsuite/gcc.dg/vect/vect-95.c
-+++ b/gcc/testsuite/gcc.dg/vect/vect-95.c
-@@ -62,8 +62,8 @@ int main (void)
- stores and generate misaligned accesses for the loads. For targets that
- don't support unaligned loads we version for all four accesses. */
-
--/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { xfail vect_no_align } } } */
--/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 2 "vect" { xfail vect_no_align } } } */
-+/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { xfail { vect_no_align || vect_element_align } } } } */
-+/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 2 "vect" { xfail { vect_no_align || vect_element_align } } } } */
- /* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" { target vect_no_align } } } */
- /* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 4 "vect" { target vect_no_align } } } */
- /* { dg-final { cleanup-tree-dump "vect" } } */
---- a/gcc/testsuite/gcc.dg/vect/vect-align-2.c
-+++ b/gcc/testsuite/gcc.dg/vect/vect-align-2.c
-@@ -43,6 +43,6 @@ int main (void)
-
-
- /* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 0 "vect" } } */
--/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 1 "vect" } } */
-+/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 1 "vect" { target { ! vect_element_align } } } } */
- /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
- /* { dg-final { cleanup-tree-dump "vect" } } */
---- a/gcc/testsuite/gcc.dg/vect/vect-multitypes-1.c
-+++ b/gcc/testsuite/gcc.dg/vect/vect-multitypes-1.c
-@@ -78,11 +78,11 @@ int main (void)
- return 0;
- }
-
--/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" { xfail *-*-* } } } */
--/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail vect_no_align } } } */
-+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" { xfail { ! vect_element_align } } } } */
-+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail { vect_no_align || vect_element_align } } } } */
- /* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 2 "vect" { xfail *-*-* } } } */
--/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { xfail vect_no_align } } } */
-+/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { xfail { vect_no_align || vect_element_align } } } } */
- /* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 4 "vect" { xfail *-*-* } } } */
--/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { xfail vect_no_align } } } */
-+/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { xfail { vect_no_align || vect_element_align } } } } */
- /* { dg-final { cleanup-tree-dump "vect" } } */
-
---- a/gcc/testsuite/gcc.dg/vect/vect-multitypes-3.c
-+++ b/gcc/testsuite/gcc.dg/vect/vect-multitypes-3.c
-@@ -54,6 +54,6 @@ int main (void)
-
- /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
- /* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 3 "vect" { target vect_no_align } } } */
--/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 3 "vect" {xfail vect_no_align } } } */
-+/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 3 "vect" {xfail { vect_no_align || vect_element_align } } } } */
- /* { dg-final { cleanup-tree-dump "vect" } } */
-
---- a/gcc/testsuite/gcc.dg/vect/vect-multitypes-4.c
-+++ b/gcc/testsuite/gcc.dg/vect/vect-multitypes-4.c
-@@ -85,11 +85,11 @@ int main (void)
- return 0;
- }
-
--/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" { xfail *-*-* } } } */
--/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail vect_no_align } } } */
-+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" { xfail { ! vect_element_align } } } } */
-+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail { vect_no_align || vect_element_align } } } } */
- /* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 2 "vect" { xfail *-*-* } } } */
--/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { xfail vect_no_align } } } */
-+/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { xfail { vect_no_align || vect_element_align } } } } */
- /* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 8 "vect" { xfail *-*-* } } } */
--/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 4 "vect" { xfail vect_no_align } } } */
-+/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 4 "vect" { xfail { vect_no_align || vect_element_align } } } } */
- /* { dg-final { cleanup-tree-dump "vect" } } */
-
---- a/gcc/testsuite/gcc.dg/vect/vect-multitypes-6.c
-+++ b/gcc/testsuite/gcc.dg/vect/vect-multitypes-6.c
-@@ -61,6 +61,6 @@ int main (void)
-
- /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail { sparc*-*-* && ilp32 } }} } */
- /* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 6 "vect" { target vect_no_align } } } */
--/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 6 "vect" {xfail vect_no_align } } } */
-+/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 6 "vect" {xfail { vect_no_align || vect_element_align } } } } */
- /* { dg-final { cleanup-tree-dump "vect" } } */
-
---- /dev/null
-+++ b/gcc/testsuite/gcc.dg/vect/vect-shift-2.c
-@@ -0,0 +1,37 @@
-+/* { dg-require-effective-target vect_shift_char } */
-+/* { dg-require-effective-target vect_int } */
-+
-+#include "tree-vect.h"
-+
-+#define N 32
-+
-+unsigned char dst[N] __attribute__((aligned(N)));
-+unsigned char src[N] __attribute__((aligned(N)));
-+
-+__attribute__ ((noinline))
-+void array_shift(void)
-+{
-+ int i;
-+ for (i = 0; i < N; i++)
-+ dst[i] = src[i] >> 3;
-+}
-+
-+int main()
-+{
-+ volatile int i;
-+ check_vect ();
-+
-+ for (i = 0; i < N; i++)
-+ src[i] = i << 3;
-+
-+ array_shift ();
-+
-+ for (i = 0; i < N; i++)
-+ if (dst[i] != i)
-+ abort ();
-+
-+ return 0;
-+}
-+
-+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
-+/* { dg-final { cleanup-tree-dump "vect" } } */
---- /dev/null
-+++ b/gcc/testsuite/gcc.dg/vect/vect-shift-3.c
-@@ -0,0 +1,37 @@
-+/* { dg-require-effective-target vect_shift } */
-+/* { dg-require-effective-target vect_int } */
-+
-+#include "tree-vect.h"
-+
-+#define N 32
-+
-+unsigned short dst[N] __attribute__((aligned(N)));
-+unsigned short src[N] __attribute__((aligned(N)));
-+
-+__attribute__ ((noinline))
-+void array_shift(void)
-+{
-+ int i;
-+ for (i = 0; i < N; i++)
-+ dst[i] = src[i] >> 3;
-+}
-+
-+int main()
-+{
-+ volatile int i;
-+ check_vect ();
-+
-+ for (i = 0; i < N; i++)
-+ src[i] = i << 3;
-+
-+ array_shift ();
-+
-+ for (i = 0; i < N; i++)
-+ if (dst[i] != i)
-+ abort ();
-+
-+ return 0;
-+}
-+
-+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
-+/* { dg-final { cleanup-tree-dump "vect" } } */
---- a/gcc/testsuite/gcc.dg/vect/vect.exp
-+++ b/gcc/testsuite/gcc.dg/vect/vect.exp
-@@ -97,7 +97,7 @@ if [istarget "powerpc-*paired*"] {
- } elseif [istarget "ia64-*-*"] {
- set dg-do-what-default run
- } elseif [is-effective-target arm_neon_ok] {
-- lappend DEFAULT_VECTCFLAGS "-mfpu=neon" "-mfloat-abi=softfp"
-+ eval lappend DEFAULT_VECTCFLAGS [add_options_for_arm_neon ""]
- if [is-effective-target arm_neon_hw] {
- set dg-do-what-default run
- } else {
-@@ -183,6 +183,12 @@ lappend DEFAULT_VECTCFLAGS "-fsection-an
- dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/section-anchors-*.\[cS\]]] \
- "" $DEFAULT_VECTCFLAGS
-
-+# alignment-sensitive -fsection-anchors tests
-+set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS
-+lappend DEFAULT_VECTCFLAGS "-fsection-anchors" "-fdump-ipa-increase_alignment"
-+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/aligned-section-anchors-*.\[cS\]]] \
-+ "" $DEFAULT_VECTCFLAGS
-+
- # -fno-section-anchors tests
- set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS
- lappend DEFAULT_VECTCFLAGS "-fno-section-anchors"
---- a/gcc/testsuite/gcc.dg/vmx/vmx.exp
-+++ b/gcc/testsuite/gcc.dg/vmx/vmx.exp
-@@ -31,7 +31,7 @@ if {![istarget powerpc*-*-*]
- # nothing but extensions.
- global DEFAULT_VMXCFLAGS
- if ![info exists DEFAULT_VMXCFLAGS] then {
-- set DEFAULT_VMXCFLAGS "-maltivec -mabi=altivec -std=gnu99"
-+ set DEFAULT_VMXCFLAGS "-maltivec -std=gnu99"
- }
-
- # If the target system supports AltiVec instructions, the default action
---- a/gcc/testsuite/gcc.misc-tests/i386-prefetch.exp
-+++ b/gcc/testsuite/gcc.misc-tests/i386-prefetch.exp
-@@ -90,6 +90,13 @@ load_lib torture-options.exp
- dg-init
- torture-init
-
-+if { [board_info target exists multilib_flags]
-+ && [string match "* -march=*" " [board_info target multilib_flags] "] } {
-+ # Multilib flags come after the -march flags we pass and override
-+ # them, so skip these tests when such flags are passed.
-+ return
-+}
-+
- set-torture-options $PREFETCH_NONE
- gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/i386-pf-none-*.c]] ""
-
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/aapcs/aapcs.exp
-@@ -0,0 +1,35 @@
-+# Copyright (C) 1997, 2004, 2006, 2007 Free Software Foundation, Inc.
-+
-+# This program is free software; you can redistribute it and/or modify
-+# it under the terms of the GNU General Public License as published by
-+# the Free Software Foundation; either version 3 of the License, or
-+# (at your option) any later version.
-+#
-+# This program is distributed in the hope that it will be useful,
-+# but WITHOUT ANY WARRANTY; without even the implied warranty of
-+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+# GNU General Public License for more details.
-+#
-+# You should have received a copy of the GNU General Public License
-+# along with GCC; see the file COPYING3. If not see
-+# <http://www.gnu.org/licenses/>.
-+
-+# GCC testsuite that uses the `dg.exp' driver.
-+
-+# Exit immediately if this isn't an ARM target.
-+if ![istarget arm*-*-*] then {
-+ return
-+}
-+
-+# Load support procs.
-+load_lib gcc-dg.exp
-+
-+# Initialize `dg'.
-+dg-init
-+
-+# Main loop.
-+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cCS\]]] \
-+ "" ""
-+
-+# All done.
-+dg-finish
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/aapcs/abitest.h
-@@ -0,0 +1,118 @@
-+#define IN_FRAMEWORK
-+
-+#ifdef VFP
-+#define D0 0
-+#define D1 8
-+#define D2 16
-+#define D3 24
-+#define D4 32
-+#define D5 40
-+#define D6 48
-+#define D7 56
-+
-+#define S0 64
-+#define S1 68
-+#define S2 72
-+#define S3 76
-+#define S4 80
-+#define S5 84
-+#define S6 88
-+#define S7 92
-+#define S8 86
-+#define S9 100
-+#define S10 104
-+#define S11 108
-+#define S12 112
-+#define S13 116
-+#define S14 120
-+#define S15 124
-+
-+#define R0 128
-+#define R1 132
-+#define R2 136
-+#define R3 140
-+
-+#define STACK 144
-+
-+#else
-+
-+#define R0 0
-+#define R1 4
-+#define R2 8
-+#define R3 12
-+
-+#define STACK 16
-+
-+#endif
-+
-+extern void abort (void);
-+
-+__attribute__((naked)) void dumpregs () __asm("myfunc");
-+__attribute__((naked)) void dumpregs ()
-+{
-+ asm(
-+ "mov ip, sp\n\t"
-+ "stmfd sp!, {r0-r3}\n\t"
-+#ifdef VFP
-+ "fstmdbs sp!, {s0-s15}\n\t"
-+ "fstmdbd sp!, {d0-d7}\n\t"
-+#endif
-+ "mov r0, sp\n\t"
-+ "stmfd sp!, {ip, r14}\n\t"
-+ "bl testfunc\n\t"
-+ "ldmfd sp!, {r0, r14}\n\t"
-+ "mov sp, r0\n\t"
-+ "bx lr");
-+}
-+
-+
-+#define LAST_ARG(type,val,offset) { type __x = val; if (memcmp(&__x, stack+offset, sizeof(type)) != 0) abort(); }
-+#define ARG(type,val,offset) LAST_ARG(type, val, offset)
-+#define ANON(type,val,offset) LAST_ARG(type, val, offset)
-+#define LAST_ANON(type,val,offset) LAST_ARG(type, val, offset)
-+#define DOTS
-+
-+void testfunc(char* stack)
-+{
-+#include TESTFILE
-+ return;
-+}
-+
-+#undef LAST_ARG
-+#undef ARG
-+#undef DOTS
-+#undef ANON
-+#undef LAST_ANON
-+#define LAST_ARG(type,val,offset) type
-+#define ARG(type,val,offset) LAST_ARG(type, val, offset),
-+#define DOTS ...
-+#define ANON(type,val, offset)
-+#define LAST_ANON(type,val, offset)
-+
-+#ifndef MYFUNCTYPE
-+#define MYFUNCTYPE void
-+#endif
-+
-+MYFUNCTYPE myfunc(
-+#include TESTFILE
-+);
-+
-+#undef LAST_ARG
-+#undef ARG
-+#undef DOTS
-+#undef ANON
-+#undef LAST_ANON
-+#define LAST_ARG(type,val,offset) val
-+#define ARG(type,val,offset) LAST_ARG(type, val, offset),
-+#define DOTS
-+#define LAST_ANON(type,val,offset) LAST_ARG(type, val, offset)
-+#define ANON(type,val,offset) LAST_ARG(type, val, offset),
-+
-+
-+int main()
-+{
-+ myfunc(
-+#include TESTFILE
-+);
-+ return 0;
-+}
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/aapcs/vfp1.c
-@@ -0,0 +1,17 @@
-+/* Test AAPCS layout (VFP variant) */
-+
-+/* { dg-do run { target arm*-*-eabi* } } */
-+/* { dg-require-effective-target arm_hard_vfp_ok } */
-+/* { dg-require-effective-target arm32 } */
-+/* { dg-options "-O -mfpu=vfp -mfloat-abi=hard" } */
-+
-+#ifndef IN_FRAMEWORK
-+#define VFP
-+#define TESTFILE "vfp1.c"
-+#include "abitest.h"
-+
-+#else
-+ ARG(int, 4, R0)
-+ ARG(double, 4.0, D0)
-+ LAST_ARG(int, 3, R1)
-+#endif
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/aapcs/vfp10.c
-@@ -0,0 +1,38 @@
-+/* Test AAPCS layout (VFP variant) */
-+
-+/* { dg-do run { target arm*-*-eabi* } } */
-+/* { dg-require-effective-target arm_hard_vfp_ok } */
-+/* { dg-require-effective-target arm32 } */
-+/* { dg-options "-O -mfpu=vfp -mfloat-abi=hard" } */
-+
-+#ifndef IN_FRAMEWORK
-+#define VFP
-+#define TESTFILE "vfp10.c"
-+
-+__complex__ x = 1.0+2.0i;
-+
-+struct y
-+{
-+ int p;
-+ int q;
-+ int r;
-+ int s;
-+} v = { 1, 2, 3, 4 };
-+
-+struct z
-+{
-+ double x[4];
-+};
-+
-+struct z a = { 5.0, 6.0, 7.0, 8.0 };
-+struct z b = { 9.0, 10.0, 11.0, 12.0 };
-+
-+#include "abitest.h"
-+#else
-+ /* A variadic function passes using the base ABI */
-+ ARG(double, 11.0, R0)
-+ DOTS
-+ ANON(struct z, a, R2)
-+ ANON(struct z, b, STACK+24)
-+ LAST_ANON(double, 0.5, STACK+56)
-+#endif
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/aapcs/vfp11.c
-@@ -0,0 +1,39 @@
-+/* Test AAPCS layout (VFP variant) */
-+
-+/* { dg-do run { target arm*-*-eabi* } } */
-+/* { dg-require-effective-target arm_hard_vfp_ok } */
-+/* { dg-require-effective-target arm32 } */
-+/* { dg-options "-O -mfpu=vfp -mfloat-abi=hard" } */
-+
-+#ifndef IN_FRAMEWORK
-+#define VFP
-+#define TESTFILE "vfp11.c"
-+
-+__complex__ x = 1.0+2.0i;
-+
-+struct y
-+{
-+ int p;
-+ int q;
-+ int r;
-+ int s;
-+} v = { 1, 2, 3, 4 };
-+
-+struct z
-+{
-+ double x[4];
-+};
-+
-+struct z a = { 5.0, 6.0, 7.0, 8.0 };
-+struct z b = { 9.0, 10.0, 11.0, 12.0 };
-+
-+#define MYFUNCTYPE struct y
-+
-+#include "abitest.h"
-+#else
-+ ARG(int, 7, R1)
-+ ARG(struct y, v, R2)
-+ ARG(struct z, a, D0)
-+ ARG(struct z, b, D4)
-+ LAST_ARG(double, 0.5, STACK+8)
-+#endif
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/aapcs/vfp12.c
-@@ -0,0 +1,38 @@
-+/* Test AAPCS layout (VFP variant) */
-+
-+/* { dg-do run { target arm*-*-eabi* } } */
-+/* { dg-require-effective-target arm_hard_vfp_ok } */
-+/* { dg-require-effective-target arm32 } */
-+/* { dg-options "-O -mfpu=vfp -mfloat-abi=hard" } */
-+
-+#ifndef IN_FRAMEWORK
-+#define VFP
-+#define TESTFILE "vfp12.c"
-+
-+__complex__ x = 1.0+2.0i;
-+
-+struct y
-+{
-+ int p;
-+ int q;
-+ int r;
-+ int s;
-+} v = { 1, 2, 3, 4 };
-+
-+struct z
-+{
-+ double x[4];
-+};
-+
-+struct z a = { 5.0, 6.0, 7.0, 8.0 };
-+struct z b = { 9.0, 10.0, 11.0, 12.0 };
-+
-+#include "abitest.h"
-+#else
-+ ARG(int, 7, R0)
-+ ARG(struct y, v, R1)
-+ ARG(struct z, a, D0)
-+ ARG(double, 1.0, D4)
-+ ARG(struct z, b, STACK+8)
-+ LAST_ARG(double, 0.5, STACK+40)
-+#endif
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/aapcs/vfp13.c
-@@ -0,0 +1,39 @@
-+/* Test AAPCS layout (VFP variant) */
-+
-+/* { dg-do run { target arm*-*-eabi* } } */
-+/* { dg-require-effective-target arm_hard_vfp_ok } */
-+/* { dg-require-effective-target arm32 } */
-+/* { dg-options "-O -mfpu=vfp -mfloat-abi=hard" } */
-+
-+#ifndef IN_FRAMEWORK
-+#define VFP
-+#define TESTFILE "vfp13.c"
-+
-+__complex__ x = 1.0+2.0i;
-+
-+struct y
-+{
-+ int p;
-+ int q;
-+ int r;
-+ int s;
-+} v = { 1, 2, 3, 4 };
-+
-+struct z
-+{
-+ double x[4];
-+};
-+
-+struct z a = { 5.0, 6.0, 7.0, 8.0 };
-+struct z b = { 9.0, 10.0, 11.0, 12.0 };
-+
-+#include "abitest.h"
-+#else
-+ ARG(int, 7, R0)
-+ ARG(int, 9, R1)
-+ ARG(struct z, a, D0)
-+ ARG(double, 1.0, D4)
-+ ARG(struct z, b, STACK)
-+ ARG(int, 4, R2)
-+ LAST_ARG(double, 0.5, STACK+32)
-+#endif
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/aapcs/vfp14.c
-@@ -0,0 +1,24 @@
-+/* Test AAPCS layout (VFP variant) */
-+
-+/* { dg-do run { target arm*-*-eabi* } } */
-+/* { dg-require-effective-target arm_hard_vfp_ok } */
-+/* { dg-require-effective-target arm32 } */
-+/* { dg-options "-O -mfpu=vfp -mfloat-abi=hard" } */
-+
-+#ifndef IN_FRAMEWORK
-+#define VFP
-+#define TESTFILE "vfp14.c"
-+
-+#include "abitest.h"
-+#else
-+ ARG(double, 1.0, D0)
-+ ARG(double, 2.0, D1)
-+ ARG(double, 3.0, D2)
-+ ARG(double, 4.0, D3)
-+ ARG(double, 5.0, D4)
-+ ARG(double, 6.0, D5)
-+ ARG(double, 7.0, D6)
-+ ARG(double, 8.0, D7)
-+ ARG(double, 9.0, STACK)
-+ LAST_ARG(double, 10.0, STACK+8)
-+#endif
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/aapcs/vfp2.c
-@@ -0,0 +1,19 @@
-+/* Test AAPCS layout (VFP variant) */
-+
-+/* { dg-do run { target arm*-*-eabi* } } */
-+/* { dg-require-effective-target arm_hard_vfp_ok } */
-+/* { dg-require-effective-target arm32 } */
-+/* { dg-options "-O -mfpu=vfp -mfloat-abi=hard" } */
-+
-+#ifndef IN_FRAMEWORK
-+#define VFP
-+#define TESTFILE "vfp2.c"
-+#include "abitest.h"
-+
-+#else
-+ ARG(float, 1.0f, S0)
-+ ARG(double, 4.0, D1)
-+ ARG(float, 2.0f, S1)
-+ ARG(double, 5.0, D2)
-+ LAST_ARG(int, 3, R0)
-+#endif
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/aapcs/vfp3.c
-@@ -0,0 +1,21 @@
-+/* Test AAPCS layout (VFP variant) */
-+
-+/* { dg-do run { target arm*-*-eabi* } } */
-+/* { dg-require-effective-target arm_hard_vfp_ok } */
-+/* { dg-require-effective-target arm32 } */
-+/* { dg-options "-O -mfpu=vfp -mfloat-abi=hard" } */
-+
-+#ifndef IN_FRAMEWORK
-+#define VFP
-+#define TESTFILE "vfp3.c"
-+
-+__complex__ x = 1.0+2.0i;
-+
-+#include "abitest.h"
-+#else
-+ ARG(float, 1.0f, S0)
-+ ARG(__complex__ double, x, D1)
-+ ARG(float, 2.0f, S1)
-+ ARG(double, 5.0, D3)
-+ LAST_ARG(int, 3, R0)
-+#endif
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/aapcs/vfp4.c
-@@ -0,0 +1,20 @@
-+/* Test AAPCS layout (VFP variant) */
-+
-+/* { dg-do run { target arm*-*-eabi* } } */
-+/* { dg-require-effective-target arm_hard_vfp_ok } */
-+/* { dg-require-effective-target arm32 } */
-+/* { dg-options "-O -mfpu=vfp -mfloat-abi=hard" } */
-+
-+#ifndef IN_FRAMEWORK
-+#define VFP
-+#define TESTFILE "vfp4.c"
-+
-+__complex__ float x = 1.0f + 2.0fi;
-+#include "abitest.h"
-+#else
-+ ARG(float, 1.0f, S0)
-+ ARG(__complex__ float, x, S1)
-+ ARG(float, 2.0f, S3)
-+ ARG(double, 5.0, D2)
-+ LAST_ARG(int, 3, R0)
-+#endif
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/aapcs/vfp5.c
-@@ -0,0 +1,30 @@
-+/* Test AAPCS layout (VFP variant) */
-+
-+/* { dg-do run { target arm*-*-eabi* } } */
-+/* { dg-require-effective-target arm_hard_vfp_ok } */
-+/* { dg-require-effective-target arm32 } */
-+/* { dg-options "-O -mfpu=vfp -mfloat-abi=hard" } */
-+
-+#ifndef IN_FRAMEWORK
-+#define VFP
-+#define TESTFILE "vfp5.c"
-+
-+__complex__ float x = 1.0+2.0i;
-+
-+struct y
-+{
-+ int p;
-+ int q;
-+ int r;
-+ int s;
-+} v = { 1, 2, 3, 4 };
-+
-+#include "abitest.h"
-+#else
-+ ARG(float, 1.0f, S0)
-+ ARG(__complex__ float, x, S1)
-+ ARG(float, 2.0f, S3)
-+ ARG(double, 5.0, D2)
-+ ARG(struct y, v, R0)
-+ LAST_ARG(int, 3, STACK)
-+#endif
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/aapcs/vfp6.c
-@@ -0,0 +1,30 @@
-+/* Test AAPCS layout (VFP variant) */
-+
-+/* { dg-do run { target arm*-*-eabi* } } */
-+/* { dg-require-effective-target arm_hard_vfp_ok } */
-+/* { dg-require-effective-target arm32 } */
-+/* { dg-options "-O -mfpu=vfp -mfloat-abi=hard" } */
-+
-+#ifndef IN_FRAMEWORK
-+#define VFP
-+#define TESTFILE "vfp6.c"
-+
-+__complex__ float x = 1.0+2.0i;
-+
-+struct y
-+{
-+ int p;
-+ int q;
-+ int r;
-+ int s;
-+} v = { 1, 2, 3, 4 };
-+
-+#include "abitest.h"
-+#else
-+ ARG(struct y, v, R0)
-+ ARG(float, 1.0f, S0)
-+ ARG(__complex__ float, x, S1)
-+ ARG(float, 2.0f, S3)
-+ ARG(double, 5.0, D2)
-+ LAST_ARG(int, 3, STACK)
-+#endif
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/aapcs/vfp7.c
-@@ -0,0 +1,37 @@
-+/* Test AAPCS layout (VFP variant) */
-+
-+/* { dg-do run { target arm*-*-eabi* } } */
-+/* { dg-require-effective-target arm_hard_vfp_ok } */
-+/* { dg-require-effective-target arm32 } */
-+/* { dg-options "-O -mfpu=vfp -mfloat-abi=hard" } */
-+
-+#ifndef IN_FRAMEWORK
-+#define VFP
-+#define TESTFILE "vfp7.c"
-+
-+__complex__ x = 1.0+2.0i;
-+
-+struct y
-+{
-+ int p;
-+ int q;
-+ int r;
-+ int s;
-+} v = { 1, 2, 3, 4 };
-+
-+struct z
-+{
-+ double x[4];
-+};
-+
-+struct z a = { 5.0, 6.0, 7.0, 8.0 };
-+struct z b = { 9.0, 10.0, 11.0, 12.0 };
-+
-+#include "abitest.h"
-+#else
-+ ARG(struct z, a, D0)
-+ ARG(struct z, b, D4)
-+ ARG(double, 0.5, STACK)
-+ ARG(int, 7, R0)
-+ LAST_ARG(struct y, v, STACK+8)
-+#endif
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/aapcs/vfp8.c
-@@ -0,0 +1,37 @@
-+/* Test AAPCS layout (VFP variant) */
-+
-+/* { dg-do run { target arm*-*-eabi* } } */
-+/* { dg-require-effective-target arm_hard_vfp_ok } */
-+/* { dg-require-effective-target arm32 } */
-+/* { dg-options "-O -mfpu=vfp -mfloat-abi=hard" } */
-+
-+#ifndef IN_FRAMEWORK
-+#define VFP
-+#define TESTFILE "vfp8.c"
-+
-+__complex__ x = 1.0+2.0i;
-+
-+struct y
-+{
-+ int p;
-+ int q;
-+ int r;
-+ int s;
-+} v = { 1, 2, 3, 4 };
-+
-+struct z
-+{
-+ double x[4];
-+};
-+
-+struct z a = { 5.0, 6.0, 7.0, 8.0 };
-+struct z b = { 9.0, 10.0, 11.0, 12.0 };
-+
-+#include "abitest.h"
-+#else
-+ ARG(int, 7, R0)
-+ ARG(struct y, v, R1)
-+ ARG(struct z, a, D0)
-+ ARG(struct z, b, D4)
-+ LAST_ARG(double, 0.5, STACK+8)
-+#endif
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/aapcs/vfp9.c
-@@ -0,0 +1,38 @@
-+/* Test AAPCS layout (VFP variant) */
-+
-+/* { dg-do run { target arm*-*-eabi* } } */
-+/* { dg-require-effective-target arm_hard_vfp_ok } */
-+/* { dg-require-effective-target arm32 } */
-+/* { dg-options "-O -mfpu=vfp -mfloat-abi=hard" } */
-+
-+#ifndef IN_FRAMEWORK
-+#define VFP
-+#define TESTFILE "vfp9.c"
-+
-+__complex__ x = 1.0+2.0i;
-+
-+struct y
-+{
-+ int p;
-+ int q;
-+ int r;
-+ int s;
-+} v = { 1, 2, 3, 4 };
-+
-+struct z
-+{
-+ double x[4];
-+};
-+
-+struct z a = { 5.0, 6.0, 7.0, 8.0 };
-+struct z b = { 9.0, 10.0, 11.0, 12.0 };
-+
-+#include "abitest.h"
-+#else
-+ /* A variadic function passes using the base ABI */
-+ ARG(int, 7, R0)
-+ DOTS
-+ ANON(struct z, a, R2)
-+ ANON(struct z, b, STACK+24)
-+ LAST_ANON(double, 0.5, STACK+56)
-+#endif
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/ctz.c
-@@ -0,0 +1,12 @@
-+/* { dg-do compile } */
-+/* { dg-require-effective-target arm32 } */
-+/* { dg-options "-O2 -march=armv6t2" } */
-+
-+unsigned int functest(unsigned int x)
-+{
-+ return __builtin_ctz(x);
-+}
-+
-+/* { dg-final { scan-assembler "rbit" } } */
-+/* { dg-final { scan-assembler "clz" } } */
-+/* { dg-final { scan-assembler-not "rsb" } } */
---- a/gcc/testsuite/gcc.target/arm/eabi1.c
-+++ b/gcc/testsuite/gcc.target/arm/eabi1.c
-@@ -30,43 +30,48 @@
- #include <stdlib.h>
- #include <math.h>
-
--#define decl_float(code, type) \
-- extern type __aeabi_ ## code ## add (type, type); \
-- extern type __aeabi_ ## code ## div (type, type); \
-- extern type __aeabi_ ## code ## mul (type, type); \
-- extern type __aeabi_ ## code ## neg (type); \
-- extern type __aeabi_ ## code ## rsub (type, type); \
-- extern type __aeabi_ ## code ## sub (type, type); \
-- extern int __aeabi_ ## code ## cmpeq (type, type); \
-- extern int __aeabi_ ## code ## cmplt (type, type); \
-- extern int __aeabi_ ## code ## cmple (type, type); \
-- extern int __aeabi_ ## code ## cmpge (type, type); \
-- extern int __aeabi_ ## code ## cmpgt (type, type); \
-- extern int __aeabi_ ## code ## cmpun (type, type); \
-- extern int __aeabi_ ## code ## 2iz (type); \
-- extern unsigned int __aeabi_ ## code ## 2uiz (type); \
-- extern long long __aeabi_ ## code ## 2lz (type); \
-- extern unsigned long long __aeabi_ ## code ## 2ulz (type); \
-- extern type __aeabi_i2 ## code (int); \
-- extern type __aeabi_ui2 ## code (int); \
-- extern type __aeabi_l2 ## code (long long); \
-- extern type __aeabi_ul2 ## code (unsigned long long); \
-- \
-- type code ## zero = 0.0; \
-- type code ## one = 1.0; \
-- type code ## two = 2.0; \
-- type code ## four = 4.0; \
-- type code ## minus_one = -1.0; \
-- type code ## minus_two = -2.0; \
-- type code ## minus_four = -4.0; \
-- type code ## epsilon = 1E-32; \
-- type code ## NaN = 0.0 / 0.0;
-+/* All these functions are defined to use the base ABI, so use the
-+ attribute to ensure the tests use the base ABI to call them even
-+ when the VFP ABI is otherwise in effect. */
-+#define PCS __attribute__((pcs("aapcs")))
-+
-+#define decl_float(code, type) \
-+ extern type __aeabi_ ## code ## add (type, type) PCS; \
-+ extern type __aeabi_ ## code ## div (type, type) PCS; \
-+ extern type __aeabi_ ## code ## mul (type, type) PCS; \
-+ extern type __aeabi_ ## code ## neg (type) PCS; \
-+ extern type __aeabi_ ## code ## rsub (type, type) PCS; \
-+ extern type __aeabi_ ## code ## sub (type, type) PCS; \
-+ extern int __aeabi_ ## code ## cmpeq (type, type) PCS; \
-+ extern int __aeabi_ ## code ## cmplt (type, type) PCS; \
-+ extern int __aeabi_ ## code ## cmple (type, type) PCS; \
-+ extern int __aeabi_ ## code ## cmpge (type, type) PCS; \
-+ extern int __aeabi_ ## code ## cmpgt (type, type) PCS; \
-+ extern int __aeabi_ ## code ## cmpun (type, type) PCS; \
-+ extern int __aeabi_ ## code ## 2iz (type) PCS; \
-+ extern unsigned int __aeabi_ ## code ## 2uiz (type) PCS; \
-+ extern long long __aeabi_ ## code ## 2lz (type) PCS; \
-+ extern unsigned long long __aeabi_ ## code ## 2ulz (type) PCS; \
-+ extern type __aeabi_i2 ## code (int) PCS; \
-+ extern type __aeabi_ui2 ## code (int) PCS; \
-+ extern type __aeabi_l2 ## code (long long) PCS; \
-+ extern type __aeabi_ul2 ## code (unsigned long long) PCS; \
-+ \
-+ type code ## zero = 0.0; \
-+ type code ## one = 1.0; \
-+ type code ## two = 2.0; \
-+ type code ## four = 4.0; \
-+ type code ## minus_one = -1.0; \
-+ type code ## minus_two = -2.0; \
-+ type code ## minus_four = -4.0; \
-+ type code ## epsilon = 1E-32; \
-+ type code ## NaN = 0.0 / 0.0;
-
- decl_float (d, double)
- decl_float (f, float)
-
--extern float __aeabi_d2f (double);
--extern double __aeabi_f2d (float);
-+extern float __aeabi_d2f (double) PCS;
-+extern double __aeabi_f2d (float) PCS;
- extern long long __aeabi_lmul (long long, long long);
- extern long long __aeabi_llsl (long long, int);
- extern long long __aeabi_llsr (long long, int);
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/fp16-builtins-1.c
-@@ -0,0 +1,92 @@
-+/* Test type-generic builtins with __fp16 arguments.
-+ Except as otherwise noted, they should behave exactly
-+ the same as those with float arguments. */
-+
-+/* { dg-do run } */
-+/* { dg-options "-mfp16-format=ieee -std=gnu99" } */
-+
-+#include <stdlib.h>
-+#include <math.h>
-+
-+volatile __fp16 h1, h2;
-+volatile float f1, f2;
-+
-+void
-+set1 (double x)
-+{
-+ h1 = x;
-+ f1 = h1;
-+}
-+
-+void
-+set2 (double x, double y)
-+{
-+ h1 = x;
-+ f1 = h1;
-+ h2 = y;
-+ f2 = h2;
-+}
-+
-+#define test1(p,x) \
-+ set1 (x); \
-+ hp = (p (h1) ? 1 : 0); \
-+ fp = (p (f1) ? 1 : 0); \
-+ if (hp ^ fp) abort ()
-+
-+#define test2(p,x,y) \
-+ set2 (x,y); \
-+ hp = (p (h1, h2) ? 1 : 0); \
-+ fp = (p (f1, f2) ? 1 : 0); \
-+ if (hp ^ fp) abort ()
-+
-+int
-+main (void)
-+{
-+ int hp, fp;
-+
-+ test1 (__builtin_isfinite, 17.0);
-+ test1 (__builtin_isfinite, INFINITY);
-+ test1 (__builtin_isinf, -0.5);
-+ test1 (__builtin_isinf, INFINITY);
-+ test1 (__builtin_isnan, 493.0);
-+ test1 (__builtin_isnan, NAN);
-+ test1 (__builtin_isnormal, 3.14159);
-+
-+ test2 (__builtin_isgreater, 5.0, 3.0);
-+ test2 (__builtin_isgreater, 3.0, 5.0);
-+ test2 (__builtin_isgreater, 73.5, 73.5);
-+ test2 (__builtin_isgreater, 1.0, NAN);
-+
-+ test2 (__builtin_isgreaterequal, 5.0, 3.0);
-+ test2 (__builtin_isgreaterequal, 3.0, 5.0);
-+ test2 (__builtin_isgreaterequal, 73.5, 73.5);
-+ test2 (__builtin_isgreaterequal, 1.0, NAN);
-+
-+ test2 (__builtin_isless, 5.0, 3.0);
-+ test2 (__builtin_isless, 3.0, 5.0);
-+ test2 (__builtin_isless, 73.5, 73.5);
-+ test2 (__builtin_isless, 1.0, NAN);
-+
-+ test2 (__builtin_islessequal, 5.0, 3.0);
-+ test2 (__builtin_islessequal, 3.0, 5.0);
-+ test2 (__builtin_islessequal, 73.5, 73.5);
-+ test2 (__builtin_islessequal, 1.0, NAN);
-+
-+ test2 (__builtin_islessgreater, 5.0, 3.0);
-+ test2 (__builtin_islessgreater, 3.0, 5.0);
-+ test2 (__builtin_islessgreater, 73.5, 73.5);
-+ test2 (__builtin_islessgreater, 1.0, NAN);
-+
-+ test2 (__builtin_isunordered, 5.0, 3.0);
-+ test2 (__builtin_isunordered, 3.0, 5.0);
-+ test2 (__builtin_isunordered, 73.5, 73.5);
-+ test2 (__builtin_isunordered, 1.0, NAN);
-+
-+ /* Test that __builtin_isnormal recognizes a denormalized __fp16 value,
-+ even if it's representable as a normalized float. */
-+ h1 = 5.96046E-8;
-+ if (__builtin_isnormal (h1))
-+ abort ();
-+
-+ return 0;
-+}
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/fp16-compile-alt-1.c
-@@ -0,0 +1,8 @@
-+/* { dg-do compile } */
-+/* { dg-options "-mfp16-format=alternative" } */
-+
-+__fp16 xx = 0.0;
-+
-+/* { dg-final { scan-assembler "\t.eabi_attribute 38, 2" } } */
-+/* { dg-final { scan-assembler "\t.size\txx, 2" } } */
-+/* { dg-final { scan-assembler "\t.space\t2" } } */
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/fp16-compile-alt-10.c
-@@ -0,0 +1,8 @@
-+/* { dg-do compile } */
-+/* { dg-options "-mfp16-format=alternative -pedantic -std=gnu99" } */
-+
-+#include <math.h>
-+
-+/* NaNs are not representable in the alternative format; we should get a
-+ diagnostic. */
-+__fp16 xx = NAN; /* { dg-warning "overflow" } */
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/fp16-compile-alt-11.c
-@@ -0,0 +1,13 @@
-+/* { dg-do compile } */
-+/* { dg-options "-mfp16-format=alternative -pedantic -std=gnu99" } */
-+
-+#include <math.h>
-+
-+/* Infinities are not representable in the alternative format;
-+ we should get a diagnostic, and the value set to the largest
-+ representable value. */
-+/* 0x7fff = 32767 */
-+__fp16 xx = INFINITY; /* { dg-warning "overflow" } */
-+
-+/* { dg-final { scan-assembler "\t.size\txx, 2" } } */
-+/* { dg-final { scan-assembler "\t.short\t32767" } } */
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/fp16-compile-alt-12.c
-@@ -0,0 +1,8 @@
-+/* { dg-do compile } */
-+/* { dg-options "-mfp16-format=alternative" } */
-+
-+float xx __attribute__((mode(HF))) = 0.0;
-+
-+/* { dg-final { scan-assembler "\t.eabi_attribute 38, 2" } } */
-+/* { dg-final { scan-assembler "\t.size\txx, 2" } } */
-+/* { dg-final { scan-assembler "\t.space\t2" } } */
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/fp16-compile-alt-2.c
-@@ -0,0 +1,9 @@
-+/* { dg-do compile } */
-+/* { dg-options "-mfp16-format=alternative" } */
-+
-+/* Encoding taken from: http://en.wikipedia.org/wiki/Half_precision */
-+/* 0x3c00 = 15360 */
-+__fp16 xx = 1.0;
-+
-+/* { dg-final { scan-assembler "\t.size\txx, 2" } } */
-+/* { dg-final { scan-assembler "\t.short\t15360" } } */
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/fp16-compile-alt-3.c
-@@ -0,0 +1,9 @@
-+/* { dg-do compile } */
-+/* { dg-options "-mfp16-format=alternative" } */
-+
-+/* Encoding taken from: http://en.wikipedia.org/wiki/Half_precision */
-+/* 0xc000 = 49152 */
-+__fp16 xx = -2.0;
-+
-+/* { dg-final { scan-assembler "\t.size\txx, 2" } } */
-+/* { dg-final { scan-assembler "\t.short\t49152" } } */
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/fp16-compile-alt-4.c
-@@ -0,0 +1,9 @@
-+/* { dg-do compile } */
-+/* { dg-options "-mfp16-format=alternative" } */
-+
-+/* Encoding taken from: http://en.wikipedia.org/wiki/Half_precision */
-+/* 0x7bff = 31743 */
-+__fp16 xx = 65504.0;
-+
-+/* { dg-final { scan-assembler "\t.size\txx, 2" } } */
-+/* { dg-final { scan-assembler "\t.short\t31743" } } */
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/fp16-compile-alt-5.c
-@@ -0,0 +1,9 @@
-+/* { dg-do compile } */
-+/* { dg-options "-mfp16-format=alternative" } */
-+
-+/* Encoding taken from: http://en.wikipedia.org/wiki/Half_precision */
-+/* 0x3555 = 13653 */
-+__fp16 xx = (1.0/3.0);
-+
-+/* { dg-final { scan-assembler "\t.size\txx, 2" } } */
-+/* { dg-final { scan-assembler "\t.short\t13653" } } */
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/fp16-compile-alt-6.c
-@@ -0,0 +1,10 @@
-+/* { dg-do compile } */
-+/* { dg-options "-mfp16-format=alternative" } */
-+
-+/* This number is the maximum value representable in the alternative
-+ encoding. */
-+/* 0x7fff = 32767 */
-+__fp16 xx = 131008.0;
-+
-+/* { dg-final { scan-assembler "\t.size\txx, 2" } } */
-+/* { dg-final { scan-assembler "\t.short\t32767" } } */
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/fp16-compile-alt-7.c
-@@ -0,0 +1,11 @@
-+/* { dg-do compile } */
-+/* { dg-options "-mfp16-format=alternative -pedantic" } */
-+
-+/* This number overflows the range of the alternative encoding. Since this
-+ encoding doesn't have infinities, we should get a pedantic warning,
-+ and the value should be set to the largest representable value. */
-+/* 0x7fff = 32767 */
-+__fp16 xx = 123456789.0; /* { dg-warning "overflow" } */
-+
-+/* { dg-final { scan-assembler "\t.size\txx, 2" } } */
-+/* { dg-final { scan-assembler "\t.short\t32767" } } */
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/fp16-compile-alt-8.c
-@@ -0,0 +1,10 @@
-+/* { dg-do compile } */
-+/* { dg-options "-mfp16-format=alternative" } */
-+
-+/* Encoding taken from: http://en.wikipedia.org/wiki/Half_precision */
-+/* This is the minimum normalized value. */
-+/* 0x0400 = 1024 */
-+__fp16 xx = 6.10352E-5;
-+
-+/* { dg-final { scan-assembler "\t.size\txx, 2" } } */
-+/* { dg-final { scan-assembler "\t.short\t1024" } } */
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/fp16-compile-alt-9.c
-@@ -0,0 +1,10 @@
-+/* { dg-do compile } */
-+/* { dg-options "-mfp16-format=alternative" } */
-+
-+/* Encoding taken from: http://en.wikipedia.org/wiki/Half_precision */
-+/* This is the minimum denormalized value. */
-+/* 0x0001 = 1 */
-+__fp16 xx = 5.96046E-8;
-+
-+/* { dg-final { scan-assembler "\t.size\txx, 2" } } */
-+/* { dg-final { scan-assembler "\t.short\t1" } } */
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/fp16-compile-exprtype.c
-@@ -0,0 +1,29 @@
-+/* Test that expressions involving __fp16 values have the right types. */
-+/* { dg-do compile } */
-+/* { dg-options "-mfp16-format=ieee" } */
-+
-+/* This produces a diagnostic if EXPR doesn't have type TYPE. */
-+#define CHECK(expr,type) \
-+ do { \
-+ type v; \
-+ __typeof (expr) *p = &v; \
-+ } while (0);
-+
-+volatile __fp16 f1;
-+volatile __fp16 f2;
-+
-+int
-+main (void)
-+{
-+ CHECK (f1, __fp16);
-+ CHECK (+f1, float);
-+ CHECK (-f1, float);
-+ CHECK (f1+f2, float);
-+ CHECK ((__fp16)(f1+f2), __fp16);
-+ CHECK ((__fp16)99.99, __fp16);
-+ CHECK ((f1+f2, f1), __fp16);
-+}
-+
-+
-+
-+
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/fp16-compile-ieee-1.c
-@@ -0,0 +1,8 @@
-+/* { dg-do compile } */
-+/* { dg-options "-mfp16-format=ieee" } */
-+
-+__fp16 xx = 0.0;
-+
-+/* { dg-final { scan-assembler "\t.eabi_attribute 38, 1" } } */
-+/* { dg-final { scan-assembler "\t.size\txx, 2" } } */
-+/* { dg-final { scan-assembler "\t.space\t2" } } */
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/fp16-compile-ieee-10.c
-@@ -0,0 +1,10 @@
-+/* { dg-do compile } */
-+/* { dg-options "-mfp16-format=ieee -std=gnu99" } */
-+
-+#include <math.h>
-+
-+/* 0x7e00 = 32256 */
-+__fp16 xx = NAN;
-+
-+/* { dg-final { scan-assembler "\t.size\txx, 2" } } */
-+/* { dg-final { scan-assembler "\t.short\t32256" } } */
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/fp16-compile-ieee-11.c
-@@ -0,0 +1,10 @@
-+/* { dg-do compile } */
-+/* { dg-options "-mfp16-format=ieee -std=gnu99" } */
-+
-+#include <math.h>
-+
-+/* 0x7c00 = 31744 */
-+__fp16 xx = INFINITY;
-+
-+/* { dg-final { scan-assembler "\t.size\txx, 2" } } */
-+/* { dg-final { scan-assembler "\t.short\t31744" } } */
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/fp16-compile-ieee-12.c
-@@ -0,0 +1,8 @@
-+/* { dg-do compile } */
-+/* { dg-options "-mfp16-format=ieee" } */
-+
-+float xx __attribute__((mode(HF))) = 0.0;
-+
-+/* { dg-final { scan-assembler "\t.eabi_attribute 38, 1" } } */
-+/* { dg-final { scan-assembler "\t.size\txx, 2" } } */
-+/* { dg-final { scan-assembler "\t.space\t2" } } */
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/fp16-compile-ieee-2.c
-@@ -0,0 +1,9 @@
-+/* { dg-do compile } */
-+/* { dg-options "-mfp16-format=ieee" } */
-+
-+/* Encoding taken from: http://en.wikipedia.org/wiki/Half_precision */
-+/* 0x3c00 = 15360 */
-+__fp16 xx = 1.0;
-+
-+/* { dg-final { scan-assembler "\t.size\txx, 2" } } */
-+/* { dg-final { scan-assembler "\t.short\t15360" } } */
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/fp16-compile-ieee-3.c
-@@ -0,0 +1,9 @@
-+/* { dg-do compile } */
-+/* { dg-options "-mfp16-format=ieee" } */
-+
-+/* Encoding taken from: http://en.wikipedia.org/wiki/Half_precision */
-+/* 0xc000 = 49152 */
-+__fp16 xx = -2.0;
-+
-+/* { dg-final { scan-assembler "\t.size\txx, 2" } } */
-+/* { dg-final { scan-assembler "\t.short\t49152" } } */
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/fp16-compile-ieee-4.c
-@@ -0,0 +1,9 @@
-+/* { dg-do compile } */
-+/* { dg-options "-mfp16-format=ieee" } */
-+
-+/* Encoding taken from: http://en.wikipedia.org/wiki/Half_precision */
-+/* 0x7bff = 31743 */
-+__fp16 xx = 65504.0;
-+
-+/* { dg-final { scan-assembler "\t.size\txx, 2" } } */
-+/* { dg-final { scan-assembler "\t.short\t31743" } } */
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/fp16-compile-ieee-5.c
-@@ -0,0 +1,9 @@
-+/* { dg-do compile } */
-+/* { dg-options "-mfp16-format=ieee" } */
-+
-+/* Encoding taken from: http://en.wikipedia.org/wiki/Half_precision */
-+/* 0x3555 = 13653 */
-+__fp16 xx = (1.0/3.0);
-+
-+/* { dg-final { scan-assembler "\t.size\txx, 2" } } */
-+/* { dg-final { scan-assembler "\t.short\t13653" } } */
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/fp16-compile-ieee-6.c
-@@ -0,0 +1,10 @@
-+/* { dg-do compile } */
-+/* { dg-options "-mfp16-format=ieee" } */
-+
-+/* Encoding taken from: http://en.wikipedia.org/wiki/Half_precision */
-+/* This number is too big and is represented as infinity. */
-+/* 0x7c00 = 31744 */
-+__fp16 xx = 131008.0;
-+
-+/* { dg-final { scan-assembler "\t.size\txx, 2" } } */
-+/* { dg-final { scan-assembler "\t.short\t31744" } } */
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/fp16-compile-ieee-7.c
-@@ -0,0 +1,11 @@
-+/* { dg-do compile } */
-+/* { dg-options "-mfp16-format=ieee -pedantic" } */
-+
-+/* Encoding taken from: http://en.wikipedia.org/wiki/Half_precision */
-+/* This number is too big and is represented as infinity. */
-+/* We should *not* get an overflow warning here. */
-+/* 0x7c00 = 31744 */
-+__fp16 xx = 123456789.0;
-+
-+/* { dg-final { scan-assembler "\t.size\txx, 2" } } */
-+/* { dg-final { scan-assembler "\t.short\t31744" } } */
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/fp16-compile-ieee-8.c
-@@ -0,0 +1,10 @@
-+/* { dg-do compile } */
-+/* { dg-options "-mfp16-format=ieee" } */
-+
-+/* Encoding taken from: http://en.wikipedia.org/wiki/Half_precision */
-+/* This is the minimum normalized value. */
-+/* 0x0400 = 1024 */
-+__fp16 xx = 6.10352E-5;
-+
-+/* { dg-final { scan-assembler "\t.size\txx, 2" } } */
-+/* { dg-final { scan-assembler "\t.short\t1024" } } */
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/fp16-compile-ieee-9.c
-@@ -0,0 +1,10 @@
-+/* { dg-do compile } */
-+/* { dg-options "-mfp16-format=ieee" } */
-+
-+/* Encoding taken from: http://en.wikipedia.org/wiki/Half_precision */
-+/* This is the minimum denormalized value. */
-+/* 0x0001 = 1 */
-+__fp16 xx = 5.96046E-8;
-+
-+/* { dg-final { scan-assembler "\t.size\txx, 2" } } */
-+/* { dg-final { scan-assembler "\t.short\t1" } } */
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/fp16-compile-none-1.c
-@@ -0,0 +1,6 @@
-+/* { dg-do compile } */
-+/* { dg-options "-mfp16-format=none" } */
-+
-+/* __fp16 type name is not recognized unless you explicitly enable it
-+ by selecting -mfp16-format=ieee or -mfp16-format=alternative. */
-+__fp16 xx = 0.0; /* { dg-error "expected" } */
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/fp16-compile-none-2.c
-@@ -0,0 +1,7 @@
-+/* { dg-do compile } */
-+/* { dg-options "-mfp16-format=none" } */
-+
-+/* mode(HF) attributes are not recognized unless you explicitly enable
-+ half-precision floating point by selecting -mfp16-format=ieee or
-+ -mfp16-format=alternative. */
-+float xx __attribute__((mode(HF))) = 0.0; /* { dg-error "HF" } */
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/fp16-compile-vcvt.c
-@@ -0,0 +1,20 @@
-+/* { dg-do compile } */
-+/* { dg-require-effective-target arm_neon_fp16_ok } */
-+/* { dg-options "-mfp16-format=ieee" } */
-+/* { dg-add-options arm_neon_fp16 } */
-+
-+/* Test generation of VFP __fp16 instructions. */
-+
-+__fp16 h1 = 0.0;
-+__fp16 h2 = 1234.0;
-+float f1 = 2.0;
-+float f2 = -999.9;
-+
-+void f (void)
-+{
-+ h1 = f1;
-+ f2 = h2;
-+}
-+
-+/* { dg-final { scan-assembler "\tvcvtb.f32.f16" } } */
-+/* { dg-final { scan-assembler "\tvcvtb.f16.f32" } } */
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/fp16-param-1.c
-@@ -0,0 +1,10 @@
-+/* { dg-do compile } */
-+/* { dg-options "-mfp16-format=ieee" } */
-+
-+/* Functions cannot have parameters of type __fp16. */
-+extern void f (__fp16); /* { dg-error "parameters cannot have __fp16 type" } */
-+extern void (*pf) (__fp16); /* { dg-error "parameters cannot have __fp16 type" } */
-+
-+/* These should be OK. */
-+extern void g (__fp16 *);
-+extern void (*pg) (__fp16 *);
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/fp16-return-1.c
-@@ -0,0 +1,10 @@
-+/* { dg-do compile } */
-+/* { dg-options "-mfp16-format=ieee" } */
-+
-+/* Functions cannot return type __fp16. */
-+extern __fp16 f (void); /* { dg-error "cannot return __fp16" } */
-+extern __fp16 (*pf) (void); /* { dg-error "cannot return __fp16" } */
-+
-+/* These should be OK. */
-+extern __fp16 *g (void);
-+extern __fp16 *(*pg) (void);
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/fp16-rounding-alt-1.c
-@@ -0,0 +1,47 @@
-+/* Test intermediate rounding of double to float and then to __fp16, using
-+ an example of a number that would round differently if it went directly
-+ from double to __fp16. */
-+
-+/* { dg-do run } */
-+/* { dg-options "-mfp16-format=alternative" } */
-+
-+#include <stdlib.h>
-+
-+/* The original double value. */
-+#define ORIG 0x1.0020008p0
-+
-+/* The expected (double)((__fp16)((float)ORIG)) value. */
-+#define ROUNDED 0x1.0000000p0
-+
-+typedef union u {
-+ __fp16 f;
-+ unsigned short h;
-+} ufh;
-+
-+ufh s = { ORIG };
-+ufh r = { ROUNDED };
-+
-+double d = ORIG;
-+
-+int
-+main (void)
-+{
-+ ufh x;
-+
-+ /* Test that the rounding is correct for static initializers. */
-+ if (s.h != r.h)
-+ abort ();
-+
-+ /* Test that the rounding is correct for a casted constant expression
-+ not in a static initializer. */
-+ x.f = (__fp16)ORIG;
-+ if (x.h != r.h)
-+ abort ();
-+
-+ /* Test that the rounding is correct for a runtime conversion. */
-+ x.f = (__fp16)d;
-+ if (x.h != r.h)
-+ abort ();
-+
-+ return 0;
-+}
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/fp16-rounding-ieee-1.c
-@@ -0,0 +1,47 @@
-+/* Test intermediate rounding of double to float and then to __fp16, using
-+ an example of a number that would round differently if it went directly
-+ from double to __fp16. */
-+
-+/* { dg-do run } */
-+/* { dg-options "-mfp16-format=ieee" } */
-+
-+#include <stdlib.h>
-+
-+/* The original double value. */
-+#define ORIG 0x1.0020008p0
-+
-+/* The expected (double)((__fp16)((float)ORIG)) value. */
-+#define ROUNDED 0x1.0000000p0
-+
-+typedef union u {
-+ __fp16 f;
-+ unsigned short h;
-+} ufh;
-+
-+ufh s = { ORIG };
-+ufh r = { ROUNDED };
-+
-+double d = ORIG;
-+
-+int
-+main (void)
-+{
-+ ufh x;
-+
-+ /* Test that the rounding is correct for static initializers. */
-+ if (s.h != r.h)
-+ abort ();
-+
-+ /* Test that the rounding is correct for a casted constant expression
-+ not in a static initializer. */
-+ x.f = (__fp16)ORIG;
-+ if (x.h != r.h)
-+ abort ();
-+
-+ /* Test that the rounding is correct for a runtime conversion. */
-+ x.f = (__fp16)d;
-+ if (x.h != r.h)
-+ abort ();
-+
-+ return 0;
-+}
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/fp16-unprototyped-1.c
-@@ -0,0 +1,21 @@
-+/* Test promotion of __fp16 to double as arguments to unprototyped
-+ function in another compilation unit. */
-+
-+/* { dg-do run } */
-+/* { dg-options "-mfp16-format=ieee" } */
-+/* { dg-additional-sources "fp16-unprototyped-2.c" } */
-+
-+#include <stdlib.h>
-+
-+extern int f ();
-+
-+static __fp16 x = 42.0;
-+static __fp16 y = -42.0;
-+
-+int
-+main (void)
-+{
-+ if (!f (x, y))
-+ abort ();
-+ return 0;
-+}
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/fp16-unprototyped-2.c
-@@ -0,0 +1,12 @@
-+/* { dg-do compile } */
-+/* { dg-options "-mfp16-format=ieee" } */
-+
-+extern int f ();
-+
-+int
-+f (double xx, double yy)
-+{
-+ if (xx == 42.0 && yy == -42.0)
-+ return 1;
-+ return 0;
-+}
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/fp16-variadic-1.c
-@@ -0,0 +1,37 @@
-+/* Test promotion of __fp16 to double as arguments to variadic function. */
-+
-+/* { dg-do run } */
-+/* { dg-options "-mfp16-format=ieee" } */
-+
-+#include <stdlib.h>
-+#include <stdarg.h>
-+
-+extern int f (int n, ...);
-+
-+int
-+f (int n, ...)
-+{
-+ if (n == 2)
-+ {
-+ double xx, yy;
-+ va_list ap;
-+ va_start (ap, n);
-+ xx = va_arg (ap, double);
-+ yy = va_arg (ap, double);
-+ va_end (ap);
-+ if (xx == 42.0 && yy == -42.0)
-+ return 1;
-+ }
-+ return 0;
-+}
-+
-+static __fp16 x = 42.0;
-+static __fp16 y = -42.0;
-+
-+int
-+main (void)
-+{
-+ if (!f (2, x, y))
-+ abort ();
-+ return 0;
-+}
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/frame-pointer-1.c
-@@ -0,0 +1,42 @@
-+/* Check local register variables using a register conventionally
-+ used as the frame pointer aren't clobbered under high register pressure. */
-+/* { dg-do run } */
-+/* { dg-options "-Os -mthumb -fomit-frame-pointer" } */
-+
-+#include <stdlib.h>
-+
-+int global=5;
-+
-+void __attribute__((noinline)) foo(int p1, int p2, int p3, int p4)
-+{
-+ if (global != 5 || p1 != 1 || p2 != 2 || p3 != 3 || p4 != 4)
-+ abort();
-+}
-+
-+int __attribute__((noinline)) test(int a, int b, int c, int d)
-+{
-+ register unsigned long r __asm__("r7") = 0xdeadbeef;
-+ int e;
-+
-+ /* ABCD are live after the call which should be enough
-+ to cause r7 to be used if it weren't for the register variable. */
-+ foo(a,b,c,d);
-+
-+ e = 0;
-+ __asm__ __volatile__ ("mov %0, %2"
-+ : "=r" (e)
-+ : "0" (e), "r" (r));
-+
-+ global = a+b+c+d;
-+
-+ return e;
-+}
-+
-+int main()
-+{
-+ if (test(1, 2, 3, 4) != 0xdeadbeef)
-+ abort();
-+ if (global != 10)
-+ abort();
-+ return 0;
-+}
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/janus-2cc-shift-1.c
-@@ -0,0 +1,17 @@
-+/* Check that a nop is inserted after a shift taking a register operand. */
-+/* { dg-do compile } */
-+/* { dg-options "-mfix-janus-2cc" } */
-+/* { dg-require-effective-target arm_not_thumb } */
-+int foo(int x)
-+{
-+ int y;
-+ int z;
-+
-+ y = x << 4;
-+ z = y << x;
-+
-+ return y+z;
-+}
-+/* { dg-final { scan-assembler "\tmov\tr\[0-9], r\[0-9], asl r\[0-9]\n\tnop\n" } } */
-+/* { dg-final { scan-assembler-not "\tmov\tr\[0-9], r\[0-9], asl #4\n\tnop\n" } } */
-+
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/janus-2cc-shift-2.c
-@@ -0,0 +1,17 @@
-+/* Check that a nop is inserted after a shift taking a register operand. */
-+/* { dg-do compile } */
-+/* { dg-options "-mfix-janus-2cc -mthumb" } */
-+/* { dg-require-effective-target arm_thumb1_ok } */
-+int foo(int x)
-+{
-+ int y;
-+ int z;
-+
-+ y = x << 4;
-+ z = y << x;
-+
-+ return y+z;
-+}
-+/* { dg-final { scan-assembler "\tlsl\tr\[0-9], r\[0-9], r\[0-9]\n\tnop\n" } } */
-+/* { dg-final { scan-assembler-not "\tlsl\tr\[0-9], r\[0-9], #4\n\tnop\n" } } */
-+
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/naked-3.c
-@@ -0,0 +1,15 @@
-+/* { dg-do compile } */
-+/* { dg-options "-O2 -Wall" } */
-+/* Check that we do not get warnings about missing return statements
-+ or bogus looking noreturn functions. */
-+int __attribute__((naked))
-+foo(void)
-+{
-+ __asm__ volatile ("mov r0, #1\r\nbx lr\n");
-+}
-+
-+int __attribute__((naked,noreturn))
-+bar(void)
-+{
-+ __asm__ volatile ("frob r0\n");
-+}
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/neon-modes-1.c
-@@ -0,0 +1,14 @@
-+/* { dg-do compile } */
-+/* { dg-require-effective-target arm_neon_ok } */
-+/* { dg-options "-O1" } */
-+/* { dg-add-options arm_neon } */
-+
-+#include <arm_neon.h>
-+
-+void neon_internal_error(int *dst, int *src)
-+{
-+ uint16x8x4_t sval;
-+
-+ sval = vld4q_u16((void *)src);
-+ vst4q_u16((void *)dst,sval);
-+}
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/neon-vmla-1.c
-@@ -0,0 +1,11 @@
-+/* { dg-require-effective-target arm_neon_hw } */
-+/* { dg-options "-O2 -ftree-vectorize" } */
-+/* { dg-add-options arm_neon } */
-+/* { dg-final { scan-assembler "vmla\\.f32" } } */
-+
-+/* Verify that VMLA is used. */
-+void f1(int n, float a, float x[], float y[]) {
-+ int i;
-+ for (i = 0; i < n; ++i)
-+ y[i] = a * x[i] + y[i];
-+}
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/neon-vmls-1.c
-@@ -0,0 +1,11 @@
-+/* { dg-require-effective-target arm_neon_hw } */
-+/* { dg-options "-O2 -ftree-vectorize" } */
-+/* { dg-add-options arm_neon } */
-+/* { dg-final { scan-assembler "vmls\\.f32" } } */
-+
-+/* Verify that VMLS is used. */
-+void f1(int n, float a, float x[], float y[]) {
-+ int i;
-+ for (i = 0; i < n; ++i)
-+ y[i] = y[i] - a * x[i];
-+}
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/neon/vfp-shift-a2t2.c
-@@ -0,0 +1,27 @@
-+/* Check that NEON vector shifts support immediate values == size. /*
-+
-+/* { dg-do compile } */
-+/* { dg-require-effective-target arm_neon_ok } */
-+/* { dg-add-options arm_neon } */
-+
-+#include <arm_neon.h>
-+
-+uint16x8_t test_vshll_n_u8 (uint8x8_t a)
-+{
-+ return vshll_n_u8(a, 8);
-+}
-+
-+uint32x4_t test_vshll_n_u16 (uint16x4_t a)
-+{
-+ return vshll_n_u16(a, 16);
-+}
-+
-+uint64x2_t test_vshll_n_u32 (uint32x2_t a)
-+{
-+ return vshll_n_u32(a, 32);
-+}
-+
-+/* { dg-final { scan-assembler "vshll\.u16\[ \]+\[qQ\]\[0-9\]+, \[dD\]\[0-9\]+, #\[0-9\]+!?\(\[ \]+@\[a-zA-Z0-9 \]+\)?\n" } } */
-+/* { dg-final { scan-assembler "vshll\.u32\[ \]+\[qQ\]\[0-9\]+, \[dD\]\[0-9\]+, #\[0-9\]+!?\(\[ \]+@\[a-zA-Z0-9 \]+\)?\n" } } */
-+/* { dg-final { scan-assembler "vshll\.u8\[ \]+\[qQ\]\[0-9\]+, \[dD\]\[0-9\]+, #\[0-9\]+!?\(\[ \]+@\[a-zA-Z0-9 \]+\)?\n" } } */
-+/* { dg-final { cleanup-saved-temps } } */
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/pr40482.c
-@@ -0,0 +1,7 @@
-+/* { dg-options "-mthumb -Os" } */
-+/* { dg-final { scan-assembler-not "ldr" } } */
-+
-+unsigned int foo (unsigned int i )
-+{
-+ return i | 0xff000000;
-+}
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/thumb2-mul-space-2.c
-@@ -0,0 +1,15 @@
-+/* In Thumb-2 mode, when optimizing for size, generate a "muls"
-+ instruction and use the resulting condition flags rather than a
-+ separate compare instruction. */
-+/* { dg-options "-mthumb -Os" } */
-+/* { dg-require-effective-target arm_thumb2_ok } */
-+/* { dg-final { scan-assembler "muls" } } */
-+/* { dg-final { scan-assembler-not "cmp" } } */
-+
-+int x;
-+
-+void f(int i, int j)
-+{
-+ if (i * j < 0)
-+ x = 1;
-+}
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/thumb2-mul-space-3.c
-@@ -0,0 +1,17 @@
-+/* In Thumb-2 mode, when optimizing for size, generate a "muls"
-+ instruction and use the resulting condition flags rather than a
-+ separate compare instruction. */
-+/* { dg-options "-mthumb -Os" } */
-+/* { dg-require-effective-target arm_thumb2_ok } */
-+/* { dg-final { scan-assembler "muls" } } */
-+/* { dg-final { scan-assembler-not "cmp" } } */
-+
-+int x;
-+
-+int f(int i, int j)
-+{
-+ i = i * j;
-+ if (i < 0)
-+ x = 1;
-+ return i;
-+}
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/thumb2-mul-space.c
-@@ -0,0 +1,10 @@
-+/* Use 16-bit multiply instruction in Thumb-2 mode when optimizing for
-+ size. */
-+/* { dg-options "-mthumb -Os" } */
-+/* { dg-require-effective-target arm_thumb2_ok } */
-+/* { dg-final { scan-assembler "muls" } } */
-+
-+int f(int i, int j)
-+{
-+ return i * j;
-+}
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/thumb2-mul-speed.c
-@@ -0,0 +1,27 @@
-+/* Do not use 16-bit multiply instructions in Thumb-2 mode when
-+ optimizing for speed. */
-+/* { dg-options "-mthumb -O2" } */
-+/* { dg-require-effective-target arm_thumb2_ok } */
-+/* { dg-final { scan-assembler-not "muls" } } */
-+
-+int f(int i, int j)
-+{
-+ return i * j;
-+}
-+
-+int x;
-+
-+void g(int i, int j)
-+{
-+ if (i * j < 0)
-+ x = 1;
-+}
-+
-+int h(int i, int j)
-+{
-+ i = i * j;
-+ if (i < 0)
-+ x = 1;
-+ return i;
-+}
-+
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/vfp-ldmdbd.c
-@@ -0,0 +1,15 @@
-+/* { dg-do compile } */
-+/* { dg-require-effective-target arm_vfp_ok } */
-+/* { dg-options "-O2 -mfpu=vfp -mfloat-abi=softfp" } */
-+
-+extern void bar (double);
-+
-+void
-+foo (double *p, double a, int n)
-+{
-+ do
-+ bar (*--p + a);
-+ while (n--);
-+}
-+
-+/* { dg-final { scan-assembler "fldmdbd" } } */
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/vfp-ldmdbs.c
-@@ -0,0 +1,15 @@
-+/* { dg-do compile } */
-+/* { dg-require-effective-target arm_vfp_ok } */
-+/* { dg-options "-O2 -mfpu=vfp -mfloat-abi=softfp" } */
-+
-+extern void baz (float);
-+
-+void
-+foo (float *p, float a, int n)
-+{
-+ do
-+ bar (*--p + a);
-+ while (n--);
-+}
-+
-+/* { dg-final { scan-assembler "fldmdbs" } } */
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/vfp-ldmiad.c
-@@ -0,0 +1,15 @@
-+/* { dg-do compile } */
-+/* { dg-require-effective-target arm_vfp_ok } */
-+/* { dg-options "-O2 -mfpu=vfp -mfloat-abi=softfp" } */
-+
-+extern void bar (double);
-+
-+void
-+foo (double *p, double a, int n)
-+{
-+ do
-+ bar (*p++ + a);
-+ while (n--);
-+}
-+
-+/* { dg-final { scan-assembler "fldmiad" } } */
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/vfp-ldmias.c
-@@ -0,0 +1,15 @@
-+/* { dg-do compile } */
-+/* { dg-require-effective-target arm_vfp_ok } */
-+/* { dg-options "-O2 -mfpu=vfp -mfloat-abi=softfp" } */
-+
-+extern void baz (float);
-+
-+void
-+foo (float *p, float a, int n)
-+{
-+ do
-+ bar (*p++ + a);
-+ while (n--);
-+}
-+
-+/* { dg-final { scan-assembler "fldmias" } } */
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/vfp-stmdbd.c
-@@ -0,0 +1,14 @@
-+/* { dg-do compile } */
-+/* { dg-require-effective-target arm_vfp_ok } */
-+/* { dg-options "-O2 -mfpu=vfp -mfloat-abi=softfp" } */
-+
-+void
-+foo (double *p, double a, double b, int n)
-+{
-+ double c = a + b;
-+ do
-+ *--p = c;
-+ while (n--);
-+}
-+
-+/* { dg-final { scan-assembler "fstmdbd" } } */
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/vfp-stmdbs.c
-@@ -0,0 +1,14 @@
-+/* { dg-do compile } */
-+/* { dg-require-effective-target arm_vfp_ok } */
-+/* { dg-options "-O2 -mfpu=vfp -mfloat-abi=softfp" } */
-+
-+void
-+foo (float *p, float a, float b, int n)
-+{
-+ float c = a + b;
-+ do
-+ *--p = c;
-+ while (n--);
-+}
-+
-+/* { dg-final { scan-assembler "fstmdbs" } } */
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/vfp-stmiad.c
-@@ -0,0 +1,14 @@
-+/* { dg-do compile } */
-+/* { dg-require-effective-target arm_vfp_ok } */
-+/* { dg-options "-O2 -mfpu=vfp -mfloat-abi=softfp" } */
-+
-+void
-+foo (double *p, double a, double b, int n)
-+{
-+ double c = a + b;
-+ do
-+ *p++ = c;
-+ while (n--);
-+}
-+
-+/* { dg-final { scan-assembler "fstmiad" } } */
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/arm/vfp-stmias.c
-@@ -0,0 +1,14 @@
-+/* { dg-do compile } */
-+/* { dg-require-effective-target arm_vfp_ok } */
-+/* { dg-options "-O2 -mfpu=vfp -mfloat-abi=softfp" } */
-+
-+void
-+foo (float *p, float a, float b, int n)
-+{
-+ float c = a + b;
-+ do
-+ *p++ = c;
-+ while (n--);
-+}
-+
-+/* { dg-final { scan-assembler "fstmias" } } */
---- a/gcc/testsuite/gcc.target/i386/387-1.c
-+++ b/gcc/testsuite/gcc.target/i386/387-1.c
-@@ -1,6 +1,7 @@
- /* Verify that -mno-fancy-math-387 works. */
- /* { dg-do compile } */
- /* { dg-require-effective-target ilp32 } */
-+/* { dg-skip-if "" { i?86-*-* x86_64-*-* } { "-march=*" } { "-march=i386" } } */
- /* { dg-options "-O -ffast-math -mfpmath=387 -mno-fancy-math-387 -march=i386" } */
- /* { dg-final { scan-assembler "call\t(.*)sin" } } */
- /* { dg-final { scan-assembler "call\t(.*)cos" } } */
---- a/gcc/testsuite/gcc.target/i386/387-5.c
-+++ b/gcc/testsuite/gcc.target/i386/387-5.c
-@@ -1,6 +1,7 @@
- /* Verify that -mno-fancy-math-387 works. */
- /* { dg-do compile } */
- /* { dg-require-effective-target ilp32 } */
-+/* { dg-skip-if "" { i?86-*-* x86_64-*-* } { "-march=*" } { "-march=i386" } } */
- /* { dg-options "-O -ffast-math -mfpmath=387 -mno-fancy-math-387 -march=i386" } */
- /* { dg-final { scan-assembler "call\t(.*)atan" } } */
- /* { dg-final { scan-assembler "call\t(.*)log1p" } } */
---- a/gcc/testsuite/gcc.target/i386/cmov7.c
-+++ b/gcc/testsuite/gcc.target/i386/cmov7.c
-@@ -1,6 +1,7 @@
- /* PR middle-end/33187 */
-
- /* { dg-do compile } */
-+/* { dg-skip-if "" { i?86-*-* x86_64-*-* } { "-march=*" } { "-march=k8" } } */
- /* { dg-options "-O2 -ffast-math -march=k8 -mbranch-cost=5 -mfpmath=387" } */
- /* { dg-final { scan-assembler "fcmov" } } */
-
---- a/gcc/testsuite/gcc.target/i386/funcspec-1.c
-+++ b/gcc/testsuite/gcc.target/i386/funcspec-1.c
-@@ -3,6 +3,7 @@
- for a function that doesn't use attribute((option)). */
- /* { dg-do compile } */
- /* { dg-require-effective-target ilp32 } */
-+/* { dg-skip-if "" { i?86-*-* x86_64-*-* } { "-march=*" } { "-march=i386" } } */
- /* { dg-options "-O3 -ftree-vectorize -march=i386" } */
- /* { dg-final { scan-assembler "addps\[ \t\]" } } */
- /* { dg-final { scan-assembler "fsubs\[ \t\]" } } */
---- a/gcc/testsuite/gcc.target/i386/funcspec-8.c
-+++ b/gcc/testsuite/gcc.target/i386/funcspec-8.c
-@@ -1,6 +1,7 @@
- /* Test whether using target specific options, we can use the x86 builtin
- functions in functions with the appropriate function specific options. */
- /* { dg-do compile } */
-+/* { dg-skip-if "" { i?86-*-* x86_64-*-* } { "-march=*" } { "-march=k8" } } */
- /* { dg-options "-O2 -march=k8 -mfpmath=sse" } */
-
- typedef float __m128 __attribute__ ((__vector_size__ (16), __may_alias__));
---- a/gcc/testsuite/gcc.target/i386/gcc-have-sync-compare-and-swap-1.c
-+++ b/gcc/testsuite/gcc.target/i386/gcc-have-sync-compare-and-swap-1.c
-@@ -1,5 +1,6 @@
- /* { dg-do preprocess } */
- /* { dg-require-effective-target ilp32 } */
-+/* { dg-skip-if "" { i?86-*-* x86_64-*-* } { "-march=*" } { "-march=i386" } } */
- /* { dg-options "-march=i386" } */
-
- #ifdef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1
---- a/gcc/testsuite/gcc.target/i386/gcc-have-sync-compare-and-swap-2.c
-+++ b/gcc/testsuite/gcc.target/i386/gcc-have-sync-compare-and-swap-2.c
-@@ -1,5 +1,6 @@
- /* { dg-do preprocess } */
- /* { dg-require-effective-target ilp32 } */
-+/* { dg-skip-if "" { i?86-*-* x86_64-*-* } { "-march=*" } { "-march=i486" } } */
- /* { dg-options "-march=i486" } */
-
- #ifndef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1
---- a/gcc/testsuite/gcc.target/i386/isa-10.c
-+++ b/gcc/testsuite/gcc.target/i386/isa-10.c
-@@ -1,4 +1,5 @@
- /* { dg-do run } */
-+/* { dg-skip-if "" { i?86-*-* x86_64-*-* } { "-march=*" } { "-march=x86-64" } } */
- /* { dg-options "-march=x86-64 -msse5 -mno-sse4" } */
-
- extern void abort (void);
---- a/gcc/testsuite/gcc.target/i386/isa-6.c
-+++ b/gcc/testsuite/gcc.target/i386/isa-6.c
-@@ -1,4 +1,5 @@
- /* { dg-do run } */
-+/* { dg-skip-if "" { i?86-*-* x86_64-*-* } { "-march=*" } { "-march=amdfam10" } } */
- /* { dg-options "-march=amdfam10 -mno-sse4" } */
-
- extern void abort (void);
---- a/gcc/testsuite/gcc.target/i386/isa-7.c
-+++ b/gcc/testsuite/gcc.target/i386/isa-7.c
-@@ -1,4 +1,5 @@
- /* { dg-do run } */
-+/* { dg-skip-if "" { i?86-*-* x86_64-*-* } { "-march=*" } { "-march=amdfam10" } } */
- /* { dg-options "-march=amdfam10 -msse5 -mno-sse4" } */
-
- extern void abort (void);
---- a/gcc/testsuite/gcc.target/i386/isa-8.c
-+++ b/gcc/testsuite/gcc.target/i386/isa-8.c
-@@ -1,4 +1,5 @@
- /* { dg-do run } */
-+/* { dg-skip-if "" { i?86-*-* x86_64-*-* } { "-march=*" } { "-march=amdfam10" } } */
- /* { dg-options "-march=amdfam10 -msse5 -mno-sse4a" } */
-
- extern void abort (void);
---- a/gcc/testsuite/gcc.target/i386/isa-9.c
-+++ b/gcc/testsuite/gcc.target/i386/isa-9.c
-@@ -1,4 +1,5 @@
- /* { dg-do run } */
-+/* { dg-skip-if "" { i?86-*-* x86_64-*-* } { "-march=*" } { "-march=amdfam10" } } */
- /* { dg-options "-march=amdfam10 -mno-sse5" } */
-
- extern void abort (void);
---- a/gcc/testsuite/gcc.target/i386/lea.c
-+++ b/gcc/testsuite/gcc.target/i386/lea.c
-@@ -1,5 +1,6 @@
- /* { dg-do compile } */
- /* { dg-require-effective-target ilp32 } */
-+/* { dg-skip-if "" { i?86-*-* x86_64-*-* } { "-march=*" } { "-march=pentiumpro" } } */
- /* { dg-options "-O2 -march=pentiumpro" } */
- /* { dg-final { scan-assembler "leal" } } */
- typedef struct {
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/i386/movbe-1.c
-@@ -0,0 +1,18 @@
-+/* { dg-do compile } */
-+/* { dg-options "-O2 -mmovbe" } */
-+
-+extern int x;
-+
-+void
-+foo (int i)
-+{
-+ x = __builtin_bswap32 (i);
-+}
-+
-+int
-+bar ()
-+{
-+ return __builtin_bswap32 (x);
-+}
-+
-+/* { dg-final { scan-assembler-times "movbe\[ \t\]" 2 } } */
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/i386/movbe-2.c
-@@ -0,0 +1,19 @@
-+/* { dg-do compile } */
-+/* { dg-options "-O2 -mmovbe" } */
-+
-+extern long long x;
-+
-+void
-+foo (long long i)
-+{
-+ x = __builtin_bswap64 (i);
-+}
-+
-+long long
-+bar ()
-+{
-+ return __builtin_bswap64 (x);
-+}
-+
-+/* { dg-final { scan-assembler-times "movbe\[ \t\]" 4 { target ilp32 } } } */
-+/* { dg-final { scan-assembler-times "movbe\[ \t\]" 2 { target lp64 } } } */
---- a/gcc/testsuite/gcc.target/i386/pentium4-not-mull.c
-+++ b/gcc/testsuite/gcc.target/i386/pentium4-not-mull.c
-@@ -1,5 +1,6 @@
- /* { dg-do compile } */
- /* { dg-require-effective-target ilp32 } */
-+/* { dg-skip-if "" { i?86-*-* x86_64-*-* } { "-march=*" } { "-march=pentium4" } } */
- /* { dg-options "-O2 -march=pentium4" } */
- /* { dg-final { scan-assembler-not "imull" } } */
-
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/i386/pr37216.c
-@@ -0,0 +1,17 @@
-+/* { dg-do run } */
-+/* { dg-options "-O3 -msse2" } */
-+/* { dg-options "-O3 -msse2 -mpe-aligned-commons" { target pe_aligned_commons } } */
-+
-+#include "sse2-check.h"
-+
-+int iarr[64];
-+int iint = 0;
-+
-+void
-+sse2_test (void)
-+{
-+ int i;
-+
-+ for (i = 0; i < 64; i++)
-+ iarr[i] = -2;
-+}
---- a/gcc/testsuite/gcc.target/i386/pr37843-1.c
-+++ b/gcc/testsuite/gcc.target/i386/pr37843-1.c
-@@ -2,8 +2,8 @@
- /* { dg-do compile { target nonpic } } */
- /* { dg-options "-O2 -mpreferred-stack-boundary=6 -mincoming-stack-boundary=5" } */
- /* { dg-final { scan-assembler "and\[lq\]?\[\\t \]*\\$-64,\[\\t \]*%\[re\]?sp" } } */
--/* { dg-final { scan-assembler "call\[\\t \]*foo" } } */
--/* { dg-final { scan-assembler-not "jmp\[\\t \]*foo" } } */
-+/* { dg-final { scan-assembler "call\[\\t \]*_?foo" } } */
-+/* { dg-final { scan-assembler-not "jmp\[\\t \]*_?foo" } } */
-
- extern int foo (void);
-
---- a/gcc/testsuite/gcc.target/i386/pr37843-2.c
-+++ b/gcc/testsuite/gcc.target/i386/pr37843-2.c
-@@ -2,8 +2,8 @@
- /* { dg-do compile { target nonpic } } */
- /* { dg-options "-O2 -mpreferred-stack-boundary=6 -mincoming-stack-boundary=6" } */
- /* { dg-final { scan-assembler-not "and\[lq\]?\[\\t \]*\\$-64,\[\\t \]*%\[re\]?sp" } } */
--/* { dg-final { scan-assembler-not "call\[\\t \]*foo" } } */
--/* { dg-final { scan-assembler "jmp\[\\t \]*foo" } } */
-+/* { dg-final { scan-assembler-not "call\[\\t \]*_?foo" } } */
-+/* { dg-final { scan-assembler "jmp\[\\t \]*_?foo" } } */
-
- extern int foo (void);
-
---- a/gcc/testsuite/gcc.target/i386/pr37843-3.c
-+++ b/gcc/testsuite/gcc.target/i386/pr37843-3.c
-@@ -2,8 +2,8 @@
- /* { dg-do compile { target { ilp32 && nonpic } } } */
- /* { dg-options "-O2 -msse2 -mpreferred-stack-boundary=4 -mstackrealign" } */
- /* { dg-final { scan-assembler-not "andl\[\\t \]*\\$-16,\[\\t \]*%\[re\]?sp" } } */
--/* { dg-final { scan-assembler-not "call\[\\t \]*foo" } } */
--/* { dg-final { scan-assembler "jmp\[\\t \]*foo" } } */
-+/* { dg-final { scan-assembler-not "call\[\\t \]*_?foo" } } */
-+/* { dg-final { scan-assembler "jmp\[\\t \]*_?foo" } } */
-
- #include <emmintrin.h>
-
---- a/gcc/testsuite/gcc.target/i386/sse-5.c
-+++ b/gcc/testsuite/gcc.target/i386/sse-5.c
-@@ -1,5 +1,6 @@
- /* { dg-do compile } */
- /* { dg-require-effective-target ilp32 } */
-+/* { dg-skip-if "" { i?86-*-* x86_64-*-* } { "-march=*" } { "-march=i386" } } */
- /* { dg-options "-Winline -O2 -march=i386" } */
-
- typedef double v2df __attribute__ ((vector_size (16)));
---- a/gcc/testsuite/gcc.target/i386/ssefn-1.c
-+++ b/gcc/testsuite/gcc.target/i386/ssefn-1.c
-@@ -7,6 +7,7 @@
- /* { dg-final { scan-assembler "mulss" } } */
- /* { dg-final { scan-assembler-not "movsd" } } */
- /* { dg-final { scan-assembler-not "mulsd" } } */
-+/* { dg-skip-if "" { i?86-*-* x86_64-*-* } { "-march=*" } { "-march=i386" } } */
- /* { dg-options "-O2 -march=i386 -msse -mfpmath=sse -fno-inline" } */
-
- static float xs (void)
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/m68k/20090709-1.c
-@@ -0,0 +1,20 @@
-+/* { dg-do compile } */
-+/* There should be 3 occurrences of .LC0 in the code:
-+ one for the definition of "0",
-+ one for use in test1() and
-+ one for use in test2().
-+ FIXME: At the moment m68k GCC does not optimize test1() to nop
-+ for some reason. */
-+/* { dg-final { scan-assembler-times ".LC0" 3 } } */
-+
-+void dummy(char *arg);
-+
-+void test1(void)
-+{
-+ char tmp[2] = "0";
-+}
-+
-+void test2(void)
-+{
-+ dummy("0");
-+}
---- a/gcc/testsuite/gcc.target/m68k/pr36134.c
-+++ b/gcc/testsuite/gcc.target/m68k/pr36134.c
-@@ -1,10 +1,15 @@
- /* pr36134.c
-
- This test ensures that the shorter LEA instruction is used in preference
-- to the longer ADD instruction. */
-+ to the longer ADD instruction.
-+
-+ This preference is applicable to ColdFire only. On CPU32, we can
-+ use a sequence of two ADDQ instructions, which is faster than the
-+ LEA instruction. */
-
- /* { dg-do compile } */
--/* { dg-options "-O2" } */
-+/* { dg-skip-if "" { *-*-* } { "-mcpu=*" } { "-mcpu=5208" } } */
-+/* { dg-options "-O2 -mcpu=5208" } */
- /* { dg-final { scan-assembler "lea" } } */
- /* { dg-final { scan-assembler-not "add" } } */
-
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/m68k/tls-gd-xgot.c
-@@ -0,0 +1,13 @@
-+/* { dg-do compile } */
-+/* { dg-skip-if "" { ! *-linux-* } { "*" } { "" } } */
-+/* { dg-options "-O2 -fpic -mxgot" } */
-+/* { dg-final { scan-assembler "#foo@TLSGD,\%\[ad\]\[0-7\]" } } */
-+/* { dg-final { scan-assembler "bsr.l __tls_get_addr@PLTPC" } } */
-+
-+extern int __thread foo;
-+
-+int *
-+bar (void)
-+{
-+ return &foo;
-+}
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/m68k/tls-gd.c
-@@ -0,0 +1,13 @@
-+/* { dg-do compile } */
-+/* { dg-skip-if "" { ! *-linux-* } { "*" } { "" } } */
-+/* { dg-options "-O2 -fpic" } */
-+/* { dg-final { scan-assembler "foo@TLSGD\\(\%a5\\)" } } */
-+/* { dg-final { scan-assembler "bsr.l __tls_get_addr@PLTPC" } } */
-+
-+extern int __thread foo;
-+
-+int *
-+bar (void)
-+{
-+ return &foo;
-+}
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/m68k/tls-ie-xgot.c
-@@ -0,0 +1,13 @@
-+/* { dg-do compile } */
-+/* { dg-skip-if "" { ! *-linux-* } { "*" } { "" } } */
-+/* { dg-options "-O2 -mxgot" } */
-+/* { dg-final { scan-assembler "jsr __m68k_read_tp" } } */
-+/* { dg-final { scan-assembler "#foo@TLSIE,\%\[ad\]\[0-7\]" } } */
-+
-+extern int __thread foo;
-+
-+int *
-+bar (void)
-+{
-+ return &foo;
-+}
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/m68k/tls-ie.c
-@@ -0,0 +1,13 @@
-+/* { dg-do compile } */
-+/* { dg-skip-if "" { ! *-linux-* } { "*" } { "" } } */
-+/* { dg-options "-O2" } */
-+/* { dg-final { scan-assembler "jsr __m68k_read_tp" } } */
-+/* { dg-final { scan-assembler "foo@TLSIE\\(\%a5\\)" } } */
-+
-+extern int __thread foo;
-+
-+int *
-+bar (void)
-+{
-+ return &foo;
-+}
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/m68k/tls-ld-xgot-xtls.c
-@@ -0,0 +1,14 @@
-+/* { dg-do compile } */
-+/* { dg-skip-if "" { ! *-linux-* } { "*" } { "" } } */
-+/* { dg-options "-O2 -fpic -mxgot -mxtls" } */
-+/* { dg-final { scan-assembler "#foo@TLSLDM,\%\[ad\]\[0-7\]" } } */
-+/* { dg-final { scan-assembler "bsr.l __tls_get_addr@PLTPC" } } */
-+/* { dg-final { scan-assembler "#foo@TLSLDO,\%\[ad\]\[0-7\]" } } */
-+
-+static int __thread foo;
-+
-+int *
-+bar (void)
-+{
-+ return &foo;
-+}
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/m68k/tls-ld-xgot.c
-@@ -0,0 +1,14 @@
-+/* { dg-do compile } */
-+/* { dg-skip-if "" { ! *-linux-* } { "*" } { "" } } */
-+/* { dg-options "-O2 -fpic -mxgot" } */
-+/* { dg-final { scan-assembler "#foo@TLSLDM,\%\[ad\]\[0-7\]" } } */
-+/* { dg-final { scan-assembler "bsr.l __tls_get_addr@PLTPC" } } */
-+/* { dg-final { scan-assembler "lea \\(foo@TLSLDO,\%a0\\)" } } */
-+
-+static int __thread foo;
-+
-+int *
-+bar (void)
-+{
-+ return &foo;
-+}
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/m68k/tls-ld-xtls.c
-@@ -0,0 +1,14 @@
-+/* { dg-do compile } */
-+/* { dg-skip-if "" { ! *-linux-* } { "*" } { "" } } */
-+/* { dg-options "-O2 -fpic -mxtls" } */
-+/* { dg-final { scan-assembler "foo@TLSLDM\\(\%a5\\)" } } */
-+/* { dg-final { scan-assembler "bsr.l __tls_get_addr@PLTPC" } } */
-+/* { dg-final { scan-assembler "#foo@TLSLDO,\%\[ad\]\[0-7\]" } } */
-+
-+static int __thread foo;
-+
-+int *
-+bar (void)
-+{
-+ return &foo;
-+}
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/m68k/tls-ld.c
-@@ -0,0 +1,14 @@
-+/* { dg-do compile } */
-+/* { dg-skip-if "" { ! *-linux-* } { "*" } { "" } } */
-+/* { dg-options "-O2 -fpic" } */
-+/* { dg-final { scan-assembler "foo@TLSLDM\\(\%a5\\)" } } */
-+/* { dg-final { scan-assembler "bsr.l __tls_get_addr@PLTPC" } } */
-+/* { dg-final { scan-assembler "lea \\(foo@TLSLDO,\%a0\\)" } } */
-+
-+static int __thread foo;
-+
-+int *
-+bar (void)
-+{
-+ return &foo;
-+}
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/m68k/tls-le-xtls.c
-@@ -0,0 +1,13 @@
-+/* { dg-do compile } */
-+/* { dg-skip-if "" { ! *-linux-* } { "*" } { "" } } */
-+/* { dg-options "-O2 -mxtls" } */
-+/* { dg-final { scan-assembler "jsr __m68k_read_tp" } } */
-+/* { dg-final { scan-assembler "#foo@TLSLE,\%\[ad\]\[0-7\]" } } */
-+
-+static int __thread foo;
-+
-+int *
-+bar (void)
-+{
-+ return &foo;
-+}
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/m68k/tls-le.c
-@@ -0,0 +1,13 @@
-+/* { dg-do compile } */
-+/* { dg-skip-if "" { ! *-linux-* } { "*" } { "" } } */
-+/* { dg-options "-O2" } */
-+/* { dg-final { scan-assembler "jsr __m68k_read_tp" } } */
-+/* { dg-final { scan-assembler "lea \\(foo@TLSLE,\%a0\\)" } } */
-+
-+static int __thread foo;
-+
-+int *
-+bar (void)
-+{
-+ return &foo;
-+}
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/mips/branch-2.c
-@@ -0,0 +1,44 @@
-+/* Check that we correctly expand out-of-range branches */
-+/* { dg-do run } */
-+/* { dg-options "-O2 -mabi=32 -fPIC" } */
-+
-+#include <stdlib.h>
-+
-+/* This is weak so the compiler cannot assume that calls from this TU
-+ necessarily arrive here. And hence that $gp may be clobbered in
-+ o32 and o64 ABIs. */
-+
-+void __attribute__ ((weak)) Foo (int i)
-+{
-+ static int once = 0;
-+
-+ if (!i && once++)
-+ exit (0);
-+
-+#if (_ABIO32 || _ABIO64)
-+ /* Clobber $gp */
-+ __asm volatile ("li $gp,0");
-+#endif
-+}
-+
-+#define N1(X) (Foo (X))
-+#define N2(X) (N1 (X), N1 (X+(1<<0)))
-+#define N3(X) (N2 (X), N2 (X+(1<<1)))
-+#define N4(X) (N3 (X), N3 (X+(1<<2)))
-+#define N5(X) (N4 (X), N4 (X+(1<<3)))
-+#define N6(X) (N5 (X), N5 (X+(1<<4)))
-+#define N7(X) (N6 (X), N6 (X+(1<<5)))
-+#define N8(X) (N7 (X), N7 (X+(1<<6)))
-+#define N9(X) (N8 (X), N8 (X+(1<<7)))
-+#define N10(X) (N9 (X), N9 (X+(1<<8)))
-+#define N11(X) (N10 (X), N10 (X+(1<<9)))
-+#define N12(X) (N11 (X), N11 (X+(1<<10)))
-+#define N13(X) (N12 (X), N12 (X+(1<<11)))
-+#define N14(X) (N13 (X), N13 (X+(1<<12)))
-+
-+int main (void)
-+{
-+ while (1)
-+ N14 (0);
-+ return 0;
-+}
---- a/gcc/testsuite/gcc.target/mips/clear-cache-2.c
-+++ b/gcc/testsuite/gcc.target/mips/clear-cache-2.c
-@@ -2,7 +2,8 @@
- /* { dg-options "-O2 -mips32" } */
- /* { dg-final { scan-assembler-not "synci" } } */
- /* { dg-final { scan-assembler-not "jr.hb" } } */
--/* { dg-final { scan-assembler "_flush_cache" } } */
-+/* { dg-final { scan-assembler "mips_sync_icache" { target { *-sde-* } } } } */
-+/* { dg-final { scan-assembler "_flush_cache" { target { ! *-sde-* } } } } */
-
- void f()
- {
---- a/gcc/testsuite/gcc.target/mips/fpr-moves-5.c
-+++ b/gcc/testsuite/gcc.target/mips/fpr-moves-5.c
-@@ -1,4 +1,5 @@
- /* { dg-options "-mabi=64 -mhard-float -O2 -EL" } */
-+/* { dg-require-effective-target mips_newabi_large_long_double } */
-
- NOMIPS16 void
- foo (long double d, long double *x)
---- a/gcc/testsuite/gcc.target/mips/fpr-moves-6.c
-+++ b/gcc/testsuite/gcc.target/mips/fpr-moves-6.c
-@@ -1,4 +1,5 @@
- /* { dg-options "-mabi=64 -mhard-float -O2 -EB" } */
-+/* { dg-require-effective-target mips_newabi_large_long_double } */
-
- NOMIPS16 void
- foo (long double d, long double *x)
---- a/gcc/testsuite/gcc.target/mips/mips.exp
-+++ b/gcc/testsuite/gcc.target/mips/mips.exp
-@@ -229,6 +229,7 @@ foreach option {
- gpopt
- local-sdata
- long-calls
-+ octeon-useun
- paired-single
- plt
- shared
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/mips/octeon-useun.c
-@@ -0,0 +1,16 @@
-+/* Check the mov_u[ls][dw] patterns. */
-+/* { dg-options "-march=octeon -O2 -mabi=64 -mocteon-useun -meb" } */
-+struct __attribute__((packed)) sl { unsigned long x; };
-+struct __attribute__((packed)) si { unsigned int x; };
-+unsigned long f1 (struct sl *s) { return s[0].x; };
-+unsigned int f2 (struct si *s) { return s[1].x; };
-+void f3 (struct sl *s, unsigned long x) { s[10].x = x; }
-+void f4 (struct si *s, unsigned int x) { s[11].x = x; }
-+void f5 (struct sl *s) { s[100].x = 0; }
-+void f6 (struct si *s) { s[101].x = 0; }
-+/* { dg-final { scan-assembler "\tjr?\t\\\$31\n\tuld\t\\\$2,0\\(\\\$4\\)\n" } } */
-+/* { dg-final { scan-assembler "\tulw\t\\\$2,4\\(\\\$4\\)\n" } } */
-+/* { dg-final { scan-assembler "\tjr?\t\\\$31\n\tusd\t\\\$5,80\\(\\\$4\\)\n" } } */
-+/* { dg-final { scan-assembler "\tjr?\t\\\$31\n\tusw\t\\\$5,44\\(\\\$4\\)\n" } } */
-+/* { dg-final { scan-assembler "\tjr?\t\\\$31\n\tusd\t\\\$0,800\\(\\\$4\\)\n" } } */
-+/* { dg-final { scan-assembler "\tjr?\t\\\$31\n\tusw\t\\\$0,404\\(\\\$4\\)\n" } } */
---- a/gcc/testsuite/gcc.target/powerpc/altivec-consts.c
-+++ b/gcc/testsuite/gcc.target/powerpc/altivec-consts.c
-@@ -1,7 +1,7 @@
- /* { dg-do run { target { powerpc*-*-* && vmx_hw } } } */
- /* { dg-do compile { target { powerpc*-*-* && { ! vmx_hw } } } } */
- /* { dg-require-effective-target powerpc_altivec_ok } */
--/* { dg-options "-maltivec -mabi=altivec -O2" } */
-+/* { dg-options "-maltivec -O2" } */
-
- /* Check that "easy" AltiVec constants are correctly synthesized. */
-
---- a/gcc/testsuite/gcc.target/powerpc/altivec-varargs-1.c
-+++ b/gcc/testsuite/gcc.target/powerpc/altivec-varargs-1.c
-@@ -1,7 +1,7 @@
- /* { dg-do run { target { powerpc*-*-* && vmx_hw } } } */
- /* { dg-do compile { target { powerpc*-*-* && { ! vmx_hw } } } } */
- /* { dg-require-effective-target powerpc_altivec_ok } */
--/* { dg-options "-maltivec -mabi=altivec -fno-inline" } */
-+/* { dg-options "-maltivec -fno-inline" } */
-
- #include <stdarg.h>
-
---- a/gcc/testsuite/gcc.target/sh/20080410-1.c
-+++ b/gcc/testsuite/gcc.target/sh/20080410-1.c
-@@ -1,5 +1,5 @@
- /* { dg-do compile { target "sh-*-*" } } */
--/* { dg-options "-O0 -m4 -ml -fira" } */
-+/* { dg-options "-O0 -m4 -ml" } */
- /* { dg-final { scan-assembler-not "add\tr0,r0" } } */
-
- /* This test checks that chain reloads conflict. I they don't
---- a/gcc/testsuite/gcc.target/sh/sh4a-bitmovua.c
-+++ b/gcc/testsuite/gcc.target/sh/sh4a-bitmovua.c
-@@ -35,15 +35,15 @@ long long f4() {
- }
-
- /* Aligned. */
--struct u0 { unsigned long long d : 32; } y0;
-+struct u0 { unsigned long long d : 32; } y_0;
- unsigned long long g0() {
-- return y0.d;
-+ return y_0.d;
- }
-
- /* Unaligned load. */
--struct u1 { long long c : 8; unsigned long long d : 32; } y1;
-+struct u1 { long long c : 8; unsigned long long d : 32; } y_1;
- unsigned long long g1() {
-- return y1.d;
-+ return y_1.d;
- }
-
- /* Unaligned load. */
---- a/gcc/testsuite/gcc.target/sh/sh4a-memmovua.c
-+++ b/gcc/testsuite/gcc.target/sh/sh4a-memmovua.c
-@@ -5,7 +5,7 @@
- /* { dg-final { scan-assembler-times "\tmovua\\.l\t(.*)+" 2 } } */
-
- #ifdef __SH4A__
--#include <stdlib.h>
-+#include <string.h>
-
- struct s { int i; char a[10], b[10]; } x;
- int f() {
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/x86_64/abi/callabi/func-2a.c
-@@ -0,0 +1,27 @@
-+/* Test for cross x86_64<->w64 abi standard calls. */
-+/* { dg-do run { target i?86-*-linux* x86_64-*-linux* } } */
-+/* { dg-options "-O2 -mabi=ms -std=gnu99 -ffast-math -fno-builtin" } */
-+/* { dg-additional-sources "func-2b.c" } */
-+
-+extern void __attribute__ ((sysv_abi)) abort (void);
-+long double func_cross (long double, double, float, long, int, char);
-+
-+long double __attribute__ ((sysv_abi))
-+func_native (long double a, double b, float c, long d, int e, char f)
-+{
-+ long double ret;
-+ ret = a + (long double) b + (long double) c;
-+ ret *= (long double) (d + (long) e);
-+ if (f>0)
-+ ret += func_native (a,b,c,d,e,-f);
-+ return ret;
-+}
-+
-+int __attribute__ ((sysv_abi))
-+main ()
-+{
-+ if (func_cross (1.0,2.0,3.0,1,2,3)
-+ != func_native (1.0,2.0,3.0,1,2,3))
-+ abort ();
-+ return 0;
-+}
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/x86_64/abi/callabi/func-2b.c
-@@ -0,0 +1,13 @@
-+/* Test for cross x86_64<->w64 abi standard calls. */
-+/* { dg-options "-mabi=ms -std=gnu99 -ffast-math -fno-builtin" } */
-+
-+long double func_cross (long double a, double b, float c, long d, int e,
-+ char f)
-+{
-+ long double ret;
-+ ret = a + (long double) b + (long double) c;
-+ ret *= (long double) (d + (long) e);
-+ if (f>0)
-+ ret += func_cross (a,b,c,d,e,-f);
-+ return ret;
-+}
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/x86_64/abi/callabi/func-indirect-2a.c
-@@ -0,0 +1,17 @@
-+/* Test for cross x86_64<->w64 abi standard calls via variable. */
-+/* { dg-do run { target i?86-*-linux* x86_64-*-linux* } } */
-+/* { dg-options "-O2 -mabi=ms -std=gnu99 -ffast-math -fno-builtin" } */
-+/* { dg-additional-sources "func-indirect-2b.c" } */
-+
-+extern void __attribute__ ((sysv_abi)) abort (void);
-+typedef int (*func)(void *, char *, char *, short, long long);
-+extern func get_callback (void);
-+
-+int __attribute__ ((sysv_abi))
-+main ()
-+{
-+ func callme = get_callback ();
-+ if (callme (0, 0, 0, 0x1234, 0x1234567890abcdefLL))
-+ abort ();
-+ return 0;
-+}
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/x86_64/abi/callabi/func-indirect-2b.c
-@@ -0,0 +1,24 @@
-+/* Test for cross x86_64<->w64 abi standard calls via variable. */
-+/* { dg-options "-O2 -mabi=ms -std=gnu99 -ffast-math -fno-builtin" } */
-+
-+typedef int (*func)(void *, char *, char *, short, long long);
-+
-+static int
-+callback (void *ptr, char *string1, char *string2, short number,
-+ long long rand)
-+{
-+ if (ptr != 0
-+ || string1 != 0
-+ || string2 != 0
-+ || number != 0x1234
-+ || rand != 0x1234567890abcdefLL)
-+ return 1;
-+ else
-+ return 0;
-+}
-+
-+func
-+get_callback (void)
-+{
-+ return callback;
-+}
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/x86_64/abi/callabi/vaarg-4a.c
-@@ -0,0 +1,24 @@
-+/* Test for cross x86_64<->w64 abi va_list calls. */
-+/* { dg-do run { target i?86-*-linux* x86_64-*-linux* } } */
-+/* { dg-options "-O2 -mabi=ms -std=gnu99 -fno-builtin" } */
-+/* { dg-additional-sources "vaarg-4b.c" } */
-+
-+extern __SIZE_TYPE__ __attribute__ ((sysv_abi)) strlen (const char *);
-+extern int __attribute__ ((sysv_abi)) sprintf (char *,const char *, ...);
-+extern void __attribute__ ((sysv_abi)) abort (void);
-+
-+extern void do_cpy (char *, ...);
-+
-+int __attribute__ ((sysv_abi))
-+main ()
-+{
-+ char s[256];
-+
-+ do_cpy (s, "1","2","3","4", "5", "6", "7", "");
-+
-+ if (s[0] != '1' || s[1] !='2' || s[2] != '3' || s[3] != '4'
-+ || s[4] != '5' || s[5] != '6' || s[6] != '7' || s[7] != 0)
-+ abort ();
-+
-+ return 0;
-+}
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/x86_64/abi/callabi/vaarg-4b.c
-@@ -0,0 +1,31 @@
-+/* Test for cross x86_64<->w64 abi va_list calls. */
-+/* { dg-options "-O2 -mabi=ms -std=gnu99 -fno-builtin" } */
-+
-+#include <stdarg.h>
-+
-+extern __SIZE_TYPE__ __attribute__ ((sysv_abi)) strlen (const char *);
-+extern int __attribute__ ((sysv_abi)) sprintf (char *, const char *, ...);
-+
-+static void
-+vdo_cpy (char *s, va_list argp)
-+{
-+ __SIZE_TYPE__ len;
-+ char *r = s;
-+ char *e;
-+ *r = 0;
-+ for (;;) {
-+ e = va_arg (argp, char *);
-+ if (*e == 0) break;
-+ sprintf (r,"%s", e);
-+ r += strlen (r);
-+ }
-+}
-+
-+void
-+do_cpy (char *s, ...)
-+{
-+ va_list argp;
-+ va_start (argp, s);
-+ vdo_cpy (s, argp);
-+ va_end (argp);
-+}
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/x86_64/abi/callabi/vaarg-5a.c
-@@ -0,0 +1,17 @@
-+/* Test for cross x86_64<->w64 abi va_list calls. */
-+/* { dg-do run { target i?86-*-linux* x86_64-*-linux* } } */
-+/* { dg-options "-O2 -mabi=ms -std=gnu99 -fno-builtin" } */
-+/* { dg-additional-sources "vaarg-5b.c" } */
-+
-+extern void __attribute__ ((sysv_abi)) abort (void);
-+extern int fct2 (int, ...);
-+
-+#define SZ_ARGS 1ll,2ll,3ll,4ll,5ll,6ll,7ll,0ll
-+
-+int __attribute__ ((sysv_abi))
-+main()
-+{
-+ if (fct2 (-1, SZ_ARGS) != 0)
-+ abort ();
-+ return 0;
-+}
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/x86_64/abi/callabi/vaarg-5b.c
-@@ -0,0 +1,37 @@
-+/* Test for cross x86_64<->w64 abi va_list calls. */
-+/* { dg-options "-O2 -mabi=ms -std=gnu99 -fno-builtin" } */
-+
-+#include <stdarg.h>
-+
-+#define SZ_ARGS 1ll,2ll,3ll,4ll,5ll,6ll,7ll,0ll
-+
-+static int __attribute__ ((sysv_abi))
-+fct1 (va_list argp, ...)
-+{
-+ long long p1,p2;
-+ int ret = 1;
-+ __builtin_sysv_va_list argp_2;
-+
-+ __builtin_sysv_va_start (argp_2, argp);
-+ do {
-+ p1 = va_arg (argp_2, long long);
-+ p2 = va_arg (argp, long long);
-+ if (p1 != p2)
-+ ret = 0;
-+ } while (ret && p1 != 0);
-+ __builtin_sysv_va_end (argp_2);
-+
-+ return ret;
-+}
-+
-+int
-+fct2 (int dummy, ...)
-+{
-+ va_list argp;
-+ int ret = dummy;
-+
-+ va_start (argp, dummy);
-+ ret += fct1 (argp, SZ_ARGS);
-+ va_end (argp);
-+ return ret;
-+}
---- a/gcc/testsuite/gfortran.dg/vect/vect.exp
-+++ b/gcc/testsuite/gfortran.dg/vect/vect.exp
-@@ -98,7 +98,7 @@ if [istarget "powerpc-*paired*"] {
- } elseif [istarget "ia64-*-*"] {
- set dg-do-what-default run
- } elseif [is-effective-target arm_neon_ok] {
-- lappend DEFAULT_VECTCFLAGS "-mfpu=neon" "-mfloat-abi=softfp"
-+ eval lappend DEFAULT_VECTCFLAGS [add_options_for_arm_neon ""]
- if [is-effective-target arm_neon_hw] {
- set dg-do-what-default run
- } else {
---- a/gcc/testsuite/lib/prune.exp
-+++ b/gcc/testsuite/lib/prune.exp
-@@ -57,3 +57,34 @@ if { [info procs prune_warnings] == "" }
- return $text
- }
- }
-+
-+# Extend prune_warnings (provided by DejaGNU itself) to prune more
-+# things. The prune_gcc_output function above is called only by some
-+# tests; prune_warnings is used by all.
-+if { [info procs prune_warnings_orig] == "" } {
-+ rename prune_warnings prune_warnings_orig
-+
-+ proc prune_warnings { text } {
-+ set text [prune_warnings_orig $text]
-+
-+ if { [ishost "sparc*-*-solaris2*"] } {
-+ # When testing a compiler built for SPARC Solaris 2.9 (or earlier)
-+ # on a host running Solaris 2.10 (or later), we get this warning
-+ # from the static linker when building with g++:
-+ #
-+ # libm.so.1, needed by .../libstdc++.so may conflict with
-+ # libm.so
-+ #
-+ # The warning is issued because libstdc++ is linked against
-+ # libm.so.1 (from the Solaris 2.9 sysroot), whereas Solaris 2.10
-+ # provides both libm.so.2 and libm.so.1. On Solaris 2.10, libc.so
-+ # depends on libm.so.2, so all programs pull in libm.so.2.
-+ #
-+ # Pulling both libraries must in fact be harmless, as, otherwise,
-+ # programs built for Solaris 2.9 would break on Solaris 2.10.
-+ regsub -all "(^|\n)\[^\n\]*: warning: libm.so.1, needed by \[^\n\]*, may conflict with libm.so.2" $text "" text
-+ }
-+
-+ return $text
-+ }
-+}
---- a/gcc/testsuite/lib/target-supports.exp
-+++ b/gcc/testsuite/lib/target-supports.exp
-@@ -491,6 +491,7 @@ proc check_profiling_available { test_wh
- || [istarget avr-*-*]
- || [istarget bfin-*-*]
- || [istarget powerpc-*-eabi*]
-+ || [istarget powerpc-*-elf]
- || [istarget cris-*-*]
- || [istarget crisv32-*-*]
- || [istarget fido-*-elf]
-@@ -618,6 +619,18 @@ proc check_effective_target_static {} {
- } "-static"]
- }
-
-+# Return 1 if compilation with -mpe-aligned-commons is error-free
-+# for trivial code, 0 otherwise.
-+
-+proc check_effective_target_pe_aligned_commons {} {
-+ if { [istarget *-*-cygwin*] || [istarget *-*-mingw*] } {
-+ return [check_no_compiler_messages pe_aligned_commons object {
-+ int foo;
-+ } "-mpe-aligned-commons"]
-+ }
-+ return 0
-+}
-+
- # Return 1 if the target supports -fstack-protector
- proc check_effective_target_fstack_protector {} {
- return [check_runtime fstack_protector {
-@@ -727,6 +740,15 @@ proc check_effective_target_mips16_attri
- } [add_options_for_mips16_attribute ""]]
- }
-
-+# Return 1 if the target supports long double larger than double when
-+# using the new ABI, 0 otherwise.
-+
-+proc check_effective_target_mips_newabi_large_long_double { } {
-+ return [check_no_compiler_messages mips_newabi_large_long_double object {
-+ int dummy[sizeof(long double) > sizeof(double) ? 1 : -1];
-+ } "-mabi=64"]
-+}
-+
- # Return 1 if the current multilib does not generate PIC by default.
-
- proc check_effective_target_nonpic { } {
-@@ -1416,6 +1438,18 @@ proc check_effective_target_arm32 { } {
- }]
- }
-
-+# Return 1 if this is an ARM target that only supports aligned vector accesses
-+proc check_effective_target_arm_vect_no_misalign { } {
-+ return [check_no_compiler_messages arm_vect_no_misalign assembly {
-+ #if !defined(__arm__) \
-+ || (defined(__ARMEL__) \
-+ && (!defined(__thumb__) || defined(__thumb2__)))
-+ #error FOO
-+ #endif
-+ }]
-+}
-+
-+
- # Return 1 if this is an ARM target supporting -mfpu=vfp
- # -mfloat-abi=softfp. Some multilibs may be incompatible with these
- # options.
-@@ -1430,18 +1464,110 @@ proc check_effective_target_arm_vfp_ok {
- }
- }
-
--# Return 1 if this is an ARM target supporting -mfpu=neon
--# -mfloat-abi=softfp. Some multilibs may be incompatible with these
-+# Return 1 if this is an ARM target supporting -mfpu=vfp
-+# -mfloat-abi=hard. Some multilibs may be incompatible with these
- # options.
-
--proc check_effective_target_arm_neon_ok { } {
-+proc check_effective_target_arm_hard_vfp_ok { } {
- if { [check_effective_target_arm32] } {
-- return [check_no_compiler_messages arm_neon_ok object {
-- int dummy;
-- } "-mfpu=neon -mfloat-abi=softfp"]
-+ return [check_no_compiler_messages arm_hard_vfp_ok executable {
-+ int main() { return 0;}
-+ } "-mfpu=vfp -mfloat-abi=hard"]
- } else {
-- return 0
-+ return 0
-+ }
-+}
-+
-+# Add the options needed for NEON. We need either -mfloat-abi=softfp
-+# or -mfloat-abi=hard, but if one is already specified by the
-+# multilib, use it. Similarly, if a -mfpu option already enables
-+# NEON, do not add -mfpu=neon.
-+
-+proc add_options_for_arm_neon { flags } {
-+ if { ! [check_effective_target_arm_neon_ok] } {
-+ return "$flags"
-+ }
-+ global et_arm_neon_flags
-+ return "$flags $et_arm_neon_flags"
-+}
-+
-+# Return 1 if this is an ARM target supporting -mfpu=neon
-+# -mfloat-abi=softfp or equivalent options. Some multilibs may be
-+# incompatible with these options. Also set et_arm_neon_flags to the
-+# best options to add.
-+
-+proc check_effective_target_arm_neon_ok_nocache { } {
-+ global et_arm_neon_flags
-+ set et_arm_neon_flags ""
-+ if { [check_effective_target_arm32] } {
-+ foreach flags {"" "-mfloat-abi=softfp" "-mfpu=neon" "-mfpu=neon -mfloat-abi=softfp"} {
-+ if { [check_no_compiler_messages_nocache arm_neon_ok object {
-+ #include "arm_neon.h"
-+ int dummy;
-+ } "$flags"] } {
-+ set et_arm_neon_flags $flags
-+ return 1
-+ }
-+ }
- }
-+
-+ return 0
-+}
-+
-+proc check_effective_target_arm_neon_ok { } {
-+ return [check_cached_effective_target arm_neon_ok \
-+ check_effective_target_arm_neon_ok_nocache]
-+}
-+
-+# Add the options needed for NEON. We need either -mfloat-abi=softfp
-+# or -mfloat-abi=hard, but if one is already specified by the
-+# multilib, use it.
-+
-+proc add_options_for_arm_neon_fp16 { flags } {
-+ if { ! [check_effective_target_arm_neon_fp16_ok] } {
-+ return "$flags"
-+ }
-+ global et_arm_neon_fp16_flags
-+ return "$flags $et_arm_neon_fp16_flags"
-+}
-+
-+# Return 1 if this is an ARM target supporting -mfpu=neon-fp16
-+# -mfloat-abi=softfp or equivalent options. Some multilibs may be
-+# incompatible with these options. Also set et_arm_neon_flags to the
-+# best options to add.
-+
-+proc check_effective_target_arm_neon_fp16_ok_nocache { } {
-+ global et_arm_neon_fp16_flags
-+ set et_arm_neon_fp16_flags ""
-+ if { [check_effective_target_arm32] } {
-+ # Always add -mfpu=neon-fp16, since there is no preprocessor
-+ # macro for FP16 support.
-+ foreach flags {"-mfpu=neon-fp16" "-mfpu=neon-fp16 -mfloat-abi=softfp"} {
-+ if { [check_no_compiler_messages_nocache arm_neon_fp16_ok object {
-+ #include "arm_neon.h"
-+ int dummy;
-+ } "$flags"] } {
-+ set et_arm_neon_fp16_flags $flags
-+ return 1
-+ }
-+ }
-+ }
-+
-+ return 0
-+}
-+
-+proc check_effective_target_arm_neon_fp16_ok { } {
-+ return [check_cached_effective_target arm_neon_fp16_ok \
-+ check_effective_target_arm_neon_fp16_ok_nocache]
-+}
-+
-+# Return 1 if this is an arm target using 32-bit instructions, but not thumb
-+proc check_effective_target_arm_not_thumb { } {
-+ return [check_no_compiler_messages arm_not_thumb assembly {
-+ #if !defined(__arm__) || defined(__thumb__)
-+ #error FOO
-+ #endif
-+ }]
- }
-
- # Return 1 is this is an ARM target where -mthumb causes Thumb-1 to be
-@@ -1455,6 +1581,17 @@ proc check_effective_target_arm_thumb1_o
- } "-mthumb"]
- }
-
-+# Return 1 is this is an ARM target where -mthumb causes Thumb-2 to be
-+# used.
-+
-+proc check_effective_target_arm_thumb2_ok { } {
-+ return [check_no_compiler_messages arm_thumb2_ok assembly {
-+ #if !defined(__thumb2__)
-+ #error FOO
-+ #endif
-+ } "-mthumb"]
-+}
-+
- # Return 1 if the target supports executing NEON instructions, 0
- # otherwise. Cache the result.
-
-@@ -1469,7 +1606,7 @@ proc check_effective_target_arm_neon_hw
- : "0" (a), "w" (b));
- return (a != 1);
- }
-- } "-mfpu=neon -mfloat-abi=softfp"]
-+ } [add_options_for_arm_neon ""]]
- }
-
- # Return 1 if this is a ARM target with NEON enabled.
-@@ -1512,6 +1649,19 @@ proc check_effective_target_arm_eabi { }
- }]
- }
-
-+# Return 1 if this is an ARM target supporting -mcpu=iwmmxt.
-+# Some multilibs may be incompatible with this option.
-+
-+proc check_effective_target_arm_iwmmxt_ok { } {
-+ if { [check_effective_target_arm32] } {
-+ return [check_no_compiler_messages arm_iwmmxt_ok object {
-+ int dummy;
-+ } "-mcpu=iwmmxt"]
-+ } else {
-+ return 0
-+ }
-+}
-+
- # Return 1 if this is a PowerPC target with floating-point registers.
-
- proc check_effective_target_powerpc_fprs { } {
-@@ -1708,6 +1858,26 @@ proc check_effective_target_vect_shift {
- return $et_vect_shift_saved
- }
-
-+# Return 1 if the target supports hardware vector shift operation for char.
-+
-+proc check_effective_target_vect_shift_char { } {
-+ global et_vect_shift_char_saved
-+
-+ if [info exists et_vect_shift_char_saved] {
-+ verbose "check_effective_target_vect_shift_char: using cached result" 2
-+ } else {
-+ set et_vect_shift_char_saved 0
-+ if { ([istarget powerpc*-*-*]
-+ && ![istarget powerpc-*-linux*paired*])
-+ || [check_effective_target_arm32] } {
-+ set et_vect_shift_char_saved 1
-+ }
-+ }
-+
-+ verbose "check_effective_target_vect_shift_char: returning $et_vect_shift_char_saved" 2
-+ return $et_vect_shift_char_saved
-+}
-+
- # Return 1 if the target supports hardware vectors of long, 0 otherwise.
- #
- # This can change for different subtargets so do not cache the result.
-@@ -2167,7 +2337,7 @@ proc check_effective_target_vect_no_alig
- if { [istarget mipsisa64*-*-*]
- || [istarget sparc*-*-*]
- || [istarget ia64-*-*]
-- || [check_effective_target_arm32] } {
-+ || [check_effective_target_arm_vect_no_misalign] } {
- set et_vect_no_align_saved 1
- }
- }
-@@ -2281,6 +2451,24 @@ proc check_effective_target_vector_align
- return $et_vector_alignment_reachable_for_64bit_saved
- }
-
-+# Return 1 if the target only requires element alignment for vector accesses
-+
-+proc check_effective_target_vect_element_align { } {
-+ global et_vect_element_align
-+
-+ if [info exists et_vect_element_align] {
-+ verbose "check_effective_target_vect_elemetn_align: using cached result" 2
-+ } else {
-+ set et_vect_element_align 0
-+ if { [istarget arm*-*-*] } {
-+ set et_vect_element_align 1
-+ }
-+ }
-+
-+ verbose "check_effective_target_vect_element_align: returning $et_vect_element_align" 2
-+ return $et_vect_element_align
-+}
-+
- # Return 1 if the target supports vector conditional operations, 0 otherwise.
-
- proc check_effective_target_vect_condition { } {
-@@ -2476,7 +2664,8 @@ proc check_effective_target_section_anch
- verbose "check_effective_target_section_anchors: using cached result" 2
- } else {
- set et_section_anchors_saved 0
-- if { [istarget powerpc*-*-*] } {
-+ if { [istarget powerpc*-*-*]
-+ || [istarget arm*-*-*] } {
- set et_section_anchors_saved 1
- }
- }
---- a/gcc/timevar.def
-+++ b/gcc/timevar.def
-@@ -134,6 +134,7 @@ DEFTIMEVAR (TV_TREE_LOOP_IVOPTS , "
- DEFTIMEVAR (TV_PREDCOM , "predictive commoning")
- DEFTIMEVAR (TV_TREE_LOOP_INIT , "tree loop init")
- DEFTIMEVAR (TV_TREE_LOOP_FINI , "tree loop fini")
-+DEFTIMEVAR (TV_TREE_LOOP_PROMOTE , "tree loop index promotion")
- DEFTIMEVAR (TV_TREE_CH , "tree copy headers")
- DEFTIMEVAR (TV_TREE_SSA_UNCPROP , "tree SSA uncprop")
- DEFTIMEVAR (TV_TREE_SSA_TO_NORMAL , "tree SSA to normal")
-@@ -141,6 +142,7 @@ DEFTIMEVAR (TV_TREE_NRV , "tree NR
- DEFTIMEVAR (TV_TREE_COPY_RENAME , "tree rename SSA copies")
- DEFTIMEVAR (TV_TREE_SSA_VERIFY , "tree SSA verifier")
- DEFTIMEVAR (TV_TREE_STMT_VERIFY , "tree STMT verifier")
-+DEFTIMEVAR (TV_TREE_RLS , "tree local static removal")
- DEFTIMEVAR (TV_TREE_SWITCH_CONVERSION, "tree switch initialization conversion")
- DEFTIMEVAR (TV_CGRAPH_VERIFY , "callgraph verifier")
- DEFTIMEVAR (TV_DOM_FRONTIERS , "dominance frontiers")
---- a/gcc/toplev.h
-+++ b/gcc/toplev.h
-@@ -139,6 +139,7 @@ extern int flag_unroll_loops;
- extern int flag_unroll_all_loops;
- extern int flag_unswitch_loops;
- extern int flag_cprop_registers;
-+extern int flag_remove_local_statics;
- extern int time_report;
- extern int flag_ira_coalesce;
- extern int flag_ira_move_spills;
---- a/gcc/tree-cfg.c
-+++ b/gcc/tree-cfg.c
-@@ -47,6 +47,7 @@ along with GCC; see the file COPYING3.
- #include "value-prof.h"
- #include "pointer-set.h"
- #include "tree-inline.h"
-+#include "target.h"
-
- /* This file contains functions for building the Control Flow Graph (CFG)
- for a function tree. */
-@@ -7052,6 +7053,9 @@ execute_warn_function_return (void)
- edge e;
- edge_iterator ei;
-
-+ if (!targetm.warn_func_result())
-+ return 0;
-+
- /* If we have a path to EXIT, then we do return. */
- if (TREE_THIS_VOLATILE (cfun->decl)
- && EDGE_COUNT (EXIT_BLOCK_PTR->preds) > 0)
---- a/gcc/tree-pass.h
-+++ b/gcc/tree-pass.h
-@@ -323,6 +323,7 @@ extern struct gimple_opt_pass pass_scev_
- extern struct gimple_opt_pass pass_empty_loop;
- extern struct gimple_opt_pass pass_record_bounds;
- extern struct gimple_opt_pass pass_graphite_transforms;
-+extern struct gimple_opt_pass pass_promote_indices;
- extern struct gimple_opt_pass pass_if_conversion;
- extern struct gimple_opt_pass pass_loop_distribution;
- extern struct gimple_opt_pass pass_vectorize;
-@@ -388,6 +389,7 @@ extern struct gimple_opt_pass pass_reass
- extern struct gimple_opt_pass pass_rebuild_cgraph_edges;
- extern struct gimple_opt_pass pass_build_cgraph_edges;
- extern struct gimple_opt_pass pass_reset_cc_flags;
-+extern struct gimple_opt_pass pass_remove_local_statics;
-
- /* IPA Passes */
- extern struct ipa_opt_pass pass_ipa_inline;
---- a/gcc/tree-sra.c
-+++ b/gcc/tree-sra.c
-@@ -274,6 +274,12 @@ sra_type_can_be_decomposed_p (tree type)
- != TYPE_PRECISION (TREE_TYPE (t))))
- goto fail;
-
-+ /* Disable optimization of bitfields on BITS_BIG_ENDIAN
-+ architectures. SRA doesn't properly handle padding bits
-+ at the bottom, see issue6713. */
-+ if (DECL_BIT_FIELD (t) && BITS_BIG_ENDIAN)
-+ goto fail;
-+
- saw_one_field = true;
- }
-
---- /dev/null
-+++ b/gcc/tree-ssa-loop-promote.c
-@@ -0,0 +1,1628 @@
-+/* Promotion of shorter-than-word-size loop indices.
-+ Copyright (C) 2009 Free Software Foundation, Inc.
-+
-+This file is part of GCC.
-+
-+GCC is free software; you can redistribute it and/or modify it
-+under the terms of the GNU General Public License as published by the
-+Free Software Foundation; either version 3, or (at your option) any
-+later version.
-+
-+GCC is distributed in the hope that it will be useful, but WITHOUT
-+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-+for more details.
-+
-+You should have received a copy of the GNU General Public License
-+along with GCC; see the file COPYING3. If not see
-+<http://www.gnu.org/licenses/>. */
-+
-+/* This pass finds loop indices that are declared as
-+ shorter-than-word-size and replaces them with word-sized loop
-+ indices. (It assumes that word-sized quantities are the most
-+ efficient type on which to do arithmetic.) The loop optimization
-+ machinery has a difficult time seeing through the casts required to
-+ promote such indices to word-sized quantities for memory addressing
-+ and/or preserving the semantics of the source language (such as C).
-+ The transformation also helps eliminate unnecessary
-+ {sign,zero}-extensions required for the same.
-+
-+ Although this is most naturally expressed as a loop optimization
-+ pass, we choose to place this pass some ways before the loop
-+ optimization passes proper, so that other scalar optimizations will
-+ run on our "cleaned-up" code. This decision has the negative of
-+ requiring us to build and destroy all the loop optimization
-+ infrastructure.
-+
-+ The algorithm is relatively simple. For each single-exit loop, we
-+ identify the loop index variable. If the loop index variable is
-+ shorter than the word size, then we have a candidate for promotion.
-+ We determine whether the scalar evolution of the loop index fits a
-+ particular pattern (incremented by 1, compared against a
-+ similarly-typed loop bound, and only modified by a single increment
-+ within the loop), as well as examining the uses of the loop index to
-+ ensure we are able to safely promote those uses (e.g. the loop index
-+ must not be stored to memory or passed to function calls). If these
-+ conditions are satisfied, we create an appropriate word-sized type
-+ and replace all uses and defs of the loop index variable with the new
-+ variable. */
-+
-+#include "config.h"
-+#include "system.h"
-+#include "coretypes.h"
-+#include "tm.h"
-+
-+#include "toplev.h"
-+#include "rtl.h"
-+#include "tm_p.h"
-+#include "hard-reg-set.h"
-+#include "obstack.h"
-+#include "basic-block.h"
-+#include "pointer-set.h"
-+#include "intl.h"
-+
-+#include "tree.h"
-+#include "gimple.h"
-+#include "hashtab.h"
-+#include "diagnostic.h"
-+#include "tree-flow.h"
-+#include "tree-dump.h"
-+#include "cfgloop.h"
-+#include "flags.h"
-+#include "timevar.h"
-+#include "tree-pass.h"
-+
-+struct promote_info {
-+ /* The loop being analyzed. */
-+ struct loop *loop;
-+
-+ /* The GIMPLE_COND controlling exit from the loop. */
-+ gimple exit_expr;
-+
-+ /* The loop index variable's SSA_NAME that is defined in a phi node in
-+ LOOP->HEADER. Note that this SSA_NAME may be different than the
-+ one appearing in EXIT_EXPR. */
-+ tree loop_index_name;
-+
-+ /* The bound of the loop. */
-+ tree loop_limit;
-+
-+ /* Whether we've warned about things with
-+ warn_unsafe_loop_optimizations. */
-+ bool warned;
-+
-+ /* LOOP_INDEX_NAME's underlying VAR_DECL. */
-+ tree var_decl;
-+
-+ /* The types to which defs/uses of LOOP_INDEX_NAME are cast via
-+ NOP_EXPRs. */
-+ VEC(tree, heap) *cast_types;
-+
-+ /* The number of times we have seen a cast to the corresponding type
-+ (as determined by types_compatible_p) in CAST_TYPES. */
-+ VEC(int, heap) *cast_counts;
-+
-+ /* Whether LOOP_INDEX_NAME is suitable for promotion. */
-+ bool can_be_promoted_p;
-+
-+ /* If CAN_BE_PROMOTED_P, the promoted type. */
-+ tree promoted_type;
-+
-+ /* If CAN_BE_PROMOTED_P, the promoted VAR_DECL. */
-+ tree promoted_var;
-+};
-+
-+/* A set of `struct promote_info'. */
-+
-+static struct pointer_set_t *promotion_info;
-+
-+/* A set of all potentially promotable SSA_NAMEs, used for quick
-+decision-making during analysis. */
-+
-+static struct pointer_set_t *promotable_names;
-+
-+/* A map from SSA_NAMEs to the VAR_DECL to which they will be
-+ promoted. */
-+
-+static struct pointer_map_t *variable_map;
-+
-+/* A set of the stmts that we have already rebuilt with promoted variables. */
-+
-+static struct pointer_set_t *promoted_stmts;
-+
-+\f
-+/* Add CASTED to PI->CAST_TYPES if we haven't seen CASTED before. */
-+
-+static void
-+add_casted_type (struct promote_info *pi, tree casted)
-+{
-+ int i;
-+ tree type;
-+
-+ /* For this information to be useful later, CASTED must be wider than
-+ the type of the variable. */
-+ if (TYPE_PRECISION (casted) <= TYPE_PRECISION (TREE_TYPE (pi->var_decl)))
-+ return;
-+
-+ for (i = 0; VEC_iterate (tree, pi->cast_types, i, type); i++)
-+ if (types_compatible_p (casted, type))
-+ {
-+ int c = VEC_index(int, pi->cast_counts, i);
-+ VEC_replace(int, pi->cast_counts, i, ++c);
-+ return;
-+ }
-+
-+ /* Haven't see the type before. */
-+ VEC_safe_push (tree, heap, pi->cast_types, casted);
-+ VEC_safe_push (int, heap, pi->cast_counts, 1);
-+}
-+
-+/* Return the most-casted-to type in PI->CAST_TYPES. Return an
-+ appropriately signed variant of size_type_node if the variable wasn't
-+ cast in some fashion. */
-+
-+static tree
-+choose_profitable_promoted_type (struct promote_info *pi)
-+{
-+ int i;
-+ int count;
-+ tree type = NULL_TREE;
-+ int maxuse = -1;
-+
-+ for (i = 0; VEC_iterate (int, pi->cast_counts, i, count); i++)
-+ if (count > maxuse)
-+ {
-+ maxuse = count;
-+ type = VEC_index (tree, pi->cast_types, i);
-+ }
-+
-+ if (type == NULL_TREE)
-+ {
-+ if (dump_file)
-+ {
-+ fprintf (dump_file, "Warning, failed to find upcast type for ");
-+ print_generic_expr (dump_file, pi->loop_index_name, 0);
-+ fprintf (dump_file, "\n");
-+ }
-+ return (TYPE_UNSIGNED (TREE_TYPE (pi->var_decl))
-+ ? size_type_node
-+ : signed_type_for (size_type_node));
-+ }
-+ else
-+ return signed_type_for (type);
-+}
-+
-+/* Intuit the loop index for LOOP from PHI. There must be a path that
-+ only goes through NOP_EXPRs or CONVERT_EXPRs from the result of PHI
-+ to one of the operands of COND. If such a path cannot be found,
-+ return NULL_TREE. If LIMIT is not NULL and a path can be found,
-+ store the other operand of COND into LIMIT. */
-+
-+static tree
-+find_promotion_candidate_from_phi (struct loop *loop, gimple cond,
-+ gimple phi, tree *limit)
-+{
-+ tree op0, op1;
-+ tree result, candidate;
-+
-+ result = candidate = PHI_RESULT (phi);
-+ /* Must be an integer variable. */
-+ if (TREE_CODE (TREE_TYPE (candidate)) != INTEGER_TYPE)
-+ return NULL_TREE;
-+
-+ op0 = gimple_cond_lhs (cond);
-+ op1 = gimple_cond_rhs (cond);
-+
-+ /* See if there's a path from CANDIDATE to an operand of COND. */
-+ while (true)
-+ {
-+ use_operand_p use;
-+ imm_use_iterator iui;
-+ gimple use_stmt = NULL;
-+
-+ if (candidate == op0)
-+ {
-+ if (limit) *limit = op1;
-+ break;
-+ }
-+ if (candidate == op1)
-+ {
-+ if (limit) *limit = op0;
-+ break;
-+ }
-+
-+ /* Find a single use in the loop header. Give up if there's
-+ multiple ones. */
-+ FOR_EACH_IMM_USE_FAST (use, iui, candidate)
-+ {
-+ gimple stmt = USE_STMT (use);
-+
-+ if (gimple_bb (stmt) == loop->header)
-+ {
-+ if (use_stmt)
-+ {
-+ if (dump_file)
-+ {
-+ fprintf (dump_file, "Rejecting ");
-+ print_generic_expr (dump_file, candidate, 0);
-+ fprintf (dump_file, " because it has multiple uses in the loop header (bb #%d).\n",
-+ loop->header->index);
-+ fprintf (dump_file, "first use: ");
-+ print_gimple_stmt (dump_file, use_stmt, 0, 0);
-+ fprintf (dump_file, "\nsecond use: ");
-+ print_gimple_stmt (dump_file, stmt, 0, 0);
-+ fprintf (dump_file, "\n(possibly more, but unanalyzed)\n");
-+ }
-+ return NULL_TREE;
-+ }
-+ else
-+ use_stmt = stmt;
-+ }
-+ }
-+
-+ /* No uses in the loop header, bail. */
-+ if (use_stmt == NULL)
-+ return NULL_TREE;
-+
-+ if (gimple_code (use_stmt) != GIMPLE_ASSIGN
-+ || TREE_CODE (gimple_assign_lhs (use_stmt)) != SSA_NAME
-+ || (gimple_assign_rhs_code (use_stmt) != NOP_EXPR
-+ && gimple_assign_rhs_code (use_stmt) != CONVERT_EXPR))
-+ {
-+ if (dump_file)
-+ {
-+ fprintf (dump_file, "Rejecting ");
-+ print_generic_expr (dump_file, candidate, 0);
-+ fprintf (dump_file, " because of use in ");
-+ print_gimple_stmt (dump_file, use_stmt, 0, 0);
-+ fprintf (dump_file, "\n");
-+ }
-+ return NULL_TREE;
-+ }
-+
-+ candidate = gimple_assign_lhs (use_stmt);
-+ }
-+
-+ /* CANDIDATE is now what we believe to be the loop index variable. There
-+ are two possibilities:
-+
-+ - CANDIDATE is not the "true" loop index variable, but rather is a
-+ promoted version of RESULT, done for purposes of satisfying a
-+ language's semantics;
-+
-+ - CANDIDATE is the "true" loop index variable. */
-+ if (!types_compatible_p (TREE_TYPE (result), TREE_TYPE (candidate)))
-+ candidate = result;
-+
-+ /* The type of candidate must be "short" to consider promoting it. */
-+ if (TREE_CODE (TREE_TYPE (candidate)) != INTEGER_TYPE
-+ || TYPE_PRECISION (TREE_TYPE (candidate)) >= TYPE_PRECISION (size_type_node))
-+ return NULL_TREE;
-+
-+ return candidate;
-+}
-+
-+/* Find the loop index variable of LOOP. LOOP's exit is controlled by
-+ the COND_EXPR EXPR. IF we can't determine what the loop index
-+ variable is, or EXPR does not appear to be analyzable, then return
-+ NULL_TREE. */
-+
-+static tree
-+find_promotion_candidate (struct loop *loop, gimple cond, tree *limit)
-+{
-+ tree candidate = NULL_TREE;
-+ gimple_stmt_iterator gsi;
-+
-+ switch (gimple_cond_code (cond))
-+ {
-+ case GT_EXPR:
-+ case GE_EXPR:
-+ case NE_EXPR:
-+ case LT_EXPR:
-+ case LE_EXPR:
-+ break;
-+
-+ default:
-+ return NULL_TREE;
-+ }
-+
-+ /* We'd like to examine COND and intuit the loop index variable from
-+ there. Instead, we're going to start from the phi nodes in BB and
-+ attempt to work our way forwards to one of the operands of COND,
-+ since starting from COND might yield an upcast loop index. If we
-+ find multiple phi nodes whose results reach COND, then give up. */
-+ for (gsi = gsi_start_phis (loop->header); !gsi_end_p (gsi); gsi_next (&gsi))
-+ {
-+ gimple phi = gsi_stmt (gsi);
-+ tree t = find_promotion_candidate_from_phi (loop, cond, phi, limit);
-+
-+ if (t == NULL_TREE)
-+ continue;
-+ else if (candidate == NULL_TREE)
-+ candidate = t;
-+ else
-+ {
-+ if (dump_file)
-+ {
-+ fprintf (dump_file, "Can't find a candidate from ");
-+ print_gimple_stmt (dump_file, cond, 0, 0);
-+ fprintf (dump_file, "\n because too many phi node results reach the condition.\n");
-+ }
-+ return NULL_TREE;
-+ }
-+ }
-+
-+ return candidate;
-+}
-+
-+/* Return true if X is something that could be promoted. */
-+
-+static bool
-+could_be_promoted (tree x)
-+{
-+ return (TREE_CODE (x) == INTEGER_CST
-+ || (TREE_CODE (x) == SSA_NAME
-+ && pointer_set_contains (promotable_names, x)));
-+}
-+
-+/* Examine the RHS of STMT's suitability with respect to being able to
-+ promote VAR. */
-+
-+static bool
-+check_rhs_for_promotability (struct promote_info *pi, tree var, gimple stmt,
-+ bool is_assign)
-+{
-+ enum tree_code subcode = gimple_assign_rhs_code (stmt);
-+
-+ bool ok = true;
-+
-+ switch (subcode)
-+ {
-+ case PLUS_EXPR:
-+ case MINUS_EXPR:
-+ case MULT_EXPR:
-+ case EQ_EXPR:
-+ case NE_EXPR:
-+ case LT_EXPR:
-+ case LE_EXPR:
-+ case GT_EXPR:
-+ case GE_EXPR:
-+ {
-+ tree op0 = gimple_assign_rhs1 (stmt);
-+ tree op1 = gimple_assign_rhs2 (stmt);
-+
-+ ok = ((op0 == var && could_be_promoted (op1))
-+ || (op1 == var && could_be_promoted (op0)));
-+ break;
-+ }
-+ case COND_EXPR:
-+ if (gimple_expr_type (stmt) == NULL
-+ || gimple_expr_type (stmt) == void_type_node)
-+ ok = true;
-+ else
-+ /* This is conservative; it's possible that these sorts of nodes
-+ could be promoted, but we'd have to be very careful about
-+ checking in which parts of the COND_EXPR the promotable
-+ variable(s) are. */
-+ ok = false;
-+ break;
-+ case SSA_NAME:
-+ {
-+ tree expr = gimple_assign_rhs1 (stmt);
-+ ok = (expr == var || could_be_promoted (expr));
-+ }
-+ break;
-+ case INTEGER_CST:
-+ break;
-+ case NOP_EXPR:
-+ case CONVERT_EXPR:
-+ if (!is_assign)
-+ {
-+ add_casted_type (pi, gimple_expr_type (stmt));
-+ break;
-+ }
-+ /* Fallthrough. */
-+ default:
-+ ok = false;
-+ break;
-+ }
-+
-+ return ok;
-+}
-+
-+/* Analyze the loop index VAR for promotability. The rules for
-+ promotability are:
-+
-+ For uses:
-+
-+ - The underlying variable may be used in NOP_EXPRs.
-+
-+ - The underlying variable may be used in simple arithmmetic
-+ expressions so long as the other parts are potentially promotable
-+ variables or constants (so we don't go willy-nilly on promoting
-+ things).
-+
-+ - The underlying variable may not be stored to memory.
-+
-+ - All uses must occur inside the loop.
-+
-+ For defs:
-+
-+ - The underlying variable may not be loaded from memory; and
-+
-+ - The underlying variable may only be formed from expressions
-+ involving potentially promotable varibles or constants.
-+
-+ Note that defs may occur outside of the loop; we do this to handle
-+ initial conditions before entering the loop. */
-+
-+static void
-+analyze_loop_index_uses (tree var, struct promote_info *pi)
-+{
-+ imm_use_iterator iui;
-+ use_operand_p use;
-+ gimple bad_stmt = NULL;
-+ const char *reason = NULL;
-+
-+ FOR_EACH_IMM_USE_FAST (use, iui, var)
-+ {
-+ basic_block bb;
-+ gimple use_stmt = USE_STMT (use);
-+
-+ /* Uses must exist only within the loop. */
-+ bb = gimple_bb (use_stmt);
-+
-+ if (dump_file)
-+ {
-+ fprintf (dump_file, "Checking ");
-+ print_gimple_stmt (dump_file, use_stmt, 0, 0);
-+ fprintf (dump_file, "\n");
-+ }
-+
-+ if (!flow_bb_inside_loop_p (pi->loop, bb))
-+ {
-+ bad_stmt = use_stmt;
-+ reason = " is involved in stmt outside loop ";
-+ break;
-+ }
-+
-+ /* We cannot store the index to memory. */
-+ if (gimple_references_memory_p (use_stmt))
-+ {
-+ bad_stmt = use_stmt;
-+ reason = " is stored to memory in ";
-+ break;
-+ }
-+
-+ if (gimple_code (use_stmt) == GIMPLE_CALL)
-+ {
-+ /* We cannot pass the variable to a function. */
-+ bad_stmt = use_stmt;
-+ reason = " is passed to function in ";
-+ break;
-+ }
-+ else if (gimple_code (use_stmt) == GIMPLE_ASSIGN)
-+ {
-+ tree lhs = gimple_assign_lhs (use_stmt);
-+
-+ if (!check_rhs_for_promotability (pi, var, use_stmt,
-+ /*is_assign=*/false))
-+ {
-+ bad_stmt = use_stmt;
-+ reason = " is involved in non-promotable expression ";
-+ break;
-+ }
-+ else if ((TREE_CODE_CLASS (gimple_assign_rhs_code (use_stmt)) == tcc_binary
-+ || gimple_assign_rhs_code (use_stmt) == SSA_NAME)
-+ && !could_be_promoted (lhs))
-+ {
-+ bad_stmt = use_stmt;
-+ reason = " is being assigned to non-promotable variable ";
-+ break;
-+ }
-+ }
-+ else if (gimple_code (use_stmt) != GIMPLE_COND
-+ && gimple_code (use_stmt) != GIMPLE_PHI)
-+ {
-+ /* Use of the variable in some statement we don't know how to
-+ analyze. */
-+ bad_stmt = use_stmt;
-+ reason = " is used in unanalyzable expression in ";
-+ break;
-+ }
-+ }
-+
-+ if (bad_stmt && reason)
-+ {
-+ if (dump_file)
-+ {
-+ fprintf (dump_file, "Loop index ");
-+ print_generic_expr (dump_file, var, 0);
-+ fprintf (dump_file, "%s", reason);
-+ print_gimple_stmt (dump_file, bad_stmt, 0, 0);
-+ fprintf (dump_file, "\n");
-+ }
-+ pi->can_be_promoted_p = false;
-+ }
-+}
-+
-+/* Check that the uses and def of VAR, defined in STMT, conform to the
-+ rules given above. */
-+
-+static bool
-+analyze_loop_index (tree var, gimple stmt, void *data)
-+{
-+ struct promote_info *pi = (struct promote_info *) data;
-+
-+ if (dump_file)
-+ {
-+ fprintf (dump_file, "Analyzing loop index ");
-+ print_generic_expr (dump_file, var, 0);
-+ fprintf (dump_file, " defined in ");
-+ print_gimple_stmt (dump_file, stmt, 0, 0);
-+ fprintf (dump_file, "\n");
-+ }
-+
-+ /* Check the definition. */
-+ switch (gimple_code (stmt))
-+ {
-+ case GIMPLE_PHI:
-+ /* Phi nodes are OK. */
-+ break;
-+
-+ case GIMPLE_ASSIGN:
-+ if (!check_rhs_for_promotability (pi, var, stmt,
-+ /*is_assign=*/true))
-+ break;
-+ /* Fallthrough. */
-+
-+ default:
-+ /* Something we can't handle or the variable is being loaded from
-+ memory. */
-+ pi->can_be_promoted_p = false;
-+ goto done;
-+ }
-+
-+ if (gimple_code (stmt) == GIMPLE_PHI)
-+ {
-+ unsigned int i;
-+
-+ for (i = 0; i < gimple_phi_num_args (stmt); i++)
-+ {
-+ tree arg = PHI_ARG_DEF (stmt, i);
-+
-+ if (TREE_CODE (arg) == SSA_NAME)
-+ pointer_set_insert (promotable_names, arg);
-+ }
-+
-+ analyze_loop_index_uses (PHI_RESULT (stmt), pi);
-+ }
-+ else
-+ analyze_loop_index_uses (var, pi);
-+
-+ /* Only worth continuing if we think the loop index can be
-+ promoted. */
-+ done:
-+ if (dump_file)
-+ {
-+ fprintf (dump_file, "Done analyzing ");
-+ print_generic_expr (dump_file, var, 0);
-+ fprintf (dump_file, " defined in ");
-+ print_gimple_stmt (dump_file, stmt, 0, 0);
-+ fprintf (dump_file, "...%s to analyze\n\n",
-+ pi->can_be_promoted_p ? "continuing" : "not continuing");
-+ }
-+ return !pi->can_be_promoted_p;
-+}
-+
-+/* Determine whether T is an INTEGER_CST or a single-use SSA_NAME
-+ defined as the result of a NOP_EXPR or CONVERT_EXPR. Return the
-+ operand of the NOP_EXPR or CONVERT_EXPR if so. */
-+
-+static tree
-+upcast_operand_p (tree t)
-+{
-+ gimple def;
-+
-+ if (TREE_CODE (t) == INTEGER_CST)
-+ return t;
-+
-+ if (TREE_CODE (t) != SSA_NAME
-+ || !has_single_use (t))
-+ return NULL_TREE;
-+
-+ def = SSA_NAME_DEF_STMT (t);
-+ if (gimple_code (def) != GIMPLE_ASSIGN)
-+ return NULL_TREE;
-+
-+ if (gimple_assign_rhs_code (def) != CONVERT_EXPR
-+ && gimple_assign_rhs_code (def) != NOP_EXPR)
-+ return NULL_TREE;
-+
-+ return gimple_assign_rhs1 (def);
-+}
-+
-+/* Check for the idiom:
-+
-+ short x, y;
-+ unsigned short x.2, y.2, tmp;
-+ ...
-+ x.2 = (unsigned short) x;
-+ y.2 = (unsigned short) y;
-+ tmp = x.2 + y.2;
-+ x = (short) tmp;
-+
-+ which is generated by convert for avoiding signed arithmetic
-+ overflow. RHS is TMP in the above statement. If RHS is
-+ defined via such an idiom, store x and y into *OP0 and *OP1,
-+ respectively. We permit y.2 to be a constant if necessary. */
-+
-+static bool
-+signed_arithmetic_overflow_idiom_p (tree rhs, tree *op0, tree *op1)
-+{
-+ gimple op_stmt = SSA_NAME_DEF_STMT (rhs);
-+ tree x2, y2;
-+ bool yes = false;
-+ enum tree_code code;
-+
-+ if (!has_single_use (rhs)
-+ || gimple_code (op_stmt) != GIMPLE_ASSIGN)
-+ goto done;
-+
-+ /* This could probably profitably be expanded to consider
-+ MINUS_EXPR, MULT_EXPR, etc. */
-+ code = gimple_assign_rhs_code (op_stmt);
-+ if (code != PLUS_EXPR)
-+ goto done;
-+ x2 = gimple_assign_rhs1 (op_stmt);
-+ y2 = gimple_assign_rhs2 (op_stmt);
-+
-+ x2 = upcast_operand_p (x2);
-+ if (x2 == NULL_TREE)
-+ goto done;
-+ y2 = upcast_operand_p (y2);
-+ if (y2 == NULL_TREE)
-+ goto done;
-+
-+ *op0 = x2;
-+ *op1 = y2;
-+ yes = true;
-+
-+ done:
-+ return yes;
-+}
-+
-+/* Simple wrapper around flow_bb_inside_loop_p that handles NULL
-+ statements and initial definitions of variables. */
-+
-+static bool
-+stmt_in_loop_p (gimple t, struct loop *loop)
-+{
-+ basic_block bb;
-+
-+ if (t == NULL)
-+ return false;
-+
-+ bb = gimple_bb (t);
-+ if (bb == NULL)
-+ return false;
-+
-+ return flow_bb_inside_loop_p (loop, bb);
-+}
-+
-+/* The loop index should have a specific usage pattern:
-+
-+ - It should be defined in a phi node with two incoming values:
-+
-+ LI_phi = PHI (LI_out, LI_in)
-+
-+ - One incoming value, LI_out, should be from outside the loop.
-+
-+ - The other incoming value, LI_in, should be defined thusly:
-+
-+ LI_in = LI_phi + increment
-+
-+ - increment should be 1. We permit other increments with
-+ -funsafe-loop-optimizations.
-+
-+ - Finally, in the comparison to exit the loop, the loop index must be
-+ compared against a variable that has a type at least as precise as
-+ the loop index's type. For instance, something like:
-+
-+ char limit;
-+ short i;
-+
-+ for (i = 0; i < limit; i++) ...
-+
-+ would not be permitted. */
-+
-+static bool
-+analyze_loop_index_definition_pattern (struct promote_info *pi)
-+{
-+ gimple phi = SSA_NAME_DEF_STMT (pi->loop_index_name);
-+ bool ok = false, warn = false;
-+ tree in0, in1;
-+ bool inside0, inside1;
-+ gimple def0, def1;
-+ tree op0, op1, increment = NULL_TREE;
-+
-+ if (gimple_code (phi) != GIMPLE_PHI
-+ || gimple_phi_num_args (phi) != 2)
-+ goto done;
-+
-+ in0 = PHI_ARG_DEF (phi, 0);
-+ in1 = PHI_ARG_DEF (phi, 1);
-+
-+ /* Figure out which value comes from outside the loop. */
-+ def0 = TREE_CODE (in0) == SSA_NAME ? SSA_NAME_DEF_STMT (in0) : NULL;
-+ def1 = TREE_CODE (in1) == SSA_NAME ? SSA_NAME_DEF_STMT (in1) : NULL;
-+
-+ inside0 = stmt_in_loop_p (def0, pi->loop);
-+ inside1 = stmt_in_loop_p (def1, pi->loop);
-+
-+ if (inside0 && inside1)
-+ goto done;
-+ else if (inside0)
-+ {
-+ tree t = in0;
-+ gimple g;
-+ in0 = in1;
-+ in1 = t;
-+ g = def0;
-+ def0 = def1;
-+ def1 = g;
-+ }
-+ else if (!inside1)
-+ goto done;
-+
-+ /* IN0 comes from outside the loop, IN1 from inside. Analyze IN1. */
-+ if (gimple_code (def1) != GIMPLE_ASSIGN)
-+ goto done;
-+
-+ switch (gimple_assign_rhs_code (def1))
-+ {
-+ case CONVERT_EXPR:
-+ case NOP_EXPR:
-+ if (!signed_arithmetic_overflow_idiom_p (gimple_assign_rhs1 (def1),
-+ &op0, &op1))
-+ goto done;
-+ goto plus;
-+ case PLUS_EXPR:
-+ op0 = gimple_assign_rhs1 (def1);
-+ op1 = gimple_assign_rhs2 (def1);
-+ plus:
-+ {
-+ bool op0_li = op0 == PHI_RESULT (phi);
-+ bool op1_li = op1 == PHI_RESULT (phi);
-+ if (op0_li && op1_li)
-+ /* This is weird, and definitely is not a case we can support
-+ for promotion. */
-+ goto done;
-+ else if (op0_li)
-+ increment = op1;
-+ else if (op1_li)
-+ increment = op0;
-+ else
-+ goto done;
-+ break;
-+ }
-+ default:
-+ break;
-+ }
-+
-+
-+ /* Check that the exit condition for the loop is OK. */
-+ {
-+ enum tree_code code = gimple_cond_code (pi->exit_expr);
-+
-+ op0 = gimple_cond_lhs (pi->exit_expr);
-+ op1 = gimple_cond_rhs (pi->exit_expr);
-+
-+ if (op0 == pi->loop_limit)
-+ {
-+ tree t = op0;
-+ op0 = op1;
-+ op1 = t;
-+ code = swap_tree_comparison (code);
-+ }
-+
-+ if (code != LT_EXPR && code != LE_EXPR)
-+ goto done;
-+
-+ if (!types_compatible_p (TREE_TYPE (pi->loop_index_name),
-+ TREE_TYPE (pi->loop_limit)))
-+ {
-+ switch (TREE_CODE (pi->loop_limit))
-+ {
-+ case INTEGER_CST:
-+ if (!int_fits_type_p (pi->loop_limit,
-+ TREE_TYPE (pi->loop_index_name)))
-+ goto done;
-+ break;
-+ case SSA_NAME:
-+ {
-+ tree v = pi->loop_limit;
-+ gimple def = SSA_NAME_DEF_STMT (v);
-+
-+ /* Backtrack through CONVERT_EXPRs and/or NOP_EXPRs to
-+ determine if the variables "started out" as the same
-+ type. */
-+ while (gimple_code (def) == GIMPLE_ASSIGN)
-+ {
-+ enum tree_code rhs_code = gimple_assign_rhs_code (def);
-+
-+ if (rhs_code != NOP_EXPR && rhs_code != CONVERT_EXPR)
-+ break;
-+
-+ v = gimple_assign_rhs1 (def);
-+ def = SSA_NAME_DEF_STMT (v);
-+ }
-+ /* Permit comparisons between non-compatible types with
-+ flag_unsafe_loop_optimizations, since we can assume the
-+ loop index does not overflow. */
-+ if (types_compatible_p (TREE_TYPE (pi->loop_index_name),
-+ TREE_TYPE (v))
-+ || flag_unsafe_loop_optimizations)
-+ break;
-+ /* Fallthrough. */
-+ default:
-+ goto done;
-+ }
-+ }
-+ }
-+ }
-+
-+ if (increment == NULL_TREE)
-+ goto done;
-+ if (TREE_CODE (increment) != INTEGER_CST
-+ || compare_tree_int (increment, 1) != 0)
-+ {
-+ warn = true;
-+ if (!flag_unsafe_loop_optimizations)
-+ goto done;
-+ }
-+
-+ ok = true;
-+ done:
-+ if (warn && !pi->warned)
-+ {
-+ pi->warned = true;
-+ /* We can promote unsigned indices only if -funsafe-loop-optimizations
-+ is in effect, since the user might be depending on the modulo
-+ wraparound behavior of unsigned types. */
-+ if (warn_unsafe_loop_optimizations)
-+ {
-+ const char *wording;
-+
-+ wording = (flag_unsafe_loop_optimizations
-+ ? N_("assuming that the loop counter does not overflow")
-+ : N_("cannot optimize loop, the loop counter may overflow"));
-+ warning (OPT_Wunsafe_loop_optimizations, "%s", gettext (wording));
-+ }
-+ }
-+
-+ return ok;
-+}
-+
-+/* Analyze the loop associated with PI_ to see if its loop index can be
-+ promoted. */
-+
-+static bool
-+analyze_loop (const void *pi_, void *data)
-+{
-+ struct promote_info *pi = CONST_CAST (struct promote_info *,
-+ (const struct promote_info *) pi_);
-+ bool *changed = (bool *) data;
-+
-+ /* We previously determined we can't promote this; go ahead and
-+ continue iterating. */
-+ if (pi->loop_index_name == NULL_TREE)
-+ return true;
-+
-+ /* Assume we can always promote the loop index, even if it doesn't
-+ exist. */
-+ pi->can_be_promoted_p = true;
-+
-+ if (dump_file)
-+ {
-+ fprintf (dump_file, "Analyzing ");
-+ print_generic_expr (dump_file, pi->loop_index_name, 0);
-+ fprintf (dump_file, "\n");
-+ }
-+
-+ if (pi->loop_index_name
-+ && analyze_loop_index_definition_pattern (pi))
-+ {
-+ /* Clear any previously gathered information. */
-+ VEC_truncate (tree, pi->cast_types, 0);
-+ VEC_truncate (int, pi->cast_counts, 0);
-+
-+ walk_use_def_chains (pi->loop_index_name, analyze_loop_index, pi, false);
-+ }
-+ else
-+ pi->can_be_promoted_p = false;
-+
-+ /* If we determined the loop index is used in strange ways, clear it
-+ so we don't examine it again. */
-+ if (!pi->can_be_promoted_p)
-+ pi->loop_index_name = NULL_TREE;
-+
-+ /* Let our caller know whether to re-do the analysis. */
-+ *changed = *changed || !pi->can_be_promoted_p;
-+ /* Continue if PI is promotable. */
-+ return pi->can_be_promoted_p;
-+}
-+
-+/* Add PI_->LOOP_INDEX_NAME to the set of variables, DATA, that we are
-+ considering for promotion. */
-+
-+static bool
-+add_variable (const void *pi_, void *data ATTRIBUTE_UNUSED)
-+{
-+ const struct promote_info *pi = (const struct promote_info *) pi_;
-+ struct pointer_set_t *pset = (struct pointer_set_t *) data;
-+ int presentp;
-+
-+ if (pi->loop_index_name != NULL_TREE)
-+ {
-+ presentp = pointer_set_insert (pset, pi->loop_index_name);
-+ gcc_assert (!presentp);
-+ }
-+
-+ /* Continue traversal. */
-+ return true;
-+}
-+
-+/* For each promotable variable:
-+
-+ - create a new, promoted VAR_DECL;
-+
-+ - walk through all the uses and defs and create new statements using
-+ the promoted variables. We don't create new phi nodes; post-pass
-+ SSA update will handle those for us. */
-+
-+/* Make dump files readable. */
-+#define PROMOTED_VAR_SUFFIX ".promoted"
-+
-+/* Create a variable NAME with TYPE and do the necessary work to inform
-+ the SSA machinery about it. */
-+
-+static tree
-+create_pli_var (tree type, char *name)
-+{
-+ tree var = create_tmp_var (type, name);
-+ create_var_ann (var);
-+ mark_sym_for_renaming (var);
-+ add_referenced_var (var);
-+ return var;
-+}
-+
-+/* Associate the SSA_NAME VAR with the promoted variable DATA. */
-+
-+static bool
-+associate_name_with_var (tree var, gimple def_stmt, void *data)
-+{
-+ tree promoted_var = (tree) data;
-+ void **p;
-+
-+ gcc_assert (promoted_var != NULL_TREE);
-+
-+ if (gimple_code (def_stmt) == GIMPLE_PHI)
-+ var = PHI_RESULT (def_stmt);
-+
-+ p = pointer_map_insert (variable_map, var);
-+
-+ if (!*p)
-+ {
-+ if (dump_file)
-+ {
-+ fprintf (dump_file, "Associating ");
-+ print_generic_expr (dump_file, var, 0);
-+ fprintf (dump_file, " with ");
-+ print_generic_expr (dump_file, promoted_var, 0);
-+ fprintf (dump_file, "\n\n");
-+ }
-+ *(tree *)p = promoted_var;
-+ }
-+
-+ /* Continue traversal. */
-+ return false;
-+}
-+
-+/* Create a promoted variable for the variable from PI_. */
-+
-+static bool
-+create_promoted_variable (const void *pi_, void *data ATTRIBUTE_UNUSED)
-+{
-+ struct promote_info *pi = CONST_CAST (struct promote_info *,
-+ (const struct promote_info *) pi_);
-+
-+ if (pi->can_be_promoted_p)
-+ {
-+ tree type = choose_profitable_promoted_type (pi);
-+ tree orig_name = DECL_NAME (pi->var_decl);
-+ size_t id_len = IDENTIFIER_LENGTH (orig_name);
-+ size_t name_len = id_len + strlen (PROMOTED_VAR_SUFFIX) + 1;
-+ char *name;
-+
-+ name = (char *) alloca (name_len);
-+ strcpy (name, IDENTIFIER_POINTER (orig_name));
-+ strcpy (name + id_len, PROMOTED_VAR_SUFFIX);
-+
-+ pi->promoted_type = type;
-+ pi->promoted_var = create_pli_var (type, name);
-+
-+ if (dump_file)
-+ {
-+ fprintf (dump_file, "Created new variable ");
-+ print_generic_expr (dump_file, pi->promoted_var, 0);
-+ fprintf (dump_file, " to stand in for ");
-+ print_generic_expr (dump_file, pi->loop_index_name, 0);
-+ fprintf (dump_file, "\n\n");
-+ }
-+
-+ walk_use_def_chains (pi->loop_index_name,
-+ associate_name_with_var,
-+ pi->promoted_var, false);
-+ }
-+
-+ /* Continue traversal. */
-+ return true;
-+}
-+
-+/* Rebuild T with newly promoted variables; STMT is the original
-+ statement in which T appeared and may be equivalent to T. TYPE is
-+ non-null when rebuilding the rhs of a GIMPLE_ASSIGN and indicates the
-+ type of the lhs. */
-+
-+static tree
-+rebuild_tree_with_promotion (tree t, gimple stmt, tree type,
-+ gimple_stmt_iterator gsi,
-+ struct promote_info *pi)
-+{
-+ tree op0, op1;
-+
-+ switch (TREE_CODE (t))
-+ {
-+ case NOP_EXPR:
-+ case CONVERT_EXPR:
-+ {
-+ tree pvar = rebuild_tree_with_promotion (TREE_OPERAND (t, 0), stmt, type, gsi, pi);
-+
-+ if (types_compatible_p (type, TREE_TYPE (pvar)))
-+ return pvar;
-+ else
-+ return build1 (TREE_CODE (t), type, pvar);
-+ }
-+ case INTEGER_CST:
-+ {
-+ return build_int_cst_wide (pi->promoted_type,
-+ TREE_INT_CST_LOW (t),
-+ TREE_INT_CST_HIGH (t));
-+ }
-+ case COND_EXPR:
-+ {
-+ tree orig_op0 = TREE_OPERAND (t, 0);
-+ op0 = rebuild_tree_with_promotion (orig_op0, stmt, type, gsi, pi);
-+ gcc_assert (orig_op0 != op0);
-+ TREE_OPERAND (t, 0) = op0;
-+ return t;
-+ }
-+ case PLUS_EXPR:
-+ case MINUS_EXPR:
-+ case MULT_EXPR:
-+ type = pi->promoted_type;
-+ goto binary_expr;
-+ case EQ_EXPR:
-+ case NE_EXPR:
-+ case LT_EXPR:
-+ case LE_EXPR:
-+ case GT_EXPR:
-+ case GE_EXPR:
-+ type = TREE_TYPE (t);
-+ binary_expr:
-+ op0 = TREE_OPERAND (t, 0);
-+ op1 = TREE_OPERAND (t, 1);
-+ op0 = rebuild_tree_with_promotion (op0, stmt, type, gsi, pi);
-+ op1 = rebuild_tree_with_promotion (op1, stmt, type, gsi, pi);
-+ return build2 (TREE_CODE (t), type, op0, op1);
-+ case SSA_NAME:
-+ {
-+ void **p = pointer_map_contains (variable_map, t);
-+
-+ if (p == NULL)
-+ {
-+ /* This is unexpected, but it does happen if we were dealing
-+ with COND_EXPRs and such. Just go ahead and create a
-+ temporary for it. */
-+ if (types_compatible_p (TREE_TYPE (t), pi->promoted_type)
-+ || SSA_NAME_DEF_STMT (t) == stmt)
-+ return t;
-+ else
-+ goto insert_cast;
-+ }
-+ else
-+ return *(tree *)p;
-+ }
-+ case VAR_DECL:
-+ return t;
-+ default:
-+ insert_cast:
-+ {
-+ gimple cast;
-+ tree tmp, nop;
-+ tree to_upcast = t;
-+
-+ /* If we are dealing with a memory reference, then we can't have
-+ wrap it in a NOP_EXPR; we need to load the value from memory
-+ first, then convert it. */
-+ if (!is_gimple_reg (to_upcast))
-+ {
-+ tree tmp = create_pli_var (TREE_TYPE (to_upcast),
-+ CONST_CAST (char *, "loadtmp"));
-+ gimple stmt = gimple_build_assign (tmp, to_upcast);
-+ gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
-+ to_upcast = tmp;
-+ }
-+
-+ tmp = create_pli_var (pi->promoted_type,
-+ CONST_CAST (char *, "promotetmp"));
-+ nop = build1 (NOP_EXPR, pi->promoted_type, to_upcast);
-+ cast = gimple_build_assign (tmp, nop);
-+ if (dump_file)
-+ {
-+ fprintf (dump_file, "Inserting cast ");
-+ print_gimple_stmt (dump_file, cast, 0, 0);
-+ fprintf (dump_file, " prior to ");
-+ print_gimple_stmt (dump_file, stmt, 0, 0);
-+ fprintf (dump_file, "\n");
-+ }
-+ gsi_insert_before (&gsi, cast, GSI_SAME_STMT);
-+ return tmp;
-+ }
-+ }
-+}
-+
-+/* Split E and place STMT in the block created by doing so. */
-+
-+static void
-+insert_along_edge (gimple stmt, edge e)
-+{
-+ basic_block bb = split_edge (e);
-+
-+ gimple_set_bb (stmt, bb);
-+ set_bb_seq (bb, gimple_seq_alloc_with_stmt (stmt));
-+}
-+
-+/* Rebuild STMT, which contains uses or a def of the promotable variable
-+ associated with PI. */
-+
-+static void
-+rebuild_with_promotion (gimple stmt, struct promote_info *pi)
-+{
-+ gimple_stmt_iterator gsi;
-+
-+ if (pointer_set_insert (promoted_stmts, stmt))
-+ return;
-+
-+ if (dump_file)
-+ {
-+ fprintf (dump_file, "Rebuilding stmt ");
-+ print_gimple_stmt (dump_file, stmt, 0, 0);
-+ fprintf (dump_file, "\n");
-+ }
-+
-+ gsi = gsi_for_stmt (stmt);
-+
-+ switch (gimple_code (stmt))
-+ {
-+ case GIMPLE_ASSIGN:
-+ {
-+ enum tree_code subcode = gimple_assign_rhs_code (stmt);
-+ enum tree_code newcode = subcode;
-+ tree lhs = gimple_assign_lhs (stmt);
-+ tree rhs1 = gimple_assign_rhs1 (stmt);
-+ tree rhs2 = gimple_assign_rhs2 (stmt);
-+ tree x, y;
-+ void **v;
-+
-+ /* If we are defining a promotable variable, check for special
-+ idioms. */
-+ v = pointer_map_contains (variable_map, lhs);
-+ if (v != NULL
-+ && *(tree *)v == pi->promoted_var
-+ && (subcode == NOP_EXPR || subcode == CONVERT_EXPR)
-+ && signed_arithmetic_overflow_idiom_p (rhs1, &x, &y))
-+ {
-+ void **xp;
-+ void **yp;
-+ if (TYPE_PRECISION (TREE_TYPE (rhs1))
-+ >= TYPE_PRECISION (pi->promoted_type))
-+ goto done;
-+
-+ /* It's possible that we've already promoted the operands of
-+ one or both of the NOP_EXPRs. In that case, we can
-+ bypass the logic below and go straight to rebuilding the
-+ rhs that we really want to transform. */
-+ if (TREE_CODE (x) == VAR_DECL
-+ || TREE_CODE (y) == VAR_DECL)
-+ goto build_fake;
-+ xp = pointer_map_contains (variable_map, x);
-+ yp = pointer_map_contains (variable_map, y);
-+
-+ /* Nothing to see here. */
-+ if (!types_compatible_p (TREE_TYPE (x),
-+ TREE_TYPE (y))
-+ || (xp == NULL && yp == NULL))
-+ goto done;
-+ x = (xp == NULL ? NULL_TREE : *(tree *)xp);
-+ y = (yp == NULL ? NULL_TREE : *(tree *)yp);
-+
-+ if (x != pi->promoted_var && y != pi->promoted_var)
-+ goto done;
-+
-+ build_fake:
-+ newcode = PLUS_EXPR;
-+ rhs1 = x;
-+ rhs2 = y;
-+ if (dump_file)
-+ {
-+ fprintf (dump_file, "Substituting ");
-+ print_generic_expr (dump_file, x, 0);
-+ fprintf (dump_file, " + ");
-+ print_generic_expr (dump_file, y, 0);
-+ fprintf (dump_file, " for rhs of original statement\n");
-+ }
-+
-+ done:
-+ ;
-+ }
-+
-+ lhs = rebuild_tree_with_promotion (lhs, stmt, NULL, gsi, pi);
-+ rhs1 = rebuild_tree_with_promotion (rhs1, stmt, NULL, gsi, pi);
-+ if (rhs2)
-+ rhs2 = rebuild_tree_with_promotion (rhs2, stmt, NULL, gsi, pi);
-+
-+ if (newcode != subcode)
-+ {
-+ gimple newstmt = gimple_build_assign_with_ops (newcode,
-+ lhs, rhs1, rhs2);
-+ gsi_replace (&gsi, newstmt, true);
-+ stmt = newstmt;
-+ }
-+ else
-+ {
-+ gimple_assign_set_lhs (stmt, lhs);
-+ gimple_assign_set_rhs1 (stmt, rhs1);
-+ if (rhs2)
-+ gimple_assign_set_rhs2 (stmt, rhs2);
-+ }
-+ }
-+ break;
-+ case GIMPLE_COND:
-+ {
-+ tree lhs = gimple_cond_lhs (stmt);
-+ tree rhs = gimple_cond_rhs (stmt);
-+
-+ lhs = rebuild_tree_with_promotion (lhs, stmt, NULL, gsi, pi);
-+ rhs = rebuild_tree_with_promotion (rhs, stmt, NULL, gsi, pi);
-+
-+ gimple_cond_set_lhs (stmt, lhs);
-+ gimple_cond_set_rhs (stmt, rhs);
-+ }
-+ break;
-+ case GIMPLE_PHI:
-+ {
-+ unsigned int i;
-+ bool promoted_result = could_be_promoted (PHI_RESULT (stmt));
-+
-+ for (i = 0; i < gimple_phi_num_args (stmt); i++)
-+ {
-+ tree var = gimple_phi_arg_def (stmt, i);
-+ edge e = gimple_phi_arg_edge (stmt, i);
-+ gimple assign = NULL;
-+
-+ if (TREE_CODE (var) == INTEGER_CST && promoted_result)
-+ {
-+ tree cst = build_int_cst_wide (pi->promoted_type,
-+ TREE_INT_CST_LOW (var),
-+ TREE_INT_CST_HIGH (var));
-+
-+ assign = gimple_build_assign (pi->promoted_var, cst);
-+ insert_along_edge (assign, e);
-+ }
-+ else if (TREE_CODE (var) == SSA_NAME
-+ && SSA_NAME_VAR (var) == pi->var_decl
-+ && !promoted_result)
-+ {
-+ tree t = create_pli_var (TREE_TYPE (PHI_RESULT (stmt)),
-+ CONST_CAST (char *, "promotetmp"));
-+ tree name;
-+ assign = gimple_build_assign_with_ops (CONVERT_EXPR,
-+ t, pi->promoted_var,
-+ NULL_TREE);
-+
-+ name = make_ssa_name (t, assign);
-+ gimple_assign_set_lhs (assign, name);
-+
-+ insert_along_edge (assign, e);
-+ SET_PHI_ARG_DEF (stmt, i, name);
-+ }
-+ }
-+ }
-+ break;
-+ default:
-+ gcc_unreachable ();
-+ }
-+
-+ if (dump_file)
-+ {
-+ fprintf (dump_file, "Converted stmt ");
-+ print_gimple_stmt (dump_file, stmt, 0, 0);
-+ fprintf (dump_file, "\n\n");
-+ }
-+ update_stmt (stmt);
-+}
-+
-+/* Helper function for promote_variable that walks over use/def
-+ chains. */
-+
-+static bool
-+promote_variable_1 (tree var, gimple stmt, void *data)
-+{
-+ struct promote_info *pi = (struct promote_info *) data;
-+ imm_use_iterator imi;
-+ gimple use_stmt;
-+
-+ rebuild_with_promotion (stmt, pi);
-+
-+ if (gimple_code (stmt) == GIMPLE_PHI)
-+ var = PHI_RESULT (stmt);
-+
-+ if (could_be_promoted (var))
-+ FOR_EACH_IMM_USE_STMT (use_stmt, imi, var)
-+ {
-+ rebuild_with_promotion (use_stmt, pi);
-+ }
-+
-+ return false;
-+}
-+
-+/* Convert all uses and defs of PI_->LOOP_INDEX_NAME as linked by
-+ use-def chains to uses and defs of PI_->PROMOTED_VAR. */
-+
-+static bool
-+promote_variable (const void *pi_, void *data ATTRIBUTE_UNUSED)
-+{
-+ const struct promote_info *pi = (const struct promote_info *) pi_;
-+
-+ if (pi->can_be_promoted_p)
-+ {
-+ walk_use_def_chains (pi->loop_index_name, promote_variable_1,
-+ CONST_CAST (struct promote_info *, pi), false);
-+ }
-+
-+ /* Continue traversal. */
-+ return true;
-+}
-+
-+/* Free PI_ and its associated data. */
-+
-+static bool
-+free_pi_entries (const void *pi_, void *data ATTRIBUTE_UNUSED)
-+{
-+ struct promote_info *pi = CONST_CAST (struct promote_info *,
-+ (const struct promote_info *) pi_);
-+
-+ VEC_free (tree, heap, pi->cast_types);
-+ VEC_free (int, heap, pi->cast_counts);
-+ free (pi);
-+
-+ /* Continue traversal. */
-+ return true;
-+}
-+
-+/* Collect information about variables that we believe to be loop
-+ indices in PROMOTION_INFO. */
-+
-+static void
-+collect_promotion_candidates (void)
-+{
-+ loop_iterator li;
-+ struct loop *loop;
-+
-+ FOR_EACH_LOOP (li, loop, 0)
-+ {
-+ basic_block header = loop->header;
-+ gimple exit_cond = last_stmt (header);
-+
-+ if (exit_cond && gimple_code (exit_cond) == GIMPLE_COND)
-+ {
-+ tree loop_index;
-+ tree limit = NULL_TREE;
-+ tree decl;
-+ struct promote_info *pi;
-+
-+ loop_index = find_promotion_candidate (loop, exit_cond, &limit);
-+ if (loop_index == NULL_TREE)
-+ continue;
-+ decl = SSA_NAME_VAR (loop_index);
-+ if (TREE_ADDRESSABLE (decl))
-+ continue;
-+
-+ if (dump_file)
-+ {
-+ fprintf (dump_file, "Found loop index ");
-+ print_generic_expr (dump_file, loop_index, 0);
-+ fprintf (dump_file, " involved in ");
-+ print_gimple_stmt (dump_file, exit_cond, 0, 0);
-+ fprintf (dump_file, "\n\n");
-+ }
-+
-+ pi = XCNEW (struct promote_info);
-+ pi->loop = loop;
-+ pi->exit_expr = exit_cond;
-+ pi->loop_index_name = loop_index;
-+ pi->loop_limit = limit;
-+ pi->var_decl = decl;
-+ /* We think so, anyway... */
-+ pi->can_be_promoted_p = true;
-+ pointer_set_insert (promotion_info, pi);
-+ }
-+ else if (dump_file)
-+ {
-+ fprintf (dump_file, "\nSkipping analysis of loop %d (header bb #%d)\n",
-+ loop->num, loop->header->index);
-+ if (exit_cond)
-+ {
-+ fprintf (dump_file, "Exit condition was ");
-+ print_gimple_stmt (dump_file, exit_cond, 0, 0);
-+ fprintf (dump_file, "\n");
-+ }
-+ }
-+ }
-+}
-+
-+/* Free memory associated with global variables that we used. */
-+
-+static void
-+pli_cleanup (void)
-+{
-+ if (promoted_stmts)
-+ {
-+ pointer_set_destroy (promoted_stmts);
-+ promoted_stmts = NULL;
-+ }
-+ if (variable_map)
-+ {
-+ pointer_map_destroy (variable_map);
-+ variable_map = NULL;
-+ }
-+ if (promotable_names)
-+ {
-+ pointer_set_destroy (promotable_names);
-+ promotable_names = NULL;
-+ }
-+ if (promotion_info)
-+ {
-+ pointer_set_traverse (promotion_info, free_pi_entries, NULL);
-+ pointer_set_destroy (promotion_info);
-+ promotion_info = NULL;
-+ }
-+}
-+
-+/* The guts of the pass. */
-+
-+static unsigned int
-+promote_short_indices (void)
-+{
-+ bool did_something = false;
-+ bool changed;
-+ size_t max_iterations, i, n_promoted;
-+
-+ promotion_info = pointer_set_create ();
-+ collect_promotion_candidates ();
-+
-+ if (dump_file)
-+ fprintf (dump_file, "Found %d candidates for promotion\n",
-+ (int) pointer_set_n_elements (promotion_info));
-+
-+ /* Nothing to do. */
-+ if (pointer_set_n_elements (promotion_info) == 0)
-+ goto cleanup;
-+
-+ /* We have information about which variables are loop index variables.
-+ We now need to determine the promotability of the loop indices.
-+ Since the promotability of loop indices may depend on other loop
-+ indices, we need to repeat this until we reach a fixed point. */
-+ changed = true;
-+ max_iterations = pointer_set_n_elements (promotion_info);
-+ i = 0;
-+
-+ promotable_names = pointer_set_create ();
-+
-+ while (changed)
-+ {
-+ changed = false;
-+ pointer_set_clear (promotable_names);
-+ pointer_set_traverse (promotion_info, add_variable,
-+ promotable_names);
-+ n_promoted = pointer_set_n_elements (promotable_names);
-+
-+ if (dump_file)
-+ fprintf (dump_file, "\nIteration %d, have %d variables to consider\n",
-+ (int) i, (int) n_promoted);
-+
-+ if (n_promoted == 0)
-+ break;
-+ gcc_assert (i < max_iterations);
-+ pointer_set_traverse (promotion_info, analyze_loop, &changed);
-+ i++;
-+ }
-+
-+ if (dump_file)
-+ fprintf (dump_file, "Promoting %d variables\n",
-+ (int) n_promoted);
-+
-+ if (n_promoted != 0)
-+ {
-+ did_something = true;
-+ variable_map = pointer_map_create ();
-+ promoted_stmts = pointer_set_create ();
-+ pointer_set_traverse (promotion_info, create_promoted_variable, NULL);
-+ pointer_set_traverse (promotion_info, promote_variable, NULL);
-+ }
-+
-+ cleanup:
-+ pli_cleanup ();
-+ return did_something ? TODO_update_ssa : 0;
-+}
-+
-+/* Entry point for the short loop index promotion pass. */
-+
-+static unsigned int
-+tree_short_index_promotion (void)
-+{
-+ unsigned int changed = 0;
-+
-+ /* Initialize all the necessary loop infrastructure. */
-+ loop_optimizer_init (LOOPS_HAVE_PREHEADERS | LOOPS_HAVE_SIMPLE_LATCHES | LOOPS_HAVE_RECORDED_EXITS);
-+ add_noreturn_fake_exit_edges ();
-+ connect_infinite_loops_to_exit ();
-+
-+ if (number_of_loops () > 1)
-+ changed = promote_short_indices ();
-+
-+ /* Tear down loop optimization infrastructure. */
-+ remove_fake_exit_edges ();
-+ free_numbers_of_iterations_estimates ();
-+ loop_optimizer_finalize ();
-+
-+ return changed;
-+}
-+
-+static bool
-+gate_short_index_promotion (void)
-+{
-+ return optimize > 0 && flag_promote_loop_indices;
-+}
-+
-+struct gimple_opt_pass pass_promote_indices =
-+{
-+ {
-+ GIMPLE_PASS,
-+ "promoteshort", /* name */
-+ gate_short_index_promotion, /* gate */
-+ tree_short_index_promotion, /* execute */
-+ NULL, /* sub */
-+ NULL, /* next */
-+ 0, /* static_pass_number */
-+ TV_TREE_LOOP_PROMOTE, /* tv_id */
-+ PROP_cfg | PROP_ssa, /* properties_required */
-+ 0, /* properties_provided */
-+ 0, /* properties_destroyed */
-+ 0, /* todo_flags_start */
-+ TODO_dump_func | TODO_verify_loops
-+ | TODO_ggc_collect /* todo_flags_finish */
-+ }
-+};
---- a/gcc/tree-ssa-pre.c
-+++ b/gcc/tree-ssa-pre.c
-@@ -104,6 +104,10 @@ along with GCC; see the file COPYING3.
- In order to make it fully redundant, we insert the expression into
- the predecessors where it is not available, but is ANTIC.
-
-+ When optimizing for size, we only eliminate the partial redundancy
-+ if we need to insert in only one predecessor. This avoids almost
-+ completely the code size increase that PRE usually causes.
-+
- For the partial anticipation case, we only perform insertion if it
- is partially anticipated in some block, and fully available in all
- of the predecessors.
-@@ -425,6 +429,7 @@ static pre_expr bitmap_find_leader (bitm
- static void bitmap_value_insert_into_set (bitmap_set_t, pre_expr);
- static void bitmap_value_replace_in_set (bitmap_set_t, pre_expr);
- static void bitmap_set_copy (bitmap_set_t, bitmap_set_t);
-+static void bitmap_set_and (bitmap_set_t, bitmap_set_t);
- static bool bitmap_set_contains_value (bitmap_set_t, unsigned int);
- static void bitmap_insert_into_set (bitmap_set_t, pre_expr);
- static void bitmap_insert_into_set_1 (bitmap_set_t, pre_expr, bool);
-@@ -2948,13 +2953,6 @@ insert_into_preds_of_block (basic_block
- tree temp;
- gimple phi;
-
-- if (dump_file && (dump_flags & TDF_DETAILS))
-- {
-- fprintf (dump_file, "Found partial redundancy for expression ");
-- print_pre_expr (dump_file, expr);
-- fprintf (dump_file, " (%04d)\n", val);
-- }
--
- /* Make sure we aren't creating an induction variable. */
- if (block->loop_depth > 0 && EDGE_COUNT (block->preds) == 2
- && expr->kind != REFERENCE)
-@@ -3152,6 +3150,47 @@ insert_into_preds_of_block (basic_block
- }
-
-
-+/* Indicate if, when optimizing for speed, it is appropriate to make
-+ INSERTS_NEEDED insertions in order to make EXPR in BLOCK redundant. */
-+static bool
-+ppre_n_insert_for_speed_p (pre_expr expr, basic_block block,
-+ unsigned int inserts_needed)
-+{
-+ /* The more expensive EXPR is, the more we should be prepared to insert
-+ in the predecessors of BLOCK to make EXPR fully redundant.
-+ For now, only recognize AND, OR, XOR, PLUS and MINUS of a multiple-use
-+ SSA_NAME with a constant as cheap. */
-+ int cost;
-+
-+ if (flag_tree_pre_partial_partial_obliviously)
-+ return true;
-+ if (expr->kind == NARY)
-+ {
-+ vn_nary_op_t nary = PRE_EXPR_NARY (expr);
-+ switch (nary->opcode)
-+ {
-+ tree name, cnst;
-+ case BIT_AND_EXPR: case BIT_IOR_EXPR: case BIT_XOR_EXPR:
-+ case PLUS_EXPR: case MINUS_EXPR:
-+
-+ gcc_assert (nary->length == 2);
-+ name = nary->op[0];
-+ cnst = nary->op[1];
-+ if (TREE_CODE (name) != SSA_NAME || has_single_use (name))
-+ return true;
-+ if (!is_gimple_min_invariant (cnst))
-+ return true;
-+ cost = 1;
-+ break;
-+ default:
-+ return true;
-+ }
-+ }
-+ else
-+ return true;
-+ return EDGE_COUNT (block->preds) * cost >= inserts_needed;
-+
-+}
-
- /* Perform insertion of partially redundant values.
- For BLOCK, do the following:
-@@ -3186,6 +3225,7 @@ do_regular_insertion (basic_block block,
- pre_expr *avail;
- unsigned int val;
- bool by_some = false;
-+ unsigned int inserts_needed = 0;
- bool cant_insert = false;
- bool all_same = true;
- pre_expr first_s = NULL;
-@@ -3240,6 +3280,7 @@ do_regular_insertion (basic_block block,
- {
- avail[bprime->index] = eprime;
- all_same = false;
-+ inserts_needed++;
- }
- else
- {
-@@ -3249,6 +3290,11 @@ do_regular_insertion (basic_block block,
- first_s = edoubleprime;
- else if (!pre_expr_eq (first_s, edoubleprime))
- all_same = false;
-+ /* If the available value is not a NAME, PREing this
-+ value will probably result in a copy on the edge
-+ to assign the expression to a register. */
-+ if (edoubleprime->kind != NAME)
-+ inserts_needed++;
- }
- }
- /* If we can insert it, it's not the same value
-@@ -3257,9 +3303,27 @@ do_regular_insertion (basic_block block,
- partially redundant. */
- if (!cant_insert && !all_same && by_some && dbg_cnt (treepre_insert))
- {
-- if (insert_into_preds_of_block (block, get_expression_id (expr),
-- avail))
-- new_stuff = true;
-+ if (dump_file && (dump_flags & TDF_DETAILS))
-+ {
-+ fprintf (dump_file,
-+ "Found partial redundancy for expression ");
-+ print_pre_expr (dump_file, expr);
-+ fprintf (dump_file, " (%04d)\n", get_expr_value_id (expr));
-+ }
-+
-+ /* If optimizing for size, insert at most one
-+ new expression to avoid increasing code size. */
-+ if (optimize_function_for_speed_p (cfun)
-+ ? 1 : EDGE_COUNT (block->preds) - inserts_needed == 1)
-+ new_stuff |=
-+ insert_into_preds_of_block (block,
-+ get_expression_id (expr),
-+ avail);
-+ else if (dump_file && (dump_flags & TDF_DETAILS))
-+ fprintf (dump_file, "Not inserting (optimizing for %s)\n",
-+ optimize_function_for_speed_p (cfun)
-+ ? "speed" : "size");
-+
- }
- /* If all edges produce the same value and that value is
- an invariant, then the PHI has the same value on all
-@@ -3388,9 +3452,28 @@ do_partial_partial_insertion (basic_bloc
- if (!cant_insert && by_all && dbg_cnt (treepre_insert))
- {
- pre_stats.pa_insert++;
-- if (insert_into_preds_of_block (block, get_expression_id (expr),
-- avail))
-- new_stuff = true;
-+ if (dump_file && (dump_flags & TDF_DETAILS))
-+ {
-+ fprintf (dump_file,
-+ "Found partial redundancy for expression ");
-+ print_pre_expr (dump_file, expr);
-+ fprintf (dump_file, " (%04d)\n", get_expr_value_id (expr));
-+ }
-+ /* Assuming the expression is 50% anticipatable, we have to
-+ multiply the number of insertions needed by two for a cost
-+ comparison. */
-+ if (!optimize_function_for_speed_p (cfun)
-+ || ppre_n_insert_for_speed_p (expr, block,
-+ 2 * EDGE_COUNT (block->preds)))
-+ new_stuff |=
-+ insert_into_preds_of_block (block,
-+ get_expression_id (expr),
-+ avail);
-+ else if (dump_file && (dump_flags & TDF_DETAILS))
-+ fprintf (dump_file, "Not inserting (optimizing for %s)\n",
-+ optimize_function_for_speed_p (cfun)
-+ ? "speed" : "size");
-+
- }
- free (avail);
- }
-@@ -3431,7 +3514,9 @@ insert_aux (basic_block block)
- if (!single_pred_p (block))
- {
- new_stuff |= do_regular_insertion (block, dom);
-- if (do_partial_partial)
-+ /* Don't bother with partial-partial redundancies when
-+ optimizing for size. */
-+ if (do_partial_partial && ! optimize_function_for_size_p (cfun))
- new_stuff |= do_partial_partial_insertion (block, dom);
- }
- }
-@@ -4171,11 +4256,11 @@ fini_pre (bool do_fre)
- only wants to do full redundancy elimination. */
-
- static unsigned int
--execute_pre (bool do_fre ATTRIBUTE_UNUSED)
-+execute_pre (bool do_fre)
- {
- unsigned int todo = 0;
-
-- do_partial_partial = optimize > 2;
-+ do_partial_partial = flag_tree_pre_partial_partial;
-
- /* This has to happen before SCCVN runs because
- loop_optimizer_init may create new phis, etc. */
-@@ -4247,19 +4332,20 @@ execute_pre (bool do_fre ATTRIBUTE_UNUSE
- return todo;
- }
-
--/* Gate and execute functions for PRE. */
-+/* Gate and execute functions for FRE/PRE. */
-
- static unsigned int
- do_pre (void)
- {
-- return TODO_rebuild_alias | execute_pre (false);
-+ return TODO_rebuild_alias
-+ | execute_pre (! flag_tree_pre);
- }
-
- static bool
- gate_pre (void)
- {
-- /* PRE tends to generate bigger code. */
-- return flag_tree_pre != 0 && optimize_function_for_speed_p (cfun);
-+ /* Run FRE even if we don't run PRE. */
-+ return (flag_tree_fre || flag_tree_pre);
- }
-
- struct gimple_opt_pass pass_pre =
---- /dev/null
-+++ b/gcc/tree-ssa-remove-local-statics.c
-@@ -0,0 +1,868 @@
-+/* Local static variable elimination pass.
-+ Copyright (C) 2007 Free Software Foundation, Inc.
-+ Contributed by Nathan Froyd <froydnj@codesourcery.com>
-+
-+This file is part of GCC.
-+
-+GCC is free software; you can redistribute it and/or modify it
-+under the terms of the GNU General Public License as published by the
-+Free Software Foundation; either version 3, or (at your option) any
-+later version.
-+
-+GCC is distributed in the hope that it will be useful, but WITHOUT
-+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-+for more details.
-+
-+You should have received a copy of the GNU General Public License
-+along with GCC; see the file COPYING3. If not see
-+<http://www.gnu.org/licenses/>. */
-+
-+/* Converting static function-local variables to automatic variables.
-+
-+ The motivating example is a function like:
-+
-+ void
-+ foo (unsigned n)
-+ {
-+ static int var;
-+ unsigned i;
-+
-+ for (i = 0; i != n; i++)
-+ {
-+ var = ...
-+
-+ do other things with var...
-+ }
-+ }
-+
-+ Because VAR is static, doing things like code motion to loads and
-+ stores of VAR is difficult. Furthermore, accesses to VAR are
-+ inefficient. This pass aims to recognize the cases where it is not
-+ necessary for VAR to be static and modify the code so that later
-+ passes will do the appropriate optimizations.
-+
-+ The criteria for a static function-local variable V in a function F
-+ being converted to an automatic variable are:
-+
-+ 1. F does not call setjmp; and
-+ 2. V's address is never taken; and
-+ 3. V is not declared volatile; and
-+ 4. V is not used in any nested function;
-+ 5. V is not an aggregate value (union, struct, array, etc.); and
-+ 6. Every use of V is defined along all paths leading to the use.
-+
-+ NOTE: For ease of implementation, we currently treat a function call
-+ as killing all previous definitions of static variables, since we
-+ could have:
-+
-+ static void
-+ foo (...)
-+ {
-+ static int x;
-+
-+ x = ...; (1)
-+
-+ f (...); (2)
-+
-+ ... = x; (3)
-+ }
-+
-+ The use at (3) needs to pick up a possible definition made by the
-+ call at (2). If the call at (2) does not call back into 'foo',
-+ then the call is not a killing call. We currently treat it as
-+ though it is. */
-+
-+#include "config.h"
-+#include "system.h"
-+#include "coretypes.h"
-+#include "tm.h"
-+
-+#include "rtl.h"
-+#include "tm_p.h"
-+#include "hard-reg-set.h"
-+#include "obstack.h"
-+#include "basic-block.h"
-+
-+#include "tree.h"
-+#include "gimple.h"
-+#include "hashtab.h"
-+#include "diagnostic.h"
-+#include "tree-flow.h"
-+#include "tree-dump.h"
-+#include "flags.h"
-+#include "timevar.h"
-+#include "tree-pass.h"
-+
-+struct rls_decl_info
-+{
-+ /* The variable declaration. */
-+ tree orig_var;
-+
-+ /* Its index in rls_block_local_data. */
-+ int index;
-+
-+ /* Whether we can optimize this variable. */
-+ bool optimizable_p;
-+
-+ /* The new variable declaration, if we can optimize away the staticness
-+ of 'orig_var'. */
-+ tree new_var;
-+};
-+
-+/* Filled with 'struct rls_decl_info'; keyed off ORIG_VAR. */
-+static htab_t static_variables;
-+
-+struct rls_stmt_info
-+{
-+ /* The variable declaration. */
-+ tree var;
-+
-+ /* The statement in which we found a def or a use of the variable. */
-+ gimple stmt;
-+
-+ /* Whether STMT represents a use of VAR. */
-+ bool use_p;
-+
-+ /* A bitmap whose entries denote what variables have been defined
-+ when execution arrives at STMT. This field is only used when
-+ USE_P is true. */
-+ sbitmap defined;
-+};
-+
-+/* Filled with 'struct rls_stmt_info'; keyed off STMT. */
-+static htab_t defuse_statements;
-+
-+static struct
-+{
-+ /* The number of static variables we found. */
-+ size_t n_statics;
-+
-+ /* The number of optimizable variables we found. */
-+ size_t n_optimizable;
-+} stats;
-+
-+struct rls_block_dataflow_data {
-+ /* A bitmap whose entries denote what variables have been defined on
-+ entry to this block. */
-+ sbitmap defined_in;
-+
-+ /* A bitmap whose entries denote what variables have been defined on
-+ exit from this block. */
-+ sbitmap defined_out;
-+};
-+
-+/* Parameters for the 'static_variables' hash table. */
-+
-+static hashval_t
-+rls_hash_decl_info (const void *x)
-+{
-+ return htab_hash_pointer
-+ ((const void *) ((const struct rls_decl_info *) x)->orig_var);
-+}
-+
-+static int
-+rls_eq_decl_info (const void *x, const void *y)
-+{
-+ const struct rls_decl_info *a = (const struct rls_decl_info *) x;
-+ const struct rls_decl_info *b = (const struct rls_decl_info *) y;
-+
-+ return a->orig_var == b->orig_var;
-+}
-+
-+static void
-+rls_free_decl_info (void *info)
-+{
-+ free (info);
-+}
-+
-+/* Parameters for the 'defuse_statements' hash table. */
-+
-+static hashval_t
-+rls_hash_use_info (const void *x)
-+{
-+ return htab_hash_pointer
-+ ((const void *) ((const struct rls_stmt_info *) x)->stmt);
-+}
-+
-+static int
-+rls_eq_use_info (const void *x, const void *y)
-+{
-+ const struct rls_stmt_info *a = (const struct rls_stmt_info *) x;
-+ const struct rls_stmt_info *b = (const struct rls_stmt_info *) y;
-+
-+ return a->stmt == b->stmt;
-+}
-+
-+static void
-+rls_free_use_info (void *info)
-+{
-+ struct rls_stmt_info *stmt_info = (struct rls_stmt_info *) info;
-+
-+ if (stmt_info->defined)
-+ sbitmap_free (stmt_info->defined);
-+
-+ free (stmt_info);
-+}
-+
-+/* Initialize data structures and statistics. */
-+
-+static void
-+rls_init (void)
-+{
-+ basic_block bb;
-+
-+ /* We expect relatively few static variables, hence the small
-+ initial size for the hash table. */
-+ static_variables = htab_create (8, rls_hash_decl_info,
-+ rls_eq_decl_info, rls_free_decl_info);
-+
-+ /* We expect quite a few statements. */
-+ defuse_statements = htab_create (128, rls_hash_use_info,
-+ rls_eq_use_info, rls_free_use_info);
-+
-+ FOR_ALL_BB (bb)
-+ {
-+ struct rls_block_dataflow_data *data;
-+
-+ data = XNEW (struct rls_block_dataflow_data);
-+ memset (data, 0, sizeof (*data));
-+ bb->aux = data;
-+ }
-+
-+ stats.n_statics = 0;
-+ stats.n_optimizable = 0;
-+}
-+
-+/* Free data structures. */
-+
-+static void
-+rls_done (void)
-+{
-+ basic_block bb;
-+
-+ htab_delete (static_variables);
-+ htab_delete (defuse_statements);
-+
-+ FOR_ALL_BB (bb)
-+ {
-+ struct rls_block_dataflow_data *data
-+ = (struct rls_block_dataflow_data *) bb->aux;
-+
-+ gcc_assert (data);
-+
-+ if (data->defined_in)
-+ sbitmap_free (data->defined_in);
-+ if (data->defined_out)
-+ sbitmap_free (data->defined_out);
-+ free (data);
-+ bb->aux = NULL;
-+ }
-+}
-+
-+\f
-+/* Doing the initial work to find static variables. */
-+
-+/* Examine the defining statement for VAR and determine whether it is a
-+ static variable we could potentially optimize. If so, stick in it
-+ in the 'static_variables' hashtable.
-+
-+ STMT is the statement in which a definition or use of VAR occurs.
-+ USE_P indicates whether VAR is used or defined in STMT. Enter STMT
-+ into 'defuse_statements' as well for use during dataflow
-+ analysis. */
-+
-+static void
-+maybe_discover_new_declaration (tree var, gimple stmt, bool use_p)
-+{
-+ tree def_stmt = SSA_NAME_VAR (var);
-+
-+ if (TREE_CODE (def_stmt) == VAR_DECL
-+ && DECL_CONTEXT (def_stmt) != NULL_TREE
-+ && TREE_CODE (DECL_CONTEXT (def_stmt)) == FUNCTION_DECL
-+ /* We cannot optimize away a static used in multiple functions (as
-+ might happen in C++). */
-+ && !DECL_NONLOCAL(def_stmt)
-+ && TREE_STATIC (def_stmt)
-+ /* We cannot optimize away aggregate statics, as we would have to
-+ prove that definitions of every field of the aggregate dominate
-+ uses. */
-+ && !AGGREGATE_TYPE_P (TREE_TYPE (def_stmt))
-+ /* GCC doesn't normally treat vectors as aggregates; we need to,
-+ though, since a user could use intrinsics to read/write
-+ particular fields of the vector, thereby treating it as an
-+ array. */
-+ && TREE_CODE (TREE_TYPE (def_stmt)) != VECTOR_TYPE
-+ && !TREE_ADDRESSABLE (def_stmt)
-+ && !TREE_THIS_VOLATILE (def_stmt))
-+ {
-+ struct rls_decl_info dummy;
-+ void **slot;
-+
-+ dummy.orig_var = def_stmt;
-+ slot = htab_find_slot (static_variables, &dummy, INSERT);
-+
-+ if (*slot == NULL)
-+ {
-+ /* Found a use or a def of a new declaration. */
-+ struct rls_decl_info *info = XNEW (struct rls_decl_info);
-+
-+ info->orig_var = def_stmt;
-+ info->index = stats.n_statics++;
-+ /* Optimistically assume that we can optimize. */
-+ info->optimizable_p = true;
-+ info->new_var = NULL_TREE;
-+ *slot = (void *) info;
-+ }
-+
-+ /* Enter the statement into DEFUSE_STATEMENTS. */
-+ {
-+ struct rls_stmt_info dummy;
-+ struct rls_stmt_info *info;
-+
-+ dummy.stmt = stmt;
-+ slot = htab_find_slot (defuse_statements, &dummy, INSERT);
-+
-+ /* We should never insert the same statement into the
-+ hashtable twice. */
-+ gcc_assert (*slot == NULL
-+ || ((struct rls_stmt_info *)(*slot))->stmt == stmt);
-+
-+ if (*slot != NULL && ((struct rls_stmt_info *)(*slot))->stmt == stmt)
-+ return;
-+
-+ info = XNEW (struct rls_stmt_info);
-+ info->var = def_stmt;
-+ info->stmt = stmt;
-+ if (dump_file)
-+ {
-+ fprintf (dump_file, "entering as %s ", use_p ? "use" : "def");
-+ print_gimple_stmt (dump_file, stmt, 0, TDF_DETAILS | TDF_VOPS);
-+ }
-+ info->use_p = use_p;
-+ /* We don't know how big to make the bitmap yet. */
-+ info->defined = NULL;
-+ *slot = (void *) info;
-+ }
-+ }
-+}
-+
-+/* Grovel through all the statements in the program, looking for
-+ SSA_NAMEs whose SSA_NAME_VAR is a VAR_DECL. We look at both use and
-+ def SSA_NAMEs. */
-+
-+static void
-+find_static_nonvolatile_declarations (void)
-+{
-+ basic_block bb;
-+
-+ FOR_EACH_BB (bb)
-+ {
-+ gimple_stmt_iterator i;
-+
-+ for (i = gsi_start_bb (bb); !gsi_end_p (i); gsi_next (&i))
-+ {
-+ tree var;
-+ ssa_op_iter iter;
-+ gimple stmt = gsi_stmt (i);
-+
-+ /* If there's a call expression in STMT, then previous passes
-+ will have determined if the call transitively defines some
-+ static variable. However, we need more precise
-+ information--we need to know whether static variables are
-+ live out after the call.
-+
-+ Since we'll never see something like:
-+
-+ staticvar = foo (bar, baz);
-+
-+ in GIMPLE (the result of the call will be assigned to a
-+ normal, non-static local variable which is then assigned to
-+ STATICVAR in a subsequent statement), don't bother finding
-+ new declarations if we see a GIMPLE_CALL.
-+
-+ In a similar fashion, asm statements that clobber memory
-+ will appear to define static variables. In general,
-+ however, assuming that asm statements define static
-+ variables would cause us to see that in the following
-+ situation:
-+
-+ static int foo = 0;
-+
-+ __asm__ (... : "memory");
-+ foo++;
-+
-+ foo could be unstaticized because the asm has "defined"
-+ foo. This is likely false. (Even if the asm does happen
-+ to define foo--and only foo--that situation would be
-+ sufficiently unusual that not optimizing it seems OK.) */
-+ if (gimple_code (stmt) != GIMPLE_CALL
-+ && gimple_code (stmt) != GIMPLE_ASM)
-+ FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_VDEF)
-+ {
-+ maybe_discover_new_declaration (var, stmt, false);
-+ }
-+
-+ FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_VUSE)
-+ {
-+ maybe_discover_new_declaration (var, stmt, true);
-+ }
-+ }
-+ }
-+}
-+
-+\f
-+/* Determining if we have anything to optimize. */
-+
-+/* Examine *SLOT (which is a 'struct rls_decl_info *') to see whether
-+ the associated variable is optimizable. If it is, create a new,
-+ non-static declaration for the variable; this new variable will be
-+ used during a subsequent rewrite of the function. */
-+
-+#define NEW_VAR_PREFIX ".unstatic"
-+
-+static int
-+maybe_create_new_variable (void **slot, void *data ATTRIBUTE_UNUSED)
-+{
-+ struct rls_decl_info *info = (struct rls_decl_info *) *slot;
-+ tree id_node = DECL_NAME (info->orig_var);
-+ size_t id_len = IDENTIFIER_LENGTH (id_node);
-+ size_t name_len = id_len + strlen (NEW_VAR_PREFIX) + 1;
-+ char *name;
-+
-+ /* Don't create a new variable multiple times. */
-+ gcc_assert (!info->new_var);
-+
-+ /* Tie the new name to the old one to aid debugging dumps. */
-+ name = (char *) alloca (name_len);
-+ strcpy (name, IDENTIFIER_POINTER (id_node));
-+ strcpy (name + id_len, NEW_VAR_PREFIX);
-+ info->new_var = create_tmp_var (TREE_TYPE (info->orig_var), name);
-+
-+ if (dump_file)
-+ {
-+ fprintf (dump_file, "new variable ");
-+ print_generic_expr (dump_file, info->new_var, 0);
-+ fprintf (dump_file, "\n");
-+ }
-+
-+ /* Inform SSA about this new variable. */
-+ create_var_ann (info->new_var);
-+ mark_sym_for_renaming (info->new_var);
-+ /* We need to make sure we rebuild bits for the original variable,
-+ such as virtual operands attached to statements. */
-+ mark_sym_for_renaming (info->orig_var);
-+ add_referenced_var (info->new_var);
-+
-+ /* Always continue scanning. */
-+ return 1;
-+}
-+
-+#undef NEW_VAR_PREFIX
-+
-+/* Traverse the 'defuse_statements' hash table. For every use,
-+ determine if the associated variable is defined along all paths
-+ leading to said use. Remove the associated variable from
-+ 'static_variables' if it is not. */
-+
-+static int
-+check_definedness (void **slot, void *data ATTRIBUTE_UNUSED)
-+{
-+ struct rls_stmt_info *info = (struct rls_stmt_info *) *slot;
-+ struct rls_decl_info dummy;
-+
-+ /* We don't need to look at definitions. Continue scanning. */
-+ if (!info->use_p)
-+ return 1;
-+
-+ dummy.orig_var = info->var;
-+ slot = htab_find_slot (static_variables, &dummy, INSERT);
-+
-+ /* Might not be there because we deleted it already. */
-+ if (*slot)
-+ {
-+ struct rls_decl_info *decl = (struct rls_decl_info *) *slot;
-+
-+ if (!TEST_BIT (info->defined, decl->index))
-+ {
-+ if (dump_file)
-+ {
-+ fprintf (dump_file, "not optimizing ");
-+ print_generic_expr (dump_file, decl->orig_var, 0);
-+ fprintf (dump_file, "due to uncovered use in ");
-+ print_gimple_stmt (dump_file, info->stmt, 0, 0);
-+ fprintf (dump_file, "\n");
-+ }
-+
-+ htab_clear_slot (static_variables, slot);
-+ stats.n_optimizable--;
-+ }
-+ }
-+
-+ /* Continue scan. */
-+ return 1;
-+}
-+
-+/* Check all statements in 'defuse_statements' to see if all the
-+ statements that use a static variable have that variable defined
-+ along all paths leading to the statement. Once that's done, go
-+ through and create new, non-static variables for any static variables
-+ that can be optimized. */
-+
-+static size_t
-+determine_optimizable_statics (void)
-+{
-+ htab_traverse (defuse_statements, check_definedness, NULL);
-+
-+ htab_traverse (static_variables, maybe_create_new_variable, NULL);
-+
-+ return stats.n_optimizable;
-+}
-+
-+/* Look at STMT to see if we have uses or defs of a static variable.
-+ STMT is passed in DATA. Definitions of a static variable are found
-+ by the presence of a V_MUST_DEF, while uses are found by the presence
-+ of a VUSE. */
-+
-+static int
-+unstaticize_variable (void **slot, void *data)
-+{
-+ struct rls_decl_info *info = (struct rls_decl_info *) *slot;
-+ gimple stmt = (gimple) data;
-+ tree vdef;
-+ tree vuse;
-+ int continue_scan = 1;
-+
-+ /* We should have removed unoptimizable variables during an earlier
-+ traversal. */
-+ gcc_assert (info->optimizable_p);
-+
-+ /* Check for virtual definitions first. */
-+ vdef = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_VDEF);
-+
-+ if (vdef != NULL
-+ && ZERO_SSA_OPERANDS (stmt, SSA_OP_DEF)
-+ && gimple_code (stmt) == GIMPLE_ASSIGN
-+ && TREE_CODE (gimple_assign_lhs (stmt)) == VAR_DECL
-+ && gimple_assign_lhs(stmt) == info->orig_var)
-+ {
-+ /* Make the statement define the new name. The new name has
-+ already been marked for renaming, so no need to do that
-+ here. */
-+ gimple_assign_set_lhs (stmt, info->new_var);
-+ if (dump_file)
-+ {
-+ fprintf (dump_file, "found virtual definition!\n");
-+ print_gimple_stmt (dump_file, stmt, 0, TDF_VOPS | TDF_DETAILS);
-+ fprintf (dump_file, "\n");
-+ }
-+ continue_scan = 0;
-+ goto done;
-+ }
-+
-+ /* Check for virtual uses. */
-+ vuse = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_VUSE);
-+
-+ if (vuse != NULL
-+ && gimple_code (stmt) == GIMPLE_ASSIGN
-+ && gimple_assign_rhs_code (stmt) == VAR_DECL
-+ && gimple_assign_rhs1 (stmt) == info->orig_var)
-+ {
-+ /* Make the statement use the new name. */
-+ gimple_assign_set_rhs1 (stmt, info->new_var);
-+ if (dump_file)
-+ {
-+ fprintf (dump_file, "found virtual use!\n");
-+ print_gimple_stmt (dump_file, stmt, 0, TDF_VOPS | TDF_DETAILS);
-+ fprintf (dump_file, "\n");
-+ }
-+ continue_scan = 0;
-+ goto done;
-+ }
-+
-+ done:
-+ if (!continue_scan)
-+ {
-+ /* None of the other optimizable static variables can occur
-+ in this statement. Stop the scan. */
-+ update_stmt (stmt);
-+
-+ if (dump_file)
-+ {
-+ fprintf (dump_file, "updated stmt\n");
-+ print_gimple_stmt (dump_file, stmt, 0, TDF_VOPS | TDF_DETAILS);
-+ }
-+ }
-+
-+ return continue_scan;
-+}
-+
-+/* Determine if we have any static variables we can optimize. If so,
-+ replace any defs or uses of those variables in their defining/using
-+ statements. */
-+
-+static void
-+maybe_remove_static_from_declarations (void)
-+{
-+ size_t n_optimizable = determine_optimizable_statics ();
-+ basic_block bb;
-+
-+ if (n_optimizable)
-+ /* Replace any optimizable variables with new, non-static variables. */
-+ FOR_EACH_BB (bb)
-+ {
-+ gimple_stmt_iterator gsi;
-+
-+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
-+ {
-+ gimple stmt = gsi_stmt (gsi);
-+
-+ htab_traverse (static_variables, unstaticize_variable, stmt);
-+ }
-+ }
-+}
-+
-+/* Callback for htab_traverse to initialize the bitmap for *SLOT, which
-+ is a 'struct rls_stmt_info'. */
-+
-+static int
-+initialize_statement_dataflow (void **slot, void *data ATTRIBUTE_UNUSED)
-+{
-+ struct rls_stmt_info *info = (struct rls_stmt_info *) *slot;
-+
-+ gcc_assert (!info->defined);
-+
-+ if (info->use_p)
-+ {
-+ info->defined = sbitmap_alloc (stats.n_statics);
-+ /* Assume defined along all paths until otherwise informed. */
-+ sbitmap_ones (info->defined);
-+ }
-+
-+ /* Continue traversal. */
-+ return 1;
-+}
-+
-+/* We have N_STATICS static variables to consider. Go through all the
-+ blocks and all the use statements to initialize their bitmaps. */
-+
-+static void
-+initialize_block_and_statement_dataflow (size_t n_statics)
-+{
-+ basic_block bb;
-+
-+ FOR_ALL_BB (bb)
-+ {
-+ struct rls_block_dataflow_data *data
-+ = (struct rls_block_dataflow_data *) bb->aux;
-+
-+ gcc_assert (data);
-+
-+ data->defined_in = sbitmap_alloc (n_statics);
-+ sbitmap_zero (data->defined_in);
-+ data->defined_out = sbitmap_alloc (n_statics);
-+ sbitmap_zero (data->defined_out);
-+ }
-+
-+ htab_traverse (defuse_statements, initialize_statement_dataflow, NULL);
-+}
-+
-+/* Apply the individual effects of the stmts in BB to update the
-+ dataflow analysis information for BB. */
-+
-+static void
-+compute_definedness_for_block (basic_block bb)
-+{
-+ bool changed_p = false;
-+ struct rls_block_dataflow_data *data
-+ = (struct rls_block_dataflow_data *) bb->aux;
-+ gimple_stmt_iterator gsi;
-+
-+ sbitmap_copy (data->defined_out, data->defined_in);
-+
-+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
-+ {
-+ gimple stmt = gsi_stmt (gsi);
-+
-+ if (gimple_code (stmt) == GIMPLE_CALL)
-+ /* If there's a call expression in STMT, then previous passes
-+ will have determined if the call transitively defines some
-+ static variable. However, we need more precise
-+ information--we need to know whether static variables are
-+ live out after the call. In the absence of such information,
-+ simply declare that all static variables are clobbered by the
-+ call. A better analysis would be interprocedural and compute
-+ the liveness information we require, but for now, we're being
-+ pessimistic. */
-+ sbitmap_zero (data->defined_out);
-+ else
-+ {
-+ struct rls_stmt_info dummy;
-+ void **slot;
-+
-+ /* See if this statement uses or defines a static variable. */
-+ dummy.stmt = stmt;
-+ slot = htab_find_slot (defuse_statements, &dummy, INSERT);
-+
-+ /* Check for uses. */
-+ if (*slot != NULL)
-+ {
-+ struct rls_stmt_info *info = (struct rls_stmt_info *) *slot;
-+
-+ if (info->use_p)
-+ {
-+ gcc_assert (info->defined);
-+
-+ /* Found a statement that uses a function-local static
-+ variable. Copy the current state of definedness. */
-+ sbitmap_copy (info->defined, data->defined_out);
-+ }
-+ else
-+ {
-+ struct rls_decl_info dummy;
-+ struct rls_decl_info *decl;
-+
-+ gcc_assert (!info->defined);
-+
-+ /* Found a statement that defines a function-local static
-+ variable. Look up the associated variable's information
-+ and mark it as defined in the block. */
-+ dummy.orig_var = info->var;
-+ slot = htab_find_slot (static_variables, &dummy, INSERT);
-+
-+ gcc_assert (*slot);
-+
-+ decl = (struct rls_decl_info *) *slot;
-+
-+ SET_BIT (data->defined_out, decl->index);
-+ changed_p |= true;
-+ }
-+ }
-+ }
-+ }
-+}
-+
-+/* Solve the dataflow equations:
-+
-+ DEFINED_IN(b) = intersect DEFINED_OUT(p) for p in preds(b)
-+ DEFINED_OUT(b) = VARIABLES_DEFINED (b, DEFINED_IN (b))
-+
-+ via a simple iterative solver. VARIABLES_DEFINED is computed by
-+ 'compute_definedness_for_block'. */
-+
-+static void
-+compute_definedness (void)
-+{
-+ basic_block bb;
-+ bool changed_p;
-+ sbitmap tmp_bitmap = sbitmap_alloc (stats.n_statics);
-+
-+ /* Compute initial sets. */
-+ FOR_EACH_BB (bb)
-+ {
-+ compute_definedness_for_block (bb);
-+ }
-+
-+ /* Iterate. */
-+ do {
-+ changed_p = false;
-+
-+ FOR_EACH_BB (bb)
-+ {
-+ edge e;
-+ edge_iterator ei;
-+ struct rls_block_dataflow_data *data
-+ = (struct rls_block_dataflow_data *) bb->aux;
-+ bool bitmap_changed_p = false;
-+
-+ sbitmap_ones (tmp_bitmap);
-+
-+ gcc_assert (data);
-+
-+ /* We require information about whether a variable was defined
-+ over all paths leading to a particular use. Therefore, we
-+ intersect the DEFINED sets of all predecessors. */
-+ FOR_EACH_EDGE (e, ei, bb->preds)
-+ {
-+ struct rls_block_dataflow_data *pred_data
-+ = (struct rls_block_dataflow_data *) e->src->aux;
-+
-+ gcc_assert (pred_data);
-+
-+ sbitmap_a_and_b (tmp_bitmap, tmp_bitmap, pred_data->defined_out);
-+ }
-+
-+ bitmap_changed_p = !sbitmap_equal (tmp_bitmap, data->defined_in);
-+
-+ if (bitmap_changed_p)
-+ {
-+ sbitmap_copy (data->defined_in, tmp_bitmap);
-+ compute_definedness_for_block (bb);
-+ }
-+
-+ changed_p |= bitmap_changed_p;
-+ }
-+ } while (changed_p);
-+
-+ sbitmap_free (tmp_bitmap);
-+}
-+
-+static unsigned int
-+execute_rls (void)
-+{
-+ rls_init ();
-+
-+ find_static_nonvolatile_declarations ();
-+
-+ /* Can we optimize anything? */
-+ if (stats.n_statics != 0)
-+ {
-+ stats.n_optimizable = stats.n_statics;
-+
-+ if (dump_file)
-+ fprintf (dump_file, "found %d static variables to consider\n",
-+ stats.n_statics);
-+
-+ initialize_block_and_statement_dataflow (stats.n_statics);
-+
-+ compute_definedness ();
-+
-+ maybe_remove_static_from_declarations ();
-+
-+ if (dump_file)
-+ fprintf (dump_file, "removed %d static variables\n",
-+ stats.n_optimizable);
-+ }
-+
-+ rls_done ();
-+
-+ return 0;
-+}
-+
-+static bool
-+gate_rls (void)
-+{
-+ return (flag_remove_local_statics != 0
-+ && !cfun->calls_setjmp
-+ && !cgraph_node (current_function_decl)->ever_was_nested);
-+}
-+
-+struct gimple_opt_pass pass_remove_local_statics =
-+{
-+ {
-+ GIMPLE_PASS,
-+ "remlocstatic", /* name */
-+ gate_rls, /* gate */
-+ execute_rls, /* execute */
-+ NULL, /* sub */
-+ NULL, /* next */
-+ 0, /* static_pass_number */
-+ TV_TREE_RLS, /* tv_id */
-+ PROP_cfg | PROP_ssa, /* properties_required */
-+ 0, /* properties_provided */
-+ 0, /* properties_destroyed */
-+ 0, /* todo_flags_start */
-+ TODO_dump_func | TODO_verify_ssa | TODO_verify_stmts
-+ | TODO_rebuild_alias | TODO_update_ssa /* todo_flags_finish */
-+ }
-+};
---- a/gcc/tree-ssa-sink.c
-+++ b/gcc/tree-ssa-sink.c
-@@ -449,6 +449,47 @@ sink_code_in_bb (basic_block bb)
- last = false;
- continue;
- }
-+
-+ /* We cannot move statements that contain references to block-scope
-+ variables out of that block, as this may lead to incorrect aliasing
-+ when we lay out the stack frame in cfgexpand.c.
-+ In lieu of more sophisticated analysis, be very conservative here
-+ and prohibit moving any statement that references memory out of a
-+ block with variables. */
-+ if (gimple_references_memory_p (stmt))
-+ {
-+ tree fromblock = gimple_block (stmt);
-+ while (fromblock
-+ && fromblock != current_function_decl
-+ && !BLOCK_VARS (fromblock))
-+ fromblock = BLOCK_SUPERCONTEXT (fromblock);
-+ if (fromblock && fromblock != current_function_decl)
-+ {
-+ gimple tostmt;
-+ tree toblock;
-+
-+ if (gsi_end_p (togsi))
-+ tostmt = gimple_seq_last_stmt (gsi_seq (togsi));
-+ else
-+ tostmt = gsi_stmt (togsi);
-+ if (tostmt)
-+ toblock = gimple_block (tostmt);
-+ else
-+ toblock = NULL;
-+ while (toblock
-+ && toblock != current_function_decl
-+ && toblock != fromblock)
-+ toblock = BLOCK_SUPERCONTEXT (toblock);
-+ if (!toblock || toblock != fromblock)
-+ {
-+ if (!gsi_end_p (gsi))
-+ gsi_prev (&gsi);
-+ last = false;
-+ continue;
-+ }
-+ }
-+ }
-+
- if (dump_file)
- {
- fprintf (dump_file, "Sinking ");
---- a/gcc/tree-ssa-structalias.c
-+++ b/gcc/tree-ssa-structalias.c
-@@ -2928,7 +2928,8 @@ get_constraint_for_component_ref (tree t
- /* Some people like to do cute things like take the address of
- &0->a.b */
- forzero = t;
-- while (!SSA_VAR_P (forzero) && !CONSTANT_CLASS_P (forzero))
-+ while (!SSA_VAR_P (forzero) && TREE_CODE (forzero) != FUNCTION_DECL
-+ && !CONSTANT_CLASS_P (forzero))
- forzero = TREE_OPERAND (forzero, 0);
-
- if (CONSTANT_CLASS_P (forzero) && integer_zerop (forzero))
---- a/gcc/tree-vect-analyze.c
-+++ b/gcc/tree-vect-analyze.c
-@@ -1459,7 +1459,7 @@ vect_compute_data_ref_alignment (struct
- }
-
- base = build_fold_indirect_ref (base_addr);
-- alignment = ssize_int (TYPE_ALIGN (vectype)/BITS_PER_UNIT);
-+ alignment = ssize_int (targetm.vectorize.vector_min_alignment (vectype));
-
- if ((aligned_to && tree_int_cst_compare (aligned_to, alignment) < 0)
- || !misalign)
-@@ -1510,7 +1510,8 @@ vect_compute_data_ref_alignment (struct
- /* At this point we assume that the base is aligned. */
- gcc_assert (base_aligned
- || (TREE_CODE (base) == VAR_DECL
-- && DECL_ALIGN (base) >= TYPE_ALIGN (vectype)));
-+ && (DECL_ALIGN (base)
-+ >= targetm.vectorize.vector_min_alignment (vectype))));
-
- /* Modulo alignment. */
- misalign = size_binop (TRUNC_MOD_EXPR, misalign, alignment);
---- a/gcc/tree-vect-transform.c
-+++ b/gcc/tree-vect-transform.c
-@@ -5444,7 +5444,21 @@ vectorizable_store (gimple stmt, gimple_
- vect_permute_store_chain(). */
- vec_oprnd = VEC_index (tree, result_chain, i);
-
-- data_ref = build_fold_indirect_ref (dataref_ptr);
-+ if (alignment_support_scheme == dr_aligned
-+ && !targetm.vectorize.always_misalign(vectype))
-+ {
-+ data_ref = build_fold_indirect_ref (dataref_ptr);
-+ }
-+ else
-+ {
-+ /* TODO: Record actual alignment in always_misalign case. */
-+ int mis = DR_MISALIGNMENT (first_dr);
-+ tree tmis;
-+ tmis = (mis == -1 ? size_zero_node : size_int (mis));
-+ tmis = size_binop (MULT_EXPR, tmis, size_int(BITS_PER_UNIT));
-+ data_ref =
-+ build2 (MISALIGNED_INDIRECT_REF, vectype, dataref_ptr, tmis);
-+ }
-
- /* Arguments are ready. Create the new vector stmt. */
- new_stmt = gimple_build_assign (data_ref, vec_oprnd);
-@@ -6623,10 +6637,15 @@ vectorizable_load (gimple stmt, gimple_s
- {
- case dr_aligned:
- gcc_assert (aligned_access_p (first_dr));
-- data_ref = build_fold_indirect_ref (dataref_ptr);
-- break;
-+ if (!targetm.vectorize.always_misalign(vectype))
-+ {
-+ data_ref = build_fold_indirect_ref (dataref_ptr);
-+ break;
-+ }
-+ /* Fall through... */
- case dr_unaligned_supported:
- {
-+ /* TODO: Record actual alignment in always_misalign case. */
- int mis = DR_MISALIGNMENT (first_dr);
- tree tmis = (mis == -1 ? size_zero_node : size_int (mis));
-
-@@ -7597,7 +7616,7 @@ vect_gen_niters_for_prolog_loop (loop_ve
- gimple dr_stmt = DR_STMT (dr);
- stmt_vec_info stmt_info = vinfo_for_stmt (dr_stmt);
- tree vectype = STMT_VINFO_VECTYPE (stmt_info);
-- int vectype_align = TYPE_ALIGN (vectype) / BITS_PER_UNIT;
-+ int vectype_align = targetm.vectorize.vector_min_alignment (vectype);
- tree niters_type = TREE_TYPE (loop_niters);
- int step = 1;
- int element_size = GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (DR_REF (dr))));
---- a/gcc/tree-vectorizer.c
-+++ b/gcc/tree-vectorizer.c
-@@ -2868,11 +2868,13 @@ increase_alignment (void)
- vnode = vnode->next_needed)
- {
- tree vectype, decl = vnode->decl;
-+ tree t;
- unsigned int alignment;
-
-- if (TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE)
-+ t = TREE_TYPE(decl);
-+ if (TREE_CODE (t) != ARRAY_TYPE)
- continue;
-- vectype = get_vectype_for_scalar_type (TREE_TYPE (TREE_TYPE (decl)));
-+ vectype = get_vectype_for_scalar_type (strip_array_types (t));
- if (!vectype)
- continue;
- alignment = TYPE_ALIGN (vectype);
-@@ -2887,6 +2889,7 @@ increase_alignment (void)
- {
- fprintf (dump_file, "Increasing alignment of decl: ");
- print_generic_expr (dump_file, decl, TDF_SLIM);
-+ fprintf (dump_file, "\n");
- }
- }
- }
---- a/gcc/tree.c
-+++ b/gcc/tree.c
-@@ -4062,6 +4062,7 @@ handle_dll_attribute (tree * pnode, tree
- bool *no_add_attrs)
- {
- tree node = *pnode;
-+ bool is_dllimport;
-
- /* These attributes may apply to structure and union types being created,
- but otherwise should pass to the declaration involved. */
-@@ -4109,9 +4110,11 @@ handle_dll_attribute (tree * pnode, tree
- return NULL_TREE;
- }
-
-+ is_dllimport = is_attribute_p ("dllimport", name);
-+
- /* Report error on dllimport ambiguities seen now before they cause
- any damage. */
-- else if (is_attribute_p ("dllimport", name))
-+ if (is_dllimport)
- {
- /* Honor any target-specific overrides. */
- if (!targetm.valid_dllimport_attribute_p (node))
-@@ -4153,6 +4156,9 @@ handle_dll_attribute (tree * pnode, tree
- if (*no_add_attrs == false)
- DECL_DLLIMPORT_P (node) = 1;
- }
-+ else if (DECL_DECLARED_INLINE_P (node))
-+ /* An exported function, even if inline, must be emitted. */
-+ DECL_EXTERNAL (node) = 0;
-
- /* Report error if symbol is not accessible at global scope. */
- if (!TREE_PUBLIC (node)
---- a/gcc/tree.h
-+++ b/gcc/tree.h
-@@ -381,8 +381,10 @@ struct tree_base GTY(())
- unsigned lang_flag_5 : 1;
- unsigned lang_flag_6 : 1;
- unsigned visited : 1;
-+ unsigned packed_flag : 1;
-+ unsigned user_align : 1;
-
-- unsigned spare : 23;
-+ unsigned spare : 21;
-
- union tree_ann_d *ann;
- };
-@@ -2140,7 +2142,7 @@ extern enum machine_mode vector_type_mod
-
- /* 1 if the alignment for this type was requested by "aligned" attribute,
- 0 if it is the default for this type. */
--#define TYPE_USER_ALIGN(NODE) (TYPE_CHECK (NODE)->type.user_align)
-+#define TYPE_USER_ALIGN(NODE) (TYPE_CHECK (NODE)->common.base.user_align)
-
- /* The alignment for NODE, in bytes. */
- #define TYPE_ALIGN_UNIT(NODE) (TYPE_ALIGN (NODE) / BITS_PER_UNIT)
-@@ -2246,7 +2248,7 @@ extern enum machine_mode vector_type_mod
-
- /* Indicated that objects of this type should be laid out in as
- compact a way as possible. */
--#define TYPE_PACKED(NODE) (TYPE_CHECK (NODE)->type.packed_flag)
-+#define TYPE_PACKED(NODE) (TYPE_CHECK (NODE)->common.base.packed_flag)
-
- /* Used by type_contains_placeholder_p to avoid recomputation.
- Values are: 0 (unknown), 1 (false), 2 (true). Never access
-@@ -2265,17 +2267,16 @@ struct tree_type GTY(())
- tree attributes;
- unsigned int uid;
-
-- unsigned int precision : 9;
-- ENUM_BITFIELD(machine_mode) mode : 7;
--
-- unsigned string_flag : 1;
-+ unsigned int precision : 10;
- unsigned no_force_blk_flag : 1;
- unsigned needs_constructing_flag : 1;
- unsigned transparent_union_flag : 1;
-- unsigned packed_flag : 1;
- unsigned restrict_flag : 1;
- unsigned contains_placeholder_bits : 2;
-
-+ ENUM_BITFIELD(machine_mode) mode : 8;
-+
-+ unsigned string_flag : 1;
- unsigned lang_flag_0 : 1;
- unsigned lang_flag_1 : 1;
- unsigned lang_flag_2 : 1;
-@@ -2283,7 +2284,6 @@ struct tree_type GTY(())
- unsigned lang_flag_4 : 1;
- unsigned lang_flag_5 : 1;
- unsigned lang_flag_6 : 1;
-- unsigned user_align : 1;
-
- unsigned int align;
- alias_set_type alias_set;
-@@ -2584,7 +2584,7 @@ struct tree_memory_partition_tag GTY(())
- #define DECL_ALIGN_UNIT(NODE) (DECL_ALIGN (NODE) / BITS_PER_UNIT)
- /* Set if the alignment of this DECL has been set by the user, for
- example with an 'aligned' attribute. */
--#define DECL_USER_ALIGN(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.user_align)
-+#define DECL_USER_ALIGN(NODE) (DECL_COMMON_CHECK (NODE)->common.base.user_align)
- /* Holds the machine mode corresponding to the declaration of a variable or
- field. Always equal to TYPE_MODE (TREE_TYPE (decl)) except for a
- FIELD_DECL. */
-@@ -2621,7 +2621,7 @@ struct tree_memory_partition_tag GTY(())
- example, for a FUNCTION_DECL, DECL_SAVED_TREE may be non-NULL and
- DECL_EXTERNAL may be true simultaneously; that can be the case for
- a C99 "extern inline" function. */
--#define DECL_EXTERNAL(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.decl_flag_2)
-+#define DECL_EXTERNAL(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.decl_flag_1)
-
- /* Nonzero in a ..._DECL means this variable is ref'd from a nested function.
- For VAR_DECL nodes, PARM_DECL nodes, and FUNCTION_DECL nodes.
-@@ -2696,7 +2696,6 @@ struct tree_decl_common GTY(())
- unsigned ignored_flag : 1;
- unsigned abstract_flag : 1;
- unsigned artificial_flag : 1;
-- unsigned user_align : 1;
- unsigned preserve_flag: 1;
- unsigned debug_expr_is_from : 1;
-
-@@ -2712,22 +2711,20 @@ struct tree_decl_common GTY(())
- /* In LABEL_DECL, this is DECL_ERROR_ISSUED.
- In VAR_DECL and PARM_DECL, this is DECL_REGISTER. */
- unsigned decl_flag_0 : 1;
-- /* In FIELD_DECL, this is DECL_PACKED. */
-- unsigned decl_flag_1 : 1;
- /* In FIELD_DECL, this is DECL_BIT_FIELD
- In VAR_DECL and FUNCTION_DECL, this is DECL_EXTERNAL.
-- In TYPE_DECL, this is TYPE_DECL_SUPRESS_DEBUG. */
-- unsigned decl_flag_2 : 1;
-+ In TYPE_DECL, this is TYPE_DECL_SUPPRESS_DEBUG. */
-+ unsigned decl_flag_1 : 1;
- /* In FIELD_DECL, this is DECL_NONADDRESSABLE_P
-- In VAR_DECL and PARM_DECL, this is DECL_HAS_VALUE_EXPR. */
-- unsigned decl_flag_3 : 1;
-+ In VAR_DECL and PARM_DECL, this is DECL_HAS_VALUE_EXPR_P. */
-+ unsigned decl_flag_2 : 1;
- /* Logically, these two would go in a theoretical base shared by var and
- parm decl. */
- unsigned gimple_reg_flag : 1;
- /* In a DECL with pointer type, set if no TBAA should be done. */
- unsigned no_tbaa_flag : 1;
- /* Padding so that 'align' can be on a 32-bit boundary. */
-- unsigned decl_common_unused : 2;
-+ unsigned decl_common_unused : 4;
-
- unsigned int align : 24;
- /* DECL_OFFSET_ALIGN, used only for FIELD_DECLs. */
-@@ -2751,7 +2748,7 @@ extern void decl_value_expr_insert (tree
- decl itself. This should only be used for debugging; once this field has
- been set, the decl itself may not legitimately appear in the function. */
- #define DECL_HAS_VALUE_EXPR_P(NODE) \
-- (TREE_CHECK2 (NODE, VAR_DECL, PARM_DECL)->decl_common.decl_flag_3)
-+ (TREE_CHECK2 (NODE, VAR_DECL, PARM_DECL)->decl_common.decl_flag_2)
- #define DECL_VALUE_EXPR(NODE) \
- (decl_value_expr_lookup (DECL_WRTL_CHECK (NODE)))
- #define SET_DECL_VALUE_EXPR(NODE, VAL) \
-@@ -2830,11 +2827,11 @@ struct tree_decl_with_rtl GTY(())
- #define DECL_FCONTEXT(NODE) (FIELD_DECL_CHECK (NODE)->field_decl.fcontext)
-
- /* In a FIELD_DECL, indicates this field should be bit-packed. */
--#define DECL_PACKED(NODE) (FIELD_DECL_CHECK (NODE)->decl_common.decl_flag_1)
-+#define DECL_PACKED(NODE) (FIELD_DECL_CHECK (NODE)->common.base.packed_flag)
-
- /* Nonzero in a FIELD_DECL means it is a bit field, and must be accessed
- specially. */
--#define DECL_BIT_FIELD(NODE) (FIELD_DECL_CHECK (NODE)->decl_common.decl_flag_2)
-+#define DECL_BIT_FIELD(NODE) (FIELD_DECL_CHECK (NODE)->decl_common.decl_flag_1)
-
- /* Used in a FIELD_DECL to indicate that we cannot form the address of
- this component. This makes it possible for Type-Based Alias Analysis
-@@ -2852,7 +2849,7 @@ struct tree_decl_with_rtl GTY(())
- accesses to s.i must not be given the alias set of the type of 'i'
- (int) but instead directly that of the type of 's' (struct S). */
- #define DECL_NONADDRESSABLE_P(NODE) \
-- (FIELD_DECL_CHECK (NODE)->decl_common.decl_flag_3)
-+ (FIELD_DECL_CHECK (NODE)->decl_common.decl_flag_2)
-
- struct tree_field_decl GTY(())
- {
-@@ -3337,7 +3334,7 @@ struct tree_function_decl GTY(())
- into stabs. Instead it will generate cross reference ('x') of names.
- This uses the same flag as DECL_EXTERNAL. */
- #define TYPE_DECL_SUPPRESS_DEBUG(NODE) \
-- (TYPE_DECL_CHECK (NODE)->decl_common.decl_flag_2)
-+ (TYPE_DECL_CHECK (NODE)->decl_common.decl_flag_1)
-
- /* Getter of the imported declaration associated to the
- IMPORTED_DECL node. */
---- a/gcc/unwind-dw2.c
-+++ b/gcc/unwind-dw2.c
-@@ -1414,16 +1414,12 @@ uw_advance_context (struct _Unwind_Conte
- /* Fill in CONTEXT for top-of-stack. The only valid registers at this
- level will be the return address and the CFA. */
-
--#define uw_init_context(CONTEXT) \
-- do \
-- { \
-- /* Do any necessary initialization to access arbitrary stack frames. \
-- On the SPARC, this means flushing the register windows. */ \
-- __builtin_unwind_init (); \
-- uw_init_context_1 (CONTEXT, __builtin_dwarf_cfa (), \
-- __builtin_return_address (0)); \
-- } \
-- while (0)
-+#define uw_init_context(CONTEXT) \
-+ /* Do any necessary initialization to access arbitrary stack frames. \
-+ On the SPARC, this means flushing the register windows. */ \
-+ (__builtin_unwind_init (), \
-+ uw_init_context_1 ((CONTEXT), __builtin_dwarf_cfa (), \
-+ __builtin_return_address (0)))
-
- static inline void
- init_dwarf_reg_size_table (void)
-@@ -1431,7 +1427,7 @@ init_dwarf_reg_size_table (void)
- __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table);
- }
-
--static void
-+static _Unwind_Reason_Code
- uw_init_context_1 (struct _Unwind_Context *context,
- void *outer_cfa, void *outer_ra)
- {
-@@ -1445,7 +1441,8 @@ uw_init_context_1 (struct _Unwind_Contex
- context->flags = EXTENDED_CONTEXT_BIT;
-
- code = uw_frame_state_for (context, &fs);
-- gcc_assert (code == _URC_NO_REASON);
-+ if (code != _URC_NO_REASON)
-+ return code;
-
- #if __GTHREADS
- {
-@@ -1471,6 +1468,8 @@ uw_init_context_1 (struct _Unwind_Contex
- initialization context, then we can't see it in the given
- call frame data. So have the initialization context tell us. */
- context->ra = __builtin_extract_return_addr (outer_ra);
-+
-+ return _URC_NO_REASON;
- }
-
-
---- a/gcc/unwind-sjlj.c
-+++ b/gcc/unwind-sjlj.c
-@@ -292,10 +292,11 @@ uw_advance_context (struct _Unwind_Conte
- uw_update_context (context, fs);
- }
-
--static inline void
-+static inline _Unwind_Reason_Code
- uw_init_context (struct _Unwind_Context *context)
- {
- context->fc = _Unwind_SjLj_GetContext ();
-+ return _URC_NO_REASON;
- }
-
- static void __attribute__((noreturn))
---- a/gcc/unwind.inc
-+++ b/gcc/unwind.inc
-@@ -85,7 +85,8 @@ _Unwind_RaiseException(struct _Unwind_Ex
- _Unwind_Reason_Code code;
-
- /* Set up this_context to describe the current stack frame. */
-- uw_init_context (&this_context);
-+ code = uw_init_context (&this_context);
-+ gcc_assert (code == _URC_NO_REASON);
- cur_context = this_context;
-
- /* Phase 1: Search. Unwind the stack, calling the personality routine
-@@ -198,7 +199,8 @@ _Unwind_ForcedUnwind (struct _Unwind_Exc
- struct _Unwind_Context this_context, cur_context;
- _Unwind_Reason_Code code;
-
-- uw_init_context (&this_context);
-+ code = uw_init_context (&this_context);
-+ gcc_assert (code == _URC_NO_REASON);
- cur_context = this_context;
-
- exc->private_1 = (_Unwind_Ptr) stop;
-@@ -221,7 +223,8 @@ _Unwind_Resume (struct _Unwind_Exception
- struct _Unwind_Context this_context, cur_context;
- _Unwind_Reason_Code code;
-
-- uw_init_context (&this_context);
-+ code = uw_init_context (&this_context);
-+ gcc_assert (code == _URC_NO_REASON);
- cur_context = this_context;
-
- /* Choose between continuing to process _Unwind_RaiseException
-@@ -251,7 +254,8 @@ _Unwind_Resume_or_Rethrow (struct _Unwin
- if (exc->private_1 == 0)
- return _Unwind_RaiseException (exc);
-
-- uw_init_context (&this_context);
-+ code = uw_init_context (&this_context);
-+ gcc_assert (code == _URC_NO_REASON);
- cur_context = this_context;
-
- code = _Unwind_ForcedUnwind_Phase2 (exc, &cur_context);
-@@ -280,7 +284,9 @@ _Unwind_Backtrace(_Unwind_Trace_Fn trace
- struct _Unwind_Context context;
- _Unwind_Reason_Code code;
-
-- uw_init_context (&context);
-+ code = uw_init_context (&context);
-+ if (code != _URC_NO_REASON)
-+ return _URC_FATAL_PHASE1_ERROR;
-
- while (1)
- {
---- a/gcc/varasm.c
-+++ b/gcc/varasm.c
-@@ -1126,11 +1126,14 @@ align_variable (tree decl, bool dont_out
- {
- #ifdef DATA_ALIGNMENT
- unsigned int data_align = DATA_ALIGNMENT (TREE_TYPE (decl), align);
-+#else
-+ unsigned int data_align = align;
-+#endif
-+ data_align = alignment_for_aligned_arrays (TREE_TYPE (decl), data_align);
- /* Don't increase alignment too much for TLS variables - TLS space
- is too precious. */
- if (! DECL_THREAD_LOCAL_P (decl) || data_align <= BITS_PER_WORD)
- align = data_align;
--#endif
- #ifdef CONSTANT_ALIGNMENT
- if (DECL_INITIAL (decl) != 0 && DECL_INITIAL (decl) != error_mark_node)
- {
-@@ -3198,6 +3201,10 @@ build_constant_desc (tree exp)
- set_mem_alias_set (rtl, 0);
- set_mem_alias_set (rtl, const_alias_set);
-
-+ /* We cannot share RTX'es in pool entries.
-+ Mark this piece of RTL as required for unsharing. */
-+ RTX_FLAG (rtl, used) = 1;
-+
- /* Set flags or add text to the name to record information, such as
- that it is a local symbol. If the name is changed, the macro
- ASM_OUTPUT_LABELREF will have to know how to strip this
---- a/gcc/vmsdbgout.c
-+++ b/gcc/vmsdbgout.c
-@@ -213,6 +213,7 @@ const struct gcc_debug_hooks vmsdbg_debu
- debug_nothing_int, /* handle_pch */
- debug_nothing_rtx, /* var_location */
- debug_nothing_void, /* switch_text_section */
-+ debug_nothing_tree_tree, /* set_name */
- 0 /* start_end_main_source_file */
- };
-
---- a/include/libiberty.h
-+++ b/include/libiberty.h
-@@ -591,6 +591,10 @@ extern int pexecute (const char *, char
-
- extern int pwait (int, int *, int);
-
-+/* Convert a Cygwin path to a Windows path. */
-+
-+extern int cygpath (const char *, char []);
-+
- #if !HAVE_DECL_ASPRINTF
- /* Like sprintf but provides a pointer to malloc'd storage, which must
- be freed by the caller. */
---- a/libcpp/Makefile.in
-+++ b/libcpp/Makefile.in
-@@ -72,13 +72,12 @@ ALL_CFLAGS = $(CFLAGS) $(WARN_CFLAGS) $(
- libcpp_a_OBJS = charset.o directives.o directives-only.o errors.o \
- expr.o files.o identifiers.o init.o lex.o line-map.o macro.o \
- mkdeps.o pch.o symtab.o traditional.o
--makedepend_OBJS = makedepend.o
-
- libcpp_a_SOURCES = charset.c directives.c directives-only.c errors.c \
- expr.c files.c identifiers.c init.c lex.c line-map.c macro.c \
- mkdeps.c pch.c symtab.c traditional.c
-
--all: libcpp.a makedepend$(EXEEXT) $(USED_CATALOGS)
-+all: libcpp.a $(USED_CATALOGS)
-
- .SUFFIXES:
- .SUFFIXES: .c .gmo .o .obj .po .pox
-@@ -88,12 +87,6 @@ libcpp.a: $(libcpp_a_OBJS)
- $(AR) $(ARFLAGS) libcpp.a $(libcpp_a_OBJS)
- $(RANLIB) libcpp.a
-
--makedepend$(EXEEXT): $(makedepend_OBJS) libcpp.a ../libiberty/libiberty.a
-- @rm -f makedepend$(EXEEXT)
-- $(CC) $(CFLAGS) $(LDFLAGS) -o makedepend$(EXEEXT) \
-- $(makedepend_OBJS) libcpp.a ../libiberty/libiberty.a \
-- $(LIBINTL) $(LIBICONV)
--
- # Rules to rebuild the configuration
-
- Makefile: $(srcdir)/Makefile.in config.status
-@@ -165,7 +158,7 @@ mostlyclean:
- -rm -f *.o
-
- clean: mostlyclean
-- -rm -rf makedepend$(EXEEXT) libcpp.a $(srcdir)/autom4te.cache
-+ -rm -rf libcpp.a $(srcdir)/autom4te.cache
-
- distclean: clean
- -rm -f config.h stamp-h1 config.status config.cache config.log \
-@@ -247,7 +240,7 @@ po/$(PACKAGE).pot: $(libcpp_a_SOURCES)
- sed 's:$(srcdir)/::g' <po/$(PACKAGE).pot.tmp >po/$(PACKAGE).pot
- rm po/$(PACKAGE).pot.tmp
-
--TAGS_SOURCES = $(libcpp_a_SOURCES) makedepend.c internal.h ucnid.h \
-+TAGS_SOURCES = $(libcpp_a_SOURCES) internal.h ucnid.h \
- include/line-map.h include/symtab.h include/cpp-id-data.h \
- include/cpplib.h include/mkdeps.h system.h
-
-@@ -259,7 +252,7 @@ TAGS: $(TAGS_SOURCES)
- .NOEXPORT:
-
- # Dependencies
---include $(patsubst %.o, $(DEPDIR)/%.Po, $(libcpp_a_OBJS) $(makedepend_OBJS))
-+-include $(patsubst %.o, $(DEPDIR)/%.Po, $(libcpp_a_OBJS))
-
- # Dependencies on generated headers have to be explicit.
- init.o: localedir.h
---- a/libcpp/directives.c
-+++ b/libcpp/directives.c
-@@ -2376,13 +2376,6 @@ handle_assertion (cpp_reader *pfile, con
- run_directive (pfile, type, str, count);
- }
-
--/* The number of errors for a given reader. */
--unsigned int
--cpp_errors (cpp_reader *pfile)
--{
-- return pfile->errors;
--}
--
- /* The options structure. */
- cpp_options *
- cpp_get_options (cpp_reader *pfile)
---- a/libcpp/errors.c
-+++ b/libcpp/errors.c
-@@ -28,171 +28,69 @@ along with this program; see the file CO
- #include "cpplib.h"
- #include "internal.h"
-
--static void print_location (cpp_reader *, source_location, unsigned int);
--
--/* Print the logical file location (LINE, COL) in preparation for a
-- diagnostic. Outputs the #include chain if it has changed. A line
-- of zero suppresses the include stack, and outputs the program name
-- instead. */
--static void
--print_location (cpp_reader *pfile, source_location line, unsigned int col)
--{
-- if (line == 0)
-- fprintf (stderr, "%s: ", progname);
-- else
-- {
-- const struct line_map *map;
-- linenum_type lin;
--
-- map = linemap_lookup (pfile->line_table, line);
-- linemap_print_containing_files (pfile->line_table, map);
--
-- lin = SOURCE_LINE (map, line);
-- if (col == 0)
-- {
-- col = SOURCE_COLUMN (map, line);
-- if (col == 0)
-- col = 1;
-- }
--
-- if (lin == 0)
-- fprintf (stderr, "%s:", map->to_file);
-- else if (CPP_OPTION (pfile, show_column) == 0)
-- fprintf (stderr, "%s:%u:", map->to_file, lin);
-- else
-- fprintf (stderr, "%s:%u:%u:", map->to_file, lin, col);
--
-- fputc (' ', stderr);
-- }
--}
--
--/* Set up for a diagnostic: print the file and line, bump the error
-- counter, etc. SRC_LOC is the logical line number; zero means to print
-- at the location of the previously lexed token, which tends to be
-- the correct place by default. The column number can be specified either
-- using COLUMN or (if COLUMN==0) extracting SOURCE_COLUMN from SRC_LOC.
-- (This may seem redundant, but is useful when pre-scanning (cleaning) a line,
-- when we haven't yet verified whether the current line_map has a
-- big enough max_column_hint.)
--
-- Returns 0 if the error has been suppressed. */
--static int
--_cpp_begin_message (cpp_reader *pfile, int code,
-- source_location src_loc, unsigned int column)
--{
-- int level = CPP_DL_EXTRACT (code);
--
-- switch (level)
-- {
-- case CPP_DL_WARNING:
-- case CPP_DL_PEDWARN:
-- if (cpp_in_system_header (pfile)
-- && ! CPP_OPTION (pfile, warn_system_headers))
-- return 0;
-- /* Fall through. */
--
-- case CPP_DL_WARNING_SYSHDR:
-- if (CPP_OPTION (pfile, warnings_are_errors)
-- || (level == CPP_DL_PEDWARN && CPP_OPTION (pfile, pedantic_errors)))
-- {
-- if (CPP_OPTION (pfile, inhibit_errors))
-- return 0;
-- level = CPP_DL_ERROR;
-- pfile->errors++;
-- }
-- else if (CPP_OPTION (pfile, inhibit_warnings))
-- return 0;
-- break;
--
-- case CPP_DL_ERROR:
-- if (CPP_OPTION (pfile, inhibit_errors))
-- return 0;
-- /* ICEs cannot be inhibited. */
-- case CPP_DL_ICE:
-- pfile->errors++;
-- break;
-- }
--
-- print_location (pfile, src_loc, column);
-- if (CPP_DL_WARNING_P (level))
-- fputs (_("warning: "), stderr);
-- else if (level == CPP_DL_ICE)
-- fputs (_("internal error: "), stderr);
-- else
-- fputs (_("error: "), stderr);
--
-- return 1;
--}
--
--/* Don't remove the blank before do, as otherwise the exgettext
-- script will mistake this as a function definition */
--#define v_message(msgid, ap) \
-- do { vfprintf (stderr, _(msgid), ap); putc ('\n', stderr); } while (0)
--
--/* Exported interface. */
--
- /* Print an error at the location of the previously lexed token. */
--void
-+bool
- cpp_error (cpp_reader * pfile, int level, const char *msgid, ...)
- {
- source_location src_loc;
- va_list ap;
--
-+ bool ret;
-+
- va_start (ap, msgid);
-
-- if (CPP_OPTION (pfile, client_diagnostic))
-- pfile->cb.error (pfile, level, _(msgid), &ap);
-- else
-+ if (CPP_OPTION (pfile, traditional))
- {
-- if (CPP_OPTION (pfile, traditional))
-- {
-- if (pfile->state.in_directive)
-- src_loc = pfile->directive_line;
-- else
-- src_loc = pfile->line_table->highest_line;
-- }
-- /* We don't want to refer to a token before the beginning of the
-- current run -- that is invalid. */
-- else if (pfile->cur_token == pfile->cur_run->base)
-- {
-- if (pfile->cur_run->prev != NULL)
-- src_loc = pfile->cur_run->prev->limit->src_loc;
-- else
-- src_loc = 0;
-- }
-+ if (pfile->state.in_directive)
-+ src_loc = pfile->directive_line;
- else
-- {
-- src_loc = pfile->cur_token[-1].src_loc;
-- }
--
-- if (_cpp_begin_message (pfile, level, src_loc, 0))
-- v_message (msgid, ap);
-+ src_loc = pfile->line_table->highest_line;
-+ }
-+ /* We don't want to refer to a token before the beginning of the
-+ current run -- that is invalid. */
-+ else if (pfile->cur_token == pfile->cur_run->base)
-+ {
-+ if (pfile->cur_run->prev != NULL)
-+ src_loc = pfile->cur_run->prev->limit->src_loc;
-+ else
-+ src_loc = 0;
- }
-+ else
-+ {
-+ src_loc = pfile->cur_token[-1].src_loc;
-+ }
-+
-+ if (!pfile->cb.error)
-+ abort ();
-+ ret = pfile->cb.error (pfile, level, src_loc, 0, _(msgid), &ap);
-
- va_end (ap);
-+ return ret;
- }
-
- /* Print an error at a specific location. */
--void
-+bool
- cpp_error_with_line (cpp_reader *pfile, int level,
- source_location src_loc, unsigned int column,
- const char *msgid, ...)
- {
- va_list ap;
-+ bool ret;
-
- va_start (ap, msgid);
-
-- if (_cpp_begin_message (pfile, level, src_loc, column))
-- v_message (msgid, ap);
-+ if (!pfile->cb.error)
-+ abort ();
-+ ret = pfile->cb.error (pfile, level, src_loc, column, _(msgid), &ap);
-
- va_end (ap);
-+ return ret;
- }
-
--void
-+bool
- cpp_errno (cpp_reader *pfile, int level, const char *msgid)
- {
- if (msgid[0] == '\0')
- msgid = _("stdout");
-
-- cpp_error (pfile, level, "%s: %s", msgid, xstrerror (errno));
-+ return cpp_error (pfile, level, "%s: %s", msgid, xstrerror (errno));
- }
---- a/libcpp/files.c
-+++ b/libcpp/files.c
-@@ -488,7 +488,6 @@ _cpp_find_file (cpp_reader *pfile, const
- return file;
- }
-
-- open_file_failed (pfile, file, angle_brackets);
- if (invalid_pch)
- {
- cpp_error (pfile, CPP_DL_ERROR,
-@@ -497,6 +496,7 @@ _cpp_find_file (cpp_reader *pfile, const
- cpp_error (pfile, CPP_DL_ERROR,
- "use -Winvalid-pch for more information");
- }
-+ open_file_failed (pfile, file, angle_brackets);
- break;
- }
-
-@@ -934,15 +934,28 @@ open_file_failed (cpp_reader *pfile, _cp
-
- errno = file->err_no;
- if (print_dep && CPP_OPTION (pfile, deps.missing_files) && errno == ENOENT)
-- deps_add_dep (pfile->deps, file->name);
-+ {
-+ deps_add_dep (pfile->deps, file->name);
-+ /* If the preprocessor output (other than dependency information) is
-+ being used, we must also flag an error. */
-+ if (CPP_OPTION (pfile, deps.need_preprocessor_output))
-+ cpp_errno (pfile, CPP_DL_FATAL, file->path);
-+ }
- else
- {
-- /* If we are outputting dependencies but not for this file then
-- don't error because we can still produce correct output. */
-- if (CPP_OPTION (pfile, deps.style) && ! print_dep)
-- cpp_errno (pfile, CPP_DL_WARNING, file->path);
-+ /* If we are not outputting dependencies, or if we are and dependencies
-+ were requested for this file, or if preprocessor output is needed
-+ in addition to dependency information, this is an error.
-+
-+ Otherwise (outputting dependencies but not for this file, and not
-+ using the preprocessor output), we can still produce correct output
-+ so it's only a warning. */
-+ if (CPP_OPTION (pfile, deps.style) == DEPS_NONE
-+ || print_dep
-+ || CPP_OPTION (pfile, deps.need_preprocessor_output))
-+ cpp_errno (pfile, CPP_DL_FATAL, file->path);
- else
-- cpp_errno (pfile, CPP_DL_ERROR, file->path);
-+ cpp_errno (pfile, CPP_DL_WARNING, file->path);
- }
- }
-
---- a/libcpp/include/cpplib.h
-+++ b/libcpp/include/cpplib.h
-@@ -302,22 +302,9 @@ struct cpp_options
- /* Nonzero means print names of header files (-H). */
- unsigned char print_include_names;
-
-- /* Nonzero means cpp_pedwarn causes a hard error. */
-- unsigned char pedantic_errors;
--
-- /* Nonzero means don't print warning messages. */
-- unsigned char inhibit_warnings;
--
- /* Nonzero means complain about deprecated features. */
- unsigned char warn_deprecated;
-
-- /* Nonzero means don't suppress warnings from system headers. */
-- unsigned char warn_system_headers;
--
-- /* Nonzero means don't print error messages. Has no option to
-- select it, but can be set by a user of cpplib (e.g. fix-header). */
-- unsigned char inhibit_errors;
--
- /* Nonzero means warn if slash-star appears in a comment. */
- unsigned char warn_comments;
-
-@@ -353,9 +340,6 @@ struct cpp_options
- explicitly undefined. */
- unsigned char warn_builtin_macro_redefined;
-
-- /* Nonzero means turn warnings into errors. */
-- unsigned char warnings_are_errors;
--
- /* Nonzero means we should look for header.gcc files that remap file
- names. */
- unsigned char remap;
-@@ -432,6 +416,10 @@ struct cpp_options
-
- /* If true, no dependency is generated on the main file. */
- bool ignore_main_file;
-+
-+ /* If true, intend to use the preprocessor output (e.g., for compilation)
-+ in addition to the dependency info. */
-+ bool need_preprocessor_output;
- } deps;
-
- /* Target-specific features set by the front end or client. */
-@@ -450,9 +438,6 @@ struct cpp_options
- /* Nonzero means __STDC__ should have the value 0 in system headers. */
- unsigned char stdc_0_in_system_headers;
-
-- /* True means error callback should be used for diagnostics. */
-- bool client_diagnostic;
--
- /* True disables tokenization outside of preprocessing directives. */
- bool directives_only;
- };
-@@ -492,10 +477,11 @@ struct cpp_callbacks
- be expanded. */
- cpp_hashnode * (*macro_to_expand) (cpp_reader *, const cpp_token *);
-
-- /* Called to emit a diagnostic if client_diagnostic option is true.
-- This callback receives the translated message. */
-- void (*error) (cpp_reader *, int, const char *, va_list *)
-- ATTRIBUTE_FPTR_PRINTF(3,0);
-+ /* Called to emit a diagnostic. This callback receives the
-+ translated message. */
-+ bool (*error) (cpp_reader *, int, source_location, unsigned int,
-+ const char *, va_list *)
-+ ATTRIBUTE_FPTR_PRINTF(5,0);
-
- /* Callbacks for when a macro is expanded, or tested (whether
- defined or not at the time) in #ifdef, #ifndef or "defined". */
-@@ -697,19 +683,13 @@ extern void cpp_init_iconv (cpp_reader *
-
- /* Call this to finish preprocessing. If you requested dependency
- generation, pass an open stream to write the information to,
-- otherwise NULL. It is your responsibility to close the stream.
--
-- Returns cpp_errors (pfile). */
--extern int cpp_finish (cpp_reader *, FILE *deps_stream);
-+ otherwise NULL. It is your responsibility to close the stream. */
-+extern void cpp_finish (cpp_reader *, FILE *deps_stream);
-
- /* Call this to release the handle at the end of preprocessing. Any
-- use of the handle after this function returns is invalid. Returns
-- cpp_errors (pfile). */
-+ use of the handle after this function returns is invalid. */
- extern void cpp_destroy (cpp_reader *);
-
--/* Error count. */
--extern unsigned int cpp_errors (cpp_reader *);
--
- extern unsigned int cpp_token_len (const cpp_token *);
- extern unsigned char *cpp_token_as_text (cpp_reader *, const cpp_token *);
- extern unsigned char *cpp_spell_token (cpp_reader *, const cpp_token *,
-@@ -835,24 +815,23 @@ cpp_num cpp_num_sign_extend (cpp_num, si
- /* An internal consistency check failed. Prints "internal error: ",
- otherwise the same as CPP_DL_ERROR. */
- #define CPP_DL_ICE 0x04
--/* Extracts a diagnostic level from an int. */
--#define CPP_DL_EXTRACT(l) (l & 0xf)
--/* Nonzero if a diagnostic level is one of the warnings. */
--#define CPP_DL_WARNING_P(l) (CPP_DL_EXTRACT (l) >= CPP_DL_WARNING \
-- && CPP_DL_EXTRACT (l) <= CPP_DL_PEDWARN)
-+/* An informative note following a warning. */
-+#define CPP_DL_NOTE 0x05
-+/* A fatal error. */
-+#define CPP_DL_FATAL 0x06
-
- /* Output a diagnostic of some kind. */
--extern void cpp_error (cpp_reader *, int, const char *msgid, ...)
-+extern bool cpp_error (cpp_reader *, int, const char *msgid, ...)
- ATTRIBUTE_PRINTF_3;
-
- /* Output a diagnostic with "MSGID: " preceding the
- error string of errno. No location is printed. */
--extern void cpp_errno (cpp_reader *, int, const char *msgid);
-+extern bool cpp_errno (cpp_reader *, int, const char *msgid);
-
- /* Same as cpp_error, except additionally specifies a position as a
- (translation unit) physical line and physical column. If the line is
- zero, then no location is printed. */
--extern void cpp_error_with_line (cpp_reader *, int, source_location, unsigned,
-+extern bool cpp_error_with_line (cpp_reader *, int, source_location, unsigned,
- const char *msgid, ...) ATTRIBUTE_PRINTF_5;
-
- /* In lex.c */
---- a/libcpp/include/line-map.h
-+++ b/libcpp/include/line-map.h
-@@ -144,12 +144,6 @@ extern const struct line_map *linemap_ad
- extern const struct line_map *linemap_lookup
- (struct line_maps *, source_location);
-
--/* Print the file names and line numbers of the #include commands
-- which led to the map MAP, if any, to stderr. Nothing is output if
-- the most recently listed stack is the same as the current one. */
--extern void linemap_print_containing_files (struct line_maps *,
-- const struct line_map *);
--
- /* Converts a map and a source_location to source line. */
- #define SOURCE_LINE(MAP, LOC) \
- ((((LOC) - (MAP)->start_location) >> (MAP)->column_bits) + (MAP)->to_line)
---- a/libcpp/init.c
-+++ b/libcpp/init.c
-@@ -631,12 +631,11 @@ read_original_directory (cpp_reader *pfi
- }
-
- /* This is called at the end of preprocessing. It pops the last
-- buffer and writes dependency output, and returns the number of
-- errors.
-+ buffer and writes dependency output.
-
- Maybe it should also reset state, such that you could call
- cpp_start_read with a new filename to restart processing. */
--int
-+void
- cpp_finish (cpp_reader *pfile, FILE *deps_stream)
- {
- /* Warn about unused macros before popping the final buffer. */
-@@ -651,9 +650,8 @@ cpp_finish (cpp_reader *pfile, FILE *dep
- while (pfile->buffer)
- _cpp_pop_buffer (pfile);
-
-- /* Don't write the deps file if there are errors. */
- if (CPP_OPTION (pfile, deps.style) != DEPS_NONE
-- && deps_stream && pfile->errors == 0)
-+ && deps_stream)
- {
- deps_write (pfile->deps, deps_stream, 72);
-
-@@ -664,8 +662,6 @@ cpp_finish (cpp_reader *pfile, FILE *dep
- /* Report on headers that could use multiple include guards. */
- if (CPP_OPTION (pfile, print_include_names))
- _cpp_report_missing_guards (pfile);
--
-- return pfile->errors;
- }
-
- static void
---- a/libcpp/internal.h
-+++ b/libcpp/internal.h
-@@ -398,9 +398,6 @@ struct cpp_reader
- /* Nonzero prevents the lexer from re-using the token runs. */
- unsigned int keep_tokens;
-
-- /* Error counter for exit code. */
-- unsigned int errors;
--
- /* Buffer to hold macro definition string. */
- unsigned char *macro_buffer;
- unsigned int macro_buffer_len;
---- a/libcpp/line-map.c
-+++ b/libcpp/line-map.c
-@@ -302,45 +302,6 @@ linemap_lookup (struct line_maps *set, s
- return &set->maps[mn];
- }
-
--/* Print the file names and line numbers of the #include commands
-- which led to the map MAP, if any, to stderr. Nothing is output if
-- the most recently listed stack is the same as the current one. */
--
--void
--linemap_print_containing_files (struct line_maps *set,
-- const struct line_map *map)
--{
-- if (MAIN_FILE_P (map) || set->last_listed == map->included_from)
-- return;
--
-- set->last_listed = map->included_from;
-- map = INCLUDED_FROM (set, map);
--
-- fprintf (stderr, _("In file included from %s:%u"),
-- map->to_file, LAST_SOURCE_LINE (map));
--
-- while (! MAIN_FILE_P (map))
-- {
-- map = INCLUDED_FROM (set, map);
-- /* Translators note: this message is used in conjunction
-- with "In file included from %s:%ld" and some other
-- tricks. We want something like this:
--
-- | In file included from sys/select.h:123,
-- | from sys/types.h:234,
-- | from userfile.c:31:
-- | bits/select.h:45: <error message here>
--
-- with all the "from"s lined up.
-- The trailing comma is at the beginning of this message,
-- and the trailing colon is not translated. */
-- fprintf (stderr, _(",\n from %s:%u"),
-- map->to_file, LAST_SOURCE_LINE (map));
-- }
--
-- fputs (":\n", stderr);
--}
--
- /* Print an include trace, for e.g. the -H option of the preprocessor. */
-
- static void
---- a/libcpp/macro.c
-+++ b/libcpp/macro.c
-@@ -1833,11 +1833,13 @@ _cpp_create_definition (cpp_reader *pfil
-
- if (warn_of_redefinition (pfile, node, macro))
- {
-- cpp_error_with_line (pfile, CPP_DL_PEDWARN, pfile->directive_line, 0,
-- "\"%s\" redefined", NODE_NAME (node));
-+ bool warned;
-+ warned = cpp_error_with_line (pfile, CPP_DL_PEDWARN,
-+ pfile->directive_line, 0,
-+ "\"%s\" redefined", NODE_NAME (node));
-
-- if (node->type == NT_MACRO && !(node->flags & NODE_BUILTIN))
-- cpp_error_with_line (pfile, CPP_DL_PEDWARN,
-+ if (warned && node->type == NT_MACRO && !(node->flags & NODE_BUILTIN))
-+ cpp_error_with_line (pfile, CPP_DL_NOTE,
- node->value.macro->line, 0,
- "this is the location of the previous definition");
- }
---- a/libcpp/makedepend.c
-+++ /dev/null
-@@ -1,206 +0,0 @@
--/* Dependency generator utility.
-- Copyright (C) 2004 Free Software Foundation, Inc.
-- Contributed by Zack Weinberg, May 2004
--
--This program is free software; you can redistribute it and/or modify it
--under the terms of the GNU General Public License as published by the
--Free Software Foundation; either version 2, or (at your option) any
--later version.
--
--This program is distributed in the hope that it will be useful,
--but WITHOUT ANY WARRANTY; without even the implied warranty of
--MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
--GNU General Public License for more details.
--
--You should have received a copy of the GNU General Public License
--along with this program; if not, write to the Free Software
--Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
--
-- In other words, you are welcome to use, share and improve this program.
-- You are forbidden to forbid anyone else to use, share and improve
-- what you give them. Help stamp out software-hoarding! */
--
--#include "config.h"
--#include "system.h"
--#include "line-map.h"
--#include "cpplib.h"
--#include "getopt.h"
--#include "mkdeps.h"
--
--const char *progname;
--const char *vpath;
--
--static const char *output_file;
--static bool had_errors;
--
--/* Option lists, to give to cpplib before each input file. */
--struct cmd_line_macro
--{
-- struct cmd_line_macro *next;
-- bool is_undef;
-- const char *macro;
--};
--
--static struct cmd_line_macro *cmd_line_macros;
--static cpp_dir *cmd_line_searchpath;
--
--static void
--add_clm (const char *macro, bool is_undef)
--{
-- struct cmd_line_macro *clm = XNEW (struct cmd_line_macro);
-- clm->next = cmd_line_macros;
-- clm->is_undef = is_undef;
-- clm->macro = macro;
-- cmd_line_macros = clm;
--}
--
--static void
--add_dir (char *name, bool sysp)
--{
-- cpp_dir *dir = XNEW (cpp_dir);
-- dir->next = cmd_line_searchpath;
-- dir->name = name;
-- dir->sysp = sysp;
-- dir->construct = 0;
-- dir->user_supplied_p = 1;
-- cmd_line_searchpath = dir;
--}
--
--/* Command line processing. */
--
--static void ATTRIBUTE_NORETURN
--usage (int errcode)
--{
-- fprintf (stderr,
--"usage: %s [-vh] [-V vpath] [-Dname[=def]...] [-Uname] [-Idir...] [-o file] sources...\n",
-- progname);
-- exit (errcode);
--}
--
--static int
--parse_options (int argc, char **argv)
--{
-- static const struct option longopts[] = {
-- { "--help", no_argument, 0, 'h' },
-- { 0, 0, 0, 0 }
-- };
--
-- for (;;)
-- switch (getopt_long (argc, argv, "hD:U:I:J:o:V:", longopts, 0))
-- {
-- case 'h': usage (0);
-- case 'D': add_clm (optarg, false); break;
-- case 'U': add_clm (optarg, true); break;
-- case 'I': add_dir (optarg, false); break;
-- case 'J': add_dir (optarg, true); break;
-- case 'o':
-- if (output_file)
-- {
-- fprintf (stderr, "%s: too many output files\n", progname);
-- usage (2);
-- }
-- output_file = optarg;
-- break;
-- case 'V':
-- if (vpath)
-- {
-- fprintf (stderr, "%s: too many vpaths\n", progname);
-- usage (2);
-- }
-- vpath = optarg;
-- break;
-- case '?':
-- usage (2); /* getopt has issued the error message. */
--
-- case -1: /* end of options */
-- if (optind == argc)
-- {
-- fprintf (stderr, "%s: no input files\n", progname);
-- usage (2);
-- }
-- return optind;
--
-- default:
-- abort ();
-- }
--}
--
--/* Set up cpplib from command line options. */
--static cpp_reader *
--reader_init (struct line_maps *line_table)
--{
-- cpp_reader *reader;
-- cpp_options *options;
--
-- linemap_init (line_table);
-- reader = cpp_create_reader (CLK_GNUC89, 0, line_table);
--
-- /* Ignore warnings and errors (we don't have access to system
-- headers). Request dependency output. */
-- options = cpp_get_options (reader);
-- options->inhibit_warnings = 1;
-- options->inhibit_errors = 1;
-- options->deps.style = DEPS_USER;
--
-- /* Further initialization. */
-- cpp_post_options (reader);
-- cpp_init_iconv (reader);
-- cpp_set_include_chains (reader, cmd_line_searchpath, cmd_line_searchpath,
-- false);
-- if (vpath)
-- {
-- struct deps *deps = cpp_get_deps (reader);
-- deps_add_vpath (deps, vpath);
-- }
--
-- return reader;
--}
--
--/* Process one input source file. */
--static void
--process_file (const char *file)
--{
-- struct line_maps line_table;
-- cpp_reader *reader = reader_init (&line_table);
--
-- if (!cpp_read_main_file (reader, file))
-- had_errors = true;
-- else
-- {
-- struct cmd_line_macro *clm;
--
-- cpp_init_builtins (reader, true);
-- for (clm = cmd_line_macros; clm; clm = clm->next)
-- (clm->is_undef ? cpp_undef : cpp_define) (reader, clm->macro);
--
-- cpp_scan_nooutput (reader);
-- if (cpp_finish (reader, stdout))
-- had_errors = true;
-- }
-- cpp_destroy (reader);
-- linemap_free (&line_table);
--}
--
--/* Master control. */
--
--int
--main(int argc, char **argv)
--{
-- int first_input, i;
--
-- progname = argv[0];
-- xmalloc_set_program_name (progname);
--
-- first_input = parse_options (argc, argv);
-- if (output_file)
-- if (!freopen (output_file, "w", stdout))
-- {
-- perror (output_file);
-- return 1;
-- }
--
-- for (i = first_input; i < argc; i++)
-- process_file (argv[i]);
--
-- return had_errors;
--}
---- a/libgcc/Makefile.in
-+++ b/libgcc/Makefile.in
-@@ -389,18 +389,24 @@ libgcc-s-objects += $(patsubst %,%_s$(ob
- endif
- endif
-
-+ifeq ($(LIB2_DIVMOD_EXCEPTION_FLAGS),)
-+# Provide default flags for compiling divmod functions, if they haven't been
-+# set already by a target-specific Makefile fragment.
-+LIB2_DIVMOD_EXCEPTION_FLAGS := -fexceptions -fnon-call-exceptions
-+endif
-+
- # Build LIB2_DIVMOD_FUNCS.
- lib2-divmod-o = $(patsubst %,%$(objext),$(LIB2_DIVMOD_FUNCS))
- $(lib2-divmod-o): %$(objext): $(gcc_srcdir)/libgcc2.c
- $(gcc_compile) -DL$* -c $(gcc_srcdir)/libgcc2.c \
-- -fexceptions -fnon-call-exceptions $(vis_hide)
-+ $(LIB2_DIVMOD_EXCEPTION_FLAGS) $(vis_hide)
- libgcc-objects += $(lib2-divmod-o)
-
- ifeq ($(enable_shared),yes)
- lib2-divmod-s-o = $(patsubst %,%_s$(objext),$(LIB2_DIVMOD_FUNCS))
- $(lib2-divmod-s-o): %_s$(objext): $(gcc_srcdir)/libgcc2.c
- $(gcc_s_compile) -DL$* -c $(gcc_srcdir)/libgcc2.c \
-- -fexceptions -fnon-call-exceptions
-+ $(LIB2_DIVMOD_EXCEPTION_FLAGS)
- libgcc-s-objects += $(lib2-divmod-s-o)
- endif
-
---- a/libgcc/config.host
-+++ b/libgcc/config.host
-@@ -203,12 +203,15 @@ arm*-*-netbsdelf*)
- arm*-*-netbsd*)
- ;;
- arm*-*-linux*) # ARM GNU/Linux with ELF
-+ tmake_file="${tmake_file} arm/t-divmod-ef"
- ;;
- arm*-*-uclinux*) # ARM ucLinux
-+ tmake_file="${tmake_file} arm/t-divmod-ef"
- ;;
- arm*-*-ecos-elf)
- ;;
- arm*-*-eabi* | arm*-*-symbianelf* )
-+ tmake_file="${tmake_file} arm/t-divmod-ef"
- ;;
- arm*-*-rtems*)
- ;;
-@@ -394,8 +397,12 @@ mips-sgi-irix[56]*)
- mips*-*-netbsd*) # NetBSD/mips, either endian.
- ;;
- mips64*-*-linux*)
-+ extra_parts="$extra_parts crtfastmath.o"
-+ tmake_file="{$tmake_file} mips/t-crtfm"
- ;;
- mips*-*-linux*) # Linux MIPS, either endian.
-+ extra_parts="$extra_parts crtfastmath.o"
-+ tmake_file="{$tmake_file} mips/t-crtfm"
- ;;
- mips*-*-openbsd*)
- ;;
---- /dev/null
-+++ b/libgcc/config/arm/t-divmod-ef
-@@ -0,0 +1,4 @@
-+# On ARM, specifying -fnon-call-exceptions will needlessly pull in
-+# the unwinder in simple programs which use 64-bit division. Omitting
-+# the option is safe.
-+LIB2_DIVMOD_EXCEPTION_FLAGS := -fexceptions
---- /dev/null
-+++ b/libgcc/config/mips/t-crtfm
-@@ -0,0 +1,3 @@
-+crtfastmath.o: $(gcc_srcdir)/config/mips/crtfastmath.c
-+ $(gcc_compile) -c $(gcc_srcdir)/config/mips/crtfastmath.c
-+
---- a/libgcc/config/rs6000/t-ppccomm
-+++ b/libgcc/config/rs6000/t-ppccomm
-@@ -101,3 +101,63 @@ ncrti$(objext): ncrti.S
-
- ncrtn$(objext): ncrtn.S
- $(crt_compile) -c ncrtn.S
-+
-+crtsavres$(objext): crtsavres.S
-+ $(crt_compile) -c crtsavres.S
-+
-+crtsavfpr$(objext): crtsavfpr.S
-+ $(crt_compile) -c crtsavfpr.S
-+
-+crtresfpr$(objext): crtresfpr.S
-+ $(crt_compile) -c crtresfpr.S
-+
-+crtsavgpr$(objext): crtsavgpr.S
-+ $(crt_compile) -c crtsavgpr.S
-+
-+crtresgpr$(objext): crtresgpr.S
-+ $(crt_compile) -c crtresgpr.S
-+
-+crtresxfpr$(objext): crtresxfpr.S
-+ $(crt_compile) -c crtresxfpr.S
-+
-+crtresxgpr$(objext): crtresxgpr.S
-+ $(crt_compile) -c crtresxgpr.S
-+
-+e500crtres32gpr$(objext): e500crtres32gpr.S
-+ $(crt_compile) -c e500crtres32gpr.S
-+
-+e500crtres64gpr$(objext): e500crtres64gpr.S
-+ $(crt_compile) -c e500crtres64gpr.S
-+
-+e500crtres64gprctr$(objext): e500crtres64gprctr.S
-+ $(crt_compile) -c e500crtres64gprctr.S
-+
-+e500crtrest32gpr$(objext): e500crtrest32gpr.S
-+ $(crt_compile) -c e500crtrest32gpr.S
-+
-+e500crtrest64gpr$(objext): e500crtrest64gpr.S
-+ $(crt_compile) -c e500crtrest64gpr.S
-+
-+e500crtresx32gpr$(objext): e500crtresx32gpr.S
-+ $(crt_compile) -c e500crtresx32gpr.S
-+
-+e500crtresx64gpr$(objext): e500crtresx64gpr.S
-+ $(crt_compile) -c e500crtresx64gpr.S
-+
-+e500crtsav32gpr$(objext): e500crtsav32gpr.S
-+ $(crt_compile) -c e500crtsav32gpr.S
-+
-+e500crtsav64gpr$(objext): e500crtsav64gpr.S
-+ $(crt_compile) -c e500crtsav64gpr.S
-+
-+e500crtsav64gprctr$(objext): e500crtsav64gprctr.S
-+ $(crt_compile) -c e500crtsav64gprctr.S
-+
-+e500crtsavg32gpr$(objext): e500crtsavg32gpr.S
-+ $(crt_compile) -c e500crtsavg32gpr.S
-+
-+e500crtsavg64gpr$(objext): e500crtsavg64gpr.S
-+ $(crt_compile) -c e500crtsavg64gpr.S
-+
-+e500crtsavg64gprctr$(objext): e500crtsavg64gprctr.S
-+ $(crt_compile) -c e500crtsavg64gprctr.S
---- a/libgcc/shared-object.mk
-+++ b/libgcc/shared-object.mk
-@@ -8,11 +8,13 @@ base := $(basename $(notdir $o))
-
- ifeq ($(suffix $o),.c)
-
-+c_flags-$(base)$(objext) := $(c_flags)
- $(base)$(objext): $o
-- $(gcc_compile) $(c_flags) -c $< $(vis_hide)
-+ $(gcc_compile) $(c_flags-$@) -c $< $(vis_hide)
-
-+c_flags-$(base)_s$(objext) := $(c_flags)
- $(base)_s$(objext): $o
-- $(gcc_s_compile) $(c_flags) -c $<
-+ $(gcc_s_compile) $(c_flags-$@) -c $<
-
- else
-
---- a/libgcc/static-object.mk
-+++ b/libgcc/static-object.mk
-@@ -8,8 +8,9 @@ base := $(basename $(notdir $o))
-
- ifeq ($(suffix $o),.c)
-
-+c_flags-$(base)$(objext) := $(c_flags)
- $(base)$(objext): $o
-- $(gcc_compile) $(c_flags) -c $< $(vis_hide)
-+ $(gcc_compile) $(c_flags-$@) -c $< $(vis_hide)
-
- else
-
---- a/libgomp/Makefile.am
-+++ b/libgomp/Makefile.am
-@@ -1,5 +1,10 @@
- ## Process this file with automake to produce Makefile.in
-
-+datarootdir = @datarootdir@
-+docdir = @docdir@
-+htmldir = @htmldir@
-+pdfdir = @pdfdir@
-+
- ACLOCAL_AMFLAGS = -I .. -I ../config
- SUBDIRS = testsuite
-
-@@ -41,6 +46,12 @@ if USE_FORTRAN
- nodist_finclude_HEADERS = omp_lib.h omp_lib.f90 omp_lib.mod omp_lib_kinds.mod
- endif
-
-+LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS))
-+
-+LINK = $(LIBTOOL) --tag CC --mode=link $(CCLD) $(AM_CCFLAGS) $(CFLAGS) \
-+ $(AM_LDFLAGS) $(LTLDFLAGS) -o $@
-+
-+
- omp_lib_kinds.mod: omp_lib.mod
- :
- omp_lib.mod: omp_lib.f90
-@@ -50,10 +61,30 @@ fortran.o: libgomp_f.h
- env.lo: libgomp_f.h
- env.o: libgomp_f.h
-
-+HTMLS_INSTALL=libgomp
-+HTMLS_BUILD=libgomp/index.html
-
--# No install-html or install-pdf support in automake yet
--.PHONY: install-html install-pdf
--install-html:
-+$(HTMLS_BUILD): $(info_TEXINFOS)
-+ $(TEXI2HTML) $(MAKEINFOFLAGS) -I$(srcdir) -o $(@D) $<
-+
-+html__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
-+
-+install-html: $(HTMLS_BUILD)
-+ @$(NORMAL_INSTALL)
-+ test -z "$(htmldir)" || $(mkinstalldirs) "$(DESTDIR)$(htmldir)"
-+ @list='$(HTMLS_INSTALL)'; for p in $$list; do \
-+ if test -f "$$p" || test -d "$$p"; then d=""; else d="$(srcdir)/"; fi; \
-+ f=$(html__strip_dir) \
-+ if test -d "$$d$$p"; then \
-+ echo " $(mkinstalldirs) '$(DESTDIR)$(htmldir)/$$f'"; \
-+ $(mkinstalldirs) "$(DESTDIR)$(htmldir)/$$f" || exit 1; \
-+ echo " $(INSTALL_DATA) '$$d$$p'/* '$(DESTDIR)$(htmldir)/$$f'"; \
-+ $(INSTALL_DATA) "$$d$$p"/* "$(DESTDIR)$(htmldir)/$$f"; \
-+ else \
-+ echo " $(INSTALL_DATA) '$$d$$p' '$(DESTDIR)$(htmldir)/$$f'"; \
-+ $(INSTALL_DATA) "$$d$$p" "$(DESTDIR)$(htmldir)/$$f"; \
-+ fi; \
-+ done
-
- install-pdf: $(PDFS)
- @$(NORMAL_INSTALL)
-@@ -71,6 +102,7 @@ install-pdf: $(PDFS)
- # `texinfo.tex' for your package. The value of this variable should be
- # the relative path from the current `Makefile.am' to `texinfo.tex'.
- TEXINFO_TEX = ../gcc/doc/include/texinfo.tex
-+TEXI2HTML = $(MAKEINFO) --html
-
- # Defines info, dvi, pdf and html targets
- MAKEINFOFLAGS = -I $(srcdir)/../gcc/doc/include
---- a/libgomp/Makefile.in
-+++ b/libgomp/Makefile.in
-@@ -97,8 +97,6 @@ LTCOMPILE = $(LIBTOOL) --tag=CC --mode=c
- $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
- $(AM_CFLAGS) $(CFLAGS)
- CCLD = $(CC)
--LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
-- $(AM_LDFLAGS) $(LDFLAGS) -o $@
- SOURCES = $(libgomp_la_SOURCES)
- DIST_SOURCES = $(libgomp_la_SOURCES)
- MULTISRCTOP =
-@@ -259,6 +257,8 @@ build_os = @build_os@
- build_vendor = @build_vendor@
- config_path = @config_path@
- datadir = @datadir@
-+datarootdir = @datarootdir@
-+docdir = @docdir@
- enable_shared = @enable_shared@
- enable_static = @enable_static@
- exec_prefix = @exec_prefix@
-@@ -267,6 +267,7 @@ host_alias = @host_alias@
- host_cpu = @host_cpu@
- host_os = @host_os@
- host_vendor = @host_vendor@
-+htmldir = @htmldir@
- includedir = @includedir@
- infodir = @infodir@
- install_sh = @install_sh@
-@@ -280,6 +281,7 @@ mandir = @mandir@
- mkdir_p = @mkdir_p@
- multi_basedir = @multi_basedir@
- oldincludedir = @oldincludedir@
-+pdfdir = @pdfdir@
- prefix = @prefix@
- program_transform_name = @program_transform_name@
- sbindir = @sbindir@
-@@ -317,6 +319,13 @@ libgomp_la_SOURCES = alloc.c barrier.c c
- nodist_noinst_HEADERS = libgomp_f.h
- nodist_libsubinclude_HEADERS = omp.h
- @USE_FORTRAN_TRUE@nodist_finclude_HEADERS = omp_lib.h omp_lib.f90 omp_lib.mod omp_lib_kinds.mod
-+LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS))
-+LINK = $(LIBTOOL) --tag CC --mode=link $(CCLD) $(AM_CCFLAGS) $(CFLAGS) \
-+ $(AM_LDFLAGS) $(LTLDFLAGS) -o $@
-+
-+HTMLS_INSTALL = libgomp
-+HTMLS_BUILD = libgomp/index.html
-+html__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
-
- # Automake Documentation:
- # If your package has Texinfo files in many directories, you can use the
-@@ -324,6 +333,7 @@ nodist_libsubinclude_HEADERS = omp.h
- # `texinfo.tex' for your package. The value of this variable should be
- # the relative path from the current `Makefile.am' to `texinfo.tex'.
- TEXINFO_TEX = ../gcc/doc/include/texinfo.tex
-+TEXI2HTML = $(MAKEINFO) --html
-
- # Defines info, dvi, pdf and html targets
- MAKEINFOFLAGS = -I $(srcdir)/../gcc/doc/include
-@@ -1085,9 +1095,25 @@ fortran.o: libgomp_f.h
- env.lo: libgomp_f.h
- env.o: libgomp_f.h
-
--# No install-html or install-pdf support in automake yet
--.PHONY: install-html install-pdf
--install-html:
-+$(HTMLS_BUILD): $(info_TEXINFOS)
-+ $(TEXI2HTML) $(MAKEINFOFLAGS) -I$(srcdir) -o $(@D) $<
-+
-+install-html: $(HTMLS_BUILD)
-+ @$(NORMAL_INSTALL)
-+ test -z "$(htmldir)" || $(mkinstalldirs) "$(DESTDIR)$(htmldir)"
-+ @list='$(HTMLS_INSTALL)'; for p in $$list; do \
-+ if test -f "$$p" || test -d "$$p"; then d=""; else d="$(srcdir)/"; fi; \
-+ f=$(html__strip_dir) \
-+ if test -d "$$d$$p"; then \
-+ echo " $(mkinstalldirs) '$(DESTDIR)$(htmldir)/$$f'"; \
-+ $(mkinstalldirs) "$(DESTDIR)$(htmldir)/$$f" || exit 1; \
-+ echo " $(INSTALL_DATA) '$$d$$p'/* '$(DESTDIR)$(htmldir)/$$f'"; \
-+ $(INSTALL_DATA) "$$d$$p"/* "$(DESTDIR)$(htmldir)/$$f"; \
-+ else \
-+ echo " $(INSTALL_DATA) '$$d$$p' '$(DESTDIR)$(htmldir)/$$f'"; \
-+ $(INSTALL_DATA) "$$d$$p" "$(DESTDIR)$(htmldir)/$$f"; \
-+ fi; \
-+ done
-
- install-pdf: $(PDFS)
- @$(NORMAL_INSTALL)
---- a/libgomp/configure
-+++ b/libgomp/configure
-@@ -457,7 +457,7 @@ ac_includes_default="\
- # include <unistd.h>
- #endif"
-
--ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS GENINSRC_TRUE GENINSRC_FALSE build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar multi_basedir toolexecdir toolexeclibdir CC ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CFLAGS AR ac_ct_AR RANLIB ac_ct_RANLIB PERL BUILD_INFO_TRUE BUILD_INFO_FALSE LIBTOOL SED EGREP FGREP GREP LD DUMPBIN ac_ct_DUMPBIN NM LN_S OBJDUMP ac_ct_OBJDUMP lt_ECHO DSYMUTIL ac_ct_DSYMUTIL NMEDIT ac_ct_NMEDIT LIPO ac_ct_LIPO OTOOL ac_ct_OTOOL OTOOL64 ac_ct_OTOOL64 CPP CPPFLAGS enable_shared enable_static MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT FC FCFLAGS LDFLAGS ac_ct_FC libtool_VERSION SECTION_LDFLAGS OPT_LDFLAGS LIBGOMP_BUILD_VERSIONED_SHLIB_TRUE LIBGOMP_BUILD_VERSIONED_SHLIB_FALSE config_path XCFLAGS XLDFLAGS link_gomp USE_FORTRAN_TRUE USE_FORTRAN_FALSE OMP_LOCK_SIZE OMP_LOCK_ALIGN OMP_NEST_LOCK_SIZE OMP_NEST_LOCK_ALIGN OMP_LOCK_KIND OMP_NEST_LOCK_KIND OMP_LOCK_25_SIZE OMP_LOCK_25_ALIGN OMP_NEST_LOCK_25_SIZE OMP_NEST_LOCK_25_ALIGN OMP_LOCK_25_KIND OMP_NEST_LOCK_25_KIND LIBOBJS LTLIBOBJS'
-+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS GENINSRC_TRUE GENINSRC_FALSE build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar multi_basedir toolexecdir toolexeclibdir datarootdir docdir pdfdir htmldir CC ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CFLAGS AR ac_ct_AR RANLIB ac_ct_RANLIB PERL BUILD_INFO_TRUE BUILD_INFO_FALSE LIBTOOL SED EGREP FGREP GREP LD DUMPBIN ac_ct_DUMPBIN NM LN_S OBJDUMP ac_ct_OBJDUMP lt_ECHO DSYMUTIL ac_ct_DSYMUTIL NMEDIT ac_ct_NMEDIT LIPO ac_ct_LIPO OTOOL ac_ct_OTOOL OTOOL64 ac_ct_OTOOL64 CPP CPPFLAGS enable_shared enable_static MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT FC FCFLAGS LDFLAGS ac_ct_FC libtool_VERSION SECTION_LDFLAGS OPT_LDFLAGS LIBGOMP_BUILD_VERSIONED_SHLIB_TRUE LIBGOMP_BUILD_VERSIONED_SHLIB_FALSE config_path XCFLAGS XLDFLAGS link_gomp USE_FORTRAN_TRUE USE_FORTRAN_FALSE OMP_LOCK_SIZE OMP_LOCK_ALIGN OMP_NEST_LOCK_SIZE OMP_NEST_LOCK_ALIGN OMP_LOCK_KIND OMP_NEST_LOCK_KIND OMP_LOCK_25_SIZE OMP_LOCK_25_ALIGN OMP_NEST_LOCK_25_SIZE OMP_NEST_LOCK_25_ALIGN OMP_LOCK_25_KIND OMP_NEST_LOCK_25_KIND LIBOBJS LTLIBOBJS'
- ac_subst_files=''
- ac_pwd=`pwd`
-
-@@ -1029,6 +1029,10 @@ Optional Features:
- Optional Packages:
- --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
- --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
-+ --with-datarootdir=DIR Use DIR as the data root [PREFIX/share]
-+ --with-docdir=DIR Install documentation in DIR [DATAROOTDIR]
-+ --with-pdfdir install pdf in this directory.
-+ --with-htmldir=DIR html documentation in in DIR [DOCDIR]
- --with-pic try to use only PIC/non-PIC objects [default=use
- both]
- --with-gnu-ld assume the C compiler uses GNU ld [default=no]
-@@ -2201,6 +2205,46 @@ esac
-
-
-
-+
-+# Check whether --with-datarootdir or --without-datarootdir was given.
-+if test "${with_datarootdir+set}" = set; then
-+ withval="$with_datarootdir"
-+ datarootdir="\${prefix}/$with_datarootdir"
-+else
-+ datarootdir='$(prefix)/share'
-+fi;
-+
-+
-+
-+# Check whether --with-docdir or --without-docdir was given.
-+if test "${with_docdir+set}" = set; then
-+ withval="$with_docdir"
-+ docdir="\${prefix}/$with_docdir"
-+else
-+ docdir='$(datarootdir)'
-+fi;
-+
-+
-+
-+# Check whether --with-pdfdir or --without-pdfdir was given.
-+if test "${with_pdfdir+set}" = set; then
-+ withval="$with_pdfdir"
-+ pdfdir="\${prefix}/${withval}"
-+else
-+ pdfdir="\${docdir}"
-+fi;
-+
-+
-+
-+# Check whether --with-htmldir or --without-htmldir was given.
-+if test "${with_htmldir+set}" = set; then
-+ withval="$with_htmldir"
-+ htmldir="\${prefix}/$with_htmldir"
-+else
-+ htmldir='$(docdir)'
-+fi;
-+
-+
- # Check the compiler.
- # The same as in boehm-gc and libstdc++. Have to borrow it from there.
- # We must force CC to /not/ be precious variables; otherwise
-@@ -4156,13 +4200,13 @@ if test "${lt_cv_nm_interface+set}" = se
- else
- lt_cv_nm_interface="BSD nm"
- echo "int some_variable = 0;" > conftest.$ac_ext
-- (eval echo "\"\$as_me:4159: $ac_compile\"" >&5)
-+ (eval echo "\"\$as_me:4203: $ac_compile\"" >&5)
- (eval "$ac_compile" 2>conftest.err)
- cat conftest.err >&5
-- (eval echo "\"\$as_me:4162: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
-+ (eval echo "\"\$as_me:4206: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
- (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
- cat conftest.err >&5
-- (eval echo "\"\$as_me:4165: output\"" >&5)
-+ (eval echo "\"\$as_me:4209: output\"" >&5)
- cat conftest.out >&5
- if $GREP 'External.*some_variable' conftest.out > /dev/null; then
- lt_cv_nm_interface="MS dumpbin"
-@@ -5320,7 +5364,7 @@ ia64-*-hpux*)
- ;;
- *-*-irix6*)
- # Find out which ABI we are using.
-- echo '#line 5323 "configure"' > conftest.$ac_ext
-+ echo '#line 5367 "configure"' > conftest.$ac_ext
- if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
-@@ -7101,11 +7145,11 @@ else
- -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
- -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
- -e 's:$: $lt_compiler_flag:'`
-- (eval echo "\"\$as_me:7104: $lt_compile\"" >&5)
-+ (eval echo "\"\$as_me:7148: $lt_compile\"" >&5)
- (eval "$lt_compile" 2>conftest.err)
- ac_status=$?
- cat conftest.err >&5
-- echo "$as_me:7108: \$? = $ac_status" >&5
-+ echo "$as_me:7152: \$? = $ac_status" >&5
- if (exit $ac_status) && test -s "$ac_outfile"; then
- # The compiler can only warn and ignore the option if not recognized
- # So say no if there are warnings other than the usual output.
-@@ -7440,11 +7484,11 @@ else
- -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
- -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
- -e 's:$: $lt_compiler_flag:'`
-- (eval echo "\"\$as_me:7443: $lt_compile\"" >&5)
-+ (eval echo "\"\$as_me:7487: $lt_compile\"" >&5)
- (eval "$lt_compile" 2>conftest.err)
- ac_status=$?
- cat conftest.err >&5
-- echo "$as_me:7447: \$? = $ac_status" >&5
-+ echo "$as_me:7491: \$? = $ac_status" >&5
- if (exit $ac_status) && test -s "$ac_outfile"; then
- # The compiler can only warn and ignore the option if not recognized
- # So say no if there are warnings other than the usual output.
-@@ -7545,11 +7589,11 @@ else
- -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
- -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
- -e 's:$: $lt_compiler_flag:'`
-- (eval echo "\"\$as_me:7548: $lt_compile\"" >&5)
-+ (eval echo "\"\$as_me:7592: $lt_compile\"" >&5)
- (eval "$lt_compile" 2>out/conftest.err)
- ac_status=$?
- cat out/conftest.err >&5
-- echo "$as_me:7552: \$? = $ac_status" >&5
-+ echo "$as_me:7596: \$? = $ac_status" >&5
- if (exit $ac_status) && test -s out/conftest2.$ac_objext
- then
- # The compiler can only warn and ignore the option if not recognized
-@@ -7600,11 +7644,11 @@ else
- -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
- -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
- -e 's:$: $lt_compiler_flag:'`
-- (eval echo "\"\$as_me:7603: $lt_compile\"" >&5)
-+ (eval echo "\"\$as_me:7647: $lt_compile\"" >&5)
- (eval "$lt_compile" 2>out/conftest.err)
- ac_status=$?
- cat out/conftest.err >&5
-- echo "$as_me:7607: \$? = $ac_status" >&5
-+ echo "$as_me:7651: \$? = $ac_status" >&5
- if (exit $ac_status) && test -s out/conftest2.$ac_objext
- then
- # The compiler can only warn and ignore the option if not recognized
-@@ -10412,7 +10456,7 @@ else
- lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
- lt_status=$lt_dlunknown
- cat > conftest.$ac_ext <<_LT_EOF
--#line 10415 "configure"
-+#line 10459 "configure"
- #include "confdefs.h"
-
- #if HAVE_DLFCN_H
-@@ -10508,7 +10552,7 @@ else
- lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
- lt_status=$lt_dlunknown
- cat > conftest.$ac_ext <<_LT_EOF
--#line 10511 "configure"
-+#line 10555 "configure"
- #include "confdefs.h"
-
- #if HAVE_DLFCN_H
-@@ -10859,7 +10903,7 @@ fi
-
-
- # Provide some information about the compiler.
--echo "$as_me:10862:" \
-+echo "$as_me:10906:" \
- "checking for Fortran compiler version" >&5
- ac_compiler=`set X $ac_compile; echo $2`
- { (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
-@@ -11095,7 +11139,7 @@ fi
-
-
- # Provide some information about the compiler.
--echo "$as_me:11098:" \
-+echo "$as_me:11142:" \
- "checking for Fortran compiler version" >&5
- ac_compiler=`set X $ac_compile; echo $2`
- { (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
-@@ -11835,11 +11879,11 @@ else
- -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
- -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
- -e 's:$: $lt_compiler_flag:'`
-- (eval echo "\"\$as_me:11838: $lt_compile\"" >&5)
-+ (eval echo "\"\$as_me:11882: $lt_compile\"" >&5)
- (eval "$lt_compile" 2>conftest.err)
- ac_status=$?
- cat conftest.err >&5
-- echo "$as_me:11842: \$? = $ac_status" >&5
-+ echo "$as_me:11886: \$? = $ac_status" >&5
- if (exit $ac_status) && test -s "$ac_outfile"; then
- # The compiler can only warn and ignore the option if not recognized
- # So say no if there are warnings other than the usual output.
-@@ -11934,11 +11978,11 @@ else
- -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
- -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
- -e 's:$: $lt_compiler_flag:'`
-- (eval echo "\"\$as_me:11937: $lt_compile\"" >&5)
-+ (eval echo "\"\$as_me:11981: $lt_compile\"" >&5)
- (eval "$lt_compile" 2>out/conftest.err)
- ac_status=$?
- cat out/conftest.err >&5
-- echo "$as_me:11941: \$? = $ac_status" >&5
-+ echo "$as_me:11985: \$? = $ac_status" >&5
- if (exit $ac_status) && test -s out/conftest2.$ac_objext
- then
- # The compiler can only warn and ignore the option if not recognized
-@@ -11986,11 +12030,11 @@ else
- -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
- -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
- -e 's:$: $lt_compiler_flag:'`
-- (eval echo "\"\$as_me:11989: $lt_compile\"" >&5)
-+ (eval echo "\"\$as_me:12033: $lt_compile\"" >&5)
- (eval "$lt_compile" 2>out/conftest.err)
- ac_status=$?
- cat out/conftest.err >&5
-- echo "$as_me:11993: \$? = $ac_status" >&5
-+ echo "$as_me:12037: \$? = $ac_status" >&5
- if (exit $ac_status) && test -s out/conftest2.$ac_objext
- then
- # The compiler can only warn and ignore the option if not recognized
-@@ -15133,7 +15177,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- int
- main ()
- {
-@@ -15197,7 +15242,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- int
- main ()
- {
-@@ -15238,7 +15284,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- int
- main ()
- {
-@@ -15295,7 +15342,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- int
- main ()
- {
-@@ -15336,7 +15384,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- int
- main ()
- {
-@@ -15401,7 +15450,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- int
- main ()
- {
-@@ -15469,7 +15519,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- long longval () { return (long) (sizeof (void *)); }
- unsigned long ulongval () { return (long) (sizeof (void *)); }
- #include <stdio.h>
-@@ -15557,7 +15608,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- int
- main ()
- {
-@@ -15621,7 +15673,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- int
- main ()
- {
-@@ -15662,7 +15715,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- int
- main ()
- {
-@@ -15719,7 +15773,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- int
- main ()
- {
-@@ -15760,7 +15815,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- int
- main ()
- {
-@@ -15825,7 +15881,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- int
- main ()
- {
-@@ -15893,7 +15950,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- long longval () { return (long) (sizeof (long)); }
- unsigned long ulongval () { return (long) (sizeof (long)); }
- #include <stdio.h>
-@@ -15981,7 +16039,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- int
- main ()
- {
-@@ -16045,7 +16104,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- int
- main ()
- {
-@@ -16086,7 +16146,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- int
- main ()
- {
-@@ -16143,7 +16204,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- int
- main ()
- {
-@@ -16184,7 +16246,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- int
- main ()
- {
-@@ -16249,7 +16312,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- int
- main ()
- {
-@@ -16317,7 +16381,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- long longval () { return (long) (sizeof (int)); }
- unsigned long ulongval () { return (long) (sizeof (int)); }
- #include <stdio.h>
-@@ -16401,7 +16466,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- int
- main ()
- {
-@@ -16465,7 +16531,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- int
- main ()
- {
-@@ -16506,7 +16573,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- int
- main ()
- {
-@@ -16563,7 +16631,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- int
- main ()
- {
-@@ -16604,7 +16673,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- int
- main ()
- {
-@@ -16669,7 +16739,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- int
- main ()
- {
-@@ -16737,7 +16808,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- long longval () { return (long) (sizeof (short)); }
- unsigned long ulongval () { return (long) (sizeof (short)); }
- #include <stdio.h>
-@@ -16821,7 +16893,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- int
- main ()
- {
-@@ -16885,7 +16958,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- int
- main ()
- {
-@@ -16926,7 +17000,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- int
- main ()
- {
-@@ -16983,7 +17058,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- int
- main ()
- {
-@@ -17024,7 +17100,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- int
- main ()
- {
-@@ -17089,7 +17166,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- int
- main ()
- {
-@@ -17157,7 +17235,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- long longval () { return (long) (sizeof (char)); }
- unsigned long ulongval () { return (long) (sizeof (char)); }
- #include <stdio.h>
-@@ -17906,6 +17985,64 @@ if { (eval echo "$as_me:$LINENO: \"$ac_l
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
-+ chktls_save_LDFLAGS="$LDFLAGS"
-+ case $host in
-+ *-*-linux*)
-+ LDFLAGS="-shared -Wl,--no-undefined $LDFLAGS"
-+ ;;
-+ esac
-+ chktls_save_CFLAGS="$CFLAGS"
-+ CFLAGS="-fPIC $CFLAGS"
-+ cat >conftest.$ac_ext <<_ACEOF
-+int f() { return 0; }
-+_ACEOF
-+rm -f conftest.$ac_objext conftest$ac_exeext
-+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-+ (eval $ac_link) 2>conftest.er1
-+ ac_status=$?
-+ grep -v '^ *+' conftest.er1 >conftest.err
-+ rm -f conftest.er1
-+ cat conftest.err >&5
-+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
-+ (exit $ac_status); } &&
-+ { ac_try='test -z "$ac_c_werror_flag"
-+ || test ! -s conftest.err'
-+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-+ (eval $ac_try) 2>&5
-+ ac_status=$?
-+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
-+ (exit $ac_status); }; } &&
-+ { ac_try='test -s conftest$ac_exeext'
-+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-+ (eval $ac_try) 2>&5
-+ ac_status=$?
-+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
-+ (exit $ac_status); }; }; then
-+ cat >conftest.$ac_ext <<_ACEOF
-+__thread int a; int b; int f() { return a = b; }
-+_ACEOF
-+rm -f conftest.$ac_objext conftest$ac_exeext
-+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-+ (eval $ac_link) 2>conftest.er1
-+ ac_status=$?
-+ grep -v '^ *+' conftest.er1 >conftest.err
-+ rm -f conftest.er1
-+ cat conftest.err >&5
-+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
-+ (exit $ac_status); } &&
-+ { ac_try='test -z "$ac_c_werror_flag"
-+ || test ! -s conftest.err'
-+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-+ (eval $ac_try) 2>&5
-+ ac_status=$?
-+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
-+ (exit $ac_status); }; } &&
-+ { ac_try='test -s conftest$ac_exeext'
-+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-+ (eval $ac_try) 2>&5
-+ ac_status=$?
-+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
-+ (exit $ac_status); }; }; then
- gcc_cv_have_tls=yes
- else
- echo "$as_me: failed program was:" >&5
-@@ -17915,6 +18052,24 @@ gcc_cv_have_tls=no
- fi
- rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-+else
-+ echo "$as_me: failed program was:" >&5
-+sed 's/^/| /' conftest.$ac_ext >&5
-+
-+gcc_cv_have_tls=yes
-+fi
-+rm -f conftest.err conftest.$ac_objext \
-+ conftest$ac_exeext conftest.$ac_ext
-+ CFLAGS="$chktls_save_CFLAGS"
-+ LDFLAGS="$chktls_save_LDFLAGS"
-+else
-+ echo "$as_me: failed program was:" >&5
-+sed 's/^/| /' conftest.$ac_ext >&5
-+
-+gcc_cv_have_tls=no
-+fi
-+rm -f conftest.err conftest.$ac_objext \
-+ conftest$ac_exeext conftest.$ac_ext
-
-
- else
-@@ -22801,6 +22956,10 @@ s,@am__untar@,$am__untar,;t t
- s,@multi_basedir@,$multi_basedir,;t t
- s,@toolexecdir@,$toolexecdir,;t t
- s,@toolexeclibdir@,$toolexeclibdir,;t t
-+s,@datarootdir@,$datarootdir,;t t
-+s,@docdir@,$docdir,;t t
-+s,@pdfdir@,$pdfdir,;t t
-+s,@htmldir@,$htmldir,;t t
- s,@CC@,$CC,;t t
- s,@ac_ct_CC@,$ac_ct_CC,;t t
- s,@EXEEXT@,$EXEEXT,;t t
---- a/libgomp/configure.ac
-+++ b/libgomp/configure.ac
-@@ -94,6 +94,30 @@ esac
- AC_SUBST(toolexecdir)
- AC_SUBST(toolexeclibdir)
-
-+AC_ARG_WITH(datarootdir,
-+[ --with-datarootdir=DIR Use DIR as the data root [[PREFIX/share]]],
-+datarootdir="\${prefix}/$with_datarootdir",
-+datarootdir='$(prefix)/share')
-+AC_SUBST(datarootdir)
-+
-+AC_ARG_WITH(docdir,
-+[ --with-docdir=DIR Install documentation in DIR [[DATAROOTDIR]]],
-+docdir="\${prefix}/$with_docdir",
-+docdir='$(datarootdir)')
-+AC_SUBST(docdir)
-+
-+AC_ARG_WITH(pdfdir,
-+[ --with-pdfdir install pdf in this directory.],
-+[pdfdir="\${prefix}/${withval}"],
-+[pdfdir="\${docdir}"])
-+AC_SUBST(pdfdir)
-+
-+AC_ARG_WITH(htmldir,
-+[ --with-htmldir=DIR html documentation in in DIR [[DOCDIR]]],
-+htmldir="\${prefix}/$with_htmldir",
-+htmldir='$(docdir)')
-+AC_SUBST(htmldir)
-+
- # Check the compiler.
- # The same as in boehm-gc and libstdc++. Have to borrow it from there.
- # We must force CC to /not/ be precious variables; otherwise
---- a/libgomp/libgomp.texi
-+++ b/libgomp/libgomp.texi
-@@ -94,7 +94,7 @@ for multi-platform shared-memory paralle
- How you can copy and share this manual.
- * Funding:: How to help assure continued work for free
- software.
--* Index:: Index of this documentation.
-+* Library Index:: Index of this documentation.
- @end menu
-
-
-@@ -1713,8 +1713,8 @@ Bugs in the GNU OpenMP implementation sh
- @c Index
- @c ---------------------------------------------------------------------
-
--@node Index
--@unnumbered Index
-+@node Library Index
-+@unnumbered Library Index
-
- @printindex cp
-
---- a/libgomp/testsuite/Makefile.in
-+++ b/libgomp/testsuite/Makefile.in
-@@ -177,6 +177,8 @@ build_os = @build_os@
- build_vendor = @build_vendor@
- config_path = @config_path@
- datadir = @datadir@
-+datarootdir = @datarootdir@
-+docdir = @docdir@
- enable_shared = @enable_shared@
- enable_static = @enable_static@
- exec_prefix = @exec_prefix@
-@@ -185,6 +187,7 @@ host_alias = @host_alias@
- host_cpu = @host_cpu@
- host_os = @host_os@
- host_vendor = @host_vendor@
-+htmldir = @htmldir@
- includedir = @includedir@
- infodir = @infodir@
- install_sh = @install_sh@
-@@ -198,6 +201,7 @@ mandir = @mandir@
- mkdir_p = @mkdir_p@
- multi_basedir = @multi_basedir@
- oldincludedir = @oldincludedir@
-+pdfdir = @pdfdir@
- prefix = @prefix@
- program_transform_name = @program_transform_name@
- sbindir = @sbindir@
---- a/libiberty/Makefile.in
-+++ b/libiberty/Makefile.in
-@@ -124,7 +124,7 @@ COMPILE.c = $(CC) -c @DEFS@ $(CFLAGS) $(
- CFILES = alloca.c argv.c asprintf.c atexit.c \
- basename.c bcmp.c bcopy.c bsearch.c bzero.c \
- calloc.c choose-temp.c clock.c concat.c cp-demangle.c \
-- cp-demint.c cplus-dem.c \
-+ cp-demint.c cplus-dem.c cygpath.c \
- dyn-string.c \
- fdmatch.c ffs.c fibheap.c filename_cmp.c floatformat.c \
- fnmatch.c fopen_unlocked.c \
-@@ -182,7 +182,7 @@ REQUIRED_OFILES = \
- # maint-missing" and "make check".
- CONFIGURED_OFILES = ./asprintf.o ./atexit.o \
- ./basename.o ./bcmp.o ./bcopy.o ./bsearch.o ./bzero.o \
-- ./calloc.o ./clock.o ./copysign.o \
-+ ./calloc.o ./clock.o ./copysign.o ./cygpath.o \
- ./_doprnt.o \
- ./ffs.o \
- ./getcwd.o ./getpagesize.o ./gettimeofday.o \
-@@ -619,6 +619,13 @@ $(CONFIGURED_OFILES): stamp-picdir
- else true; fi
- $(COMPILE.c) $(srcdir)/cplus-dem.c $(OUTPUT_OPTION)
-
-+./cygpath.o: $(srcdir)/cygpath.c config.h $(INCDIR)/ansidecl.h \
-+ $(INCDIR)/libiberty.h
-+ if [ x"$(PICFLAG)" != x ]; then \
-+ $(COMPILE.c) $(PICFLAG) $(srcdir)/cygpath.c -o pic/$@; \
-+ else true; fi
-+ $(COMPILE.c) $(srcdir)/cygpath.c $(OUTPUT_OPTION)
-+
- ./dyn-string.o: $(srcdir)/dyn-string.c config.h $(INCDIR)/ansidecl.h \
- $(INCDIR)/dyn-string.h $(INCDIR)/libiberty.h
- if [ x"$(PICFLAG)" != x ]; then \
---- a/libiberty/argv.c
-+++ b/libiberty/argv.c
-@@ -119,6 +119,24 @@ void freeargv (char **vector)
- }
- }
-
-+static void
-+consume_whitespace (const char **input)
-+{
-+ while (ISSPACE (**input))
-+ {
-+ (*input)++;
-+ }
-+}
-+
-+static int
-+only_whitespace (const char* input)
-+{
-+ while (*input != EOS && ISSPACE (*input))
-+ input++;
-+
-+ return (*input == EOS);
-+}
-+
- /*
-
- @deftypefn Extension char** buildargv (char *@var{sp})
-@@ -179,10 +197,8 @@ char **buildargv (const char *input)
- do
- {
- /* Pick off argv[argc] */
-- while (ISBLANK (*input))
-- {
-- input++;
-- }
-+ consume_whitespace (&input);
-+
- if ((maxargc == 0) || (argc >= (maxargc - 1)))
- {
- /* argv needs initialization, or expansion */
-@@ -278,10 +294,7 @@ char **buildargv (const char *input)
- argc++;
- argv[argc] = NULL;
-
-- while (ISSPACE (*input))
-- {
-- input++;
-- }
-+ consume_whitespace (&input);
- }
- while (*input != EOS);
- }
-@@ -420,8 +433,17 @@ expandargv (int *argcp, char ***argvp)
- goto error;
- /* Add a NUL terminator. */
- buffer[len] = '\0';
-- /* Parse the string. */
-- file_argv = buildargv (buffer);
-+ /* If the file is empty or contains only whitespace, buildargv would
-+ return a single empty argument. In this context we want no arguments,
-+ instead. */
-+ if (only_whitespace (buffer))
-+ {
-+ file_argv = (char **) xmalloc (sizeof (char *));
-+ file_argv[0] = NULL;
-+ }
-+ else
-+ /* Parse the string. */
-+ file_argv = buildargv (buffer);
- /* If *ARGVP is not already dynamically allocated, copy it. */
- if (!argv_dynamic)
- {
-@@ -434,7 +456,7 @@ expandargv (int *argcp, char ***argvp)
- }
- /* Count the number of arguments. */
- file_argc = 0;
-- while (file_argv[file_argc] && *file_argv[file_argc])
-+ while (file_argv[file_argc])
- ++file_argc;
- /* Now, insert FILE_ARGV into ARGV. The "+1" below handles the
- NULL terminator at the end of ARGV. */
---- a/libiberty/configure
-+++ b/libiberty/configure
-@@ -8891,6 +8891,20 @@ case "${host}" in
- esac
-
-
-+# On MinGW, add support for Cygwin paths.
-+case "${host}" in
-+ *-*-mingw*)
-+ case $LIBOBJS in
-+ "cygpath.$ac_objext" | \
-+ *" cygpath.$ac_objext" | \
-+ "cygpath.$ac_objext "* | \
-+ *" cygpath.$ac_objext "* ) ;;
-+ *) LIBOBJS="$LIBOBJS cygpath.$ac_objext" ;;
-+esac
-+
-+ ;;
-+esac
-+
- if test x$gcc_no_link = xyes; then
- if test "x${ac_cv_func_mmap_fixed_mapped+set}" != xset; then
- ac_cv_func_mmap_fixed_mapped=no
---- a/libiberty/configure.ac
-+++ b/libiberty/configure.ac
-@@ -663,6 +663,13 @@ case "${host}" in
- esac
- AC_SUBST(pexecute)
-
-+# On MinGW, add support for Cygwin paths.
-+case "${host}" in
-+ *-*-mingw*)
-+ AC_LIBOBJ([cygpath])
-+ ;;
-+esac
-+
- libiberty_AC_FUNC_STRNCMP
-
- # Install a library built with a cross compiler in $(tooldir) rather
---- /dev/null
-+++ b/libiberty/cygpath.c
-@@ -0,0 +1,591 @@
-+/* Support Cygwin paths under MinGW.
-+ Copyright (C) 2006 Free Software Foundation, Inc.
-+ Written by CodeSourcery.
-+
-+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., 51 Franklin Street - Fifth
-+Floor, Boston, MA 02110-1301, USA. */
-+
-+#include <windows.h>
-+#include <errno.h>
-+#include <fcntl.h>
-+#include <sys/stat.h>
-+#include <sys/types.h>
-+#include <io.h>
-+#include <process.h>
-+#include <stdbool.h>
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include "libiberty.h"
-+
-+/* If non-zero, we have attempted to use cygpath. CYGPATH_PEX may
-+ still be NULL, if cygpath is unavailable. */
-+static int cygpath_initialized;
-+
-+/* If non-NULL, an instance of cygpath connected via a pipe. */
-+static struct pex_obj *cygpath_pex;
-+
-+/* The input to cygpath. */
-+static FILE *cygpath_in;
-+
-+/* The output from cygpath. */
-+static FILE *cygpath_out;
-+
-+/* If non-NULL, a file to which path translations are logged. */
-+static FILE *cygpath_log;
-+
-+/* Record MESSAGE in the CYGPATH_LOG. MESSAGE is a format string,
-+ which is expected to have a single "%s" field, to be replaced by
-+ ARG. */
-+static void
-+cygpath_log_msg_arg (const char *message, const char *arg)
-+{
-+ if (!cygpath_log)
-+ return;
-+ fprintf (cygpath_log, "[%d] cygpath: ", _getpid ());
-+ fprintf (cygpath_log, message, arg);
-+ fprintf (cygpath_log, "\n");
-+ fflush (cygpath_log);
-+}
-+
-+/* Record MESSAGE in the CYGPATH_LOG. */
-+static void
-+cygpath_log_msg (const char *message)
-+{
-+ cygpath_log_msg_arg ("%s", message);
-+}
-+
-+/* An error has occured. Add the MESSAGE to the CYGPATH_LOG, noting
-+ the cause of the error based on errno. */
-+static void
-+cygpath_perror (const char *message)
-+{
-+ if (!cygpath_log)
-+ return;
-+ fprintf (cygpath_log, "[%d] cygpath: error: %s: %s\n",
-+ _getpid(), message, strerror (errno));
-+ fflush (cygpath_log);
-+}
-+
-+/* Closes CYGPATH_PEX and frees all associated
-+ resoures. */
-+static void
-+cygpath_close (void)
-+{
-+ /* Free resources. */
-+ if (cygpath_out)
-+ {
-+ fclose (cygpath_out);
-+ cygpath_out = NULL;
-+ }
-+ if (cygpath_in)
-+ {
-+ fclose (cygpath_in);
-+ cygpath_in = NULL;
-+ }
-+ if (cygpath_pex)
-+ {
-+ pex_free (cygpath_pex);
-+ cygpath_pex = NULL;
-+ }
-+ if (cygpath_log)
-+ {
-+ cygpath_log_msg ("end");
-+ cygpath_log = NULL;
-+ }
-+}
-+
-+/* CYG_PATH is a pointer to a Cygwin path. This function converts the
-+ Cygwin path to a Windows path, storing the result in
-+ WIN32_PATH. Returns true if the conversion was successful; false
-+ otherwise. */
-+int
-+cygpath (const char *cyg_path, char win32_path[MAX_PATH + 1])
-+{
-+ bool ok;
-+ bool retrying;
-+
-+ /* Special-case the empty path. cygpath cannot handle the empty
-+ path correctly. It ignores the empty line, waiting for a
-+ non-empty line, which in turn causes an application using this
-+ function to appear stuck. */
-+ if (cyg_path[0] == '\0')
-+ {
-+ win32_path[0] = '\0';
-+ return true;
-+ }
-+
-+ retrying = false;
-+
-+ retry:
-+ if (!cygpath_initialized)
-+ {
-+ const char *argv[] = { "cygpath", "-w", "-f", "-", NULL };
-+ const char *cygpath_path;
-+ const char *log;
-+ int err;
-+
-+ /* If we are unable to invoke cygpath, we do not want to try
-+ again. So, we set the initialized flag at this point; if
-+ errors occur during the invocation, it will remain set. */
-+ cygpath_initialized = 1;
-+ /* Check to see if the user wants cygpath support. */
-+ cygpath_path = getenv ("CYGPATH");
-+ if (!cygpath_path)
-+ /* The user doesn't need to support Cygwin paths. */
-+ goto error;
-+ /* If debugging, open the log file. */
-+ log = getenv ("CSL_DEBUG_CYGPATH");
-+ if (log && log[0])
-+ {
-+ /* The log file is opened for "append" so that multiple
-+ processes (perhaps invoked from "make") can share it. */
-+ cygpath_log = fopen (log, "a");
-+ if (cygpath_log)
-+ cygpath_log_msg ("begin");
-+ }
-+ /* If the environment variable is set to a non-empty string, use
-+ that string as the path to cygpath. */
-+ if (cygpath_path[0] != '\0')
-+ argv[0] = cygpath_path;
-+ /* Create the pex object. */
-+ cygpath_pex = pex_init (PEX_SEARCH | PEX_USE_PIPES,
-+ "cygpath", NULL);
-+ if (!cygpath_pex)
-+ goto error;
-+ /* Get the FILE we will use to write to the child. */
-+ cygpath_in = pex_input_pipe (cygpath_pex, /*binary=*/0);
-+ if (!cygpath_in)
-+ goto error;
-+ /* Start the child process. */
-+ if (pex_run (cygpath_pex, PEX_SEARCH | PEX_USE_PIPES,
-+ argv[0], (char**) argv,
-+ NULL, NULL,
-+ &err) != NULL)
-+ goto error;
-+ /* Get the FILE we will use to read from the child. */
-+ cygpath_out = pex_read_output (cygpath_pex, /*binary=*/1);
-+ if (!cygpath_out)
-+ goto error;
-+ }
-+ else if (!cygpath_pex)
-+ /* We previously tried to use cygpath, but something went wrong. */
-+ return false;
-+
-+ /* Write CYG_PATH to the child, on a line by itself. */
-+ cygpath_log_msg_arg ("-> %s", cyg_path);
-+ if (fprintf (cygpath_in, "%s\n", cyg_path) < 0)
-+ {
-+ cygpath_perror ("write failed");
-+ goto error;
-+ }
-+ /* Flush the output. (We cannot set the stream into line-buffered
-+ mode with setvbuf because Windows treats _IOLBF as a synonym for
-+ _IOFBF.) */
-+ if (fflush (cygpath_in))
-+ cygpath_perror ("flush failed");
-+ /* Read the output. */
-+ ok = true;
-+ while (1)
-+ {
-+ size_t pathlen;
-+ if (!fgets (win32_path, MAX_PATH, cygpath_out))
-+ {
-+ if (ferror (cygpath_out))
-+ cygpath_perror ("read failed");
-+ else
-+ {
-+ cygpath_log_msg ("error: EOF");
-+ /* Unfortunately, cygpath sometimes crashes for no
-+ apparent reason. We give it two chances... */
-+ if (!retrying)
-+ {
-+ retrying = true;
-+ cygpath_log_msg ("retrying");
-+ cygpath_close ();
-+ cygpath_initialized = 0;
-+ goto retry;
-+ }
-+ }
-+ goto error;
-+ }
-+ pathlen = strlen (win32_path);
-+ if (pathlen == 0 && ok)
-+ /* This isn't a well-formed response from cygpath. */
-+ goto error;
-+ if (win32_path[pathlen - 1] == '\n')
-+ {
-+ win32_path[pathlen - 1] = '\0';
-+ cygpath_log_msg_arg ("<- %s", win32_path);
-+ break;
-+ }
-+ /* We didn't reach the end of the line. There's no point in
-+ trying to use this output, since we know the length of
-+ paths are limited to MAX_PATH characters, but we read the
-+ entire line so that we are still in sync with
-+ cygpath. */
-+ ok = false;
-+ if (cygpath_log)
-+ cygpath_log_msg_arg ("error: invalid response: %s",
-+ win32_path);
-+ }
-+
-+ return ok;
-+
-+ error:
-+ cygpath_close();
-+ return false;
-+}
-+
-+/* Returns the handle for the MVCRT DLL, or NULL if it is not
-+ available. */
-+static HMODULE
-+msvcrt_dll (void)
-+{
-+ static HMODULE dll = (HMODULE)(-1);
-+
-+ /* After we call LoadLibrary, DLL will be either a valid handle or
-+ NULL, so this check ensures that we only try to load the library
-+ once. */
-+ if (dll == (HMODULE)(-1))
-+ dll = LoadLibrary ("msvcrt.dll");
-+
-+ return dll;
-+}
-+
-+/* Call the underlying MSVCRT fopen with PATH and MODE, and return
-+ what it returns. */
-+static FILE *
-+msvcrt_fopen (const char *path, const char *mode)
-+{
-+ typedef FILE *(fopen_type)(const char *path,
-+ const char *mode);
-+
-+ static fopen_type *f = NULL;
-+
-+ /* Get the address of "fopen". */
-+ if (!f)
-+ {
-+ HMODULE dll = msvcrt_dll ();
-+ if (!dll)
-+ {
-+ errno = ENOSYS;
-+ return NULL;
-+ }
-+ f = (fopen_type *) GetProcAddress (dll, "fopen");
-+ if (!f)
-+ {
-+ errno = ENOSYS;
-+ return NULL;
-+ }
-+ }
-+
-+ /* Call fopen. */
-+ return (*f)(path, mode);
-+}
-+
-+FILE *
-+fopen (const char *path, const char *mode)
-+{
-+ FILE *f;
-+ char win32_path[MAX_PATH + 1];
-+
-+ /* Assume PATH is a Windows path. */
-+ f = msvcrt_fopen (path, mode);
-+ if (f || errno != ENOENT)
-+ return f;
-+ /* Perhaps it is a Cygwin path? */
-+ if (cygpath (path, win32_path))
-+ f = msvcrt_fopen (win32_path, mode);
-+ return f;
-+}
-+
-+int
-+open (const char *path, int oflag, ...)
-+{
-+ int fd;
-+ char win32_path[MAX_PATH + 1];
-+ int pmode = 0;
-+
-+ if ((oflag & _O_CREAT))
-+ {
-+ va_list ap;
-+ va_start (ap, oflag);
-+ pmode = va_arg (ap, int);
-+ va_end (ap);
-+ }
-+
-+ /* Assume PATH is a Windows path. */
-+ fd = _open (path, oflag, pmode);
-+ if (fd != -1 || errno != ENOENT)
-+ return fd;
-+ /* Perhaps it is a Cygwin path? */
-+ if (cygpath (path, win32_path))
-+ fd = _open (win32_path, oflag, pmode);
-+ return fd;
-+}
-+
-+int
-+stat (const char *path, struct stat *buffer)
-+{
-+ int r;
-+ char win32_path[MAX_PATH + 1];
-+
-+ /* Assume PATH is a Windows path. */
-+ r = _stat (path, (struct _stat *) buffer);
-+ if (r != -1 || errno != ENOENT)
-+ return r;
-+ /* Perhaps it is a Cygwin path? */
-+ if (cygpath (path, win32_path))
-+ r = _stat (win32_path, (struct _stat *) buffer);
-+ return r;
-+}
-+
-+int
-+access (const char *path, int mode)
-+{
-+ int r;
-+ char win32_path[MAX_PATH + 1];
-+
-+#ifdef _WIN32
-+ /* Some GNU tools mistakenly defined X_OK to 1 on Windows. */
-+ mode = mode & ~1;
-+#endif
-+ /* Assume PATH is a Windows path. */
-+ r = _access (path, mode);
-+ if (r != -1 || errno != ENOENT)
-+ return r;
-+ /* Perhaps it is a Cygwin path? */
-+ if (cygpath (path, win32_path))
-+ r = _access (win32_path, mode);
-+ return r;
-+}
-+
-+/* Given the WINDOWS_CODE (typically the result of GetLastError), set
-+ ERRNO to the corresponding error code. If there is no obvious
-+ correspondence, ERRNO will be set to EACCES. */
-+static void
-+set_errno_from_windows_code (DWORD windows_code)
-+{
-+ int mapping[][2] = {
-+ {ERROR_ACCESS_DENIED, EACCES},
-+ {ERROR_ACCOUNT_DISABLED, EACCES},
-+ {ERROR_ACCOUNT_RESTRICTION, EACCES},
-+ {ERROR_ALREADY_ASSIGNED, EBUSY},
-+ {ERROR_ALREADY_EXISTS, EEXIST},
-+ {ERROR_ARITHMETIC_OVERFLOW, ERANGE},
-+ {ERROR_BAD_COMMAND, EIO},
-+ {ERROR_BAD_DEVICE, ENODEV},
-+ {ERROR_BAD_DRIVER_LEVEL, ENXIO},
-+ {ERROR_BAD_EXE_FORMAT, ENOEXEC},
-+ {ERROR_BAD_FORMAT, ENOEXEC},
-+ {ERROR_BAD_LENGTH, EINVAL},
-+ {ERROR_BAD_PATHNAME, ENOENT},
-+ {ERROR_BAD_PIPE, EPIPE},
-+ {ERROR_BAD_UNIT, ENODEV},
-+ {ERROR_BAD_USERNAME, EINVAL},
-+ {ERROR_BROKEN_PIPE, EPIPE},
-+ {ERROR_BUFFER_OVERFLOW, ENOMEM},
-+ {ERROR_BUSY, EBUSY},
-+ {ERROR_BUSY_DRIVE, EBUSY},
-+ {ERROR_CALL_NOT_IMPLEMENTED, ENOSYS},
-+ {ERROR_CRC, EIO},
-+ {ERROR_CURRENT_DIRECTORY, EINVAL},
-+ {ERROR_DEVICE_IN_USE, EBUSY},
-+ {ERROR_DIR_NOT_EMPTY, EEXIST},
-+ {ERROR_DIRECTORY, ENOENT},
-+ {ERROR_DISK_CHANGE, EIO},
-+ {ERROR_DISK_FULL, ENOSPC},
-+ {ERROR_DRIVE_LOCKED, EBUSY},
-+ {ERROR_ENVVAR_NOT_FOUND, EINVAL},
-+ {ERROR_EXE_MARKED_INVALID, ENOEXEC},
-+ {ERROR_FILE_EXISTS, EEXIST},
-+ {ERROR_FILE_INVALID, ENODEV},
-+ {ERROR_FILE_NOT_FOUND, ENOENT},
-+ {ERROR_FILENAME_EXCED_RANGE, ENAMETOOLONG},
-+ {ERROR_GEN_FAILURE, EIO},
-+ {ERROR_HANDLE_DISK_FULL, ENOSPC},
-+ {ERROR_INSUFFICIENT_BUFFER, ENOMEM},
-+ {ERROR_INVALID_ACCESS, EINVAL},
-+ {ERROR_INVALID_ADDRESS, EFAULT},
-+ {ERROR_INVALID_BLOCK, EFAULT},
-+ {ERROR_INVALID_DATA, EINVAL},
-+ {ERROR_INVALID_DRIVE, ENODEV},
-+ {ERROR_INVALID_EXE_SIGNATURE, ENOEXEC},
-+ {ERROR_INVALID_FLAGS, EINVAL},
-+ {ERROR_INVALID_FUNCTION, ENOSYS},
-+ {ERROR_INVALID_HANDLE, EBADF},
-+ {ERROR_INVALID_LOGON_HOURS, EACCES},
-+ {ERROR_INVALID_NAME, ENOENT},
-+ {ERROR_INVALID_OWNER, EINVAL},
-+ {ERROR_INVALID_PARAMETER, EINVAL},
-+ {ERROR_INVALID_PASSWORD, EPERM},
-+ {ERROR_INVALID_PRIMARY_GROUP, EINVAL},
-+ {ERROR_INVALID_SIGNAL_NUMBER, EINVAL},
-+ {ERROR_INVALID_TARGET_HANDLE, EIO},
-+ {ERROR_INVALID_WORKSTATION, EACCES},
-+ {ERROR_IO_DEVICE, EIO},
-+ {ERROR_IO_INCOMPLETE, EINTR},
-+ {ERROR_LOCKED, EBUSY},
-+ {ERROR_LOGON_FAILURE, EACCES},
-+ {ERROR_MAPPED_ALIGNMENT, EINVAL},
-+ {ERROR_META_EXPANSION_TOO_LONG, E2BIG},
-+ {ERROR_MORE_DATA, EPIPE},
-+ {ERROR_NEGATIVE_SEEK, ESPIPE},
-+ {ERROR_NO_DATA, EPIPE},
-+ {ERROR_NO_MORE_SEARCH_HANDLES, EIO},
-+ {ERROR_NO_PROC_SLOTS, EAGAIN},
-+ {ERROR_NO_SUCH_PRIVILEGE, EACCES},
-+ {ERROR_NOACCESS, EFAULT},
-+ {ERROR_NONE_MAPPED, EINVAL},
-+ {ERROR_NOT_ENOUGH_MEMORY, ENOMEM},
-+ {ERROR_NOT_READY, ENODEV},
-+ {ERROR_NOT_SAME_DEVICE, EXDEV},
-+ {ERROR_OPEN_FAILED, EIO},
-+ {ERROR_OPERATION_ABORTED, EINTR},
-+ {ERROR_OUTOFMEMORY, ENOMEM},
-+ {ERROR_PASSWORD_EXPIRED, EACCES},
-+ {ERROR_PATH_BUSY, EBUSY},
-+ {ERROR_PATH_NOT_FOUND, ENOTDIR},
-+ {ERROR_PIPE_BUSY, EBUSY},
-+ {ERROR_PIPE_CONNECTED, EPIPE},
-+ {ERROR_PIPE_LISTENING, EPIPE},
-+ {ERROR_PIPE_NOT_CONNECTED, EPIPE},
-+ {ERROR_PRIVILEGE_NOT_HELD, EACCES},
-+ {ERROR_READ_FAULT, EIO},
-+ {ERROR_SEEK, ESPIPE},
-+ {ERROR_SEEK_ON_DEVICE, ESPIPE},
-+ {ERROR_SHARING_BUFFER_EXCEEDED, ENFILE},
-+ {ERROR_STACK_OVERFLOW, ENOMEM},
-+ {ERROR_SWAPERROR, ENOENT},
-+ {ERROR_TOO_MANY_MODULES, EMFILE},
-+ {ERROR_TOO_MANY_OPEN_FILES, EMFILE},
-+ {ERROR_UNRECOGNIZED_MEDIA, ENXIO},
-+ {ERROR_UNRECOGNIZED_VOLUME, ENODEV},
-+ {ERROR_WAIT_NO_CHILDREN, ECHILD},
-+ {ERROR_WRITE_FAULT, EIO},
-+ {ERROR_WRITE_PROTECT, EROFS}
-+/* MinGW does not define ETXTBSY as yet.
-+ {ERROR_LOCK_VIOLATION, ETXTBSY},
-+ {ERROR_SHARING_VIOLATION, ETXTBSY},
-+*/
-+ };
-+
-+ size_t i;
-+
-+ for (i = 0; i < sizeof (mapping)/sizeof (mapping[0]); ++i)
-+ if (mapping[i][0] == windows_code)
-+ {
-+ errno = mapping[i][1];
-+ return;
-+ }
-+
-+ /* Unrecognized error. Use EACCESS to have some error code,
-+ not misleading "No error" thing. */
-+ errno = EACCES;
-+}
-+
-+int rename (const char *oldpath, const char *newpath)
-+{
-+ BOOL r;
-+ int oldpath_converted = 0;
-+ char win32_oldpath[MAX_PATH + 1];
-+ char win32_newpath[MAX_PATH + 1];
-+
-+ /* Older versions of the cygpath program called FindFirstFile, but
-+ not FindClose. As a result, a long-running cygpath program ends
-+ up leaking these handles, and, as a result, the Windows kernel
-+ will not let us remove or rename things in directories. Therefore,
-+ we kill the child cygpath program now.
-+
-+ The defect in cygpath was corrected by this patch:
-+
-+ http://cygwin.com/ml/cygwin-patches/2007-q1/msg00033.html
-+
-+ but older versions of cygpath will be in use for the forseeable
-+ future. */
-+
-+ cygpath_close ();
-+ cygpath_initialized = 0;
-+
-+ /* Assume all paths are Windows paths. */
-+ r = MoveFileEx (oldpath, newpath, MOVEFILE_REPLACE_EXISTING);
-+ if (r)
-+ return 0;
-+ else if (GetLastError () != ERROR_PATH_NOT_FOUND)
-+ goto error;
-+
-+ /* Perhaps the old path is a cygwin path? */
-+ if (cygpath (oldpath, win32_oldpath))
-+ {
-+ oldpath_converted = 1;
-+ r = MoveFileEx (win32_oldpath, newpath, MOVEFILE_REPLACE_EXISTING);
-+ if (r)
-+ return 0;
-+ else if (GetLastError () != ERROR_PATH_NOT_FOUND)
-+ goto error;
-+ }
-+
-+ /* Perhaps the new path is a cygwin path? */
-+ if (cygpath (newpath, win32_newpath))
-+ {
-+ r = MoveFileEx (oldpath_converted ? win32_oldpath : oldpath,
-+ win32_newpath, MOVEFILE_REPLACE_EXISTING);
-+ if (r == TRUE)
-+ return 0;
-+ }
-+error:
-+ set_errno_from_windows_code (GetLastError ());
-+ return -1;
-+}
-+
-+int remove (const char *pathname)
-+{
-+ int r;
-+ char win32_path[MAX_PATH + 1];
-+
-+ cygpath_close ();
-+ cygpath_initialized = 0;
-+
-+ /* Assume PATH is a Windows path. */
-+ r = _unlink (pathname);
-+ if (r != -1 || errno != ENOENT)
-+ return r;
-+ /* Perhaps it is a Cygwin path? */
-+ if (cygpath (pathname, win32_path))
-+ r = _unlink (win32_path);
-+ return r;
-+}
-+
-+int unlink(const char *pathname)
-+{
-+ return remove (pathname);
-+}
-+
-+int
-+chdir (const char *path)
-+{
-+ int ret;
-+ char win32_path[MAX_PATH + 1];
-+
-+ /* Assume PATH is a Windows path. */
-+ ret = _chdir (path);
-+ if (ret != -1 || errno != ENOENT)
-+ return ret;
-+ /* Perhaps it is a Cygwin path? */
-+ if (cygpath (path, win32_path))
-+ ret = _chdir (win32_path);
-+ return ret;
-+}
---- a/libiberty/lrealpath.c
-+++ b/libiberty/lrealpath.c
-@@ -138,6 +138,17 @@ lrealpath (const char *filename)
- {
- char buf[MAX_PATH];
- char* basename;
-+
-+ if (_access (filename, F_OK) != 0)
-+ {
-+ char cygbuf[MAX_PATH + 1];
-+ /* The file does not exist. It's fine to call lrealpath
-+ on a non-existing path... but if this would be an existing
-+ path after cygpath conversion, use that instead. */
-+ if (cygpath (filename, cygbuf) && _access (cygbuf, F_OK) == 0)
-+ filename = cygbuf;
-+ }
-+
- DWORD len = GetFullPathName (filename, MAX_PATH, buf, &basename);
- if (len == 0 || len > MAX_PATH - 1)
- return strdup (filename);
---- a/libiberty/pex-win32.c
-+++ b/libiberty/pex-win32.c
-@@ -119,7 +119,7 @@ static int
- pex_win32_open_read (struct pex_obj *obj ATTRIBUTE_UNUSED, const char *name,
- int binary)
- {
-- return _open (name, _O_RDONLY | (binary ? _O_BINARY : _O_TEXT));
-+ return open (name, _O_RDONLY | (binary ? _O_BINARY : _O_TEXT));
- }
-
- /* Open a file for writing. */
-@@ -130,10 +130,10 @@ pex_win32_open_write (struct pex_obj *ob
- {
- /* Note that we can't use O_EXCL here because gcc may have already
- created the temporary file via make_temp_file. */
-- return _open (name,
-- (_O_WRONLY | _O_CREAT | _O_TRUNC
-- | (binary ? _O_BINARY : _O_TEXT)),
-- _S_IREAD | _S_IWRITE);
-+ return open (name,
-+ (_O_WRONLY | _O_CREAT | _O_TRUNC
-+ | (binary ? _O_BINARY : _O_TEXT)),
-+ _S_IREAD | _S_IWRITE);
- }
-
- /* Close a file. */
-@@ -746,6 +746,28 @@ pex_win32_exec_child (struct pex_obj *ob
- OSVERSIONINFO version_info;
- STARTUPINFO si;
- PROCESS_INFORMATION pi;
-+ int orig_out, orig_in, orig_err;
-+ BOOL separate_stderr = !(flags & PEX_STDERR_TO_STDOUT);
-+
-+ /* Ensure we have inheritable descriptors to pass to the child, and close the
-+ original descriptors. */
-+ orig_in = in;
-+ in = _dup (orig_in);
-+ if (orig_in != STDIN_FILENO)
-+ _close (orig_in);
-+
-+ orig_out = out;
-+ out = _dup (orig_out);
-+ if (orig_out != STDOUT_FILENO)
-+ _close (orig_out);
-+
-+ if (separate_stderr)
-+ {
-+ orig_err = errdes;
-+ errdes = _dup (orig_err);
-+ if (orig_err != STDERR_FILENO)
-+ _close (orig_err);
-+ }
-
- stdin_handle = INVALID_HANDLE_VALUE;
- stdout_handle = INVALID_HANDLE_VALUE;
-@@ -753,7 +775,7 @@ pex_win32_exec_child (struct pex_obj *ob
-
- stdin_handle = (HANDLE) _get_osfhandle (in);
- stdout_handle = (HANDLE) _get_osfhandle (out);
-- if (!(flags & PEX_STDERR_TO_STDOUT))
-+ if (separate_stderr)
- stderr_handle = (HANDLE) _get_osfhandle (errdes);
- else
- stderr_handle = stdout_handle;
-@@ -822,12 +844,13 @@ pex_win32_exec_child (struct pex_obj *ob
- *errmsg = "CreateProcess";
- }
-
-- /* Close the standard output and standard error handles in the
-- parent. */
-- if (out != STDOUT_FILENO)
-- obj->funcs->close (obj, out);
-- if (errdes != STDERR_FILENO)
-- obj->funcs->close (obj, errdes);
-+ /* Close the standard input, standard output and standard error handles
-+ in the parent. */
-+
-+ _close (in);
-+ _close (out);
-+ if (separate_stderr)
-+ _close (errdes);
-
- return pid;
- }
-@@ -883,7 +906,7 @@ static int
- pex_win32_pipe (struct pex_obj *obj ATTRIBUTE_UNUSED, int *p,
- int binary)
- {
-- return _pipe (p, 256, binary ? _O_BINARY : _O_TEXT);
-+ return _pipe (p, 256, (binary ? _O_BINARY : _O_TEXT) | _O_NOINHERIT);
- }
-
- /* Get a FILE pointer to read from a file descriptor. */
---- a/libiberty/testsuite/test-expandargv.c
-+++ b/libiberty/testsuite/test-expandargv.c
-@@ -107,6 +107,38 @@ const char *test_data[] = {
- ARGV0,
- 0,
-
-+ /* Test 4 - Check for options beginning with an empty line. */
-+ "\na\nb", /* Test 4 data */
-+ ARGV0,
-+ "@test-expandargv-4.lst",
-+ 0,
-+ ARGV0,
-+ "a",
-+ "b",
-+ 0,
-+
-+ /* Test 5 - Check for options containing an empty argument. */
-+ "a\n''\nb", /* Test 5 data */
-+ ARGV0,
-+ "@test-expandargv-5.lst",
-+ 0,
-+ ARGV0,
-+ "a",
-+ "",
-+ "b",
-+ 0,
-+
-+ /* Test 6 - Check for options containing a quoted newline. */
-+ "a\n'a\n\nb'\nb", /* Test 6 data */
-+ ARGV0,
-+ "@test-expandargv-6.lst",
-+ 0,
-+ ARGV0,
-+ "a",
-+ "a\n\nb",
-+ "b",
-+ 0,
-+
- 0 /* Test done marker, don't remove. */
- };
-
-@@ -246,7 +278,7 @@ run_tests (const char **test_data)
- /* Compare each of the argv's ... */
- else
- for (k = 0; k < argc_after; k++)
-- if (strncmp (argv_before[k], argv_after[k], strlen(argv_after[k])) != 0)
-+ if (strcmp (argv_before[k], argv_after[k]) != 0)
- {
- printf ("FAIL: test-expandargv-%d. Arguments don't match.\n", i);
- failed++;
---- a/libjava/Makefile.am
-+++ b/libjava/Makefile.am
-@@ -55,9 +55,14 @@ endif
-
- dbexec_LTLIBRARIES = libjvm.la
-
--pkgconfigdir = $(libdir)/pkgconfig
-+# Install the pkgconfig file in a target-specific directory, since the
-+# libraries it indicates
-
--jardir = $(datadir)/java
-+pkgconfigdir = $(toolexeclibdir)/pkgconfig
-+
-+# We install the JAR in a target-specific directory so that toolchains
-+# build from different sources can be installed in the same directory.
-+jardir = $(prefix)/$(target_noncanonical)/share/java
- jar_DATA = libgcj-$(gcc_version).jar libgcj-tools-$(gcc_version).jar
- if INSTALL_ECJ_JAR
- jar_DATA += $(ECJ_BUILD_JAR)
---- a/libjava/Makefile.in
-+++ b/libjava/Makefile.in
-@@ -915,8 +915,14 @@ toolexeclib_LTLIBRARIES = libgcj.la libg
- $(am__append_2) $(am__append_3)
- toolexecmainlib_DATA = libgcj.spec
- dbexec_LTLIBRARIES = libjvm.la
--pkgconfigdir = $(libdir)/pkgconfig
--jardir = $(datadir)/java
-+
-+# Install the pkgconfig file in a target-specific directory, since the
-+# libraries it indicates
-+pkgconfigdir = $(toolexeclibdir)/pkgconfig
-+
-+# We install the JAR in a target-specific directory so that toolchains
-+# build from different sources can be installed in the same directory.
-+jardir = $(prefix)/$(target_noncanonical)/share/java
- jar_DATA = libgcj-$(gcc_version).jar libgcj-tools-$(gcc_version).jar \
- $(am__append_4)
- @JAVA_HOME_SET_FALSE@JAVA_HOME_DIR = $(prefix)
---- a/libjava/classpath/Makefile.in
-+++ b/libjava/classpath/Makefile.in
-@@ -380,9 +380,12 @@ sysconfdir = @sysconfdir@
- target = @target@
- target_alias = @target_alias@
- target_cpu = @target_cpu@
-+target_noncanonical = @target_noncanonical@
- target_os = @target_os@
- target_vendor = @target_vendor@
-+toolexecdir = @toolexecdir@
- toolexeclibdir = @toolexeclibdir@
-+toolexecmainlibdir = @toolexecmainlibdir@
- uudecode = @uudecode@
- vm_classes = @vm_classes@
-
---- a/libjava/classpath/configure
-+++ b/libjava/classpath/configure
-@@ -461,7 +461,7 @@ ac_includes_default="\
- # include <unistd.h>
- #endif"
-
--ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os JAVA_MAINTAINER_MODE_TRUE JAVA_MAINTAINER_MODE_FALSE GENINSRC_TRUE GENINSRC_FALSE multi_basedir INSTALL_BINARIES_TRUE INSTALL_BINARIES_FALSE LIBVERSION CLASSPATH_MODULE CLASSPATH_CONVENIENCE INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar CREATE_COLLECTIONS_TRUE CREATE_COLLECTIONS_FALSE CREATE_JNI_LIBRARIES_TRUE CREATE_JNI_LIBRARIES_FALSE CREATE_CORE_JNI_LIBRARIES_TRUE CREATE_CORE_JNI_LIBRARIES_FALSE CREATE_GCONF_PEER_LIBRARIES_TRUE CREATE_GCONF_PEER_LIBRARIES_FALSE CREATE_GSTREAMER_PEER_LIBRARIES_TRUE CREATE_GSTREAMER_PEER_LIBRARIES_FALSE default_toolkit CREATE_XMLJ_LIBRARY_TRUE CREATE_XMLJ_LIBRARY_FALSE CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CPP EGREP CREATE_ALSA_LIBRARIES_TRUE CREATE_ALSA_LIBRARIES_FALSE CREATE_DSSI_LIBRARIES_TRUE CREATE_DSSI_LIBRARIES_FALSE CREATE_GTK_PEER_LIBRARIES_TRUE CREATE_GTK_PEER_LIBRARIES_FALSE CREATE_QT_PEER_LIBRARIES_TRUE CREATE_QT_PEER_LIBRARIES_FALSE CREATE_PLUGIN_TRUE CREATE_PLUGIN_FALSE CREATE_GJDOC_TRUE CREATE_GJDOC_FALSE toolexeclibdir nativeexeclibdir glibjdir CREATE_JNI_HEADERS_TRUE CREATE_JNI_HEADERS_FALSE CREATE_GJDOC_PARSER_TRUE CREATE_GJDOC_PARSER_FALSE CREATE_WRAPPERS_TRUE CREATE_WRAPPERS_FALSE LN_S LIBTOOL SED FGREP GREP LD DUMPBIN ac_ct_DUMPBIN NM OBJDUMP ac_ct_OBJDUMP AR ac_ct_AR RANLIB ac_ct_RANLIB lt_ECHO DSYMUTIL ac_ct_DSYMUTIL NMEDIT ac_ct_NMEDIT LIPO ac_ct_LIPO OTOOL ac_ct_OTOOL OTOOL64 ac_ct_OTOOL64 CXX CXXFLAGS ac_ct_CXX CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE CXXCPP PERL COLLECTIONS_PREFIX LIBMAGIC LIBICONV LTLIBICONV WARNING_CFLAGS EXTRA_CFLAGS STRICT_WARNING_CFLAGS ERROR_CFLAGS PKG_CONFIG XML_CFLAGS XML_LIBS XSLT_CFLAGS XSLT_LIBS X_CFLAGS X_PRE_LIBS X_LIBS X_EXTRA_LIBS GTK_CFLAGS GTK_LIBS FREETYPE2_CFLAGS FREETYPE2_LIBS PANGOFT2_CFLAGS PANGOFT2_LIBS CAIRO_CFLAGS CAIRO_LIBS XTEST_LIBS GCONF_CFLAGS GCONF_LIBS GDK_CFLAGS GDK_LIBS GSTREAMER_CFLAGS GSTREAMER_LIBS GSTREAMER_BASE_CFLAGS GSTREAMER_BASE_LIBS GSTREAMER_PLUGINS_BASE_CFLAGS GSTREAMER_PLUGINS_BASE_LIBS GST_PLUGIN_LDFLAGS GSTREAMER_FILE_READER GSTREAMER_MIXER_PROVIDER QT_CFLAGS QT_LIBS MOC MOZILLA_CFLAGS MOZILLA_LIBS GLIB_CFLAGS GLIB_LIBS PLUGIN_DIR GMP_CFLAGS GMP_LIBS USER_JAVAH CLASSPATH_INCLUDES vm_classes MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT LIBDEBUG INIT_LOAD_LIBRARY ECJ_JAR JAVA_LANG_SYSTEM_EXPLICIT_INITIALIZATION REMOVE MKDIR CP DATE FIND ZIP JAR WITH_JAR_TRUE WITH_JAR_FALSE INSTALL_GLIBJ_ZIP_TRUE INSTALL_GLIBJ_ZIP_FALSE INSTALL_CLASS_FILES_TRUE INSTALL_CLASS_FILES_FALSE BUILD_CLASS_FILES_TRUE BUILD_CLASS_FILES_FALSE EXAMPLESDIR TOOLSDIR GJDOC CREATE_API_DOCS_TRUE CREATE_API_DOCS_FALSE JAY JAY_SKELETON REGEN_PARSERS_TRUE REGEN_PARSERS_FALSE USE_PREBUILT_GLIBJ_ZIP_TRUE USE_PREBUILT_GLIBJ_ZIP_FALSE PATH_TO_GLIBJ_ZIP JAVA uudecode JAVAC JAVAC_IS_GCJ GCJ_JAVAC_TRUE GCJ_JAVAC_FALSE ANTLR_JAR ANTLR ac_ct_ANTLR JAVAC_MEM_OPT USE_ESCHER_TRUE USE_ESCHER_FALSE PATH_TO_ESCHER ENABLE_LOCAL_SOCKETS_TRUE ENABLE_LOCAL_SOCKETS_FALSE DEFAULT_PREFS_PEER WANT_NATIVE_BIG_INTEGER CREATE_GMPBI_LIBRARY_TRUE CREATE_GMPBI_LIBRARY_FALSE LIBOBJS LTLIBOBJS'
-+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os JAVA_MAINTAINER_MODE_TRUE JAVA_MAINTAINER_MODE_FALSE GENINSRC_TRUE GENINSRC_FALSE multi_basedir INSTALL_BINARIES_TRUE INSTALL_BINARIES_FALSE LIBVERSION CLASSPATH_MODULE CLASSPATH_CONVENIENCE INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar CREATE_COLLECTIONS_TRUE CREATE_COLLECTIONS_FALSE CREATE_JNI_LIBRARIES_TRUE CREATE_JNI_LIBRARIES_FALSE CREATE_CORE_JNI_LIBRARIES_TRUE CREATE_CORE_JNI_LIBRARIES_FALSE CREATE_GCONF_PEER_LIBRARIES_TRUE CREATE_GCONF_PEER_LIBRARIES_FALSE CREATE_GSTREAMER_PEER_LIBRARIES_TRUE CREATE_GSTREAMER_PEER_LIBRARIES_FALSE default_toolkit CREATE_XMLJ_LIBRARY_TRUE CREATE_XMLJ_LIBRARY_FALSE CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CPP EGREP CREATE_ALSA_LIBRARIES_TRUE CREATE_ALSA_LIBRARIES_FALSE CREATE_DSSI_LIBRARIES_TRUE CREATE_DSSI_LIBRARIES_FALSE CREATE_GTK_PEER_LIBRARIES_TRUE CREATE_GTK_PEER_LIBRARIES_FALSE CREATE_QT_PEER_LIBRARIES_TRUE CREATE_QT_PEER_LIBRARIES_FALSE CREATE_PLUGIN_TRUE CREATE_PLUGIN_FALSE CREATE_GJDOC_TRUE CREATE_GJDOC_FALSE target_noncanonical toolexecdir toolexecmainlibdir toolexeclibdir nativeexeclibdir glibjdir CREATE_JNI_HEADERS_TRUE CREATE_JNI_HEADERS_FALSE CREATE_GJDOC_PARSER_TRUE CREATE_GJDOC_PARSER_FALSE CREATE_WRAPPERS_TRUE CREATE_WRAPPERS_FALSE LN_S LIBTOOL SED FGREP GREP LD DUMPBIN ac_ct_DUMPBIN NM OBJDUMP ac_ct_OBJDUMP AR ac_ct_AR RANLIB ac_ct_RANLIB lt_ECHO DSYMUTIL ac_ct_DSYMUTIL NMEDIT ac_ct_NMEDIT LIPO ac_ct_LIPO OTOOL ac_ct_OTOOL OTOOL64 ac_ct_OTOOL64 CXX CXXFLAGS ac_ct_CXX CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE CXXCPP PERL COLLECTIONS_PREFIX LIBMAGIC LIBICONV LTLIBICONV WARNING_CFLAGS EXTRA_CFLAGS STRICT_WARNING_CFLAGS ERROR_CFLAGS PKG_CONFIG XML_CFLAGS XML_LIBS XSLT_CFLAGS XSLT_LIBS X_CFLAGS X_PRE_LIBS X_LIBS X_EXTRA_LIBS GTK_CFLAGS GTK_LIBS FREETYPE2_CFLAGS FREETYPE2_LIBS PANGOFT2_CFLAGS PANGOFT2_LIBS CAIRO_CFLAGS CAIRO_LIBS XTEST_LIBS GCONF_CFLAGS GCONF_LIBS GDK_CFLAGS GDK_LIBS GSTREAMER_CFLAGS GSTREAMER_LIBS GSTREAMER_BASE_CFLAGS GSTREAMER_BASE_LIBS GSTREAMER_PLUGINS_BASE_CFLAGS GSTREAMER_PLUGINS_BASE_LIBS GST_PLUGIN_LDFLAGS GSTREAMER_FILE_READER GSTREAMER_MIXER_PROVIDER QT_CFLAGS QT_LIBS MOC MOZILLA_CFLAGS MOZILLA_LIBS GLIB_CFLAGS GLIB_LIBS PLUGIN_DIR GMP_CFLAGS GMP_LIBS USER_JAVAH CLASSPATH_INCLUDES vm_classes MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT LIBDEBUG INIT_LOAD_LIBRARY ECJ_JAR JAVA_LANG_SYSTEM_EXPLICIT_INITIALIZATION REMOVE MKDIR CP DATE FIND ZIP JAR WITH_JAR_TRUE WITH_JAR_FALSE INSTALL_GLIBJ_ZIP_TRUE INSTALL_GLIBJ_ZIP_FALSE INSTALL_CLASS_FILES_TRUE INSTALL_CLASS_FILES_FALSE BUILD_CLASS_FILES_TRUE BUILD_CLASS_FILES_FALSE EXAMPLESDIR TOOLSDIR GJDOC CREATE_API_DOCS_TRUE CREATE_API_DOCS_FALSE JAY JAY_SKELETON REGEN_PARSERS_TRUE REGEN_PARSERS_FALSE USE_PREBUILT_GLIBJ_ZIP_TRUE USE_PREBUILT_GLIBJ_ZIP_FALSE PATH_TO_GLIBJ_ZIP JAVA uudecode JAVAC JAVAC_IS_GCJ GCJ_JAVAC_TRUE GCJ_JAVAC_FALSE ANTLR_JAR ANTLR ac_ct_ANTLR JAVAC_MEM_OPT USE_ESCHER_TRUE USE_ESCHER_FALSE PATH_TO_ESCHER ENABLE_LOCAL_SOCKETS_TRUE ENABLE_LOCAL_SOCKETS_FALSE DEFAULT_PREFS_PEER WANT_NATIVE_BIG_INTEGER CREATE_GMPBI_LIBRARY_TRUE CREATE_GMPBI_LIBRARY_FALSE LIBOBJS LTLIBOBJS'
- ac_subst_files=''
- ac_pwd=`pwd`
-
-@@ -1063,6 +1063,9 @@ Optional Features:
- (disabled by --disable-gmp) default=yes
- --disable-gjdoc compile GJDoc (disabled by --disable-gjdoc)
- default=yes
-+ --enable-version-specific-runtime-libs
-+ specify that runtime libraries should be installed
-+ in a compiler-specific directory
- --enable-regen-headers automatically regenerate JNI headers default=yes if
- headers don't exist
- --enable-regen-gjdoc-parser
-@@ -4838,11 +4841,57 @@ else
- fi
-
-
-+# Check whether --enable-version-specific-runtime-libs or --disable-version-specific-runtime-libs was given.
-+if test "${enable_version_specific_runtime_libs+set}" = set; then
-+ enableval="$enable_version_specific_runtime_libs"
-+ case "$enableval" in
-+ yes) version_specific_libs=yes ;;
-+ no) version_specific_libs=no ;;
-+ *) { { echo "$as_me:$LINENO: error: Unknown argument to enable/disable version-specific libs" >&5
-+echo "$as_me: error: Unknown argument to enable/disable version-specific libs" >&2;}
-+ { (exit 1); exit 1; }; };;
-+ esac
-+else
-+ version_specific_libs=no
-+
-+fi;
-+
-+ case ${host_alias} in
-+ "") host_noncanonical=${build_noncanonical} ;;
-+ *) host_noncanonical=${host_alias} ;;
-+ esac
-+ case ${target_alias} in
-+ "") target_noncanonical=${host_noncanonical} ;;
-+ *) target_noncanonical=${target_alias} ;;
-+ esac
-+
-
-- multi_os_directory=`$CC -print-multi-os-directory`
-- case $multi_os_directory in
-- .) toolexeclibdir=${libdir} ;; # Avoid trailing /.
-- *) toolexeclibdir=${libdir}/${multi_os_directory} ;;
-+ case ${version_specific_libs} in
-+ yes)
-+ # Need the gcc compiler version to know where to install libraries
-+ # and header files if --enable-version-specific-runtime-libs option
-+ # is selected.
-+ includedir='$(libdir)/gcc/$(target_noncanonical)/$(gcc_version)/include/'
-+ toolexecdir='$(libdir)/gcc/$(target_noncanonical)'
-+ toolexecmainlibdir='$(toolexecdir)/$(gcc_version)$(MULTISUBDIR)'
-+ toolexeclibdir=$toolexecmainlibdir
-+ ;;
-+ no)
-+ if test -n "$with_cross_host" &&
-+ test x"$with_cross_host" != x"no"; then
-+ # Install a library built with a cross compiler in tooldir, not libdir.
-+ toolexecdir='$(exec_prefix)/$(target_noncanonical)'
-+ toolexecmainlibdir='$(toolexecdir)/lib'
-+ else
-+ toolexecdir='$(libdir)/gcc-lib/$(target_noncanonical)'
-+ toolexecmainlibdir='$(libdir)'
-+ fi
-+ multi_os_directory=`$CC -print-multi-os-directory`
-+ case $multi_os_directory in
-+ .) toolexeclibdir=$toolexecmainlibdir ;; # Avoid trailing /.
-+ *) toolexeclibdir=$toolexecmainlibdir/$multi_os_directory ;;
-+ esac
-+ ;;
- esac
-
-
-@@ -5753,13 +5802,13 @@ if test "${lt_cv_nm_interface+set}" = se
- else
- lt_cv_nm_interface="BSD nm"
- echo "int some_variable = 0;" > conftest.$ac_ext
-- (eval echo "\"\$as_me:5756: $ac_compile\"" >&5)
-+ (eval echo "\"\$as_me:5807: $ac_compile\"" >&5)
- (eval "$ac_compile" 2>conftest.err)
- cat conftest.err >&5
-- (eval echo "\"\$as_me:5759: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
-+ (eval echo "\"\$as_me:5810: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
- (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
- cat conftest.err >&5
-- (eval echo "\"\$as_me:5762: output\"" >&5)
-+ (eval echo "\"\$as_me:5813: output\"" >&5)
- cat conftest.out >&5
- if $GREP 'External.*some_variable' conftest.out > /dev/null; then
- lt_cv_nm_interface="MS dumpbin"
-@@ -6905,7 +6954,7 @@ ia64-*-hpux*)
- ;;
- *-*-irix6*)
- # Find out which ABI we are using.
-- echo '#line 6908 "configure"' > conftest.$ac_ext
-+ echo '#line 6959 "configure"' > conftest.$ac_ext
- if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
-@@ -8191,11 +8240,11 @@ else
- -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
- -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
- -e 's:$: $lt_compiler_flag:'`
-- (eval echo "\"\$as_me:8194: $lt_compile\"" >&5)
-+ (eval echo "\"\$as_me:8245: $lt_compile\"" >&5)
- (eval "$lt_compile" 2>conftest.err)
- ac_status=$?
- cat conftest.err >&5
-- echo "$as_me:8198: \$? = $ac_status" >&5
-+ echo "$as_me:8249: \$? = $ac_status" >&5
- if (exit $ac_status) && test -s "$ac_outfile"; then
- # The compiler can only warn and ignore the option if not recognized
- # So say no if there are warnings other than the usual output.
-@@ -8530,11 +8579,11 @@ else
- -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
- -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
- -e 's:$: $lt_compiler_flag:'`
-- (eval echo "\"\$as_me:8533: $lt_compile\"" >&5)
-+ (eval echo "\"\$as_me:8584: $lt_compile\"" >&5)
- (eval "$lt_compile" 2>conftest.err)
- ac_status=$?
- cat conftest.err >&5
-- echo "$as_me:8537: \$? = $ac_status" >&5
-+ echo "$as_me:8588: \$? = $ac_status" >&5
- if (exit $ac_status) && test -s "$ac_outfile"; then
- # The compiler can only warn and ignore the option if not recognized
- # So say no if there are warnings other than the usual output.
-@@ -8635,11 +8684,11 @@ else
- -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
- -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
- -e 's:$: $lt_compiler_flag:'`
-- (eval echo "\"\$as_me:8638: $lt_compile\"" >&5)
-+ (eval echo "\"\$as_me:8689: $lt_compile\"" >&5)
- (eval "$lt_compile" 2>out/conftest.err)
- ac_status=$?
- cat out/conftest.err >&5
-- echo "$as_me:8642: \$? = $ac_status" >&5
-+ echo "$as_me:8693: \$? = $ac_status" >&5
- if (exit $ac_status) && test -s out/conftest2.$ac_objext
- then
- # The compiler can only warn and ignore the option if not recognized
-@@ -8690,11 +8739,11 @@ else
- -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
- -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
- -e 's:$: $lt_compiler_flag:'`
-- (eval echo "\"\$as_me:8693: $lt_compile\"" >&5)
-+ (eval echo "\"\$as_me:8744: $lt_compile\"" >&5)
- (eval "$lt_compile" 2>out/conftest.err)
- ac_status=$?
- cat out/conftest.err >&5
-- echo "$as_me:8697: \$? = $ac_status" >&5
-+ echo "$as_me:8748: \$? = $ac_status" >&5
- if (exit $ac_status) && test -s out/conftest2.$ac_objext
- then
- # The compiler can only warn and ignore the option if not recognized
-@@ -11557,7 +11606,7 @@ else
- lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
- lt_status=$lt_dlunknown
- cat > conftest.$ac_ext <<_LT_EOF
--#line 11560 "configure"
-+#line 11611 "configure"
- #include "confdefs.h"
-
- #if HAVE_DLFCN_H
-@@ -11653,7 +11702,7 @@ else
- lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
- lt_status=$lt_dlunknown
- cat > conftest.$ac_ext <<_LT_EOF
--#line 11656 "configure"
-+#line 11707 "configure"
- #include "confdefs.h"
-
- #if HAVE_DLFCN_H
-@@ -16084,11 +16133,11 @@ else
- -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
- -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
- -e 's:$: $lt_compiler_flag:'`
-- (eval echo "\"\$as_me:16087: $lt_compile\"" >&5)
-+ (eval echo "\"\$as_me:16138: $lt_compile\"" >&5)
- (eval "$lt_compile" 2>conftest.err)
- ac_status=$?
- cat conftest.err >&5
-- echo "$as_me:16091: \$? = $ac_status" >&5
-+ echo "$as_me:16142: \$? = $ac_status" >&5
- if (exit $ac_status) && test -s "$ac_outfile"; then
- # The compiler can only warn and ignore the option if not recognized
- # So say no if there are warnings other than the usual output.
-@@ -16183,11 +16232,11 @@ else
- -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
- -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
- -e 's:$: $lt_compiler_flag:'`
-- (eval echo "\"\$as_me:16186: $lt_compile\"" >&5)
-+ (eval echo "\"\$as_me:16237: $lt_compile\"" >&5)
- (eval "$lt_compile" 2>out/conftest.err)
- ac_status=$?
- cat out/conftest.err >&5
-- echo "$as_me:16190: \$? = $ac_status" >&5
-+ echo "$as_me:16241: \$? = $ac_status" >&5
- if (exit $ac_status) && test -s out/conftest2.$ac_objext
- then
- # The compiler can only warn and ignore the option if not recognized
-@@ -16235,11 +16284,11 @@ else
- -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
- -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
- -e 's:$: $lt_compiler_flag:'`
-- (eval echo "\"\$as_me:16238: $lt_compile\"" >&5)
-+ (eval echo "\"\$as_me:16289: $lt_compile\"" >&5)
- (eval "$lt_compile" 2>out/conftest.err)
- ac_status=$?
- cat out/conftest.err >&5
-- echo "$as_me:16242: \$? = $ac_status" >&5
-+ echo "$as_me:16293: \$? = $ac_status" >&5
- if (exit $ac_status) && test -s out/conftest2.$ac_objext
- then
- # The compiler can only warn and ignore the option if not recognized
-@@ -29270,7 +29319,7 @@ EOF
- if uudecode$EXEEXT Test.uue; then
- ac_cv_prog_uudecode_base64=yes
- else
-- echo "configure: 29273: uudecode had trouble decoding base 64 file 'Test.uue'" >&5
-+ echo "configure: 29324: uudecode had trouble decoding base 64 file 'Test.uue'" >&5
- echo "configure: failed file was:" >&5
- cat Test.uue >&5
- ac_cv_prog_uudecode_base64=no
-@@ -29417,7 +29466,7 @@ else
- JAVA_TEST=Object.java
- CLASS_TEST=Object.class
- cat << \EOF > $JAVA_TEST
--/* #line 29420 "configure" */
-+/* #line 29471 "configure" */
- package java.lang;
-
- public class Object
-@@ -29466,7 +29515,7 @@ JAVA_TEST=Test.java
- CLASS_TEST=Test.class
- TEST=Test
- cat << \EOF > $JAVA_TEST
--/* [#]line 29469 "configure" */
-+/* [#]line 29520 "configure" */
- public class Test {
- public static void main (String args[]) {
- System.exit (0);
-@@ -29786,7 +29835,7 @@ else
- JAVA_TEST=Object.java
- CLASS_TEST=Object.class
- cat << \EOF > $JAVA_TEST
--/* #line 29789 "configure" */
-+/* #line 29840 "configure" */
- package java.lang;
-
- public class Object
-@@ -29827,7 +29876,7 @@ fi
- JAVA_TEST=Test.java
- CLASS_TEST=Test.class
- cat << \EOF > $JAVA_TEST
-- /* #line 29830 "configure" */
-+ /* #line 29881 "configure" */
- public class Test
- {
- public static void main(String args)
-@@ -31681,6 +31730,9 @@ s,@CREATE_PLUGIN_TRUE@,$CREATE_PLUGIN_TR
- s,@CREATE_PLUGIN_FALSE@,$CREATE_PLUGIN_FALSE,;t t
- s,@CREATE_GJDOC_TRUE@,$CREATE_GJDOC_TRUE,;t t
- s,@CREATE_GJDOC_FALSE@,$CREATE_GJDOC_FALSE,;t t
-+s,@target_noncanonical@,$target_noncanonical,;t t
-+s,@toolexecdir@,$toolexecdir,;t t
-+s,@toolexecmainlibdir@,$toolexecmainlibdir,;t t
- s,@toolexeclibdir@,$toolexeclibdir,;t t
- s,@nativeexeclibdir@,$nativeexeclibdir,;t t
- s,@glibjdir@,$glibjdir,;t t
---- a/libjava/classpath/configure.ac
-+++ b/libjava/classpath/configure.ac
-@@ -316,6 +316,16 @@ dnl defined to the same value for all mu
- dnl so that we can refer to the multilib installation directories from
- dnl classpath's build files.
- dnl -----------------------------------------------------------
-+AC_ARG_ENABLE(version-specific-runtime-libs,
-+ AS_HELP_STRING([--enable-version-specific-runtime-libs],
-+ [specify that runtime libraries should be installed in a compiler-specific directory]),
-+ [case "$enableval" in
-+ yes) version_specific_libs=yes ;;
-+ no) version_specific_libs=no ;;
-+ *) AC_MSG_ERROR([Unknown argument to enable/disable version-specific libs]);;
-+ esac],
-+ [version_specific_libs=no]
-+)
- CLASSPATH_TOOLEXECLIBDIR
-
- dnl -----------------------------------------------------------
---- a/libjava/classpath/doc/Makefile.in
-+++ b/libjava/classpath/doc/Makefile.in
-@@ -357,9 +357,12 @@ sysconfdir = @sysconfdir@
- target = @target@
- target_alias = @target_alias@
- target_cpu = @target_cpu@
-+target_noncanonical = @target_noncanonical@
- target_os = @target_os@
- target_vendor = @target_vendor@
-+toolexecdir = @toolexecdir@
- toolexeclibdir = @toolexeclibdir@
-+toolexecmainlibdir = @toolexecmainlibdir@
- uudecode = @uudecode@
- vm_classes = @vm_classes@
- SUBDIRS = api
---- a/libjava/classpath/doc/api/Makefile.in
-+++ b/libjava/classpath/doc/api/Makefile.in
-@@ -334,9 +334,12 @@ sysconfdir = @sysconfdir@
- target = @target@
- target_alias = @target_alias@
- target_cpu = @target_cpu@
-+target_noncanonical = @target_noncanonical@
- target_os = @target_os@
- target_vendor = @target_vendor@
-+toolexecdir = @toolexecdir@
- toolexeclibdir = @toolexeclibdir@
-+toolexecmainlibdir = @toolexecmainlibdir@
- uudecode = @uudecode@
- vm_classes = @vm_classes@
- @CREATE_API_DOCS_TRUE@noinst_DATA = html
---- a/libjava/classpath/examples/Makefile.in
-+++ b/libjava/classpath/examples/Makefile.in
-@@ -343,9 +343,12 @@ sysconfdir = @sysconfdir@
- target = @target@
- target_alias = @target_alias@
- target_cpu = @target_cpu@
-+target_noncanonical = @target_noncanonical@
- target_os = @target_os@
- target_vendor = @target_vendor@
-+toolexecdir = @toolexecdir@
- toolexeclibdir = @toolexeclibdir@
-+toolexecmainlibdir = @toolexecmainlibdir@
- uudecode = @uudecode@
- vm_classes = @vm_classes@
- GLIBJ_CLASSPATH = '$(top_builddir)/lib/glibj.zip:$(top_builddir)/lib'
---- a/libjava/classpath/external/Makefile.in
-+++ b/libjava/classpath/external/Makefile.in
-@@ -341,9 +341,12 @@ sysconfdir = @sysconfdir@
- target = @target@
- target_alias = @target_alias@
- target_cpu = @target_cpu@
-+target_noncanonical = @target_noncanonical@
- target_os = @target_os@
- target_vendor = @target_vendor@
-+toolexecdir = @toolexecdir@
- toolexeclibdir = @toolexeclibdir@
-+toolexecmainlibdir = @toolexecmainlibdir@
- uudecode = @uudecode@
- vm_classes = @vm_classes@
- SUBDIRS = sax w3c_dom relaxngDatatype jsr166
---- a/libjava/classpath/external/jsr166/Makefile.in
-+++ b/libjava/classpath/external/jsr166/Makefile.in
-@@ -332,9 +332,12 @@ sysconfdir = @sysconfdir@
- target = @target@
- target_alias = @target_alias@
- target_cpu = @target_cpu@
-+target_noncanonical = @target_noncanonical@
- target_os = @target_os@
- target_vendor = @target_vendor@
-+toolexecdir = @toolexecdir@
- toolexeclibdir = @toolexeclibdir@
-+toolexecmainlibdir = @toolexecmainlibdir@
- uudecode = @uudecode@
- vm_classes = @vm_classes@
- EXTRA_DIST = IMPORTING \
---- a/libjava/classpath/external/relaxngDatatype/Makefile.in
-+++ b/libjava/classpath/external/relaxngDatatype/Makefile.in
-@@ -332,9 +332,12 @@ sysconfdir = @sysconfdir@
- target = @target@
- target_alias = @target_alias@
- target_cpu = @target_cpu@
-+target_noncanonical = @target_noncanonical@
- target_os = @target_os@
- target_vendor = @target_vendor@
-+toolexecdir = @toolexecdir@
- toolexeclibdir = @toolexeclibdir@
-+toolexecmainlibdir = @toolexecmainlibdir@
- uudecode = @uudecode@
- vm_classes = @vm_classes@
- EXTRA_DIST = README.txt \
---- a/libjava/classpath/external/sax/Makefile.in
-+++ b/libjava/classpath/external/sax/Makefile.in
-@@ -332,9 +332,12 @@ sysconfdir = @sysconfdir@
- target = @target@
- target_alias = @target_alias@
- target_cpu = @target_cpu@
-+target_noncanonical = @target_noncanonical@
- target_os = @target_os@
- target_vendor = @target_vendor@
-+toolexecdir = @toolexecdir@
- toolexeclibdir = @toolexeclibdir@
-+toolexecmainlibdir = @toolexecmainlibdir@
- uudecode = @uudecode@
- vm_classes = @vm_classes@
- EXTRA_DIST = README \
---- a/libjava/classpath/external/w3c_dom/Makefile.in
-+++ b/libjava/classpath/external/w3c_dom/Makefile.in
-@@ -332,9 +332,12 @@ sysconfdir = @sysconfdir@
- target = @target@
- target_alias = @target_alias@
- target_cpu = @target_cpu@
-+target_noncanonical = @target_noncanonical@
- target_os = @target_os@
- target_vendor = @target_vendor@
-+toolexecdir = @toolexecdir@
- toolexeclibdir = @toolexeclibdir@
-+toolexecmainlibdir = @toolexecmainlibdir@
- uudecode = @uudecode@
- vm_classes = @vm_classes@
- EXTRA_DIST = README \
---- a/libjava/classpath/include/Makefile.in
-+++ b/libjava/classpath/include/Makefile.in
-@@ -333,9 +333,12 @@ sysconfdir = @sysconfdir@
- target = @target@
- target_alias = @target_alias@
- target_cpu = @target_cpu@
-+target_noncanonical = @target_noncanonical@
- target_os = @target_os@
- target_vendor = @target_vendor@
-+toolexecdir = @toolexecdir@
- toolexeclibdir = @toolexeclibdir@
-+toolexecmainlibdir = @toolexecmainlibdir@
- uudecode = @uudecode@
- vm_classes = @vm_classes@
- @CREATE_JNI_HEADERS_FALSE@DISTCLEANFILES = jni_md.h config-int.h
---- a/libjava/classpath/lib/Makefile.in
-+++ b/libjava/classpath/lib/Makefile.in
-@@ -337,9 +337,12 @@ sysconfdir = @sysconfdir@
- target = @target@
- target_alias = @target_alias@
- target_cpu = @target_cpu@
-+target_noncanonical = @target_noncanonical@
- target_os = @target_os@
- target_vendor = @target_vendor@
-+toolexecdir = @toolexecdir@
- toolexeclibdir = @toolexeclibdir@
-+toolexecmainlibdir = @toolexecmainlibdir@
- uudecode = @uudecode@
- vm_classes = @vm_classes@
- JAVA_DEPEND = java.dep
---- a/libjava/classpath/m4/acinclude.m4
-+++ b/libjava/classpath/m4/acinclude.m4
-@@ -247,11 +247,45 @@ dnl GCJ LOCAL: Calculate toolexeclibdir
- dnl -----------------------------------------------------------
- AC_DEFUN([CLASSPATH_TOOLEXECLIBDIR],
- [
-- multi_os_directory=`$CC -print-multi-os-directory`
-- case $multi_os_directory in
-- .) toolexeclibdir=${libdir} ;; # Avoid trailing /.
-- *) toolexeclibdir=${libdir}/${multi_os_directory} ;;
-+ case ${host_alias} in
-+ "") host_noncanonical=${build_noncanonical} ;;
-+ *) host_noncanonical=${host_alias} ;;
- esac
-+ case ${target_alias} in
-+ "") target_noncanonical=${host_noncanonical} ;;
-+ *) target_noncanonical=${target_alias} ;;
-+ esac
-+ AC_SUBST(target_noncanonical)
-+
-+ case ${version_specific_libs} in
-+ yes)
-+ # Need the gcc compiler version to know where to install libraries
-+ # and header files if --enable-version-specific-runtime-libs option
-+ # is selected.
-+ includedir='$(libdir)/gcc/$(target_noncanonical)/$(gcc_version)/include/'
-+ toolexecdir='$(libdir)/gcc/$(target_noncanonical)'
-+ toolexecmainlibdir='$(toolexecdir)/$(gcc_version)$(MULTISUBDIR)'
-+ toolexeclibdir=$toolexecmainlibdir
-+ ;;
-+ no)
-+ if test -n "$with_cross_host" &&
-+ test x"$with_cross_host" != x"no"; then
-+ # Install a library built with a cross compiler in tooldir, not libdir.
-+ toolexecdir='$(exec_prefix)/$(target_noncanonical)'
-+ toolexecmainlibdir='$(toolexecdir)/lib'
-+ else
-+ toolexecdir='$(libdir)/gcc-lib/$(target_noncanonical)'
-+ toolexecmainlibdir='$(libdir)'
-+ fi
-+ multi_os_directory=`$CC -print-multi-os-directory`
-+ case $multi_os_directory in
-+ .) toolexeclibdir=$toolexecmainlibdir ;; # Avoid trailing /.
-+ *) toolexeclibdir=$toolexecmainlibdir/$multi_os_directory ;;
-+ esac
-+ ;;
-+ esac
-+ AC_SUBST(toolexecdir)
-+ AC_SUBST(toolexecmainlibdir)
- AC_SUBST(toolexeclibdir)
- ])
-
---- a/libjava/classpath/native/Makefile.in
-+++ b/libjava/classpath/native/Makefile.in
-@@ -340,9 +340,12 @@ sysconfdir = @sysconfdir@
- target = @target@
- target_alias = @target_alias@
- target_cpu = @target_cpu@
-+target_noncanonical = @target_noncanonical@
- target_os = @target_os@
- target_vendor = @target_vendor@
-+toolexecdir = @toolexecdir@
- toolexeclibdir = @toolexeclibdir@
-+toolexecmainlibdir = @toolexecmainlibdir@
- uudecode = @uudecode@
- vm_classes = @vm_classes@
- @CREATE_JNI_LIBRARIES_TRUE@JNIDIR = jni
---- a/libjava/classpath/native/fdlibm/Makefile.in
-+++ b/libjava/classpath/native/fdlibm/Makefile.in
-@@ -359,9 +359,12 @@ sysconfdir = @sysconfdir@
- target = @target@
- target_alias = @target_alias@
- target_cpu = @target_cpu@
-+target_noncanonical = @target_noncanonical@
- target_os = @target_os@
- target_vendor = @target_vendor@
-+toolexecdir = @toolexecdir@
- toolexeclibdir = @toolexeclibdir@
-+toolexecmainlibdir = @toolexecmainlibdir@
- uudecode = @uudecode@
- vm_classes = @vm_classes@
- noinst_LTLIBRARIES = libfdlibm.la
---- a/libjava/classpath/native/jawt/Makefile.in
-+++ b/libjava/classpath/native/jawt/Makefile.in
-@@ -359,9 +359,12 @@ sysconfdir = @sysconfdir@
- target = @target@
- target_alias = @target_alias@
- target_cpu = @target_cpu@
-+target_noncanonical = @target_noncanonical@
- target_os = @target_os@
- target_vendor = @target_vendor@
-+toolexecdir = @toolexecdir@
- toolexeclibdir = @toolexeclibdir@
-+toolexecmainlibdir = @toolexecmainlibdir@
- uudecode = @uudecode@
- vm_classes = @vm_classes@
- nativeexeclib_LTLIBRARIES = libjawt.la
---- a/libjava/classpath/native/jni/Makefile.in
-+++ b/libjava/classpath/native/jni/Makefile.in
-@@ -340,9 +340,12 @@ sysconfdir = @sysconfdir@
- target = @target@
- target_alias = @target_alias@
- target_cpu = @target_cpu@
-+target_noncanonical = @target_noncanonical@
- target_os = @target_os@
- target_vendor = @target_vendor@
-+toolexecdir = @toolexecdir@
- toolexeclibdir = @toolexeclibdir@
-+toolexecmainlibdir = @toolexecmainlibdir@
- uudecode = @uudecode@
- vm_classes = @vm_classes@
- @CREATE_CORE_JNI_LIBRARIES_TRUE@JNIDIRS = native-lib java-io java-lang java-net java-nio java-util
---- a/libjava/classpath/native/jni/classpath/Makefile.in
-+++ b/libjava/classpath/native/jni/classpath/Makefile.in
-@@ -350,9 +350,12 @@ sysconfdir = @sysconfdir@
- target = @target@
- target_alias = @target_alias@
- target_cpu = @target_cpu@
-+target_noncanonical = @target_noncanonical@
- target_os = @target_os@
- target_vendor = @target_vendor@
-+toolexecdir = @toolexecdir@
- toolexeclibdir = @toolexeclibdir@
-+toolexecmainlibdir = @toolexecmainlibdir@
- uudecode = @uudecode@
- vm_classes = @vm_classes@
-
---- a/libjava/classpath/native/jni/gconf-peer/Makefile.in
-+++ b/libjava/classpath/native/jni/gconf-peer/Makefile.in
-@@ -359,9 +359,12 @@ sysconfdir = @sysconfdir@
- target = @target@
- target_alias = @target_alias@
- target_cpu = @target_cpu@
-+target_noncanonical = @target_noncanonical@
- target_os = @target_os@
- target_vendor = @target_vendor@
-+toolexecdir = @toolexecdir@
- toolexeclibdir = @toolexeclibdir@
-+toolexecmainlibdir = @toolexecmainlibdir@
- uudecode = @uudecode@
- vm_classes = @vm_classes@
- nativeexeclib_LTLIBRARIES = libgconfpeer.la
---- a/libjava/classpath/native/jni/gstreamer-peer/Makefile.in
-+++ b/libjava/classpath/native/jni/gstreamer-peer/Makefile.in
-@@ -361,9 +361,12 @@ sysconfdir = @sysconfdir@
- target = @target@
- target_alias = @target_alias@
- target_cpu = @target_cpu@
-+target_noncanonical = @target_noncanonical@
- target_os = @target_os@
- target_vendor = @target_vendor@
-+toolexecdir = @toolexecdir@
- toolexeclibdir = @toolexeclibdir@
-+toolexecmainlibdir = @toolexecmainlibdir@
- uudecode = @uudecode@
- vm_classes = @vm_classes@
- nativeexeclib_LTLIBRARIES = libgstreamerpeer.la
---- a/libjava/classpath/native/jni/gtk-peer/Makefile.in
-+++ b/libjava/classpath/native/jni/gtk-peer/Makefile.in
-@@ -397,9 +397,12 @@ sysconfdir = @sysconfdir@
- target = @target@
- target_alias = @target_alias@
- target_cpu = @target_cpu@
-+target_noncanonical = @target_noncanonical@
- target_os = @target_os@
- target_vendor = @target_vendor@
-+toolexecdir = @toolexecdir@
- toolexeclibdir = @toolexeclibdir@
-+toolexecmainlibdir = @toolexecmainlibdir@
- uudecode = @uudecode@
- vm_classes = @vm_classes@
- nativeexeclib_LTLIBRARIES = libgtkpeer.la
---- a/libjava/classpath/native/jni/java-io/Makefile.in
-+++ b/libjava/classpath/native/jni/java-io/Makefile.in
-@@ -361,9 +361,12 @@ sysconfdir = @sysconfdir@
- target = @target@
- target_alias = @target_alias@
- target_cpu = @target_cpu@
-+target_noncanonical = @target_noncanonical@
- target_os = @target_os@
- target_vendor = @target_vendor@
-+toolexecdir = @toolexecdir@
- toolexeclibdir = @toolexeclibdir@
-+toolexecmainlibdir = @toolexecmainlibdir@
- uudecode = @uudecode@
- vm_classes = @vm_classes@
- nativeexeclib_LTLIBRARIES = libjavaio.la
---- a/libjava/classpath/native/jni/java-lang/Makefile.in
-+++ b/libjava/classpath/native/jni/java-lang/Makefile.in
-@@ -375,9 +375,12 @@ sysconfdir = @sysconfdir@
- target = @target@
- target_alias = @target_alias@
- target_cpu = @target_cpu@
-+target_noncanonical = @target_noncanonical@
- target_os = @target_os@
- target_vendor = @target_vendor@
-+toolexecdir = @toolexecdir@
- toolexeclibdir = @toolexeclibdir@
-+toolexecmainlibdir = @toolexecmainlibdir@
- uudecode = @uudecode@
- vm_classes = @vm_classes@
- nativeexeclib_LTLIBRARIES = libjavalang.la libjavalangreflect.la libjavalangmanagement.la
---- a/libjava/classpath/native/jni/java-math/Makefile.in
-+++ b/libjava/classpath/native/jni/java-math/Makefile.in
-@@ -359,9 +359,12 @@ sysconfdir = @sysconfdir@
- target = @target@
- target_alias = @target_alias@
- target_cpu = @target_cpu@
-+target_noncanonical = @target_noncanonical@
- target_os = @target_os@
- target_vendor = @target_vendor@
-+toolexecdir = @toolexecdir@
- toolexeclibdir = @toolexeclibdir@
-+toolexecmainlibdir = @toolexecmainlibdir@
- uudecode = @uudecode@
- vm_classes = @vm_classes@
- nativeexeclib_LTLIBRARIES = libjavamath.la
---- a/libjava/classpath/native/jni/java-net/Makefile.in
-+++ b/libjava/classpath/native/jni/java-net/Makefile.in
-@@ -371,9 +371,12 @@ sysconfdir = @sysconfdir@
- target = @target@
- target_alias = @target_alias@
- target_cpu = @target_cpu@
-+target_noncanonical = @target_noncanonical@
- target_os = @target_os@
- target_vendor = @target_vendor@
-+toolexecdir = @toolexecdir@
- toolexeclibdir = @toolexeclibdir@
-+toolexecmainlibdir = @toolexecmainlibdir@
- uudecode = @uudecode@
- vm_classes = @vm_classes@
- nativeexeclib_LTLIBRARIES = libjavanet.la
---- a/libjava/classpath/native/jni/java-nio/Makefile.in
-+++ b/libjava/classpath/native/jni/java-nio/Makefile.in
-@@ -369,9 +369,12 @@ sysconfdir = @sysconfdir@
- target = @target@
- target_alias = @target_alias@
- target_cpu = @target_cpu@
-+target_noncanonical = @target_noncanonical@
- target_os = @target_os@
- target_vendor = @target_vendor@
-+toolexecdir = @toolexecdir@
- toolexeclibdir = @toolexeclibdir@
-+toolexecmainlibdir = @toolexecmainlibdir@
- uudecode = @uudecode@
- vm_classes = @vm_classes@
- nativeexeclib_LTLIBRARIES = libjavanio.la
---- a/libjava/classpath/native/jni/java-util/Makefile.in
-+++ b/libjava/classpath/native/jni/java-util/Makefile.in
-@@ -358,9 +358,12 @@ sysconfdir = @sysconfdir@
- target = @target@
- target_alias = @target_alias@
- target_cpu = @target_cpu@
-+target_noncanonical = @target_noncanonical@
- target_os = @target_os@
- target_vendor = @target_vendor@
-+toolexecdir = @toolexecdir@
- toolexeclibdir = @toolexeclibdir@
-+toolexecmainlibdir = @toolexecmainlibdir@
- uudecode = @uudecode@
- vm_classes = @vm_classes@
- nativeexeclib_LTLIBRARIES = libjavautil.la
---- a/libjava/classpath/native/jni/midi-alsa/Makefile.in
-+++ b/libjava/classpath/native/jni/midi-alsa/Makefile.in
-@@ -361,9 +361,12 @@ sysconfdir = @sysconfdir@
- target = @target@
- target_alias = @target_alias@
- target_cpu = @target_cpu@
-+target_noncanonical = @target_noncanonical@
- target_os = @target_os@
- target_vendor = @target_vendor@
-+toolexecdir = @toolexecdir@
- toolexeclibdir = @toolexeclibdir@
-+toolexecmainlibdir = @toolexecmainlibdir@
- uudecode = @uudecode@
- vm_classes = @vm_classes@
- nativeexeclib_LTLIBRARIES = libgjsmalsa.la
---- a/libjava/classpath/native/jni/midi-dssi/Makefile.in
-+++ b/libjava/classpath/native/jni/midi-dssi/Makefile.in
-@@ -361,9 +361,12 @@ sysconfdir = @sysconfdir@
- target = @target@
- target_alias = @target_alias@
- target_cpu = @target_cpu@
-+target_noncanonical = @target_noncanonical@
- target_os = @target_os@
- target_vendor = @target_vendor@
-+toolexecdir = @toolexecdir@
- toolexeclibdir = @toolexeclibdir@
-+toolexecmainlibdir = @toolexecmainlibdir@
- uudecode = @uudecode@
- vm_classes = @vm_classes@
- nativeexeclib_LTLIBRARIES = libgjsmdssi.la
---- a/libjava/classpath/native/jni/native-lib/Makefile.in
-+++ b/libjava/classpath/native/jni/native-lib/Makefile.in
-@@ -350,9 +350,12 @@ sysconfdir = @sysconfdir@
- target = @target@
- target_alias = @target_alias@
- target_cpu = @target_cpu@
-+target_noncanonical = @target_noncanonical@
- target_os = @target_os@
- target_vendor = @target_vendor@
-+toolexecdir = @toolexecdir@
- toolexeclibdir = @toolexeclibdir@
-+toolexecmainlibdir = @toolexecmainlibdir@
- uudecode = @uudecode@
- vm_classes = @vm_classes@
- noinst_LTLIBRARIES = libclasspathnative.la
---- a/libjava/classpath/native/jni/qt-peer/Makefile.in
-+++ b/libjava/classpath/native/jni/qt-peer/Makefile.in
-@@ -376,9 +376,12 @@ sysconfdir = @sysconfdir@
- target = @target@
- target_alias = @target_alias@
- target_cpu = @target_cpu@
-+target_noncanonical = @target_noncanonical@
- target_os = @target_os@
- target_vendor = @target_vendor@
-+toolexecdir = @toolexecdir@
- toolexeclibdir = @toolexeclibdir@
-+toolexecmainlibdir = @toolexecmainlibdir@
- uudecode = @uudecode@
- vm_classes = @vm_classes@
- noinst_LTLIBRARIES = libqtpeer.la
---- a/libjava/classpath/native/jni/xmlj/Makefile.in
-+++ b/libjava/classpath/native/jni/xmlj/Makefile.in
-@@ -360,9 +360,12 @@ sysconfdir = @sysconfdir@
- target = @target@
- target_alias = @target_alias@
- target_cpu = @target_cpu@
-+target_noncanonical = @target_noncanonical@
- target_os = @target_os@
- target_vendor = @target_vendor@
-+toolexecdir = @toolexecdir@
- toolexeclibdir = @toolexeclibdir@
-+toolexecmainlibdir = @toolexecmainlibdir@
- uudecode = @uudecode@
- vm_classes = @vm_classes@
- nativeexeclib_LTLIBRARIES = libxmlj.la
---- a/libjava/classpath/native/plugin/Makefile.in
-+++ b/libjava/classpath/native/plugin/Makefile.in
-@@ -358,9 +358,12 @@ sysconfdir = @sysconfdir@
- target = @target@
- target_alias = @target_alias@
- target_cpu = @target_cpu@
-+target_noncanonical = @target_noncanonical@
- target_os = @target_os@
- target_vendor = @target_vendor@
-+toolexecdir = @toolexecdir@
- toolexeclibdir = @toolexeclibdir@
-+toolexecmainlibdir = @toolexecmainlibdir@
- uudecode = @uudecode@
- vm_classes = @vm_classes@
- nativeexeclib_LTLIBRARIES = libgcjwebplugin.la
---- a/libjava/classpath/resource/Makefile.in
-+++ b/libjava/classpath/resource/Makefile.in
-@@ -343,9 +343,12 @@ sysconfdir = @sysconfdir@
- target = @target@
- target_alias = @target_alias@
- target_cpu = @target_cpu@
-+target_noncanonical = @target_noncanonical@
- target_os = @target_os@
- target_vendor = @target_vendor@
-+toolexecdir = @toolexecdir@
- toolexeclibdir = @toolexeclibdir@
-+toolexecmainlibdir = @toolexecmainlibdir@
- uudecode = @uudecode@
- vm_classes = @vm_classes@
- logging_DATA = java/util/logging/logging.properties
---- a/libjava/classpath/scripts/Makefile.in
-+++ b/libjava/classpath/scripts/Makefile.in
-@@ -333,9 +333,12 @@ sysconfdir = @sysconfdir@
- target = @target@
- target_alias = @target_alias@
- target_cpu = @target_cpu@
-+target_noncanonical = @target_noncanonical@
- target_os = @target_os@
- target_vendor = @target_vendor@
-+toolexecdir = @toolexecdir@
- toolexeclibdir = @toolexeclibdir@
-+toolexecmainlibdir = @toolexecmainlibdir@
- uudecode = @uudecode@
- vm_classes = @vm_classes@
- EXTRA_DIST = generate-locale-list.sh import-cacerts.sh
---- a/libjava/classpath/tools/Makefile.in
-+++ b/libjava/classpath/tools/Makefile.in
-@@ -448,9 +448,12 @@ sysconfdir = @sysconfdir@
- target = @target@
- target_alias = @target_alias@
- target_cpu = @target_cpu@
-+target_noncanonical = @target_noncanonical@
- target_os = @target_os@
- target_vendor = @target_vendor@
-+toolexecdir = @toolexecdir@
- toolexeclibdir = @toolexeclibdir@
-+toolexecmainlibdir = @toolexecmainlibdir@
- uudecode = @uudecode@
- vm_classes = @vm_classes@
- @CREATE_GJDOC_TRUE@gjdoc_gendir = ${top_srcdir}/tools/generated
---- a/libjava/configure
-+++ b/libjava/configure
-@@ -26500,10 +26500,10 @@ gcjsubdir=gcj-$gcjversion-$libgcj_sovers
- multi_os_directory=`$CC -print-multi-os-directory`
- case $multi_os_directory in
- .)
-- dbexecdir='$(libdir)/'$gcjsubdir # Avoid /.
-+ dbexecdir='$(toolexeclibdir)/'$gcjsubdir # Avoid /.
- ;;
- *)
-- dbexecdir='$(libdir)/'$multi_os_directory/$gcjsubdir
-+ dbexecdir='$(toolexeclibdir)/'$multi_os_directory/$gcjsubdir
- ;;
- esac
-
-@@ -27651,6 +27651,74 @@ if { (eval echo "$as_me:$LINENO: \"$ac_l
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
-+ chktls_save_LDFLAGS="$LDFLAGS"
-+ case $host in
-+ *-*-linux*)
-+ LDFLAGS="-shared -Wl,--no-undefined $LDFLAGS"
-+ ;;
-+ esac
-+ chktls_save_CFLAGS="$CFLAGS"
-+ CFLAGS="-fPIC $CFLAGS"
-+ if test x$gcc_no_link = xyes; then
-+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
-+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
-+ { (exit 1); exit 1; }; }
-+fi
-+cat >conftest.$ac_ext <<_ACEOF
-+int f() { return 0; }
-+_ACEOF
-+rm -f conftest.$ac_objext conftest$ac_exeext
-+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-+ (eval $ac_link) 2>conftest.er1
-+ ac_status=$?
-+ grep -v '^ *+' conftest.er1 >conftest.err
-+ rm -f conftest.er1
-+ cat conftest.err >&5
-+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
-+ (exit $ac_status); } &&
-+ { ac_try='test -z "$ac_c_werror_flag"
-+ || test ! -s conftest.err'
-+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-+ (eval $ac_try) 2>&5
-+ ac_status=$?
-+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
-+ (exit $ac_status); }; } &&
-+ { ac_try='test -s conftest$ac_exeext'
-+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-+ (eval $ac_try) 2>&5
-+ ac_status=$?
-+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
-+ (exit $ac_status); }; }; then
-+ if test x$gcc_no_link = xyes; then
-+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
-+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
-+ { (exit 1); exit 1; }; }
-+fi
-+cat >conftest.$ac_ext <<_ACEOF
-+__thread int a; int b; int f() { return a = b; }
-+_ACEOF
-+rm -f conftest.$ac_objext conftest$ac_exeext
-+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-+ (eval $ac_link) 2>conftest.er1
-+ ac_status=$?
-+ grep -v '^ *+' conftest.er1 >conftest.err
-+ rm -f conftest.er1
-+ cat conftest.err >&5
-+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
-+ (exit $ac_status); } &&
-+ { ac_try='test -z "$ac_c_werror_flag"
-+ || test ! -s conftest.err'
-+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-+ (eval $ac_try) 2>&5
-+ ac_status=$?
-+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
-+ (exit $ac_status); }; } &&
-+ { ac_try='test -s conftest$ac_exeext'
-+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-+ (eval $ac_try) 2>&5
-+ ac_status=$?
-+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
-+ (exit $ac_status); }; }; then
- gcc_cv_have_tls=yes
- else
- echo "$as_me: failed program was:" >&5
-@@ -27660,6 +27728,24 @@ gcc_cv_have_tls=no
- fi
- rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-+else
-+ echo "$as_me: failed program was:" >&5
-+sed 's/^/| /' conftest.$ac_ext >&5
-+
-+gcc_cv_have_tls=yes
-+fi
-+rm -f conftest.err conftest.$ac_objext \
-+ conftest$ac_exeext conftest.$ac_ext
-+ CFLAGS="$chktls_save_CFLAGS"
-+ LDFLAGS="$chktls_save_LDFLAGS"
-+else
-+ echo "$as_me: failed program was:" >&5
-+sed 's/^/| /' conftest.$ac_ext >&5
-+
-+gcc_cv_have_tls=no
-+fi
-+rm -f conftest.err conftest.$ac_objext \
-+ conftest$ac_exeext conftest.$ac_ext
-
-
- else
---- a/libjava/configure.ac
-+++ b/libjava/configure.ac
-@@ -1489,10 +1489,10 @@ gcjsubdir=gcj-$gcjversion-$libgcj_sovers
- multi_os_directory=`$CC -print-multi-os-directory`
- case $multi_os_directory in
- .)
-- dbexecdir='$(libdir)/'$gcjsubdir # Avoid /.
-+ dbexecdir='$(toolexeclibdir)/'$gcjsubdir # Avoid /.
- ;;
- *)
-- dbexecdir='$(libdir)/'$multi_os_directory/$gcjsubdir
-+ dbexecdir='$(toolexeclibdir)/'$multi_os_directory/$gcjsubdir
- ;;
- esac
- AC_SUBST(dbexecdir)
---- a/libmudflap/configure
-+++ b/libmudflap/configure
-@@ -12787,6 +12787,64 @@ if { (eval echo "$as_me:$LINENO: \"$ac_l
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
-+ chktls_save_LDFLAGS="$LDFLAGS"
-+ case $host in
-+ *-*-linux*)
-+ LDFLAGS="-shared -Wl,--no-undefined $LDFLAGS"
-+ ;;
-+ esac
-+ chktls_save_CFLAGS="$CFLAGS"
-+ CFLAGS="-fPIC $CFLAGS"
-+ cat >conftest.$ac_ext <<_ACEOF
-+int f() { return 0; }
-+_ACEOF
-+rm -f conftest.$ac_objext conftest$ac_exeext
-+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-+ (eval $ac_link) 2>conftest.er1
-+ ac_status=$?
-+ grep -v '^ *+' conftest.er1 >conftest.err
-+ rm -f conftest.er1
-+ cat conftest.err >&5
-+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
-+ (exit $ac_status); } &&
-+ { ac_try='test -z "$ac_c_werror_flag"
-+ || test ! -s conftest.err'
-+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-+ (eval $ac_try) 2>&5
-+ ac_status=$?
-+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
-+ (exit $ac_status); }; } &&
-+ { ac_try='test -s conftest$ac_exeext'
-+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-+ (eval $ac_try) 2>&5
-+ ac_status=$?
-+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
-+ (exit $ac_status); }; }; then
-+ cat >conftest.$ac_ext <<_ACEOF
-+__thread int a; int b; int f() { return a = b; }
-+_ACEOF
-+rm -f conftest.$ac_objext conftest$ac_exeext
-+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-+ (eval $ac_link) 2>conftest.er1
-+ ac_status=$?
-+ grep -v '^ *+' conftest.er1 >conftest.err
-+ rm -f conftest.er1
-+ cat conftest.err >&5
-+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
-+ (exit $ac_status); } &&
-+ { ac_try='test -z "$ac_c_werror_flag"
-+ || test ! -s conftest.err'
-+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-+ (eval $ac_try) 2>&5
-+ ac_status=$?
-+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
-+ (exit $ac_status); }; } &&
-+ { ac_try='test -s conftest$ac_exeext'
-+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-+ (eval $ac_try) 2>&5
-+ ac_status=$?
-+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
-+ (exit $ac_status); }; }; then
- gcc_cv_have_tls=yes
- else
- echo "$as_me: failed program was:" >&5
-@@ -12796,6 +12854,24 @@ gcc_cv_have_tls=no
- fi
- rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-+else
-+ echo "$as_me: failed program was:" >&5
-+sed 's/^/| /' conftest.$ac_ext >&5
-+
-+gcc_cv_have_tls=yes
-+fi
-+rm -f conftest.err conftest.$ac_objext \
-+ conftest$ac_exeext conftest.$ac_ext
-+ CFLAGS="$chktls_save_CFLAGS"
-+ LDFLAGS="$chktls_save_LDFLAGS"
-+else
-+ echo "$as_me: failed program was:" >&5
-+sed 's/^/| /' conftest.$ac_ext >&5
-+
-+gcc_cv_have_tls=no
-+fi
-+rm -f conftest.err conftest.$ac_objext \
-+ conftest$ac_exeext conftest.$ac_ext
-
-
- else
---- a/libstdc++-v3/Makefile.in
-+++ b/libstdc++-v3/Makefile.in
-@@ -193,6 +193,8 @@ LIBICONV = @LIBICONV@
- LIBOBJS = @LIBOBJS@
- LIBS = @LIBS@
- LIBSUPCXX_PICFLAGS = @LIBSUPCXX_PICFLAGS@
-+LIBSUPCXX_PRONLY_FALSE = @LIBSUPCXX_PRONLY_FALSE@
-+LIBSUPCXX_PRONLY_TRUE = @LIBSUPCXX_PRONLY_TRUE@
- LIBTOOL = @LIBTOOL@
- LIPO = @LIPO@
- LN_S = @LN_S@
---- a/libstdc++-v3/config/cpu/sh/atomicity.h
-+++ b/libstdc++-v3/config/cpu/sh/atomicity.h
-@@ -25,47 +25,48 @@
-
- #ifdef __SH4A__
-
--#ifndef _GLIBCXX_ATOMICITY_H
--#define _GLIBCXX_ATOMICITY_H 1
-+#include <ext/atomicity.h>
-
--typedef int _Atomic_word;
-+_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
-
--static inline _Atomic_word
--__attribute__ ((__unused__))
--__exchange_and_add (volatile _Atomic_word* __mem, int __val)
--{
-- _Atomic_word __result;
-+ typedef int _Atomic_word;
-
-- __asm__ __volatile__
-- ("0:\n"
-- "\tmovli.l\t@%2,r0\n"
-- "\tmov\tr0,%1\n"
-- "\tadd\t%3,r0\n"
-- "\tmovco.l\tr0,@%2\n"
-- "\tbf\t0b"
-- : "+m" (*__mem), "=r" (__result)
-- : "r" (__mem), "rI08" (__val)
-- : "r0");
--
-- return __result;
--}
--
--
--static inline void
--__attribute__ ((__unused__))
--__atomic_add (volatile _Atomic_word* __mem, int __val)
--{
-- asm("0:\n"
-- "\tmovli.l\t@%1,r0\n"
-- "\tadd\t%2,r0\n"
-- "\tmovco.l\tr0,@%1\n"
-- "\tbf\t0b"
-- : "+m" (*__mem)
-- : "r" (__mem), "rI08" (__val)
-- : "r0");
--}
-+ _Atomic_word
-+ __attribute__ ((__unused__))
-+ __exchange_and_add (volatile _Atomic_word* __mem, int __val)
-+ {
-+ _Atomic_word __result;
-
--#endif
-+ __asm__ __volatile__
-+ ("0:\n"
-+ "\tmovli.l\t@%2,r0\n"
-+ "\tmov\tr0,%1\n"
-+ "\tadd\t%3,r0\n"
-+ "\tmovco.l\tr0,@%2\n"
-+ "\tbf\t0b"
-+ : "+m" (*__mem), "=&r" (__result)
-+ : "r" (__mem), "rI08" (__val)
-+ : "r0");
-+
-+ return __result;
-+ }
-+
-+
-+ void
-+ __attribute__ ((__unused__))
-+ __atomic_add (volatile _Atomic_word* __mem, int __val)
-+ {
-+ asm("0:\n"
-+ "\tmovli.l\t@%1,r0\n"
-+ "\tadd\t%2,r0\n"
-+ "\tmovco.l\tr0,@%1\n"
-+ "\tbf\t0b"
-+ : "+m" (*__mem)
-+ : "r" (__mem), "rI08" (__val)
-+ : "r0");
-+ }
-+
-+_GLIBCXX_END_NAMESPACE
-
- #else /* !__SH4A__ */
-
---- a/libstdc++-v3/configure
-+++ b/libstdc++-v3/configure
-@@ -458,7 +458,7 @@ ac_includes_default="\
- # include <unistd.h>
- #endif"
-
--ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS libtool_VERSION multi_basedir build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar glibcxx_builddir glibcxx_srcdir toplevel_srcdir CC ac_ct_CC EXEEXT OBJEXT CXX ac_ct_CXX CFLAGS CXXFLAGS LN_S AS ac_ct_AS AR ac_ct_AR RANLIB ac_ct_RANLIB MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT CPP CPPFLAGS EGREP LIBTOOL SED FGREP GREP LD DUMPBIN ac_ct_DUMPBIN NM OBJDUMP ac_ct_OBJDUMP lt_ECHO DSYMUTIL ac_ct_DSYMUTIL NMEDIT ac_ct_NMEDIT LIPO ac_ct_LIPO OTOOL ac_ct_OTOOL OTOOL64 ac_ct_OTOOL64 LDFLAGS CXXCPP enable_shared enable_static GLIBCXX_HOSTED_TRUE GLIBCXX_HOSTED_FALSE GLIBCXX_BUILD_PCH_TRUE GLIBCXX_BUILD_PCH_FALSE glibcxx_PCHFLAGS glibcxx_thread_h WERROR SECTION_FLAGS CSTDIO_H BASIC_FILE_H BASIC_FILE_CC check_msgfmt glibcxx_MOFILES glibcxx_POFILES glibcxx_localedir USE_NLS CLOCALE_H CMESSAGES_H CCODECVT_CC CCOLLATE_CC CCTYPE_CC CMESSAGES_CC CMONEY_CC CNUMERIC_CC CTIME_H CTIME_CC CLOCALE_CC CLOCALE_INTERNAL_H ALLOCATOR_H ALLOCATOR_NAME C_INCLUDE_DIR GLIBCXX_C_HEADERS_C_TRUE GLIBCXX_C_HEADERS_C_FALSE GLIBCXX_C_HEADERS_C_STD_TRUE GLIBCXX_C_HEADERS_C_STD_FALSE GLIBCXX_C_HEADERS_C_GLOBAL_TRUE GLIBCXX_C_HEADERS_C_GLOBAL_FALSE GLIBCXX_C_HEADERS_COMPATIBILITY_TRUE GLIBCXX_C_HEADERS_COMPATIBILITY_FALSE GLIBCXX_C_HEADERS_EXTRA_TRUE GLIBCXX_C_HEADERS_EXTRA_FALSE DEBUG_FLAGS GLIBCXX_BUILD_DEBUG_TRUE GLIBCXX_BUILD_DEBUG_FALSE ENABLE_PARALLEL_TRUE ENABLE_PARALLEL_FALSE EXTRA_CXX_FLAGS GLIBCXX_LIBS SECTION_LDFLAGS OPT_LDFLAGS LIBICONV LTLIBICONV SYMVER_FILE port_specific_symbol_files ENABLE_SYMVERS_TRUE ENABLE_SYMVERS_FALSE ENABLE_SYMVERS_GNU_TRUE ENABLE_SYMVERS_GNU_FALSE ENABLE_SYMVERS_GNU_NAMESPACE_TRUE ENABLE_SYMVERS_GNU_NAMESPACE_FALSE ENABLE_SYMVERS_DARWIN_TRUE ENABLE_SYMVERS_DARWIN_FALSE ENABLE_VISIBILITY_TRUE ENABLE_VISIBILITY_FALSE GLIBCXX_LDBL_COMPAT_TRUE GLIBCXX_LDBL_COMPAT_FALSE baseline_dir ATOMICITY_SRCDIR ATOMIC_WORD_SRCDIR ATOMIC_FLAGS CPU_DEFINES_SRCDIR ABI_TWEAKS_SRCDIR OS_INC_SRCDIR ERROR_CONSTANTS_SRCDIR glibcxx_prefixdir gxx_include_dir glibcxx_toolexecdir glibcxx_toolexeclibdir GLIBCXX_INCLUDES TOPLEVEL_INCLUDES OPTIMIZE_CXXFLAGS WARN_FLAGS LIBSUPCXX_PICFLAGS LIBOBJS LTLIBOBJS'
-+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS libtool_VERSION multi_basedir build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar glibcxx_builddir glibcxx_srcdir toplevel_srcdir CC ac_ct_CC EXEEXT OBJEXT CXX ac_ct_CXX CFLAGS CXXFLAGS LN_S AS ac_ct_AS AR ac_ct_AR RANLIB ac_ct_RANLIB MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT CPP CPPFLAGS EGREP LIBTOOL SED FGREP GREP LD DUMPBIN ac_ct_DUMPBIN NM OBJDUMP ac_ct_OBJDUMP lt_ECHO DSYMUTIL ac_ct_DSYMUTIL NMEDIT ac_ct_NMEDIT LIPO ac_ct_LIPO OTOOL ac_ct_OTOOL OTOOL64 ac_ct_OTOOL64 LDFLAGS CXXCPP enable_shared enable_static GLIBCXX_HOSTED_TRUE GLIBCXX_HOSTED_FALSE GLIBCXX_BUILD_PCH_TRUE GLIBCXX_BUILD_PCH_FALSE glibcxx_PCHFLAGS glibcxx_thread_h WERROR SECTION_FLAGS CSTDIO_H BASIC_FILE_H BASIC_FILE_CC check_msgfmt glibcxx_MOFILES glibcxx_POFILES glibcxx_localedir USE_NLS CLOCALE_H CMESSAGES_H CCODECVT_CC CCOLLATE_CC CCTYPE_CC CMESSAGES_CC CMONEY_CC CNUMERIC_CC CTIME_H CTIME_CC CLOCALE_CC CLOCALE_INTERNAL_H ALLOCATOR_H ALLOCATOR_NAME C_INCLUDE_DIR GLIBCXX_C_HEADERS_C_TRUE GLIBCXX_C_HEADERS_C_FALSE GLIBCXX_C_HEADERS_C_STD_TRUE GLIBCXX_C_HEADERS_C_STD_FALSE GLIBCXX_C_HEADERS_C_GLOBAL_TRUE GLIBCXX_C_HEADERS_C_GLOBAL_FALSE GLIBCXX_C_HEADERS_COMPATIBILITY_TRUE GLIBCXX_C_HEADERS_COMPATIBILITY_FALSE GLIBCXX_C_HEADERS_EXTRA_TRUE GLIBCXX_C_HEADERS_EXTRA_FALSE DEBUG_FLAGS GLIBCXX_BUILD_DEBUG_TRUE GLIBCXX_BUILD_DEBUG_FALSE ENABLE_PARALLEL_TRUE ENABLE_PARALLEL_FALSE EXTRA_CXX_FLAGS GLIBCXX_LIBS SECTION_LDFLAGS OPT_LDFLAGS LIBICONV LTLIBICONV SYMVER_FILE port_specific_symbol_files ENABLE_SYMVERS_TRUE ENABLE_SYMVERS_FALSE ENABLE_SYMVERS_GNU_TRUE ENABLE_SYMVERS_GNU_FALSE ENABLE_SYMVERS_GNU_NAMESPACE_TRUE ENABLE_SYMVERS_GNU_NAMESPACE_FALSE ENABLE_SYMVERS_DARWIN_TRUE ENABLE_SYMVERS_DARWIN_FALSE ENABLE_VISIBILITY_TRUE ENABLE_VISIBILITY_FALSE GLIBCXX_LDBL_COMPAT_TRUE GLIBCXX_LDBL_COMPAT_FALSE baseline_dir ATOMICITY_SRCDIR ATOMIC_WORD_SRCDIR ATOMIC_FLAGS CPU_DEFINES_SRCDIR ABI_TWEAKS_SRCDIR OS_INC_SRCDIR ERROR_CONSTANTS_SRCDIR LIBSUPCXX_PRONLY_TRUE LIBSUPCXX_PRONLY_FALSE glibcxx_prefixdir gxx_include_dir glibcxx_toolexecdir glibcxx_toolexeclibdir GLIBCXX_INCLUDES TOPLEVEL_INCLUDES OPTIMIZE_CXXFLAGS WARN_FLAGS LIBSUPCXX_PICFLAGS LIBOBJS LTLIBOBJS'
- ac_subst_files=''
- ac_pwd=`pwd`
-
-@@ -40730,6 +40730,74 @@ if { (eval echo "$as_me:$LINENO: \"$ac_l
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
-+ chktls_save_LDFLAGS="$LDFLAGS"
-+ case $host in
-+ *-*-linux*)
-+ LDFLAGS="-shared -Wl,--no-undefined $LDFLAGS"
-+ ;;
-+ esac
-+ chktls_save_CFLAGS="$CFLAGS"
-+ CFLAGS="-fPIC $CFLAGS"
-+ if test x$gcc_no_link = xyes; then
-+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
-+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
-+ { (exit 1); exit 1; }; }
-+fi
-+cat >conftest.$ac_ext <<_ACEOF
-+int f() { return 0; }
-+_ACEOF
-+rm -f conftest.$ac_objext conftest$ac_exeext
-+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-+ (eval $ac_link) 2>conftest.er1
-+ ac_status=$?
-+ grep -v '^ *+' conftest.er1 >conftest.err
-+ rm -f conftest.er1
-+ cat conftest.err >&5
-+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
-+ (exit $ac_status); } &&
-+ { ac_try='test -z "$ac_c_werror_flag"
-+ || test ! -s conftest.err'
-+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-+ (eval $ac_try) 2>&5
-+ ac_status=$?
-+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
-+ (exit $ac_status); }; } &&
-+ { ac_try='test -s conftest$ac_exeext'
-+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-+ (eval $ac_try) 2>&5
-+ ac_status=$?
-+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
-+ (exit $ac_status); }; }; then
-+ if test x$gcc_no_link = xyes; then
-+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
-+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
-+ { (exit 1); exit 1; }; }
-+fi
-+cat >conftest.$ac_ext <<_ACEOF
-+__thread int a; int b; int f() { return a = b; }
-+_ACEOF
-+rm -f conftest.$ac_objext conftest$ac_exeext
-+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-+ (eval $ac_link) 2>conftest.er1
-+ ac_status=$?
-+ grep -v '^ *+' conftest.er1 >conftest.err
-+ rm -f conftest.er1
-+ cat conftest.err >&5
-+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
-+ (exit $ac_status); } &&
-+ { ac_try='test -z "$ac_c_werror_flag"
-+ || test ! -s conftest.err'
-+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-+ (eval $ac_try) 2>&5
-+ ac_status=$?
-+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
-+ (exit $ac_status); }; } &&
-+ { ac_try='test -s conftest$ac_exeext'
-+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-+ (eval $ac_try) 2>&5
-+ ac_status=$?
-+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
-+ (exit $ac_status); }; }; then
- gcc_cv_have_tls=yes
- else
- echo "$as_me: failed program was:" >&5
-@@ -40739,6 +40807,24 @@ gcc_cv_have_tls=no
- fi
- rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-+else
-+ echo "$as_me: failed program was:" >&5
-+sed 's/^/| /' conftest.$ac_ext >&5
-+
-+gcc_cv_have_tls=yes
-+fi
-+rm -f conftest.err conftest.$ac_objext \
-+ conftest$ac_exeext conftest.$ac_ext
-+ CFLAGS="$chktls_save_CFLAGS"
-+ LDFLAGS="$chktls_save_LDFLAGS"
-+else
-+ echo "$as_me: failed program was:" >&5
-+sed 's/^/| /' conftest.$ac_ext >&5
-+
-+gcc_cv_have_tls=no
-+fi
-+rm -f conftest.err conftest.$ac_objext \
-+ conftest$ac_exeext conftest.$ac_ext
-
-
- else
-@@ -76926,6 +77012,74 @@ if { (eval echo "$as_me:$LINENO: \"$ac_l
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
-+ chktls_save_LDFLAGS="$LDFLAGS"
-+ case $host in
-+ *-*-linux*)
-+ LDFLAGS="-shared -Wl,--no-undefined $LDFLAGS"
-+ ;;
-+ esac
-+ chktls_save_CFLAGS="$CFLAGS"
-+ CFLAGS="-fPIC $CFLAGS"
-+ if test x$gcc_no_link = xyes; then
-+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
-+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
-+ { (exit 1); exit 1; }; }
-+fi
-+cat >conftest.$ac_ext <<_ACEOF
-+int f() { return 0; }
-+_ACEOF
-+rm -f conftest.$ac_objext conftest$ac_exeext
-+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-+ (eval $ac_link) 2>conftest.er1
-+ ac_status=$?
-+ grep -v '^ *+' conftest.er1 >conftest.err
-+ rm -f conftest.er1
-+ cat conftest.err >&5
-+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
-+ (exit $ac_status); } &&
-+ { ac_try='test -z "$ac_c_werror_flag"
-+ || test ! -s conftest.err'
-+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-+ (eval $ac_try) 2>&5
-+ ac_status=$?
-+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
-+ (exit $ac_status); }; } &&
-+ { ac_try='test -s conftest$ac_exeext'
-+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-+ (eval $ac_try) 2>&5
-+ ac_status=$?
-+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
-+ (exit $ac_status); }; }; then
-+ if test x$gcc_no_link = xyes; then
-+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
-+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
-+ { (exit 1); exit 1; }; }
-+fi
-+cat >conftest.$ac_ext <<_ACEOF
-+__thread int a; int b; int f() { return a = b; }
-+_ACEOF
-+rm -f conftest.$ac_objext conftest$ac_exeext
-+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-+ (eval $ac_link) 2>conftest.er1
-+ ac_status=$?
-+ grep -v '^ *+' conftest.er1 >conftest.err
-+ rm -f conftest.er1
-+ cat conftest.err >&5
-+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
-+ (exit $ac_status); } &&
-+ { ac_try='test -z "$ac_c_werror_flag"
-+ || test ! -s conftest.err'
-+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-+ (eval $ac_try) 2>&5
-+ ac_status=$?
-+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
-+ (exit $ac_status); }; } &&
-+ { ac_try='test -s conftest$ac_exeext'
-+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-+ (eval $ac_try) 2>&5
-+ ac_status=$?
-+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
-+ (exit $ac_status); }; }; then
- gcc_cv_have_tls=yes
- else
- echo "$as_me: failed program was:" >&5
-@@ -76935,6 +77089,24 @@ gcc_cv_have_tls=no
- fi
- rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-+else
-+ echo "$as_me: failed program was:" >&5
-+sed 's/^/| /' conftest.$ac_ext >&5
-+
-+gcc_cv_have_tls=yes
-+fi
-+rm -f conftest.err conftest.$ac_objext \
-+ conftest$ac_exeext conftest.$ac_ext
-+ CFLAGS="$chktls_save_CFLAGS"
-+ LDFLAGS="$chktls_save_LDFLAGS"
-+else
-+ echo "$as_me: failed program was:" >&5
-+sed 's/^/| /' conftest.$ac_ext >&5
-+
-+gcc_cv_have_tls=no
-+fi
-+rm -f conftest.err conftest.$ac_objext \
-+ conftest$ac_exeext conftest.$ac_ext
-
-
- else
-@@ -94541,6 +94713,74 @@ if { (eval echo "$as_me:$LINENO: \"$ac_l
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
-+ chktls_save_LDFLAGS="$LDFLAGS"
-+ case $host in
-+ *-*-linux*)
-+ LDFLAGS="-shared -Wl,--no-undefined $LDFLAGS"
-+ ;;
-+ esac
-+ chktls_save_CFLAGS="$CFLAGS"
-+ CFLAGS="-fPIC $CFLAGS"
-+ if test x$gcc_no_link = xyes; then
-+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
-+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
-+ { (exit 1); exit 1; }; }
-+fi
-+cat >conftest.$ac_ext <<_ACEOF
-+int f() { return 0; }
-+_ACEOF
-+rm -f conftest.$ac_objext conftest$ac_exeext
-+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-+ (eval $ac_link) 2>conftest.er1
-+ ac_status=$?
-+ grep -v '^ *+' conftest.er1 >conftest.err
-+ rm -f conftest.er1
-+ cat conftest.err >&5
-+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
-+ (exit $ac_status); } &&
-+ { ac_try='test -z "$ac_c_werror_flag"
-+ || test ! -s conftest.err'
-+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-+ (eval $ac_try) 2>&5
-+ ac_status=$?
-+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
-+ (exit $ac_status); }; } &&
-+ { ac_try='test -s conftest$ac_exeext'
-+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-+ (eval $ac_try) 2>&5
-+ ac_status=$?
-+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
-+ (exit $ac_status); }; }; then
-+ if test x$gcc_no_link = xyes; then
-+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
-+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
-+ { (exit 1); exit 1; }; }
-+fi
-+cat >conftest.$ac_ext <<_ACEOF
-+__thread int a; int b; int f() { return a = b; }
-+_ACEOF
-+rm -f conftest.$ac_objext conftest$ac_exeext
-+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-+ (eval $ac_link) 2>conftest.er1
-+ ac_status=$?
-+ grep -v '^ *+' conftest.er1 >conftest.err
-+ rm -f conftest.er1
-+ cat conftest.err >&5
-+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
-+ (exit $ac_status); } &&
-+ { ac_try='test -z "$ac_c_werror_flag"
-+ || test ! -s conftest.err'
-+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-+ (eval $ac_try) 2>&5
-+ ac_status=$?
-+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
-+ (exit $ac_status); }; } &&
-+ { ac_try='test -s conftest$ac_exeext'
-+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-+ (eval $ac_try) 2>&5
-+ ac_status=$?
-+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
-+ (exit $ac_status); }; }; then
- gcc_cv_have_tls=yes
- else
- echo "$as_me: failed program was:" >&5
-@@ -94550,6 +94790,24 @@ gcc_cv_have_tls=no
- fi
- rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-+else
-+ echo "$as_me: failed program was:" >&5
-+sed 's/^/| /' conftest.$ac_ext >&5
-+
-+gcc_cv_have_tls=yes
-+fi
-+rm -f conftest.err conftest.$ac_objext \
-+ conftest$ac_exeext conftest.$ac_ext
-+ CFLAGS="$chktls_save_CFLAGS"
-+ LDFLAGS="$chktls_save_LDFLAGS"
-+else
-+ echo "$as_me: failed program was:" >&5
-+sed 's/^/| /' conftest.$ac_ext >&5
-+
-+gcc_cv_have_tls=no
-+fi
-+rm -f conftest.err conftest.$ac_objext \
-+ conftest$ac_exeext conftest.$ac_ext
-
-
- else
-@@ -114470,7 +114728,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- int
- main ()
- {
-@@ -114534,7 +114793,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- int
- main ()
- {
-@@ -114575,7 +114835,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- int
- main ()
- {
-@@ -114632,7 +114893,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- int
- main ()
- {
-@@ -114673,7 +114935,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- int
- main ()
- {
-@@ -114738,7 +115001,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- int
- main ()
- {
-@@ -114806,7 +115070,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- long longval () { return (long) (sizeof (void *)); }
- unsigned long ulongval () { return (long) (sizeof (void *)); }
- #include <stdio.h>
-@@ -114894,7 +115159,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- int
- main ()
- {
-@@ -114958,7 +115224,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- int
- main ()
- {
-@@ -114999,7 +115266,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- int
- main ()
- {
-@@ -115056,7 +115324,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- int
- main ()
- {
-@@ -115097,7 +115366,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- int
- main ()
- {
-@@ -115162,7 +115432,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- int
- main ()
- {
-@@ -115230,7 +115501,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- long longval () { return (long) (sizeof (long)); }
- unsigned long ulongval () { return (long) (sizeof (long)); }
- #include <stdio.h>
-@@ -115318,7 +115590,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- int
- main ()
- {
-@@ -115382,7 +115655,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- int
- main ()
- {
-@@ -115423,7 +115697,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- int
- main ()
- {
-@@ -115480,7 +115755,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- int
- main ()
- {
-@@ -115521,7 +115797,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- int
- main ()
- {
-@@ -115586,7 +115863,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- int
- main ()
- {
-@@ -115654,7 +115932,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- long longval () { return (long) (sizeof (int)); }
- unsigned long ulongval () { return (long) (sizeof (int)); }
- #include <stdio.h>
-@@ -115738,7 +116017,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- int
- main ()
- {
-@@ -115802,7 +116082,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- int
- main ()
- {
-@@ -115843,7 +116124,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- int
- main ()
- {
-@@ -115900,7 +116182,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- int
- main ()
- {
-@@ -115941,7 +116224,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- int
- main ()
- {
-@@ -116006,7 +116290,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- int
- main ()
- {
-@@ -116074,7 +116359,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- long longval () { return (long) (sizeof (short)); }
- unsigned long ulongval () { return (long) (sizeof (short)); }
- #include <stdio.h>
-@@ -116158,7 +116444,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- int
- main ()
- {
-@@ -116222,7 +116509,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- int
- main ()
- {
-@@ -116263,7 +116551,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- int
- main ()
- {
-@@ -116320,7 +116609,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- int
- main ()
- {
-@@ -116361,7 +116651,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- int
- main ()
- {
-@@ -116426,7 +116717,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- int
- main ()
- {
-@@ -116494,7 +116786,8 @@ _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h. */
--$ac_includes_default
-+/* no standard headers */
-+
- long longval () { return (long) (sizeof (char)); }
- unsigned long ulongval () { return (long) (sizeof (char)); }
- #include <stdio.h>
-@@ -118004,6 +118297,24 @@ ABI_TWEAKS_SRCDIR=config/${abi_tweaks_di
-
-
-
-+# For SymbianOS, we use a highly cut-down libsupc++. This lets us
-+# conditionalise libsupc++'s Makefile.am to include only the necessary sources.
-+case "$target" in
-+ *arm*-symbianelf)
-+ LIBSUPCXX_PRONLY=yes;;
-+ *);;
-+esac
-+
-+
-+if test x$LIBSUPCXX_PRONLY = xyes; then
-+ LIBSUPCXX_PRONLY_TRUE=
-+ LIBSUPCXX_PRONLY_FALSE='#'
-+else
-+ LIBSUPCXX_PRONLY_TRUE='#'
-+ LIBSUPCXX_PRONLY_FALSE=
-+fi
-+
-+
- # Determine cross-compile flags and AM_CONDITIONALs.
- #AC_SUBST(GLIBCXX_IS_NATIVE)
- #AM_CONDITIONAL(CANADIAN, test $CANADIAN = yes)
-@@ -118582,6 +118893,13 @@ echo "$as_me: error: conditional \"GLIBC
- Usually this means the macro was only invoked conditionally." >&2;}
- { (exit 1); exit 1; }; }
- fi
-+if test -z "${LIBSUPCXX_PRONLY_TRUE}" && test -z "${LIBSUPCXX_PRONLY_FALSE}"; then
-+ { { echo "$as_me:$LINENO: error: conditional \"LIBSUPCXX_PRONLY\" was never defined.
-+Usually this means the macro was only invoked conditionally." >&5
-+echo "$as_me: error: conditional \"LIBSUPCXX_PRONLY\" was never defined.
-+Usually this means the macro was only invoked conditionally." >&2;}
-+ { (exit 1); exit 1; }; }
-+fi
-
- : ${CONFIG_STATUS=./config.status}
- ac_clean_files_save=$ac_clean_files
-@@ -119667,6 +119985,8 @@ s,@CPU_DEFINES_SRCDIR@,$CPU_DEFINES_SRCD
- s,@ABI_TWEAKS_SRCDIR@,$ABI_TWEAKS_SRCDIR,;t t
- s,@OS_INC_SRCDIR@,$OS_INC_SRCDIR,;t t
- s,@ERROR_CONSTANTS_SRCDIR@,$ERROR_CONSTANTS_SRCDIR,;t t
-+s,@LIBSUPCXX_PRONLY_TRUE@,$LIBSUPCXX_PRONLY_TRUE,;t t
-+s,@LIBSUPCXX_PRONLY_FALSE@,$LIBSUPCXX_PRONLY_FALSE,;t t
- s,@glibcxx_prefixdir@,$glibcxx_prefixdir,;t t
- s,@gxx_include_dir@,$gxx_include_dir,;t t
- s,@glibcxx_toolexecdir@,$glibcxx_toolexecdir,;t t
---- a/libstdc++-v3/configure.ac
-+++ b/libstdc++-v3/configure.ac
-@@ -329,6 +329,15 @@ AC_SUBST(OS_INC_SRCDIR)
- AC_SUBST(ERROR_CONSTANTS_SRCDIR)
-
-
-+# For SymbianOS, we use a highly cut-down libsupc++. This lets us
-+# conditionalise libsupc++'s Makefile.am to include only the necessary sources.
-+case "$target" in
-+ *arm*-symbianelf)
-+ LIBSUPCXX_PRONLY=yes;;
-+ *);;
-+esac
-+AM_CONDITIONAL(LIBSUPCXX_PRONLY, test x$LIBSUPCXX_PRONLY = xyes)
-+
- # Determine cross-compile flags and AM_CONDITIONALs.
- #AC_SUBST(GLIBCXX_IS_NATIVE)
- #AM_CONDITIONAL(CANADIAN, test $CANADIAN = yes)
---- a/libstdc++-v3/doc/Makefile.in
-+++ b/libstdc++-v3/doc/Makefile.in
-@@ -161,6 +161,8 @@ LIBICONV = @LIBICONV@
- LIBOBJS = @LIBOBJS@
- LIBS = @LIBS@
- LIBSUPCXX_PICFLAGS = @LIBSUPCXX_PICFLAGS@
-+LIBSUPCXX_PRONLY_FALSE = @LIBSUPCXX_PRONLY_FALSE@
-+LIBSUPCXX_PRONLY_TRUE = @LIBSUPCXX_PRONLY_TRUE@
- LIBTOOL = @LIBTOOL@
- LIPO = @LIPO@
- LN_S = @LN_S@
---- a/libstdc++-v3/include/Makefile.am
-+++ b/libstdc++-v3/include/Makefile.am
-@@ -1125,8 +1125,14 @@ ${pch3_output}: ${pch3_source} ${pch2_ou
- if GLIBCXX_HOSTED
- install-data-local: install-headers
- else
-+if LIBSUPCXX_PRONLY
-+# Don't install any headers if we're only putting eh_personality in
-+# libsupc++ (e.g. on SymbianOS)
-+install-data-local:
-+else
- install-data-local: install-freestanding-headers
- endif
-+endif
-
- # This is a subset of the full install-headers rule. We only need <cstddef>,
- # <limits>, <cstdlib>, <cstdarg>, <new>, <typeinfo>, <exception>, and any
---- a/libstdc++-v3/include/Makefile.in
-+++ b/libstdc++-v3/include/Makefile.in
-@@ -161,6 +161,8 @@ LIBICONV = @LIBICONV@
- LIBOBJS = @LIBOBJS@
- LIBS = @LIBS@
- LIBSUPCXX_PICFLAGS = @LIBSUPCXX_PICFLAGS@
-+LIBSUPCXX_PRONLY_FALSE = @LIBSUPCXX_PRONLY_FALSE@
-+LIBSUPCXX_PRONLY_TRUE = @LIBSUPCXX_PRONLY_TRUE@
- LIBTOOL = @LIBTOOL@
- LIPO = @LIPO@
- LN_S = @LN_S@
-@@ -1527,7 +1529,10 @@ ${pch3_output}: ${pch3_source} ${pch2_ou
- # the rest are taken from the original source tree.
-
- @GLIBCXX_HOSTED_TRUE@install-data-local: install-headers
--@GLIBCXX_HOSTED_FALSE@install-data-local: install-freestanding-headers
-+# Don't install any headers if we're only putting eh_personality in
-+# libsupc++ (e.g. on SymbianOS)
-+@GLIBCXX_HOSTED_FALSE@@LIBSUPCXX_PRONLY_TRUE@install-data-local:
-+@GLIBCXX_HOSTED_FALSE@@LIBSUPCXX_PRONLY_FALSE@install-data-local: install-freestanding-headers
-
- # This is a subset of the full install-headers rule. We only need <cstddef>,
- # <limits>, <cstdlib>, <cstdarg>, <new>, <typeinfo>, <exception>, and any
---- a/libstdc++-v3/include/c_global/cwchar
-+++ b/libstdc++-v3/include/c_global/cwchar
-@@ -156,14 +156,18 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
- using ::mbsrtowcs;
- using ::putwc;
- using ::putwchar;
-+#ifndef _GLIBCXX_HAVE_BROKEN_VSWPRINTF
- using ::swprintf;
-+#endif
- using ::swscanf;
- using ::ungetwc;
- using ::vfwprintf;
- #if _GLIBCXX_HAVE_VFWSCANF
- using ::vfwscanf;
- #endif
-+#ifndef _GLIBCXX_HAVE_BROKEN_VSWPRINTF
- using ::vswprintf;
-+#endif
- #if _GLIBCXX_HAVE_VSWSCANF
- using ::vswscanf;
- #endif
---- a/libstdc++-v3/libsupc++/Makefile.am
-+++ b/libstdc++-v3/libsupc++/Makefile.am
-@@ -30,6 +30,11 @@ toolexeclib_LTLIBRARIES = libsupc++.la
- # 2) integrated libsupc++convenience.la that is to be a part of libstdc++.a
- noinst_LTLIBRARIES = libsupc++convenience.la
-
-+if LIBSUPCXX_PRONLY
-+sources = \
-+ eh_personality.cc
-+
-+else
-
- headers = \
- exception new typeinfo cxxabi.h cxxabi-forced.h exception_defines.h \
-@@ -84,6 +89,7 @@ sources = \
- vec.cc \
- vmi_class_type_info.cc \
- vterminate.cc
-+endif
-
- libsupc___la_SOURCES = $(sources) $(c_sources)
- libsupc__convenience_la_SOURCES = $(sources) $(c_sources)
---- a/libstdc++-v3/libsupc++/Makefile.in
-+++ b/libstdc++-v3/libsupc++/Makefile.in
-@@ -38,7 +38,7 @@ POST_UNINSTALL = :
- build_triplet = @build@
- host_triplet = @host@
- target_triplet = @target@
--DIST_COMMON = $(glibcxxinstall_HEADERS) $(srcdir)/Makefile.am \
-+DIST_COMMON = $(am__glibcxxinstall_HEADERS_DIST) $(srcdir)/Makefile.am \
- $(srcdir)/Makefile.in $(top_srcdir)/fragment.am
- subdir = libsupc++
- ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-@@ -87,19 +87,29 @@ am__libsupc___la_SOURCES_DIST = array_ty
- pmem_type_info.cc pointer_type_info.cc pure.cc \
- si_class_type_info.cc tinfo.cc tinfo2.cc vec.cc \
- vmi_class_type_info.cc vterminate.cc cp-demangle.c
--am__objects_1 = array_type_info.lo atexit_arm.lo bad_cast.lo \
-- bad_typeid.lo class_type_info.lo del_op.lo del_opnt.lo \
-- del_opv.lo del_opvnt.lo dyncast.lo eh_alloc.lo eh_arm.lo \
-- eh_aux_runtime.lo eh_call.lo eh_catch.lo eh_exception.lo \
-- eh_globals.lo eh_personality.lo eh_ptr.lo eh_term_handler.lo \
-- eh_terminate.lo eh_throw.lo eh_type.lo eh_unex_handler.lo \
-- enum_type_info.lo function_type_info.lo \
-- fundamental_type_info.lo guard.lo new_handler.lo new_op.lo \
-- new_opnt.lo new_opv.lo new_opvnt.lo pbase_type_info.lo \
-- pmem_type_info.lo pointer_type_info.lo pure.lo \
-- si_class_type_info.lo tinfo.lo tinfo2.lo vec.lo \
-- vmi_class_type_info.lo vterminate.lo
--@GLIBCXX_HOSTED_TRUE@am__objects_2 = cp-demangle.lo
-+@LIBSUPCXX_PRONLY_FALSE@am__objects_1 = array_type_info.lo \
-+@LIBSUPCXX_PRONLY_FALSE@ atexit_arm.lo bad_cast.lo \
-+@LIBSUPCXX_PRONLY_FALSE@ bad_typeid.lo class_type_info.lo \
-+@LIBSUPCXX_PRONLY_FALSE@ del_op.lo del_opnt.lo del_opv.lo \
-+@LIBSUPCXX_PRONLY_FALSE@ del_opvnt.lo dyncast.lo eh_alloc.lo \
-+@LIBSUPCXX_PRONLY_FALSE@ eh_arm.lo eh_aux_runtime.lo eh_call.lo \
-+@LIBSUPCXX_PRONLY_FALSE@ eh_catch.lo eh_exception.lo \
-+@LIBSUPCXX_PRONLY_FALSE@ eh_globals.lo eh_personality.lo \
-+@LIBSUPCXX_PRONLY_FALSE@ eh_ptr.lo eh_term_handler.lo \
-+@LIBSUPCXX_PRONLY_FALSE@ eh_terminate.lo eh_throw.lo eh_type.lo \
-+@LIBSUPCXX_PRONLY_FALSE@ eh_unex_handler.lo enum_type_info.lo \
-+@LIBSUPCXX_PRONLY_FALSE@ function_type_info.lo \
-+@LIBSUPCXX_PRONLY_FALSE@ fundamental_type_info.lo guard.lo \
-+@LIBSUPCXX_PRONLY_FALSE@ new_handler.lo new_op.lo new_opnt.lo \
-+@LIBSUPCXX_PRONLY_FALSE@ new_opv.lo new_opvnt.lo \
-+@LIBSUPCXX_PRONLY_FALSE@ pbase_type_info.lo pmem_type_info.lo \
-+@LIBSUPCXX_PRONLY_FALSE@ pointer_type_info.lo pure.lo \
-+@LIBSUPCXX_PRONLY_FALSE@ si_class_type_info.lo tinfo.lo \
-+@LIBSUPCXX_PRONLY_FALSE@ tinfo2.lo vec.lo \
-+@LIBSUPCXX_PRONLY_FALSE@ vmi_class_type_info.lo vterminate.lo
-+@LIBSUPCXX_PRONLY_TRUE@am__objects_1 = eh_personality.lo
-+@GLIBCXX_HOSTED_TRUE@@LIBSUPCXX_PRONLY_FALSE@am__objects_2 = \
-+@GLIBCXX_HOSTED_TRUE@@LIBSUPCXX_PRONLY_FALSE@ cp-demangle.lo
- am_libsupc___la_OBJECTS = $(am__objects_1) $(am__objects_2)
- libsupc___la_OBJECTS = $(am_libsupc___la_OBJECTS)
- libsupc__convenience_la_LIBADD =
-@@ -132,6 +142,9 @@ CXXLD = $(CXX)
- SOURCES = $(libsupc___la_SOURCES) $(libsupc__convenience_la_SOURCES)
- DIST_SOURCES = $(am__libsupc___la_SOURCES_DIST) \
- $(am__libsupc__convenience_la_SOURCES_DIST)
-+am__glibcxxinstall_HEADERS_DIST = exception new typeinfo cxxabi.h \
-+ cxxabi-forced.h exception_defines.h initializer_list \
-+ exception_ptr.h
- glibcxxinstallHEADERS_INSTALL = $(INSTALL_HEADER)
- HEADERS = $(glibcxxinstall_HEADERS)
- ETAGS = etags
-@@ -231,6 +244,8 @@ LIBICONV = @LIBICONV@
- LIBOBJS = @LIBOBJS@
- LIBS = @LIBS@
- LIBSUPCXX_PICFLAGS = @LIBSUPCXX_PICFLAGS@
-+LIBSUPCXX_PRONLY_FALSE = @LIBSUPCXX_PRONLY_FALSE@
-+LIBSUPCXX_PRONLY_TRUE = @LIBSUPCXX_PRONLY_TRUE@
- LIBTOOL = @LIBTOOL@
- LIPO = @LIPO@
- LN_S = @LN_S@
-@@ -365,57 +380,60 @@ AM_CPPFLAGS = $(GLIBCXX_INCLUDES)
- toolexeclib_LTLIBRARIES = libsupc++.la
- # 2) integrated libsupc++convenience.la that is to be a part of libstdc++.a
- noinst_LTLIBRARIES = libsupc++convenience.la
--headers = \
-- exception new typeinfo cxxabi.h cxxabi-forced.h exception_defines.h \
-- initializer_list exception_ptr.h
--
--@GLIBCXX_HOSTED_TRUE@c_sources = \
--@GLIBCXX_HOSTED_TRUE@ cp-demangle.c
--
--sources = \
-- array_type_info.cc \
-- atexit_arm.cc \
-- bad_cast.cc \
-- bad_typeid.cc \
-- class_type_info.cc \
-- del_op.cc \
-- del_opnt.cc \
-- del_opv.cc \
-- del_opvnt.cc \
-- dyncast.cc \
-- eh_alloc.cc \
-- eh_arm.cc \
-- eh_aux_runtime.cc \
-- eh_call.cc \
-- eh_catch.cc \
-- eh_exception.cc \
-- eh_globals.cc \
-- eh_personality.cc \
-- eh_ptr.cc \
-- eh_term_handler.cc \
-- eh_terminate.cc \
-- eh_throw.cc \
-- eh_type.cc \
-- eh_unex_handler.cc \
-- enum_type_info.cc \
-- function_type_info.cc \
-- fundamental_type_info.cc \
-- guard.cc \
-- new_handler.cc \
-- new_op.cc \
-- new_opnt.cc \
-- new_opv.cc \
-- new_opvnt.cc \
-- pbase_type_info.cc \
-- pmem_type_info.cc \
-- pointer_type_info.cc \
-- pure.cc \
-- si_class_type_info.cc \
-- tinfo.cc \
-- tinfo2.cc \
-- vec.cc \
-- vmi_class_type_info.cc \
-- vterminate.cc
-+@LIBSUPCXX_PRONLY_FALSE@sources = \
-+@LIBSUPCXX_PRONLY_FALSE@ array_type_info.cc \
-+@LIBSUPCXX_PRONLY_FALSE@ atexit_arm.cc \
-+@LIBSUPCXX_PRONLY_FALSE@ bad_cast.cc \
-+@LIBSUPCXX_PRONLY_FALSE@ bad_typeid.cc \
-+@LIBSUPCXX_PRONLY_FALSE@ class_type_info.cc \
-+@LIBSUPCXX_PRONLY_FALSE@ del_op.cc \
-+@LIBSUPCXX_PRONLY_FALSE@ del_opnt.cc \
-+@LIBSUPCXX_PRONLY_FALSE@ del_opv.cc \
-+@LIBSUPCXX_PRONLY_FALSE@ del_opvnt.cc \
-+@LIBSUPCXX_PRONLY_FALSE@ dyncast.cc \
-+@LIBSUPCXX_PRONLY_FALSE@ eh_alloc.cc \
-+@LIBSUPCXX_PRONLY_FALSE@ eh_arm.cc \
-+@LIBSUPCXX_PRONLY_FALSE@ eh_aux_runtime.cc \
-+@LIBSUPCXX_PRONLY_FALSE@ eh_call.cc \
-+@LIBSUPCXX_PRONLY_FALSE@ eh_catch.cc \
-+@LIBSUPCXX_PRONLY_FALSE@ eh_exception.cc \
-+@LIBSUPCXX_PRONLY_FALSE@ eh_globals.cc \
-+@LIBSUPCXX_PRONLY_FALSE@ eh_personality.cc \
-+@LIBSUPCXX_PRONLY_FALSE@ eh_ptr.cc \
-+@LIBSUPCXX_PRONLY_FALSE@ eh_term_handler.cc \
-+@LIBSUPCXX_PRONLY_FALSE@ eh_terminate.cc \
-+@LIBSUPCXX_PRONLY_FALSE@ eh_throw.cc \
-+@LIBSUPCXX_PRONLY_FALSE@ eh_type.cc \
-+@LIBSUPCXX_PRONLY_FALSE@ eh_unex_handler.cc \
-+@LIBSUPCXX_PRONLY_FALSE@ enum_type_info.cc \
-+@LIBSUPCXX_PRONLY_FALSE@ function_type_info.cc \
-+@LIBSUPCXX_PRONLY_FALSE@ fundamental_type_info.cc \
-+@LIBSUPCXX_PRONLY_FALSE@ guard.cc \
-+@LIBSUPCXX_PRONLY_FALSE@ new_handler.cc \
-+@LIBSUPCXX_PRONLY_FALSE@ new_op.cc \
-+@LIBSUPCXX_PRONLY_FALSE@ new_opnt.cc \
-+@LIBSUPCXX_PRONLY_FALSE@ new_opv.cc \
-+@LIBSUPCXX_PRONLY_FALSE@ new_opvnt.cc \
-+@LIBSUPCXX_PRONLY_FALSE@ pbase_type_info.cc \
-+@LIBSUPCXX_PRONLY_FALSE@ pmem_type_info.cc \
-+@LIBSUPCXX_PRONLY_FALSE@ pointer_type_info.cc \
-+@LIBSUPCXX_PRONLY_FALSE@ pure.cc \
-+@LIBSUPCXX_PRONLY_FALSE@ si_class_type_info.cc \
-+@LIBSUPCXX_PRONLY_FALSE@ tinfo.cc \
-+@LIBSUPCXX_PRONLY_FALSE@ tinfo2.cc \
-+@LIBSUPCXX_PRONLY_FALSE@ vec.cc \
-+@LIBSUPCXX_PRONLY_FALSE@ vmi_class_type_info.cc \
-+@LIBSUPCXX_PRONLY_FALSE@ vterminate.cc
-+
-+@LIBSUPCXX_PRONLY_TRUE@sources = \
-+@LIBSUPCXX_PRONLY_TRUE@ eh_personality.cc
-+
-+@LIBSUPCXX_PRONLY_FALSE@headers = \
-+@LIBSUPCXX_PRONLY_FALSE@ exception new typeinfo cxxabi.h cxxabi-forced.h exception_defines.h \
-+@LIBSUPCXX_PRONLY_FALSE@ initializer_list exception_ptr.h
-+
-+@GLIBCXX_HOSTED_TRUE@@LIBSUPCXX_PRONLY_FALSE@c_sources = \
-+@GLIBCXX_HOSTED_TRUE@@LIBSUPCXX_PRONLY_FALSE@ cp-demangle.c
-
- libsupc___la_SOURCES = $(sources) $(c_sources)
- libsupc__convenience_la_SOURCES = $(sources) $(c_sources)
---- a/libstdc++-v3/libsupc++/eh_arm.cc
-+++ b/libstdc++-v3/libsupc++/eh_arm.cc
-@@ -38,7 +38,7 @@ using namespace __cxxabiv1;
- extern "C" __cxa_type_match_result
- __cxa_type_match(_Unwind_Exception* ue_header,
- const std::type_info* catch_type,
-- bool is_reference __attribute__((__unused__)),
-+ bool is_reference,
- void** thrown_ptr_p)
- {
- bool forced_unwind = __is_gxx_forced_unwind_class(ue_header->exception_class);
-@@ -68,11 +68,11 @@ __cxa_type_match(_Unwind_Exception* ue_h
- if (throw_type->__is_pointer_p())
- thrown_ptr = *(void**) thrown_ptr;
-
-- if (catch_type->__do_catch(throw_type, &thrown_ptr, 1))
-+ if (catch_type->__do_catch (throw_type, &thrown_ptr, 1 + is_reference * 2))
- {
- *thrown_ptr_p = thrown_ptr;
-
-- if (typeid(*catch_type) == typeid (typeid(void*)))
-+ if (typeid (*catch_type) == typeid (typeid(void*)))
- {
- const __pointer_type_info *catch_pointer_type =
- static_cast<const __pointer_type_info *> (catch_type);
---- a/libstdc++-v3/libsupc++/eh_personality.cc
-+++ b/libstdc++-v3/libsupc++/eh_personality.cc
-@@ -89,20 +89,22 @@ parse_lsda_header (_Unwind_Context *cont
- // Return an element from a type table.
-
- static const std::type_info*
--get_ttype_entry(lsda_header_info* info, _uleb128_t i)
-+get_ttype_entry(lsda_header_info* info, _uleb128_t i, bool &is_ref)
- {
- _Unwind_Ptr ptr;
-
- ptr = (_Unwind_Ptr) (info->TType - (i * 4));
- ptr = _Unwind_decode_target2(ptr);
-
-- return reinterpret_cast<const std::type_info *>(ptr);
-+ is_ref = ptr & 1;
-+
-+ return reinterpret_cast<const std::type_info *>(ptr & ~1);
- }
-
- // The ABI provides a routine for matching exception object types.
- typedef _Unwind_Control_Block _throw_typet;
--#define get_adjusted_ptr(catch_type, throw_type, thrown_ptr_p) \
-- (__cxa_type_match (throw_type, catch_type, false, thrown_ptr_p) \
-+#define get_adjusted_ptr(catch_type, throw_type, is_ref, thrown_ptr_p) \
-+ (__cxa_type_match (throw_type, catch_type, is_ref, thrown_ptr_p) \
- != ctm_failed)
-
- // Return true if THROW_TYPE matches one if the filter types.
-@@ -118,6 +120,7 @@ check_exception_spec(lsda_header_info* i
- {
- const std::type_info* catch_type;
- _uleb128_t tmp;
-+ bool is_ref;
-
- tmp = *e;
-
-@@ -129,13 +132,14 @@ check_exception_spec(lsda_header_info* i
- tmp = _Unwind_decode_target2((_Unwind_Word) e);
-
- // Match a ttype entry.
-- catch_type = reinterpret_cast<const std::type_info*>(tmp);
-+ is_ref = tmp & 1;
-+ catch_type = reinterpret_cast<const std::type_info*>(tmp & ~1);
-
- // ??? There is currently no way to ask the RTTI code about the
- // relationship between two types without reference to a specific
- // object. There should be; then we wouldn't need to mess with
- // thrown_ptr here.
-- if (get_adjusted_ptr(catch_type, throw_type, &thrown_ptr))
-+ if (get_adjusted_ptr(catch_type, throw_type, is_ref, &thrown_ptr))
- return true;
-
- // Advance to the next entry.
-@@ -207,7 +211,7 @@ typedef const std::type_info _throw_type
- // Return an element from a type table.
-
- static const std::type_info *
--get_ttype_entry (lsda_header_info *info, _uleb128_t i)
-+get_ttype_entry (lsda_header_info *info, _uleb128_t i, bool &is_ref)
- {
- _Unwind_Ptr ptr;
-
-@@ -215,7 +219,9 @@ get_ttype_entry (lsda_header_info *info,
- read_encoded_value_with_base (info->ttype_encoding, info->ttype_base,
- info->TType - i, &ptr);
-
-- return reinterpret_cast<const std::type_info *>(ptr);
-+ is_ref = ptr & 1;
-+
-+ return reinterpret_cast<const std::type_info *>(ptr & ~1);
- }
-
- // Given the thrown type THROW_TYPE, pointer to a variable containing a
-@@ -226,6 +232,7 @@ get_ttype_entry (lsda_header_info *info,
- static bool
- get_adjusted_ptr (const std::type_info *catch_type,
- const std::type_info *throw_type,
-+ bool is_ref,
- void **thrown_ptr_p)
- {
- void *thrown_ptr = *thrown_ptr_p;
-@@ -237,7 +244,7 @@ get_adjusted_ptr (const std::type_info *
- if (throw_type->__is_pointer_p ())
- thrown_ptr = *(void **) thrown_ptr;
-
-- if (catch_type->__do_catch (throw_type, &thrown_ptr, 1))
-+ if (catch_type->__do_catch (throw_type, &thrown_ptr, 1 + is_ref * 2))
- {
- *thrown_ptr_p = thrown_ptr;
- return true;
-@@ -267,13 +274,15 @@ check_exception_spec(lsda_header_info* i
- return false;
-
- // Match a ttype entry.
-- catch_type = get_ttype_entry (info, tmp);
-+ bool is_ref;
-+
-+ catch_type = get_ttype_entry (info, tmp, is_ref);
-
- // ??? There is currently no way to ask the RTTI code about the
- // relationship between two types without reference to a specific
- // object. There should be; then we wouldn't need to mess with
- // thrown_ptr here.
-- if (get_adjusted_ptr (catch_type, throw_type, &thrown_ptr))
-+ if (get_adjusted_ptr (catch_type, throw_type, is_ref, &thrown_ptr))
- return true;
- }
- }
-@@ -582,14 +591,16 @@ PERSONALITY_FUNCTION (int version,
- else if (ar_filter > 0)
- {
- // Positive filter values are handlers.
-- catch_type = get_ttype_entry (&info, ar_filter);
-+ bool is_ref;
-+
-+ catch_type = get_ttype_entry (&info, ar_filter, is_ref);
-
- // Null catch type is a catch-all handler; we can catch foreign
- // exceptions with this. Otherwise we must match types.
- if (! catch_type
- || (throw_type
- && get_adjusted_ptr (catch_type, throw_type,
-- &thrown_ptr)))
-+ is_ref, &thrown_ptr)))
- {
- saw_handler = true;
- break;
---- a/libstdc++-v3/po/Makefile.in
-+++ b/libstdc++-v3/po/Makefile.in
-@@ -161,6 +161,8 @@ LIBICONV = @LIBICONV@
- LIBOBJS = @LIBOBJS@
- LIBS = @LIBS@
- LIBSUPCXX_PICFLAGS = @LIBSUPCXX_PICFLAGS@
-+LIBSUPCXX_PRONLY_FALSE = @LIBSUPCXX_PRONLY_FALSE@
-+LIBSUPCXX_PRONLY_TRUE = @LIBSUPCXX_PRONLY_TRUE@
- LIBTOOL = @LIBTOOL@
- LIPO = @LIPO@
- LN_S = @LN_S@
---- a/libstdc++-v3/src/Makefile.in
-+++ b/libstdc++-v3/src/Makefile.in
-@@ -221,6 +221,8 @@ LIBICONV = @LIBICONV@
- LIBOBJS = @LIBOBJS@
- LIBS = @LIBS@
- LIBSUPCXX_PICFLAGS = @LIBSUPCXX_PICFLAGS@
-+LIBSUPCXX_PRONLY_FALSE = @LIBSUPCXX_PRONLY_FALSE@
-+LIBSUPCXX_PRONLY_TRUE = @LIBSUPCXX_PRONLY_TRUE@
- LIBTOOL = @LIBTOOL@
- LIPO = @LIPO@
- LN_S = @LN_S@
---- a/libstdc++-v3/testsuite/21_strings/basic_string/numeric_conversions/wchar_t/stod.cc
-+++ b/libstdc++-v3/testsuite/21_strings/basic_string/numeric_conversions/wchar_t/stod.cc
-@@ -1,4 +1,5 @@
- // { dg-options "-std=gnu++0x" }
-+// { dg-require-string-conversions "" }
- // 2008-06-15 Paolo Carlini <paolo.carlini@oracle.com>
-
- // Copyright (C) 2008, 2009 Free Software Foundation, Inc.
---- a/libstdc++-v3/testsuite/21_strings/basic_string/numeric_conversions/wchar_t/stof.cc
-+++ b/libstdc++-v3/testsuite/21_strings/basic_string/numeric_conversions/wchar_t/stof.cc
-@@ -1,4 +1,5 @@
- // { dg-options "-std=gnu++0x" }
-+// { dg-require-string-conversions "" }
- // 2008-06-15 Paolo Carlini <paolo.carlini@oracle.com>
-
- // Copyright (C) 2008, 2009 Free Software Foundation, Inc.
---- a/libstdc++-v3/testsuite/21_strings/basic_string/numeric_conversions/wchar_t/stoi.cc
-+++ b/libstdc++-v3/testsuite/21_strings/basic_string/numeric_conversions/wchar_t/stoi.cc
-@@ -1,4 +1,5 @@
- // { dg-options "-std=gnu++0x" }
-+// { dg-require-string-conversions "" }
- // 2008-06-15 Paolo Carlini <paolo.carlini@oracle.com>
-
- // Copyright (C) 2008, 2009 Free Software Foundation, Inc.
---- a/libstdc++-v3/testsuite/21_strings/basic_string/numeric_conversions/wchar_t/stol.cc
-+++ b/libstdc++-v3/testsuite/21_strings/basic_string/numeric_conversions/wchar_t/stol.cc
-@@ -1,4 +1,5 @@
- // { dg-options "-std=gnu++0x" }
-+// { dg-require-string-conversions "" }
- // 2008-06-15 Paolo Carlini <paolo.carlini@oracle.com>
-
- // Copyright (C) 2008, 2009 Free Software Foundation, Inc.
---- a/libstdc++-v3/testsuite/21_strings/basic_string/numeric_conversions/wchar_t/stold.cc
-+++ b/libstdc++-v3/testsuite/21_strings/basic_string/numeric_conversions/wchar_t/stold.cc
-@@ -1,4 +1,5 @@
- // { dg-options "-std=gnu++0x" }
-+// { dg-require-string-conversions "" }
- // 2008-06-15 Paolo Carlini <paolo.carlini@oracle.com>
-
- // Copyright (C) 2008, 2009 Free Software Foundation, Inc.
---- a/libstdc++-v3/testsuite/21_strings/basic_string/numeric_conversions/wchar_t/stoll.cc
-+++ b/libstdc++-v3/testsuite/21_strings/basic_string/numeric_conversions/wchar_t/stoll.cc
-@@ -1,4 +1,5 @@
- // { dg-options "-std=gnu++0x" }
-+// { dg-require-string-conversions "" }
- // 2008-06-15 Paolo Carlini <paolo.carlini@oracle.com>
-
- // Copyright (C) 2008, 2009 Free Software Foundation, Inc.
---- a/libstdc++-v3/testsuite/21_strings/basic_string/numeric_conversions/wchar_t/stoul.cc
-+++ b/libstdc++-v3/testsuite/21_strings/basic_string/numeric_conversions/wchar_t/stoul.cc
-@@ -1,4 +1,5 @@
- // { dg-options "-std=gnu++0x" }
-+// { dg-require-string-conversions "" }
- // 2008-06-15 Paolo Carlini <paolo.carlini@oracle.com>
-
- // Copyright (C) 2008, 2009 Free Software Foundation, Inc.
---- a/libstdc++-v3/testsuite/21_strings/basic_string/numeric_conversions/wchar_t/stoull.cc
-+++ b/libstdc++-v3/testsuite/21_strings/basic_string/numeric_conversions/wchar_t/stoull.cc
-@@ -1,4 +1,5 @@
- // { dg-options "-std=gnu++0x" }
-+// { dg-require-string-conversions "" }
- // 2008-06-15 Paolo Carlini <paolo.carlini@oracle.com>
-
- // Copyright (C) 2008, 2009 Free Software Foundation, Inc.
---- a/libstdc++-v3/testsuite/21_strings/basic_string/numeric_conversions/wchar_t/to_wstring.cc
-+++ b/libstdc++-v3/testsuite/21_strings/basic_string/numeric_conversions/wchar_t/to_wstring.cc
-@@ -1,4 +1,5 @@
- // { dg-options "-std=gnu++0x" }
-+// { dg-require-string-conversions "" }
- // 2008-06-15 Paolo Carlini <paolo.carlini@oracle.com>
-
- // Copyright (C) 2008, 2009 Free Software Foundation, Inc.
---- a/libstdc++-v3/testsuite/21_strings/headers/cwchar/functions_std.cc
-+++ b/libstdc++-v3/testsuite/21_strings/headers/cwchar/functions_std.cc
-@@ -1,5 +1,6 @@
- // { dg-do compile }
- // { dg-require-c-std "" }
-+// { dg-require-swprintf "" }
-
- // Copyright (C) 2007, 2009 Free Software Foundation, Inc.
- //
---- a/libstdc++-v3/testsuite/27_io/basic_filebuf/seekoff/char/1-io.cc
-+++ b/libstdc++-v3/testsuite/27_io/basic_filebuf/seekoff/char/1-io.cc
-@@ -20,6 +20,7 @@
- // 27.8.1.4 Overridden virtual functions
-
- // { dg-require-fileio "" }
-+// { dg-require-binary-io "" }
-
- #include <fstream>
- #include <testsuite_hooks.h>
---- a/libstdc++-v3/testsuite/27_io/basic_filebuf/seekoff/char/2-io.cc
-+++ b/libstdc++-v3/testsuite/27_io/basic_filebuf/seekoff/char/2-io.cc
-@@ -20,6 +20,7 @@
- // 27.8.1.4 Overridden virtual functions
-
- // { dg-require-fileio "" }
-+// { dg-require-binary-io "" }
-
- #include <fstream>
- #include <testsuite_hooks.h>
---- a/libstdc++-v3/testsuite/27_io/basic_filebuf/sgetn/char/1-in.cc
-+++ b/libstdc++-v3/testsuite/27_io/basic_filebuf/sgetn/char/1-in.cc
-@@ -24,6 +24,7 @@
- // 27.8.1.4 Overridden virtual functions
-
- // { dg-require-fileio "" }
-+// { dg-require-binary-io "" }
-
- #include <fstream>
- #include <testsuite_hooks.h>
---- a/libstdc++-v3/testsuite/27_io/basic_filebuf/sgetn/char/1-io.cc
-+++ b/libstdc++-v3/testsuite/27_io/basic_filebuf/sgetn/char/1-io.cc
-@@ -24,6 +24,7 @@
- // 27.8.1.4 Overridden virtual functions
-
- // { dg-require-fileio "" }
-+// { dg-require-binary-io "" }
-
- #include <fstream>
- #include <testsuite_hooks.h>
---- a/libstdc++-v3/testsuite/27_io/basic_filebuf/sgetn/char/2-in.cc
-+++ b/libstdc++-v3/testsuite/27_io/basic_filebuf/sgetn/char/2-in.cc
-@@ -24,6 +24,7 @@
- // 27.8.1.4 Overridden virtual functions
-
- // { dg-require-fileio "" }
-+// { dg-require-binary-io "" }
-
- #include <fstream>
- #include <testsuite_hooks.h>
---- a/libstdc++-v3/testsuite/27_io/basic_filebuf/sgetn/char/2-io.cc
-+++ b/libstdc++-v3/testsuite/27_io/basic_filebuf/sgetn/char/2-io.cc
-@@ -24,6 +24,7 @@
- // 27.8.1.4 Overridden virtual functions
-
- // { dg-require-fileio "" }
-+// { dg-require-binary-io "" }
-
- #include <fstream>
- #include <testsuite_hooks.h>
---- a/libstdc++-v3/testsuite/27_io/basic_filebuf/underflow/wchar_t/11603.cc
-+++ b/libstdc++-v3/testsuite/27_io/basic_filebuf/underflow/wchar_t/11603.cc
-@@ -17,6 +17,8 @@
-
- // 27.8.1.4 Overridden virtual functions
-
-+// { dg-require-binary-io "" }
-+
- #include <fstream>
- #include <locale>
- #include <testsuite_hooks.h>
---- a/libstdc++-v3/testsuite/27_io/basic_istream/readsome/char/6746-2.cc
-+++ b/libstdc++-v3/testsuite/27_io/basic_istream/readsome/char/6746-2.cc
-@@ -26,6 +26,7 @@
- // @diff@ %-*.tst %-*.txt
-
- // { dg-require-fileio "" }
-+// { dg-require-binary-io "" }
-
- #include <istream>
- #include <fstream>
---- a/libstdc++-v3/testsuite/27_io/basic_istream/readsome/wchar_t/6746-2.cc
-+++ b/libstdc++-v3/testsuite/27_io/basic_istream/readsome/wchar_t/6746-2.cc
-@@ -19,6 +19,8 @@
- // causes "in_avail" to return an incorrect value.
- // { dg-do run { xfail arm*-*-elf arm*-*-eabi } }
-
-+// { dg-require-binary-io "" }
-+
- // 27.6.1.3 unformatted input functions
- // @require@ %-*.tst %-*.txt
- // @diff@ %-*.tst %-*.txt
---- a/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_arithmetic/wchar_t/4402.cc
-+++ b/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_arithmetic/wchar_t/4402.cc
-@@ -1,3 +1,5 @@
-+// { dg-require-swprintf "" }
-+
- // Copyright (C) 2005, 2006, 2007, 2009 Free Software Foundation, Inc.
- //
- // This file is part of the GNU ISO C++ Library. This library is free
---- a/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_other/wchar_t/error_code.cc
-+++ b/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_other/wchar_t/error_code.cc
-@@ -1,4 +1,5 @@
- // { dg-options "-std=gnu++0x" }
-+// { dg-require-swprintf "" }
-
- // Copyright (C) 2007, 2008, 2009 Free Software Foundation
- //
---- a/libstdc++-v3/testsuite/27_io/objects/char/10.cc
-+++ b/libstdc++-v3/testsuite/27_io/objects/char/10.cc
-@@ -18,6 +18,7 @@
- // <http://www.gnu.org/licenses/>.
-
- // { dg-require-fileio "" }
-+// { dg-require-binary-io "" }
-
- #include <iostream>
- #include <cstdio>
---- a/libstdc++-v3/testsuite/Makefile.in
-+++ b/libstdc++-v3/testsuite/Makefile.in
-@@ -161,6 +161,8 @@ LIBICONV = @LIBICONV@
- LIBOBJS = @LIBOBJS@
- LIBS = @LIBS@
- LIBSUPCXX_PICFLAGS = @LIBSUPCXX_PICFLAGS@
-+LIBSUPCXX_PRONLY_FALSE = @LIBSUPCXX_PRONLY_FALSE@
-+LIBSUPCXX_PRONLY_TRUE = @LIBSUPCXX_PRONLY_TRUE@
- LIBTOOL = @LIBTOOL@
- LIPO = @LIPO@
- LN_S = @LN_S@
---- a/libstdc++-v3/testsuite/ext/vstring/element_access/char/front_back.cc
-+++ b/libstdc++-v3/testsuite/ext/vstring/element_access/char/front_back.cc
-@@ -1,4 +1,5 @@
- // { dg-options "-std=gnu++0x" }
-+// { dg-require-string-conversions "" }
-
- // 2007-10-16 Paolo Carlini <pcarlini@suse.de>
-
---- a/libstdc++-v3/testsuite/ext/vstring/element_access/wchar_t/front_back.cc
-+++ b/libstdc++-v3/testsuite/ext/vstring/element_access/wchar_t/front_back.cc
-@@ -1,4 +1,5 @@
- // { dg-options "-std=gnu++0x" }
-+// { dg-require-string-conversions "" }
-
- // 2007-10-16 Paolo Carlini <pcarlini@suse.de>
-
---- a/libstdc++-v3/testsuite/ext/vstring/init-list.cc
-+++ b/libstdc++-v3/testsuite/ext/vstring/init-list.cc
-@@ -17,6 +17,7 @@
- //
-
- // { dg-options "-std=gnu++0x" }
-+// { dg-require-string-conversions "" }
-
- #include <ext/vstring.h>
- #include <testsuite_hooks.h>
---- a/libstdc++-v3/testsuite/ext/vstring/moveable.cc
-+++ b/libstdc++-v3/testsuite/ext/vstring/moveable.cc
-@@ -1,4 +1,5 @@
- // { dg-options "-std=gnu++0x" }
-+// { dg-require-string-conversions "" }
-
- // Copyright (C) 2007, 2009 Free Software Foundation, Inc.
- //
---- a/libstdc++-v3/testsuite/ext/vstring/requirements/citerators.cc
-+++ b/libstdc++-v3/testsuite/ext/vstring/requirements/citerators.cc
-@@ -1,4 +1,5 @@
- // { dg-options "-std=gnu++0x" }
-+// { dg-require-string-conversions "" }
-
- // 2007-10-15 Paolo Carlini <pcarlini@suse.de>
-
---- a/libstdc++-v3/testsuite/ext/vstring/requirements/explicit_instantiation/char16_t/1.cc
-+++ b/libstdc++-v3/testsuite/ext/vstring/requirements/explicit_instantiation/char16_t/1.cc
-@@ -1,6 +1,7 @@
- // { dg-do compile }
- // { dg-options "-std=gnu++0x" }
- // { dg-require-cstdint "" }
-+// { dg-require-string-conversions "" }
-
- // Copyright (C) 2008, 2009 Free Software Foundation, Inc.
- //
---- a/libstdc++-v3/testsuite/ext/vstring/requirements/explicit_instantiation/char32_t/1.cc
-+++ b/libstdc++-v3/testsuite/ext/vstring/requirements/explicit_instantiation/char32_t/1.cc
-@@ -1,6 +1,7 @@
- // { dg-do compile }
- // { dg-options "-std=gnu++0x" }
- // { dg-require-cstdint "" }
-+// { dg-require-string-conversions "" }
-
- // Copyright (C) 2008, 2009 Free Software Foundation, Inc.
- //
---- a/libstdc++-v3/testsuite/lib/dg-options.exp
-+++ b/libstdc++-v3/testsuite/lib/dg-options.exp
-@@ -142,3 +142,21 @@ proc dg-require-string-conversions { arg
- }
- return
- }
-+
-+proc dg-require-swprintf { args } {
-+ if { ![ check_v3_target_swprintf ] } {
-+ upvar dg-do-what dg-do-what
-+ set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"]
-+ return
-+ }
-+ return
-+}
-+
-+proc dg-require-binary-io { args } {
-+ if { ![ check_v3_target_binary_io ] } {
-+ upvar dg-do-what dg-do-what
-+ set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"]
-+ return
-+ }
-+ return
-+}
---- a/libstdc++-v3/testsuite/lib/libstdc++.exp
-+++ b/libstdc++-v3/testsuite/lib/libstdc++.exp
-@@ -204,14 +204,23 @@ proc libstdc++_init { testfile } {
- # directory, and then add that to the search path.
- foreach src [glob "${srcdir}/util/*.h" \
- "${srcdir}/util/*.cc" \
-- "${srcdir}/util/*/*.hpp" \
-+ "${srcdir}/util/*.tcc" \
-+ "${srcdir}/util/*.hpp" \
-+ "${srcdir}/util/*/*.h" \
- "${srcdir}/util/*/*.cc" \
-+ "${srcdir}/util/*/*.tcc" \
- "${srcdir}/util/*/*.hpp" \
-+ "${srcdir}/util/*/*/*.h" \
- "${srcdir}/util/*/*/*.cc" \
-+ "${srcdir}/util/*/*/*.tcc" \
- "${srcdir}/util/*/*/*.hpp" \
-+ "${srcdir}/util/*/*/*/*.h" \
- "${srcdir}/util/*/*/*/*.cc" \
-+ "${srcdir}/util/*/*/*/*.tcc" \
- "${srcdir}/util/*/*/*/*.hpp" \
-+ "${srcdir}/util/*/*/*/*/*.h" \
- "${srcdir}/util/*/*/*/*/*.cc" \
-+ "${srcdir}/util/*/*/*/*/*.tcc" \
- "${srcdir}/util/*/*/*/*/*.hpp" ] {
- # Remove everything up to "util/..."
- set dst [string range $src [string length "${srcdir}/"] end]
-@@ -1374,3 +1383,119 @@ proc check_v3_target_string_conversions
- verbose "check_v3_target_string_conversions: $et_string_conversions" 2
- return $et_string_conversions
- }
-+
-+proc check_v3_target_swprintf { } {
-+ global cxxflags
-+ global DEFAULT_CXXFLAGS
-+ global et_swprintf
-+
-+ global tool
-+
-+ if { ![info exists et_swprintf_target_name] } {
-+ set et_swprintf_target_name ""
-+ }
-+
-+ # If the target has changed since we set the cached value, clear it.
-+ set current_target [current_target_name]
-+ if { $current_target != $et_swprintf_target_name } {
-+ verbose "check_v3_target_swprintf: `$et_swprintf_target_name'" 2
-+ set et_swprintf_target_name $current_target
-+ if [info exists et_swprintf] {
-+ verbose "check_v3_target_swprintf: removing cached result" 2
-+ unset et_swprintf
-+ }
-+ }
-+
-+ if [info exists et_swprintf] {
-+ verbose "check_v3_target_swprintf: using cached result" 2
-+ } else {
-+ set et_swprintf 0
-+
-+ # Set up and compile a C++0x test program that depends
-+ # on a standard swprintf function to be available.
-+ set src swprintf[pid].cc
-+ set exe swprintf[pid].exe
-+
-+ set f [open $src "w"]
-+ puts $f "#include <bits/c++config.h>"
-+ puts $f "int main()"
-+ puts $f "#if !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF)"
-+ puts $f "{ return 0; }"
-+ puts $f "#endif"
-+ close $f
-+
-+ set cxxflags_saved $cxxflags
-+ set cxxflags "$cxxflags $DEFAULT_CXXFLAGS -Werror"
-+
-+ set lines [v3_target_compile $src $exe executable ""]
-+ set cxxflags $cxxflags_saved
-+ file delete $src
-+
-+ if [string match "" $lines] {
-+ # No error message, compilation succeeded.
-+ set et_swprintf 1
-+ } else {
-+ verbose "check_v3_target_swprintf: compilation failed" 2
-+ }
-+ }
-+ verbose "check_v3_target_swprintf: $et_swprintf" 2
-+ return $et_swprintf
-+}
-+
-+proc check_v3_target_binary_io { } {
-+ global cxxflags
-+ global DEFAULT_CXXFLAGS
-+ global et_binary_io
-+
-+ global tool
-+
-+ if { ![info exists et_binary_io_target_name] } {
-+ set et_binary_io_target_name ""
-+ }
-+
-+ # If the target has changed since we set the cached value, clear it.
-+ set current_target [current_target_name]
-+ if { $current_target != $et_binary_io_target_name } {
-+ verbose "check_v3_target_binary_io: `$et_binary_io_target_name'" 2
-+ set et_binary_io_target_name $current_target
-+ if [info exists et_binary_io] {
-+ verbose "check_v3_target_binary_io: removing cached result" 2
-+ unset et_binary_io
-+ }
-+ }
-+
-+ if [info exists et_binary_io] {
-+ verbose "check_v3_target_binary_io: using cached result" 2
-+ } else {
-+ set et_binary_io 0
-+
-+ # Set up and compile a C++0x test program that depends
-+ # on text and binary I/O being the same.
-+ set src binary_io[pid].cc
-+ set exe binary_io[pid].exe
-+
-+ set f [open $src "w"]
-+ puts $f "#include <bits/c++config.h>"
-+ puts $f "int main()"
-+ puts $f "#if !defined(_GLIBCXX_HAVE_DOS_BASED_FILESYSTEM)"
-+ puts $f "{ return 0; }"
-+ puts $f "#endif"
-+ close $f
-+
-+ set cxxflags_saved $cxxflags
-+ set cxxflags "$cxxflags $DEFAULT_CXXFLAGS -Werror"
-+
-+ set lines [v3_target_compile $src $exe executable ""]
-+ set cxxflags $cxxflags_saved
-+ file delete $src
-+
-+ if [string match "" $lines] {
-+ # No error message, compilation succeeded.
-+ set et_binary_io 1
-+ } else {
-+ verbose "check_v3_target_binary_io: compilation failed" 2
-+ }
-+ }
-+ verbose "check_v3_target_binary_io: $et_binary_io" 2
-+ return $et_binary_io
-+}
---- a/libstdc++-v3/testsuite/lib/prune.exp
-+++ b/libstdc++-v3/testsuite/lib/prune.exp
-@@ -30,5 +30,23 @@ proc prune_g++_output { text } {
- regsub -all "(^|\n)\[^\n\]*: Additional NOP may be necessary to workaround Itanium processor A/B step errata" $text "" text
- regsub -all "(^|\n)\[^\n*\]*: Assembler messages:\[^\n\]*" $text "" text
-
-+ if { [ishost "sparc*-*-solaris2*"] } {
-+ # When testing a compiler built for SPARC Solaris 2.9 (or earlier)
-+ # on a host running Solaris 2.10 (or later), we get this warning
-+ # from the static linker when building with g++:
-+ #
-+ # libm.so.1, needed by .../libstdc++.so may conflict with
-+ # libm.so
-+ #
-+ # The warning is issued because libstdc++ is linked against
-+ # libm.so.1 (from the Solaris 2.9 sysroot), whereas Solaris 2.10
-+ # provides both libm.so.2 and libm.so.1. On Solaris 2.10, libc.so
-+ # depends on libm.so.2, so all programs pull in libm.so.2.
-+ #
-+ # Pulling both libraries must in fact be harmless, as, otherwise,
-+ # programs built for Solaris 2.9 would break on Solaris 2.10.
-+ regsub -all "(^|\n)\[^\n\]*: warning: libm.so.1, needed by \[^\n\]*, may conflict with libm.so.2" $text "" text
-+ }
-+
- return $text
- }
+++ /dev/null
---- a/contrib/regression/objs-gcc.sh
-+++ b/contrib/regression/objs-gcc.sh
-@@ -106,6 +106,10 @@
- then
- make all-gdb all-dejagnu all-ld || exit 1
- make install-gdb install-dejagnu install-ld || exit 1
-+elif [ $H_REAL_TARGET = $H_REAL_HOST -a $H_REAL_TARGET = i686-pc-linux-uclibc ]
-+ then
-+ make all-gdb all-dejagnu all-ld || exit 1
-+ make install-gdb install-dejagnu install-ld || exit 1
- elif [ $H_REAL_TARGET = $H_REAL_HOST ] ; then
- make bootstrap || exit 1
- make install || exit 1
---- a/libjava/classpath/ltconfig
-+++ b/libjava/classpath/ltconfig
-@@ -603,7 +603,7 @@
-
- # Transform linux* to *-*-linux-gnu*, to support old configure scripts.
- case $host_os in
--linux-gnu*) ;;
-+linux-gnu*|linux-uclibc*) ;;
- linux*) host=`echo $host | sed 's/^\(.*-.*-linux\)\(.*\)$/\1-gnu\2/'`
- esac
-
-@@ -1251,7 +1251,7 @@
- ;;
-
- # This must be Linux ELF.
--linux-gnu*)
-+linux*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
+++ /dev/null
---- a/boehm-gc/include/gc.h
-+++ b/boehm-gc/include/gc.h
-@@ -503,7 +503,7 @@
- #if defined(__linux__) || defined(__GLIBC__)
- # include <features.h>
- # if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1 || __GLIBC__ > 2) \
-- && !defined(__ia64__)
-+ && !defined(__ia64__) && !defined(__UCLIBC__)
- # ifndef GC_HAVE_BUILTIN_BACKTRACE
- # define GC_HAVE_BUILTIN_BACKTRACE
- # endif
+++ /dev/null
---- a/libstdc++-v3/include/c_global/cstdio
-+++ b/libstdc++-v3/include/c_global/cstdio
-@@ -139,7 +139,7 @@
-
- _GLIBCXX_END_NAMESPACE
-
--#if _GLIBCXX_USE_C99
-+#if _GLIBCXX_USE_C99 || defined __UCLIBC__
-
- #undef snprintf
- #undef vfscanf
+++ /dev/null
---- a/libmudflap/mf-hooks2.c
-+++ b/libmudflap/mf-hooks2.c
-@@ -421,7 +421,7 @@
- {
- TRACE ("%s\n", __PRETTY_FUNCTION__);
- MF_VALIDATE_EXTENT(s, n, __MF_CHECK_WRITE, "bzero region");
-- bzero (s, n);
-+ memset (s, 0, n);
- }
-
-
-@@ -431,7 +431,7 @@
- TRACE ("%s\n", __PRETTY_FUNCTION__);
- MF_VALIDATE_EXTENT(src, n, __MF_CHECK_READ, "bcopy src");
- MF_VALIDATE_EXTENT(dest, n, __MF_CHECK_WRITE, "bcopy dest");
-- bcopy (src, dest, n);
-+ memmove (dest, src, n);
- }
-
-
-@@ -441,7 +441,7 @@
- TRACE ("%s\n", __PRETTY_FUNCTION__);
- MF_VALIDATE_EXTENT(s1, n, __MF_CHECK_READ, "bcmp 1st arg");
- MF_VALIDATE_EXTENT(s2, n, __MF_CHECK_READ, "bcmp 2nd arg");
-- return bcmp (s1, s2, n);
-+ return n == 0 ? 0 : memcmp (s1, s2, n);
- }
-
-
-@@ -450,7 +450,7 @@
- size_t n = strlen (s);
- TRACE ("%s\n", __PRETTY_FUNCTION__);
- MF_VALIDATE_EXTENT(s, CLAMPADD(n, 1), __MF_CHECK_READ, "index region");
-- return index (s, c);
-+ return strchr (s, c);
- }
-
-
-@@ -459,7 +459,7 @@
- size_t n = strlen (s);
- TRACE ("%s\n", __PRETTY_FUNCTION__);
- MF_VALIDATE_EXTENT(s, CLAMPADD(n, 1), __MF_CHECK_READ, "rindex region");
-- return rindex (s, c);
-+ return strrchr (s, c);
- }
-
- /* XXX: stpcpy, memccpy */
+++ /dev/null
---- a/configure
-+++ b/configure
-@@ -2688,6 +2688,9 @@ case "${target}" in
- ip2k-*-*)
- noconfigdirs="$noconfigdirs target-libiberty target-libstdc++-v3 ${libgcj}"
- ;;
-+ ubicom32-*-*)
-+ noconfigdirs="$noconfigdirs target-libffi"
-+ ;;
- *-*-linux* | *-*-gnu* | *-*-k*bsd*-gnu | *-*-kopensolaris*-gnu)
- noconfigdirs="$noconfigdirs target-newlib target-libgloss"
- ;;
---- /dev/null
-+++ b/gcc/config/ubicom32/constraints.md
-@@ -0,0 +1,149 @@
-+; Constraint definitions for Ubicom32
-+
-+; Copyright (C) 2009 Free Software Foundation, Inc.
-+; Contributed by Ubicom, Inc.
-+
-+; This file is part of GCC.
-+
-+; GCC is free software; you can redistribute it and/or modify it
-+; under the terms of the GNU General Public License as published
-+; by the Free Software Foundation; either version 3, or (at your
-+; option) any later version.
-+
-+; GCC is distributed in the hope that it will be useful, but WITHOUT
-+; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-+; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
-+; License for more details.
-+
-+; You should have received a copy of the GNU General Public License
-+; along with GCC; see the file COPYING3. If not see
-+; <http://www.gnu.org/licenses/>.
-+
-+(define_register_constraint "a" "ALL_ADDRESS_REGS"
-+ "An An register.")
-+
-+(define_register_constraint "d" "DATA_REGS"
-+ "A Dn register.")
-+
-+(define_register_constraint "h" "ACC_REGS"
-+ "An accumulator register.")
-+
-+(define_register_constraint "l" "ACC_LO_REGS"
-+ "An accn_lo register.")
-+
-+(define_register_constraint "Z" "FDPIC_REG"
-+ "The FD-PIC GOT pointer: A0.")
-+
-+(define_constraint "I"
-+ "An 8-bit signed constant value."
-+ (and (match_code "const_int")
-+ (match_test "(ival >= -128) && (ival <= 127)")))
-+
-+(define_constraint "Q"
-+ "An 8-bit signed constant value represented as unsigned."
-+ (and (match_code "const_int")
-+ (match_test "(ival >= 0x00) && (ival <= 0xff)")))
-+
-+(define_constraint "R"
-+ "An 8-bit signed constant value represented as unsigned."
-+ (and (match_code "const_int")
-+ (match_test "((ival >= 0x0000) && (ival <= 0x007f)) || ((ival >= 0xff80) && (ival <= 0xffff))")))
-+
-+(define_constraint "J"
-+ "A 7-bit unsigned constant value."
-+ (and (match_code "const_int")
-+ (match_test "(ival >= 0) && (ival <= 127)")))
-+
-+(define_constraint "K"
-+ "A 7-bit unsigned constant value shifted << 1."
-+ (and (match_code "const_int")
-+ (match_test "(ival >= 0) && (ival <= 254) && ((ival & 1) == 0)")))
-+
-+(define_constraint "L"
-+ "A 7-bit unsigned constant value shifted << 2."
-+ (and (match_code "const_int")
-+ (match_test "(ival >= 0) && (ival <= 508) && ((ival & 3) == 0)")))
-+
-+(define_constraint "M"
-+ "A 5-bit unsigned constant value."
-+ (and (match_code "const_int")
-+ (match_test "(ival >= 0) && (ival <= 31)")))
-+
-+(define_constraint "N"
-+ "A signed 16 bit constant value."
-+ (and (match_code "const_int")
-+ (match_test "(ival >= -32768) && (ival <= 32767)")))
-+
-+(define_constraint "O"
-+ "An exact bitmask of contiguous 1 bits starting at bit 0."
-+ (and (match_code "const_int")
-+ (match_test "exact_log2 (ival + 1) != -1")))
-+
-+(define_constraint "P"
-+ "A 7-bit negative constant value shifted << 2."
-+ (and (match_code "const_int")
-+ (match_test "(ival >= -504) && (ival <= 0) && ((ival & 3) == 0)")))
-+
-+(define_constraint "S"
-+ "A symbolic reference."
-+ (match_code "symbol_ref"))
-+
-+(define_constraint "Y"
-+ "An FD-PIC symbolic reference."
-+ (and (match_test "TARGET_FDPIC")
-+ (match_test "GET_CODE (op) == UNSPEC")
-+ (ior (match_test "XINT (op, 1) == UNSPEC_FDPIC_GOT")
-+ (match_test "XINT (op, 1) == UNSPEC_FDPIC_GOT_FUNCDESC"))))
-+
-+(define_memory_constraint "T1"
-+ "A memory operand that can be used for .1 instruction."
-+ (and (match_test "memory_operand (op, GET_MODE(op))")
-+ (match_test "GET_MODE (op) == QImode")))
-+
-+(define_memory_constraint "T2"
-+ "A memory operand that can be used for .2 instruction."
-+ (and (match_test "memory_operand (op, GET_MODE(op))")
-+ (match_test "GET_MODE (op) == HImode")))
-+
-+(define_memory_constraint "T4"
-+ "A memory operand that can be used for .4 instruction."
-+ (and (match_test "memory_operand (op, GET_MODE(op))")
-+ (ior (match_test "GET_MODE (op) == SImode")
-+ (match_test "GET_MODE (op) == DImode")
-+ (match_test "GET_MODE (op) == SFmode"))))
-+
-+(define_memory_constraint "U1"
-+ "An offsettable memory operand that can be used for .1 instruction."
-+ (and (match_test "memory_operand (op, GET_MODE(op))")
-+ (match_test "GET_MODE (op) == QImode")
-+ (match_test "GET_CODE (XEXP (op, 0)) != POST_INC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_INC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != POST_DEC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_DEC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != POST_MODIFY")
-+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_MODIFY")))
-+
-+(define_memory_constraint "U2"
-+ "An offsettable memory operand that can be used for .2 instruction."
-+ (and (match_test "memory_operand (op, GET_MODE(op))")
-+ (match_test "GET_MODE (op) == HImode")
-+ (match_test "GET_CODE (XEXP (op, 0)) != POST_INC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_INC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != POST_DEC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_DEC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != POST_MODIFY")
-+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_MODIFY")))
-+
-+(define_memory_constraint "U4"
-+ "An offsettable memory operand that can be used for .4 instruction."
-+ (and (match_test "memory_operand (op, GET_MODE(op))")
-+ (ior (match_test "GET_MODE (op) == SImode")
-+ (match_test "GET_MODE (op) == DImode")
-+ (match_test "GET_MODE (op) == SFmode"))
-+ (match_test "GET_CODE (XEXP (op, 0)) != POST_INC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_INC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != POST_DEC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_DEC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != POST_MODIFY")
-+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_MODIFY")))
-+
---- /dev/null
-+++ b/gcc/config/ubicom32/crti.S
-@@ -0,0 +1,54 @@
-+/* Specialized code needed to support construction and destruction of
-+ file-scope objects in C++ and Java code, and to support exception handling.
-+ Copyright (C) 1999 Free Software Foundation, Inc.
-+ Contributed by Charles-Antoine Gauthier (charles.gauthier@iit.nrc.ca).
-+
-+This file is part of GCC.
-+
-+GCC is free software; you can redistribute it and/or modify
-+it under the terms of the GNU General Public License as published by
-+the Free Software Foundation; either version 2, or (at your option)
-+any later version.
-+
-+GCC is distributed in the hope that it will be useful,
-+but WITHOUT ANY WARRANTY; without even the implied warranty of
-+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+GNU General Public License for more details.
-+
-+You should have received a copy of the GNU General Public License
-+along with GCC; see the file COPYING. If not, write to
-+the Free Software Foundation, 59 Temple Place - Suite 330,
-+Boston, MA 02111-1307, USA. */
-+
-+/* As a special exception, if you link this library with files
-+ compiled with GCC to produce an executable, this does not cause
-+ the resulting executable to be covered by the GNU General Public License.
-+ This exception does not however invalidate any other reasons why
-+ the executable file might be covered by the GNU General Public License. */
-+
-+/*
-+ * This file just supplies function prologues for the .init and .fini
-+ * sections. It is linked in before crtbegin.o.
-+ */
-+ .file "crti.o"
-+ .ident "GNU C crti.o"
-+
-+ .section .init
-+ .align 2
-+ .globl _init
-+ .type _init, @function
-+_init:
-+ move.4 -4(sp)++, a5
-+#ifdef __UBICOM32_FDPIC__
-+ move.4 -4(sp)++, a0
-+#endif
-+
-+ .section .fini
-+ .align 2
-+ .globl _fini
-+ .type _fini, @function
-+_fini:
-+ move.4 -4(sp)++, a5
-+#ifdef __UBICOM32_FDPIC__
-+ move.4 -4(sp)++, a0
-+#endif
---- /dev/null
-+++ b/gcc/config/ubicom32/crtn.S
-@@ -0,0 +1,47 @@
-+/* Specialized code needed to support construction and destruction of
-+ file-scope objects in C++ and Java code, and to support exception handling.
-+ Copyright (C) 1999 Free Software Foundation, Inc.
-+ Contributed by Charles-Antoine Gauthier (charles.gauthier@iit.nrc.ca).
-+
-+This file is part of GCC.
-+
-+GCC is free software; you can redistribute it and/or modify
-+it under the terms of the GNU General Public License as published by
-+the Free Software Foundation; either version 2, or (at your option)
-+any later version.
-+
-+GCC is distributed in the hope that it will be useful,
-+but WITHOUT ANY WARRANTY; without even the implied warranty of
-+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+GNU General Public License for more details.
-+
-+You should have received a copy of the GNU General Public License
-+along with GCC; see the file COPYING. If not, write to
-+the Free Software Foundation, 59 Temple Place - Suite 330,
-+Boston, MA 02111-1307, USA. */
-+
-+/* As a special exception, if you link this library with files
-+ compiled with GCC to produce an executable, this does not cause
-+ the resulting executable to be covered by the GNU General Public License.
-+ This exception does not however invalidate any other reasons why
-+ the executable file might be covered by the GNU General Public License. */
-+
-+/*
-+ * This file supplies function epilogues for the .init and .fini sections.
-+ * It is linked in after all other files.
-+ */
-+
-+ .file "crtn.o"
-+ .ident "GNU C crtn.o"
-+
-+ .section .init
-+#ifdef __UBICOM32_FDPIC__
-+ move.4 a0, (sp)4++
-+#endif
-+ ret (sp)4++
-+
-+ .section .fini
-+#ifdef __UBICOM32_FDPIC__
-+ move.4 a0, (sp)4++
-+#endif
-+ ret (sp)4++
---- /dev/null
-+++ b/gcc/config/ubicom32/elf.h
-@@ -0,0 +1,29 @@
-+#undef STARTFILE_SPEC
-+#define STARTFILE_SPEC "\
-+%{msim:%{!shared:crt0%O%s}} \
-+crti%O%s crtbegin%O%s"
-+
-+#undef ENDFILE_SPEC
-+#define ENDFILE_SPEC "crtend%O%s crtn%O%s"
-+
-+#ifdef __UBICOM32_FDPIC__
-+#define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC) \
-+ asm (SECTION_OP); \
-+ asm ("move.4 a0, 0(sp);\n\t" \
-+ "call a5," USER_LABEL_PREFIX #FUNC ";"); \
-+ asm (TEXT_SECTION_ASM_OP);
-+#endif
-+
-+#undef SUBTARGET_DRIVER_SELF_SPECS
-+#define SUBTARGET_DRIVER_SELF_SPECS \
-+ "%{mfdpic:-msim} "
-+
-+#define NO_IMPLICIT_EXTERN_C
-+
-+/*
-+ * We need this to compile crtbegin/crtend. This should really be picked
-+ * up from elfos.h but at the moment including elfos.h causes other more
-+ * serous linker issues.
-+ */
-+#define INIT_SECTION_ASM_OP "\t.section\t.init"
-+#define FINI_SECTION_ASM_OP "\t.section\t.fini"
---- /dev/null
-+++ b/gcc/config/ubicom32/linux.h
-@@ -0,0 +1,80 @@
-+/* Definitions of target machine for Ubicom32-uclinux
-+
-+ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
-+ 2009 Free Software Foundation, Inc.
-+ Contributed by Ubicom, Inc.
-+
-+ This file is part of GCC.
-+
-+ GCC is free software; you can redistribute it and/or modify it
-+ under the terms of the GNU General Public License as published
-+ by the Free Software Foundation; either version 3, or (at your
-+ option) any later version.
-+
-+ GCC is distributed in the hope that it will be useful, but WITHOUT
-+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
-+ License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with GCC; see the file COPYING3. If not see
-+ <http://www.gnu.org/licenses/>. */
-+
-+/* Don't assume anything about the header files. */
-+#define NO_IMPLICIT_EXTERN_C
-+
-+#undef LIB_SPEC
-+#define LIB_SPEC \
-+ "%{pthread:-lpthread} " \
-+ "-lc"
-+
-+#undef LINK_GCC_C_SEQUENCE_SPEC
-+#define LINK_GCC_C_SEQUENCE_SPEC \
-+ "%{static:--start-group} %G %L %{static:--end-group} " \
-+ "%{!static: %G}"
-+
-+#undef STARTFILE_SPEC
-+#define STARTFILE_SPEC \
-+ "%{!shared: %{pg|p|profile:gcrt1%O%s;pie:Scrt1%O%s;:crt1%O%s}} " \
-+ "crtreloc%O%s crti%O%s %{shared|pie:crtbeginS%O%s;:crtbegin%O%s}"
-+
-+#undef ENDFILE_SPEC
-+#define ENDFILE_SPEC \
-+ "%{shared|pie:crtendS%O%s;:crtend%O%s} crtn%O%s"
-+
-+/* taken from linux.h */
-+/* The GNU C++ standard library requires that these macros be defined. */
-+#undef CPLUSPLUS_CPP_SPEC
-+#define CPLUSPLUS_CPP_SPEC "-D_GNU_SOURCE %(cpp)"
-+
-+#define TARGET_OS_CPP_BUILTINS() \
-+ do { \
-+ builtin_define_std ("__UBICOM32__"); \
-+ builtin_define_std ("__ubicom32__"); \
-+ builtin_define ("__gnu_linux__"); \
-+ builtin_define_std ("linux"); \
-+ builtin_define_std ("unix"); \
-+ builtin_assert ("system=linux"); \
-+ builtin_assert ("system=unix"); \
-+ builtin_assert ("system=posix"); \
-+ } while (0)
-+
-+#define OBJECT_FORMAT_ELF
-+
-+
-+#undef DRIVER_SELF_SPECS
-+#define DRIVER_SELF_SPECS \
-+ "%{!mno-fdpic:-mfdpic}"
-+
-+#undef LINK_SPEC
-+#define LINK_SPEC "%{mfdpic: -m elf32ubicom32fdpic -z text } %{shared} %{pie} \
-+ %{static:-dn -Bstatic} \
-+ %{shared:-G -Bdynamic} \
-+ %{!shared: %{!static: \
-+ %{rdynamic:-export-dynamic} \
-+ %{!dynamic-linker:-dynamic-linker /lib/ld-uClibc.so.0}} \
-+ %{static}} "
-+
-+/*
-+#define MD_UNWIND_SUPPORT "config/bfin/linux-unwind.h"
-+*/
---- /dev/null
-+++ b/gcc/config/ubicom32/predicates.md
-@@ -0,0 +1,327 @@
-+; Predicate definitions for Ubicom32.
-+
-+; Copyright (C) 2009 Free Software Foundation, Inc.
-+; Contributed by Ubicom, Inc.
-+
-+; This file is part of GCC.
-+
-+; GCC is free software; you can redistribute it and/or modify it
-+; under the terms of the GNU General Public License as published
-+; by the Free Software Foundation; either version 3, or (at your
-+; option) any later version.
-+
-+; GCC is distributed in the hope that it will be useful, but WITHOUT
-+; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-+; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
-+; License for more details.
-+
-+; You should have received a copy of the GNU General Public License
-+; along with GCC; see the file COPYING3. If not see
-+; <http://www.gnu.org/licenses/>.
-+
-+(define_predicate "ubicom32_move_operand"
-+ (match_code "const_int, const_double, const, mem, subreg, reg, lo_sum")
-+{
-+ if (CONST_INT_P (op))
-+ return true;
-+
-+ if (GET_CODE (op) == CONST_DOUBLE)
-+ return true;
-+
-+ if (GET_CODE (op) == CONST)
-+ return memory_address_p (mode, op);
-+
-+ if (GET_MODE (op) != mode)
-+ return false;
-+
-+ if (MEM_P (op))
-+ return memory_address_p (mode, XEXP (op, 0));
-+
-+ if (GET_CODE (op) == SUBREG) {
-+ op = SUBREG_REG (op);
-+
-+ if (REG_P (op))
-+ return true;
-+
-+ if (! MEM_P (op))
-+ return false;
-+
-+ /* Paradoxical SUBREG. */
-+ if (GET_MODE_SIZE (mode) > GET_MODE_SIZE (GET_MODE (op)))
-+ return false;
-+
-+ return memory_address_p (GET_MODE (op), XEXP (op, 0));
-+ }
-+
-+ return register_operand (op, mode);
-+})
-+
-+;; Returns true if OP is either a symbol reference or a sum of a
-+;; symbol reference and a constant.
-+
-+(define_predicate "ubicom32_symbolic_address_operand"
-+ (match_code "symbol_ref, label_ref, const")
-+{
-+ switch (GET_CODE (op))
-+ {
-+ case SYMBOL_REF:
-+ case LABEL_REF:
-+ return true;
-+
-+ case CONST:
-+ op = XEXP (op, 0);
-+ return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
-+ || GET_CODE (XEXP (op, 0)) == LABEL_REF)
-+ && CONST_INT_P (XEXP (op, 1)));
-+
-+ default:
-+ return false;
-+ }
-+})
-+
-+;; Return true if operand is the uClinux FD-PIC register.
-+
-+(define_predicate "ubicom32_fdpic_operand"
-+ (match_code "reg")
-+{
-+ if (! TARGET_FDPIC)
-+ return false;
-+
-+ if (!REG_P (op))
-+ return false;
-+
-+ if (GET_MODE (op) != mode && mode != VOIDmode)
-+ return false;
-+
-+ if (REGNO (op) != FDPIC_REGNUM && REGNO (op) < FIRST_PSEUDO_REGISTER)
-+ return false;
-+
-+ return true;
-+})
-+
-+(define_predicate "ubicom32_fdpic_got_offset_operand"
-+ (match_code "unspec")
-+{
-+ if (! TARGET_FDPIC)
-+ return false;
-+
-+ if (GET_CODE (op) != UNSPEC)
-+ return false;
-+
-+ if (XINT (op, 1) != UNSPEC_FDPIC_GOT
-+ && XINT (op, 1) != UNSPEC_FDPIC_GOT_FUNCDESC)
-+ return false;
-+
-+ return true;
-+})
-+
-+(define_predicate "ubicom32_arith_operand"
-+ (match_code "subreg, reg, const_int, lo_sum, mem")
-+{
-+ return (ubicom32_move_operand (op, mode)
-+ && ! ubicom32_symbolic_address_operand (op, mode)
-+ && (! CONST_INT_P (op)
-+ || satisfies_constraint_I (op)));
-+})
-+
-+(define_predicate "ubicom32_arith_operand_dot1"
-+ (match_code "subreg, reg, const_int, lo_sum, mem")
-+{
-+ return (ubicom32_move_operand (op, mode)
-+ && ! ubicom32_symbolic_address_operand (op, mode)
-+ && (! CONST_INT_P (op)
-+ || satisfies_constraint_Q (op)));
-+})
-+
-+(define_predicate "ubicom32_arith_operand_dot2"
-+ (match_code "subreg, reg, const_int, lo_sum, mem")
-+{
-+ return (ubicom32_move_operand (op, mode)
-+ && ! ubicom32_symbolic_address_operand (op, mode)
-+ && (! CONST_INT_P (op)
-+ || satisfies_constraint_R (op)));
-+})
-+
-+(define_predicate "ubicom32_compare_operand"
-+ (match_code "subreg, reg, const_int, lo_sum, mem")
-+{
-+ return (ubicom32_move_operand (op, mode)
-+ && ! ubicom32_symbolic_address_operand (op, mode)
-+ && (! CONST_INT_P (op)
-+ || satisfies_constraint_N (op)));
-+})
-+
-+(define_predicate "ubicom32_compare_operator"
-+ (match_code "compare"))
-+
-+(define_predicate "ubicom32_and_or_si3_operand"
-+ (match_code "subreg, reg, const_int, lo_sum, mem")
-+{
-+ return (ubicom32_arith_operand (op, mode)
-+ || (CONST_INT_P (op)
-+ && ((exact_log2 (INTVAL (op) + 1) != -1
-+ && exact_log2 (INTVAL (op) + 1) <= 31)
-+ || (exact_log2 (INTVAL (op)) != -1
-+ && exact_log2 (INTVAL (op)) <= 31)
-+ || (exact_log2 (~INTVAL (op)) != -1
-+ && exact_log2 (~INTVAL (op)) <= 31))));
-+})
-+
-+(define_predicate "ubicom32_and_or_hi3_operand"
-+ (match_code "subreg, reg, const_int, lo_sum, mem")
-+{
-+ return (ubicom32_arith_operand (op, mode)
-+ || (CONST_INT_P (op)
-+ && exact_log2 (INTVAL (op) + 1) != -1
-+ && exact_log2 (INTVAL (op) + 1) <= 15));
-+})
-+
-+(define_predicate "ubicom32_mem_or_address_register_operand"
-+ (match_code "subreg, reg, mem")
-+{
-+ unsigned int regno;
-+
-+ if (MEM_P (op)
-+ && memory_operand (op, mode))
-+ return true;
-+
-+ if (REG_P (op))
-+ regno = REGNO (op);
-+ else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
-+ {
-+ int offset;
-+ if (REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER)
-+ offset = SUBREG_BYTE (op) / (GET_MODE_SIZE (GET_MODE (op)));
-+ else
-+ offset = subreg_regno_offset (REGNO (SUBREG_REG (op)),
-+ GET_MODE (SUBREG_REG (op)),
-+ SUBREG_BYTE (op),
-+ GET_MODE (op));
-+ regno = REGNO (SUBREG_REG (op)) + offset;
-+ }
-+ else
-+ return false;
-+
-+ return (regno >= FIRST_PSEUDO_REGISTER
-+ || REGNO_REG_CLASS (regno) == FDPIC_REG
-+ || REGNO_REG_CLASS (regno) == ADDRESS_REGS);
-+})
-+
-+(define_predicate "ubicom32_data_register_operand"
-+ (match_code "subreg, reg")
-+{
-+ unsigned int regno;
-+
-+ if (REG_P (op))
-+ regno = REGNO (op);
-+ else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
-+ {
-+ int offset;
-+ if (REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER)
-+ offset = SUBREG_BYTE (op) / (GET_MODE_SIZE (GET_MODE (op)));
-+ else
-+ offset = subreg_regno_offset (REGNO (SUBREG_REG (op)),
-+ GET_MODE (SUBREG_REG (op)),
-+ SUBREG_BYTE (op),
-+ GET_MODE (op));
-+ regno = REGNO (SUBREG_REG (op)) + offset;
-+ }
-+ else
-+ return false;
-+
-+ return ((regno >= FIRST_PSEUDO_REGISTER
-+ && regno != REGNO (virtual_stack_vars_rtx))
-+ || REGNO_REG_CLASS (regno) == DATA_REGS);
-+})
-+
-+(define_predicate "ubicom32_address_register_operand"
-+ (match_code "subreg, reg")
-+{
-+ unsigned int regno;
-+
-+ if (REG_P (op))
-+ regno = REGNO (op);
-+ else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
-+ {
-+ int offset;
-+ if (REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER)
-+ offset = SUBREG_BYTE (op) / (GET_MODE_SIZE (GET_MODE (op)));
-+ else
-+ offset = subreg_regno_offset (REGNO (SUBREG_REG (op)),
-+ GET_MODE (SUBREG_REG (op)),
-+ SUBREG_BYTE (op),
-+ GET_MODE (op));
-+ regno = REGNO (SUBREG_REG (op)) + offset;
-+ }
-+ else
-+ return false;
-+
-+ return (regno >= FIRST_PSEUDO_REGISTER
-+ || REGNO_REG_CLASS (regno) == FDPIC_REG
-+ || REGNO_REG_CLASS (regno) == ADDRESS_REGS);
-+})
-+
-+(define_predicate "ubicom32_acc_lo_register_operand"
-+ (match_code "subreg, reg")
-+{
-+ unsigned int regno;
-+
-+ if (REG_P (op))
-+ regno = REGNO (op);
-+ else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
-+ {
-+ int offset;
-+ if (REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER)
-+ offset = SUBREG_BYTE (op) / (GET_MODE_SIZE (GET_MODE (op)));
-+ else
-+ offset = subreg_regno_offset (REGNO (SUBREG_REG (op)),
-+ GET_MODE (SUBREG_REG (op)),
-+ SUBREG_BYTE (op),
-+ GET_MODE (op));
-+ regno = REGNO (SUBREG_REG (op)) + offset;
-+ }
-+ else
-+ return false;
-+
-+ return ((regno >= FIRST_PSEUDO_REGISTER
-+ && regno != REGNO (virtual_stack_vars_rtx))
-+ || REGNO_REG_CLASS (regno) == ACC_LO_REGS);
-+})
-+
-+(define_predicate "ubicom32_acc_hi_register_operand"
-+ (match_code "subreg, reg")
-+{
-+ unsigned int regno;
-+
-+ if (REG_P (op))
-+ regno = REGNO (op);
-+ else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
-+ {
-+ int offset;
-+ if (REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER)
-+ offset = SUBREG_BYTE (op) / (GET_MODE_SIZE (GET_MODE (op)));
-+ else
-+ offset = subreg_regno_offset (REGNO (SUBREG_REG (op)),
-+ GET_MODE (SUBREG_REG (op)),
-+ SUBREG_BYTE (op),
-+ GET_MODE (op));
-+ regno = REGNO (SUBREG_REG (op)) + offset;
-+ }
-+ else
-+ return false;
-+
-+ return ((regno >= FIRST_PSEUDO_REGISTER
-+ && regno != REGNO (virtual_stack_vars_rtx))
-+ || REGNO_REG_CLASS (regno) == ACC_REGS);
-+})
-+
-+(define_predicate "ubicom32_call_address_operand"
-+ (match_code "symbol_ref, subreg, reg")
-+{
-+ return (GET_CODE (op) == SYMBOL_REF || REG_P (op));
-+})
-+
-+(define_special_predicate "ubicom32_cc_register_operand"
-+ (and (match_code "reg")
-+ (match_test "REGNO (op) == CC_REGNUM")))
-+
---- /dev/null
-+++ b/gcc/config/ubicom32/t-ubicom32
-@@ -0,0 +1,52 @@
-+# Name of assembly file containing libgcc1 functions.
-+# This entry must be present, but it can be empty if the target does
-+# not need any assembler functions to support its code generation.
-+CROSS_LIBGCC1 =
-+
-+# Alternatively if assembler functions *are* needed then define the
-+# entries below:
-+# CROSS_LIBGCC1 = libgcc1-asm.a
-+
-+LIB2FUNCS_EXTRA = \
-+ $(srcdir)/config/udivmodsi4.c \
-+ $(srcdir)/config/divmod.c \
-+ $(srcdir)/config/udivmod.c
-+
-+# If any special flags are necessary when building libgcc2 put them here.
-+#
-+# TARGET_LIBGCC2_CFLAGS =
-+
-+# 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
-+
-+fp-bit.c: $(srcdir)/config/fp-bit.c
-+ echo '#define FLOAT' > fp-bit.c
-+ cat $(srcdir)/config/fp-bit.c >> fp-bit.c
-+
-+dp-bit.c: $(srcdir)/config/fp-bit.c
-+ cat $(srcdir)/config/fp-bit.c > dp-bit.c
-+
-+# Commented out to speed up compiler development!
-+#
-+# MULTILIB_OPTIONS = march=ubicom32v1/march=ubicom32v2/march=ubicom32v3/march=ubicom32v4
-+# MULTILIB_DIRNAMES = ubicom32v1 ubicom32v2 ubicom32v3 ubicom32v4
-+
-+MULTILIB_OPTIONS = march=ubicom32v3/march=ubicom32v4
-+MULTILIB_OPTIONS += mfdpic
-+MULTILIB_OPTIONS += mno-ipos-abi/mipos-abi
-+MULTILIB_OPTIONS += fno-leading-underscore/fleading-underscore
-+
-+# Assemble startup files.
-+$(T)crti.o: $(srcdir)/config/ubicom32/crti.S $(GCC_PASSES)
-+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) \
-+ -c -o $(T)crti.o -x assembler-with-cpp $(srcdir)/config/ubicom32/crti.S
-+
-+$(T)crtn.o: $(srcdir)/config/ubicom32/crtn.S $(GCC_PASSES)
-+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) \
-+ -c -o $(T)crtn.o -x assembler-with-cpp $(srcdir)/config/ubicom32/crtn.S
-+
-+# these parts are required because uClibc ldso needs them to link.
-+# they are not in the specfile so they will not be included automatically.
-+EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o crtbeginS.o crtendS.o crti.o crtn.o
---- /dev/null
-+++ b/gcc/config/ubicom32/t-ubicom32-linux
-@@ -0,0 +1,35 @@
-+# Name of assembly file containing libgcc1 functions.
-+# This entry must be present, but it can be empty if the target does
-+# not need any assembler functions to support its code generation.
-+CROSS_LIBGCC1 =
-+
-+# Alternatively if assembler functions *are* needed then define the
-+# entries below:
-+# CROSS_LIBGCC1 = libgcc1-asm.a
-+
-+LIB2FUNCS_EXTRA = \
-+ $(srcdir)/config/udivmodsi4.c \
-+ $(srcdir)/config/divmod.c \
-+ $(srcdir)/config/udivmod.c
-+
-+# If any special flags are necessary when building libgcc2 put them here.
-+#
-+# TARGET_LIBGCC2_CFLAGS =
-+
-+# 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
-+
-+fp-bit.c: $(srcdir)/config/fp-bit.c
-+ echo '#define FLOAT' > fp-bit.c
-+ cat $(srcdir)/config/fp-bit.c >> fp-bit.c
-+
-+dp-bit.c: $(srcdir)/config/fp-bit.c
-+ cat $(srcdir)/config/fp-bit.c > dp-bit.c
-+
-+# We only support v3 and v4 ISAs for uClinux.
-+
-+MULTILIB_OPTIONS = march=ubicom32v3/march=ubicom32v4
-+
-+#EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o crtbeginS.o crtendS.o
---- /dev/null
-+++ b/gcc/config/ubicom32/t-ubicom32-uclinux
-@@ -0,0 +1,35 @@
-+# Name of assembly file containing libgcc1 functions.
-+# This entry must be present, but it can be empty if the target does
-+# not need any assembler functions to support its code generation.
-+CROSS_LIBGCC1 =
-+
-+# Alternatively if assembler functions *are* needed then define the
-+# entries below:
-+# CROSS_LIBGCC1 = libgcc1-asm.a
-+
-+LIB2FUNCS_EXTRA = \
-+ $(srcdir)/config/udivmodsi4.c \
-+ $(srcdir)/config/divmod.c \
-+ $(srcdir)/config/udivmod.c
-+
-+# If any special flags are necessary when building libgcc2 put them here.
-+#
-+# TARGET_LIBGCC2_CFLAGS =
-+
-+# 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
-+
-+fp-bit.c: $(srcdir)/config/fp-bit.c
-+ echo '#define FLOAT' > fp-bit.c
-+ cat $(srcdir)/config/fp-bit.c >> fp-bit.c
-+
-+dp-bit.c: $(srcdir)/config/fp-bit.c
-+ cat $(srcdir)/config/fp-bit.c > dp-bit.c
-+
-+# We only support v3 and v4 ISAs for uClinux.
-+
-+MULTILIB_OPTIONS = march=ubicom32v3/march=ubicom32v4
-+
-+EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o # crtbeginS.o crtendS.o
---- /dev/null
-+++ b/gcc/config/ubicom32/ubicom32-modes.def
-@@ -0,0 +1,30 @@
-+/* Definitions of target machine for GNU compiler, Ubicom32 architecture.
-+ Copyright (C) 2009 Free Software Foundation, Inc.
-+ Contributed by Ubicom, Inc.
-+
-+ This file is part of GCC.
-+
-+ GCC is free software; you can redistribute it and/or modify it
-+ under the terms of the GNU General Public License as published
-+ by the Free Software Foundation; either version 3, or (at your
-+ option) any later version.
-+
-+ GCC is distributed in the hope that it will be useful, but WITHOUT
-+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
-+ License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with GCC; see the file COPYING3. If not see
-+ <http://www.gnu.org/licenses/>. */
-+
-+/* Some insns set all condition code flags, some only set the Z and N flags, and
-+ some only set the Z flag. */
-+
-+CC_MODE (CCW);
-+CC_MODE (CCWZN);
-+CC_MODE (CCWZ);
-+CC_MODE (CCS);
-+CC_MODE (CCSZN);
-+CC_MODE (CCSZ);
-+
---- /dev/null
-+++ b/gcc/config/ubicom32/ubicom32-protos.h
-@@ -0,0 +1,84 @@
-+/* Function prototypes for Ubicom IP3000.
-+
-+ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
-+ 2009 Free Software Foundation, Inc.
-+ Contributed by Ubicom, Inc.
-+
-+ This file is part of GNU CC.
-+
-+ GNU CC is free software; you can redistribute it and/or modify it under
-+ the terms of the GNU General Public License as published by the Free
-+ Software Foundation; either version 2, or (at your option) any later
-+ version.
-+
-+ GNU CC is distributed in the hope that it will be useful, but WITHOUT
-+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-+ for more details.
-+
-+ You should have received a copy of the GNU General Public License along
-+ with GNU CC; see the file COPYING. If not, write to the Free Software
-+ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-+
-+#ifdef RTX_CODE
-+
-+#ifdef TREE_CODE
-+extern void ubicom32_va_start (tree, rtx);
-+#endif /* TREE_CODE */
-+
-+extern void ubicom32_print_operand (FILE *, rtx, int);
-+extern void ubicom32_print_operand_address (FILE *, rtx);
-+
-+extern void ubicom32_conditional_register_usage (void);
-+extern enum reg_class ubicom32_preferred_reload_class (rtx, enum reg_class);
-+extern int ubicom32_regno_ok_for_index_p (int, int);
-+extern void ubicom32_expand_movsi (rtx *);
-+extern void ubicom32_expand_addsi3 (rtx *);
-+extern int ubicom32_emit_mult_sequence (rtx *);
-+extern void ubicom32_emit_move_const_int (rtx, rtx);
-+extern bool ubicom32_legitimate_constant_p (rtx);
-+extern bool ubicom32_legitimate_address_p (enum machine_mode, rtx, int);
-+extern rtx ubicom32_legitimize_address (rtx, rtx, enum machine_mode);
-+extern rtx ubicom32_legitimize_reload_address (rtx, enum machine_mode, int, int);
-+extern void ubicom32_canonicalize_comparison (enum rtx_code *code, rtx *op0, rtx *op1);
-+extern int ubicom32_mode_dependent_address_p (rtx);
-+extern void ubicom32_output_cond_jump (rtx, rtx, rtx);
-+extern void ubicom32_expand_eh_return (rtx *);
-+extern void ubicom32_expand_call_fdpic (rtx *);
-+extern void ubicom32_expand_call_value_fdpic (rtx *);
-+extern enum machine_mode ubicom32_select_cc_mode (RTX_CODE, rtx, rtx);
-+extern rtx ubicom32_gen_compare_reg (RTX_CODE, rtx, rtx);
-+extern int ubicom32_shiftable_const_int (int);
-+#endif /* RTX_CODE */
-+
-+#ifdef TREE_CODE
-+extern void init_cumulative_args (CUMULATIVE_ARGS *cum,
-+ tree fntype,
-+ struct rtx_def *libname,
-+ int indirect);
-+extern struct rtx_def *function_arg (CUMULATIVE_ARGS *,
-+ enum machine_mode, tree, int);
-+extern struct rtx_def *function_incoming_arg (CUMULATIVE_ARGS *,
-+ enum machine_mode,
-+ tree, int);
-+extern int function_arg_partial_nregs (CUMULATIVE_ARGS *,
-+ enum machine_mode, tree, int);
-+extern struct rtx_def *ubicom32_va_arg (tree, tree);
-+extern int ubicom32_reg_parm_stack_space (tree);
-+#endif /* TREE_CODE */
-+
-+extern struct rtx_def * ubicom32_builtin_saveregs (void);
-+extern void asm_file_start (FILE *);
-+extern void ubicom32_expand_prologue (void);
-+extern void ubicom32_expand_epilogue (void);
-+extern int ubicom32_initial_elimination_offset (int, int);
-+extern int ubicom32_regno_ok_for_base_p (int, int);
-+extern bool ubicom32_hard_regno_mode_ok (unsigned int, enum machine_mode);
-+extern int ubicom32_can_use_return_insn_p (void);
-+extern rtx ubicom32_return_addr_rtx (int, rtx);
-+extern void ubicom32_optimization_options (int, int);
-+extern void ubicom32_override_options (void);
-+extern bool ubicom32_match_cc_mode (rtx, enum machine_mode);
-+
-+extern int ubicom32_reorg_completed;
-+
---- /dev/null
-+++ b/gcc/config/ubicom32/ubicom32.c
-@@ -0,0 +1,2881 @@
-+/* Subroutines for insn-output.c for Ubicom32
-+
-+ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
-+ 2009 Free Software Foundation, Inc.
-+ Contributed by Ubicom, Inc.
-+
-+ This file is part of GCC.
-+
-+ GCC is free software; you can redistribute it and/or modify it
-+ under the terms of the GNU General Public License as published
-+ by the Free Software Foundation; either version 3, or (at your
-+ option) any later version.
-+
-+ GCC is distributed in the hope that it will be useful, but WITHOUT
-+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
-+ License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with GCC; see the file COPYING3. If not see
-+ <http://www.gnu.org/licenses/>. */
-+
-+#include "config.h"
-+#include "system.h"
-+#include "coretypes.h"
-+#include "tm.h"
-+#include "rtl.h"
-+#include "tree.h"
-+#include "regs.h"
-+#include "hard-reg-set.h"
-+#include "real.h"
-+#include "insn-config.h"
-+#include "conditions.h"
-+#include "insn-flags.h"
-+#include "output.h"
-+#include "insn-attr.h"
-+#include "insn-codes.h"
-+#include "flags.h"
-+#include "recog.h"
-+#include "expr.h"
-+#include "function.h"
-+#include "obstack.h"
-+#include "toplev.h"
-+#include "tm_p.h"
-+#include "tm-constrs.h"
-+#include "basic-block.h"
-+#include "integrate.h"
-+#include "target.h"
-+#include "target-def.h"
-+#include "reload.h"
-+#include "df.h"
-+#include "langhooks.h"
-+#include "optabs.h"
-+
-+static tree ubicom32_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
-+static void ubicom32_layout_frame (void);
-+static void ubicom32_function_prologue (FILE *, HOST_WIDE_INT);
-+static void ubicom32_function_epilogue (FILE *, HOST_WIDE_INT);
-+static bool ubicom32_rtx_costs (rtx, int, int, int *, bool speed);
-+static bool ubicom32_fixed_condition_code_regs (unsigned int *,
-+ unsigned int *);
-+static enum machine_mode ubicom32_cc_modes_compatible (enum machine_mode,
-+ enum machine_mode);
-+static int ubicom32_naked_function_p (void);
-+static void ubicom32_machine_dependent_reorg (void);
-+static bool ubicom32_assemble_integer (rtx, unsigned int, int);
-+static void ubicom32_asm_init_sections (void);
-+static int ubicom32_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,tree,
-+ bool);
-+static bool ubicom32_pass_by_reference (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
-+ enum machine_mode mode, const_tree type,
-+ bool named ATTRIBUTE_UNUSED);
-+static bool ubicom32_callee_copies (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
-+ enum machine_mode mode, const_tree type,
-+ bool named ATTRIBUTE_UNUSED);
-+
-+static bool ubicom32_return_in_memory (const_tree type,
-+ const_tree fntype ATTRIBUTE_UNUSED);
-+static bool ubicom32_is_base_reg (rtx, int);
-+static void ubicom32_init_builtins (void);
-+static rtx ubicom32_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
-+static tree ubicom32_fold_builtin (tree, tree, bool);
-+static int ubicom32_get_valid_offset_mask (enum machine_mode);
-+static bool ubicom32_cannot_force_const_mem (rtx);
-+
-+/* Case values threshold */
-+int ubicom32_case_values_threshold = 6;
-+
-+/* Nonzero if this chip supports the Ubicom32 v3 ISA. */
-+int ubicom32_v3 = 1;
-+
-+/* Nonzero if this chip supports the Ubicom32 v4 ISA. */
-+int ubicom32_v4 = 1;
-+
-+/* Valid attributes:
-+ naked - don't generate function prologue/epilogue and `ret' command. */
-+const struct attribute_spec ubicom32_attribute_table[] =
-+{
-+ /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
-+ { "naked", 0, 0, true, false, false, ubicom32_handle_fndecl_attribute },
-+ { NULL, 0, 0, false, false, false, NULL }
-+};
-+
-+#undef TARGET_ASM_FUNCTION_PROLOGUE
-+#define TARGET_ASM_FUNCTION_PROLOGUE ubicom32_function_prologue
-+
-+#undef TARGET_ASM_FUNCTION_EPILOGUE
-+#define TARGET_ASM_FUNCTION_EPILOGUE ubicom32_function_epilogue
-+
-+#undef TARGET_ATTRIBUTE_TABLE
-+#define TARGET_ATTRIBUTE_TABLE ubicom32_attribute_table
-+
-+/* All addresses cost the same amount. */
-+#undef TARGET_ADDRESS_COST
-+#define TARGET_ADDRESS_COST hook_int_rtx_bool_0
-+
-+#undef TARGET_RTX_COSTS
-+#define TARGET_RTX_COSTS ubicom32_rtx_costs
-+
-+#undef TARGET_FIXED_CONDITION_CODE_REGS
-+#define TARGET_FIXED_CONDITION_CODE_REGS ubicom32_fixed_condition_code_regs
-+
-+#undef TARGET_CC_MODES_COMPATIBLE
-+#define TARGET_CC_MODES_COMPATIBLE ubicom32_cc_modes_compatible
-+
-+#undef TARGET_MACHINE_DEPENDENT_REORG
-+#define TARGET_MACHINE_DEPENDENT_REORG ubicom32_machine_dependent_reorg
-+
-+#undef TARGET_ASM_INTEGER
-+#define TARGET_ASM_INTEGER ubicom32_assemble_integer
-+
-+#undef TARGET_ASM_INIT_SECTIONS
-+#define TARGET_ASM_INIT_SECTIONS ubicom32_asm_init_sections
-+
-+#undef TARGET_ARG_PARTIAL_BYTES
-+#define TARGET_ARG_PARTIAL_BYTES ubicom32_arg_partial_bytes
-+
-+#undef TARGET_PASS_BY_REFERENCE
-+#define TARGET_PASS_BY_REFERENCE ubicom32_pass_by_reference
-+
-+#undef TARGET_CALLEE_COPIES
-+#define TARGET_CALLEE_COPIES ubicom32_callee_copies
-+
-+#undef TARGET_RETURN_IN_MEMORY
-+#define TARGET_RETURN_IN_MEMORY ubicom32_return_in_memory
-+
-+#undef TARGET_INIT_BUILTINS
-+#define TARGET_INIT_BUILTINS ubicom32_init_builtins
-+
-+#undef TARGET_EXPAND_BUILTIN
-+#define TARGET_EXPAND_BUILTIN ubicom32_expand_builtin
-+
-+#undef TARGET_FOLD_BUILTIN
-+#define TARGET_FOLD_BUILTIN ubicom32_fold_builtin
-+
-+#undef TARGET_CANNOT_FORCE_CONST_MEM
-+#define TARGET_CANNOT_FORCE_CONST_MEM ubicom32_cannot_force_const_mem
-+
-+struct gcc_target targetm = TARGET_INITIALIZER;
-+
-+static char save_regs[FIRST_PSEUDO_REGISTER];
-+static int nregs;
-+static int frame_size;
-+int ubicom32_stack_size = 0; /* size of allocated stack (including frame) */
-+int ubicom32_can_use_calli_to_ret;
-+
-+#define STACK_UNIT_BOUNDARY (STACK_BOUNDARY / BITS_PER_UNIT)
-+#define ROUND_CALL_BLOCK_SIZE(BYTES) \
-+ (((BYTES) + (STACK_UNIT_BOUNDARY - 1)) & ~(STACK_UNIT_BOUNDARY - 1))
-+
-+/* In case of a PRE_INC, POST_INC, PRE_DEC, POST_DEC memory reference, we
-+ must report the mode of the memory reference from PRINT_OPERAND to
-+ PRINT_OPERAND_ADDRESS. */
-+enum machine_mode output_memory_reference_mode;
-+
-+/* Flag for some split insns from the ubicom32.md. */
-+int ubicom32_reorg_completed;
-+
-+enum reg_class const ubicom32_regclass_map[FIRST_PSEUDO_REGISTER] =
-+{
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ FDPIC_REG,
-+ ADDRESS_REGS,
-+ ADDRESS_REGS,
-+ ADDRESS_REGS,
-+ ADDRESS_REGS,
-+ ADDRESS_REGS,
-+ ADDRESS_REGS,
-+ ADDRESS_REGS,
-+ ACC_REGS,
-+ ACC_LO_REGS,
-+ ACC_REGS,
-+ ACC_LO_REGS,
-+ SOURCE3_REG,
-+ ADDRESS_REGS,
-+ NO_REGS, /* CC_REG must be NO_REGS */
-+ SPECIAL_REGS,
-+ SPECIAL_REGS,
-+ SPECIAL_REGS,
-+ SPECIAL_REGS,
-+ SPECIAL_REGS,
-+ SPECIAL_REGS,
-+ SPECIAL_REGS,
-+ SPECIAL_REGS
-+};
-+
-+rtx ubicom32_compare_op0;
-+rtx ubicom32_compare_op1;
-+
-+/* Handle command line option overrides. */
-+
-+void
-+ubicom32_override_options (void)
-+{
-+ flag_pic = 0;
-+
-+ if (strcmp (ubicom32_arch_name, "ubicom32v1") == 0) {
-+ /* If we have a version 1 architecture then we want to avoid using jump
-+ tables. */
-+ ubicom32_case_values_threshold = 30000;
-+ ubicom32_v3 = 0;
-+ ubicom32_v4 = 0;
-+ } else if (strcmp (ubicom32_arch_name, "ubicom32v2") == 0) {
-+ ubicom32_v3 = 0;
-+ ubicom32_v4 = 0;
-+ } else if (strcmp (ubicom32_arch_name, "ubicom32v3") == 0) {
-+ ubicom32_v3 = 1;
-+ ubicom32_v4 = 0;
-+ } else if (strcmp (ubicom32_arch_name, "ubicom32v4") == 0) {
-+ ubicom32_v3 = 1;
-+ ubicom32_v4 = 1;
-+ }
-+
-+ /* There is no single unaligned SI op for PIC code. Sometimes we
-+ need to use ".4byte" and sometimes we need to use ".picptr".
-+ See ubicom32_assemble_integer for details. */
-+ if (TARGET_FDPIC)
-+ targetm.asm_out.unaligned_op.si = 0;
-+}
-+
-+void
-+ubicom32_conditional_register_usage (void)
-+{
-+ /* If we're using the old ipOS ABI we need to make D10 through D13
-+ caller-clobbered. */
-+ if (TARGET_IPOS_ABI)
-+ {
-+ call_used_regs[D10_REGNUM] = 1;
-+ call_used_regs[D11_REGNUM] = 1;
-+ call_used_regs[D12_REGNUM] = 1;
-+ call_used_regs[D13_REGNUM] = 1;
-+ }
-+}
-+
-+/* We have some number of optimizations that don't really work for the Ubicom32
-+ architecture so we deal with them here. */
-+
-+void
-+ubicom32_optimization_options (int level ATTRIBUTE_UNUSED,
-+ int size ATTRIBUTE_UNUSED)
-+{
-+ /* The tree IVOPTs pass seems to do really bad things for the Ubicom32
-+ architecture - it tends to turn things that would happily use pre/post
-+ increment/decrement into operations involving unecessary loop
-+ indicies. */
-+ flag_ivopts = 0;
-+
-+ /* We have problems where DSE at the RTL level misses partial stores
-+ to the stack. For now we disable it to avoid this. */
-+ flag_dse = 0;
-+}
-+
-+/* Print operand X using operand code CODE to assembly language output file
-+ FILE. */
-+
-+void
-+ubicom32_print_operand (FILE *file, rtx x, int code)
-+{
-+ switch (code)
-+ {
-+ case 'A':
-+ /* Identify the correct accumulator to use. */
-+ if (REGNO (x) == ACC0_HI_REGNUM || REGNO (x) == ACC0_LO_REGNUM)
-+ fprintf (file, "acc0");
-+ else if (REGNO (x) == ACC1_HI_REGNUM || REGNO (x) == ACC1_LO_REGNUM)
-+ fprintf (file, "acc1");
-+ else
-+ abort ();
-+ break;
-+
-+ case 'b':
-+ case 'B':
-+ {
-+ enum machine_mode mode;
-+
-+ mode = GET_MODE (XEXP (x, 0));
-+
-+ /* These are normal and reversed branches. */
-+ switch (code == 'b' ? GET_CODE (x) : reverse_condition (GET_CODE (x)))
-+ {
-+ case NE:
-+ fprintf (file, "ne");
-+ break;
-+
-+ case EQ:
-+ fprintf (file, "eq");
-+ break;
-+
-+ case GE:
-+ if (mode == CCSZNmode || mode == CCWZNmode)
-+ fprintf (file, "pl");
-+ else
-+ fprintf (file, "ge");
-+ break;
-+
-+ case GT:
-+ fprintf (file, "gt");
-+ break;
-+
-+ case LE:
-+ fprintf (file, "le");
-+ break;
-+
-+ case LT:
-+ if (mode == CCSZNmode || mode == CCWZNmode)
-+ fprintf (file, "mi");
-+ else
-+ fprintf (file, "lt");
-+ break;
-+
-+ case GEU:
-+ fprintf (file, "cs");
-+ break;
-+
-+ case GTU:
-+ fprintf (file, "hi");
-+ break;
-+
-+ case LEU:
-+ fprintf (file, "ls");
-+ break;
-+
-+ case LTU:
-+ fprintf (file, "cc");
-+ break;
-+
-+ default:
-+ abort ();
-+ }
-+ }
-+ break;
-+
-+ case 'C':
-+ /* This is used for the operand to a call instruction;
-+ if it's a REG, enclose it in parens, else output
-+ the operand normally. */
-+ if (REG_P (x))
-+ {
-+ fputc ('(', file);
-+ ubicom32_print_operand (file, x, 0);
-+ fputc (')', file);
-+ }
-+ else
-+ ubicom32_print_operand (file, x, 0);
-+ break;
-+
-+ case 'd':
-+ /* Bit operations we need bit numbers. */
-+ fprintf (file, "%d", exact_log2 (INTVAL (x)));
-+ break;
-+
-+ case 'D':
-+ /* Bit operations we need bit numbers. */
-+ fprintf (file, "%d", exact_log2 (~ INTVAL (x)));
-+ break;
-+
-+ case 'E':
-+ /* For lea, which we use to add address registers.
-+ We don't want the '#' on a constant. */
-+ if (CONST_INT_P (x))
-+ {
-+ fprintf (file, "%ld", INTVAL (x));
-+ break;
-+ }
-+ /* FALL THROUGH */
-+
-+ default:
-+ switch (GET_CODE (x))
-+ {
-+ case MEM:
-+ output_memory_reference_mode = GET_MODE (x);
-+ output_address (XEXP (x, 0));
-+ break;
-+
-+ case PLUS:
-+ output_address (x);
-+ break;
-+
-+ case REG:
-+ fprintf (file, "%s", reg_names[REGNO (x)]);
-+ break;
-+
-+ case SUBREG:
-+ fprintf (file, "%s", reg_names[subreg_regno (x)]);
-+ break;
-+
-+ /* This will only be single precision.... */
-+ case CONST_DOUBLE:
-+ {
-+ unsigned long val;
-+ REAL_VALUE_TYPE rv;
-+
-+ REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
-+ REAL_VALUE_TO_TARGET_SINGLE (rv, val);
-+ fprintf (file, "0x%lx", val);
-+ break;
-+ }
-+
-+ case CONST_INT:
-+ case SYMBOL_REF:
-+ case CONST:
-+ case LABEL_REF:
-+ case CODE_LABEL:
-+ case LO_SUM:
-+ ubicom32_print_operand_address (file, x);
-+ break;
-+
-+ case HIGH:
-+ fprintf (file, "#%%hi(");
-+ ubicom32_print_operand_address (file, XEXP (x, 0));
-+ fprintf (file, ")");
-+ break;
-+
-+ case UNSPEC:
-+ switch (XINT (x, 1))
-+ {
-+ case UNSPEC_FDPIC_GOT:
-+ fprintf (file, "#%%got_lo(");
-+ ubicom32_print_operand_address (file, XVECEXP (x, 0, 0));
-+ fprintf (file, ")");
-+ break;
-+
-+ case UNSPEC_FDPIC_GOT_FUNCDESC:
-+ fprintf (file, "#%%got_funcdesc_lo(");
-+ ubicom32_print_operand_address (file, XVECEXP (x, 0, 0));
-+ fprintf (file, ")");
-+ break;
-+
-+ default:
-+ abort ();
-+ }
-+ break;
-+
-+ default:
-+ abort ();
-+ }
-+ break;
-+ }
-+}
-+
-+/* Output assembly language output for the address ADDR to FILE. */
-+
-+void
-+ubicom32_print_operand_address (FILE *file, rtx addr)
-+{
-+ switch (GET_CODE (addr))
-+ {
-+ case POST_INC:
-+ ubicom32_print_operand_address (file, XEXP (addr, 0));
-+ fprintf (file, "%d++", GET_MODE_SIZE (output_memory_reference_mode));
-+ break;
-+
-+ case PRE_INC:
-+ fprintf (file, "%d", GET_MODE_SIZE (output_memory_reference_mode));
-+ ubicom32_print_operand_address (file, XEXP (addr, 0));
-+ fprintf (file, "++");
-+ break;
-+
-+ case POST_DEC:
-+ ubicom32_print_operand_address (file, XEXP (addr, 0));
-+ fprintf (file, "%d++", -GET_MODE_SIZE (output_memory_reference_mode));
-+ break;
-+
-+ case PRE_DEC:
-+ fprintf (file, "%d", -GET_MODE_SIZE (output_memory_reference_mode));
-+ ubicom32_print_operand_address (file, XEXP (addr, 0));
-+ fprintf (file, "++");
-+ break;
-+
-+ case POST_MODIFY:
-+ ubicom32_print_operand_address (file, XEXP (addr, 0));
-+ fprintf (file, "%ld++", INTVAL (XEXP (XEXP (addr,1), 1)));
-+ break;
-+
-+ case PRE_MODIFY:
-+ fprintf (file, "%ld", INTVAL (XEXP (XEXP (addr,1), 1)));
-+ ubicom32_print_operand_address (file, XEXP (addr, 0));
-+ fprintf (file, "++");
-+ break;
-+
-+ case REG:
-+ fputc ('(', file);
-+ fprintf (file, "%s", reg_names[REGNO (addr)]);
-+ fputc (')', file);
-+ break;
-+
-+ case PLUS:
-+ {
-+ rtx base = XEXP (addr, 0);
-+ rtx index = XEXP (addr, 1);
-+
-+ /* Switch around addresses of the form index * scaling + base. */
-+ if (! ubicom32_is_base_reg (base, 1))
-+ {
-+ rtx tmp = base;
-+ base = index;
-+ index = tmp;
-+ }
-+
-+ if (CONST_INT_P (index))
-+ {
-+ fprintf (file, "%ld", INTVAL (index));
-+ fputc ('(', file);
-+ fputs (reg_names[REGNO (base)], file);
-+ }
-+ else if (GET_CODE (index) == MULT
-+ || REG_P (index))
-+ {
-+ if (GET_CODE (index) == MULT)
-+ index = XEXP (index, 0);
-+ fputc ('(', file);
-+ fputs (reg_names[REGNO (base)], file);
-+ fputc (',', file);
-+ fputs (reg_names[REGNO (index)], file);
-+ }
-+ else
-+ abort ();
-+
-+ fputc (')', file);
-+ break;
-+ }
-+
-+ case LO_SUM:
-+ fprintf (file, "%%lo(");
-+ ubicom32_print_operand (file, XEXP (addr, 1), 'L');
-+ fprintf (file, ")(");
-+ ubicom32_print_operand (file, XEXP (addr, 0), 0);
-+ fprintf (file, ")");
-+ break;
-+
-+ case CONST_INT:
-+ fputc ('#', file);
-+ output_addr_const (file, addr);
-+ break;
-+
-+ default:
-+ output_addr_const (file, addr);
-+ break;
-+ }
-+}
-+
-+/* X and Y are two things to compare using CODE. Emit the compare insn and
-+ return the rtx for the cc reg in the proper mode. */
-+
-+rtx
-+ubicom32_gen_compare_reg (enum rtx_code code, rtx x, rtx y)
-+{
-+ enum machine_mode mode = SELECT_CC_MODE (code, x, y);
-+ rtx cc_reg;
-+
-+ cc_reg = gen_rtx_REG (mode, CC_REGNUM);
-+
-+ emit_insn (gen_rtx_SET (VOIDmode, cc_reg,
-+ gen_rtx_COMPARE (mode, x, y)));
-+
-+ return cc_reg;
-+}
-+
-+/* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
-+ return the mode to be used for the comparison. */
-+
-+enum machine_mode
-+ubicom32_select_cc_mode (enum rtx_code op, rtx x, rtx y)
-+{
-+ /* Is this a short compare? */
-+ if (GET_MODE (x) == QImode
-+ || GET_MODE (x) == HImode
-+ || GET_MODE (y) == QImode
-+ || GET_MODE (y) == HImode)
-+ {
-+ switch (op)
-+ {
-+ case EQ :
-+ case NE :
-+ return CCSZmode;
-+
-+ case GE:
-+ case LT:
-+ if (y == const0_rtx)
-+ return CCSZNmode;
-+
-+ default :
-+ return CCSmode;
-+ }
-+ }
-+
-+ /* We have a word compare. */
-+ switch (op)
-+ {
-+ case EQ :
-+ case NE :
-+ return CCWZmode;
-+
-+ case GE :
-+ case LT :
-+ if (y == const0_rtx)
-+ return CCWZNmode;
-+
-+ default :
-+ return CCWmode;
-+ }
-+}
-+
-+/* Return TRUE or FALSE depending on whether the first SET in INSN
-+ has source and destination with matching CC modes, and that the
-+ CC mode is at least as constrained as REQ_MODE. */
-+bool
-+ubicom32_match_cc_mode (rtx insn, enum machine_mode req_mode)
-+{
-+ rtx set;
-+ enum machine_mode set_mode;
-+
-+ set = PATTERN (insn);
-+ if (GET_CODE (set) == PARALLEL)
-+ set = XVECEXP (set, 0, 0);
-+ gcc_assert (GET_CODE (set) == SET);
-+ gcc_assert (GET_CODE (SET_SRC (set)) == COMPARE);
-+
-+ /* SET_MODE is the mode we have in the instruction. This must either
-+ be the same or less restrictive that the required mode REQ_MODE. */
-+ set_mode = GET_MODE (SET_DEST (set));
-+
-+ switch (req_mode)
-+ {
-+ case CCSZmode:
-+ if (set_mode != CCSZmode)
-+ return 0;
-+ break;
-+
-+ case CCSZNmode:
-+ if (set_mode != CCSZmode
-+ && set_mode != CCSZNmode)
-+ return 0;
-+ break;
-+
-+ case CCSmode:
-+ if (set_mode != CCSmode
-+ && set_mode != CCSZmode
-+ && set_mode != CCSZNmode)
-+ return 0;
-+ break;
-+
-+ case CCWZmode:
-+ if (set_mode != CCWZmode)
-+ return 0;
-+ break;
-+
-+ case CCWZNmode:
-+ if (set_mode != CCWZmode
-+ && set_mode != CCWZNmode)
-+ return 0;
-+ break;
-+
-+ case CCWmode:
-+ if (set_mode != CCWmode
-+ && set_mode != CCWZmode
-+ && set_mode != CCWZNmode)
-+ return 0;
-+ break;
-+
-+ default:
-+ gcc_unreachable ();
-+ }
-+
-+ return (GET_MODE (SET_SRC (set)) == set_mode);
-+}
-+
-+/* Replace the comparison OP0 CODE OP1 by a semantically equivalent one
-+ that we can implement more efficiently. */
-+
-+void
-+ubicom32_canonicalize_comparison (enum rtx_code *code, rtx *op0, rtx *op1)
-+{
-+ /* If we have a REG and a MEM then compare the MEM with the REG and not
-+ the other way round. */
-+ if (REG_P (*op0) && MEM_P (*op1))
-+ {
-+ rtx tem = *op0;
-+ *op0 = *op1;
-+ *op1 = tem;
-+ *code = swap_condition (*code);
-+ return;
-+ }
-+
-+ /* If we have a REG and a CONST_INT then we may want to reverse things
-+ if the constant can be represented as an "I" constraint. */
-+ if (REG_P (*op0) && CONST_INT_P (*op1) && satisfies_constraint_I (*op1))
-+ {
-+ rtx tem = *op0;
-+ *op0 = *op1;
-+ *op1 = tem;
-+ *code = swap_condition (*code);
-+ return;
-+ }
-+}
-+
-+/* Return the fixed registers used for condition codes. */
-+
-+static bool
-+ubicom32_fixed_condition_code_regs (unsigned int *p1, unsigned int *p2)
-+{
-+ *p1 = CC_REGNUM;
-+ *p2 = INVALID_REGNUM;
-+
-+ return true;
-+}
-+
-+/* If two condition code modes are compatible, return a condition code
-+ mode which is compatible with both. Otherwise, return
-+ VOIDmode. */
-+
-+static enum machine_mode
-+ubicom32_cc_modes_compatible (enum machine_mode m1, enum machine_mode m2)
-+{
-+ if (m1 == m2)
-+ return m1;
-+
-+ if (GET_MODE_CLASS (m1) != MODE_CC || GET_MODE_CLASS (m2) != MODE_CC)
-+ return VOIDmode;
-+
-+ switch (m1)
-+ {
-+ case CCWmode:
-+ if (m2 == CCWZNmode || m2 == CCWZmode)
-+ return m1;
-+
-+ return VOIDmode;
-+
-+ case CCWZNmode:
-+ if (m2 == CCWmode)
-+ return m2;
-+
-+ if (m2 == CCWZmode)
-+ return m1;
-+
-+ return VOIDmode;
-+
-+ case CCWZmode:
-+ if (m2 == CCWmode || m2 == CCWZNmode)
-+ return m2;
-+
-+ return VOIDmode;
-+
-+ case CCSmode:
-+ if (m2 == CCSZNmode || m2 == CCSZmode)
-+ return m1;
-+
-+ return VOIDmode;
-+
-+ case CCSZNmode:
-+ if (m2 == CCSmode)
-+ return m2;
-+
-+ if (m2 == CCSZmode)
-+ return m1;
-+
-+ return VOIDmode;
-+
-+ case CCSZmode:
-+ if (m2 == CCSmode || m2 == CCSZNmode)
-+ return m2;
-+
-+ return VOIDmode;
-+
-+ default:
-+ gcc_unreachable ();
-+ }
-+}
-+
-+static rtx
-+ubicom32_legitimize_fdpic_address_symbol (rtx orig, rtx reg, rtx fdpic_reg)
-+{
-+ int unspec;
-+ rtx got_offs;
-+ rtx got_offs_scaled;
-+ rtx plus_scaled;
-+ rtx tmp;
-+ rtx new_rtx;
-+
-+ gcc_assert (reg != 0);
-+
-+ if (GET_CODE (orig) == SYMBOL_REF
-+ && SYMBOL_REF_FUNCTION_P (orig))
-+ unspec = UNSPEC_FDPIC_GOT_FUNCDESC;
-+ else
-+ unspec = UNSPEC_FDPIC_GOT;
-+
-+ got_offs = gen_reg_rtx (SImode);
-+ tmp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, orig), unspec);
-+ emit_move_insn (got_offs, tmp);
-+
-+ got_offs_scaled = gen_rtx_MULT (SImode, got_offs, GEN_INT (4));
-+ plus_scaled = gen_rtx_PLUS (Pmode, fdpic_reg, got_offs_scaled);
-+ new_rtx = gen_const_mem (Pmode, plus_scaled);
-+ emit_move_insn (reg, new_rtx);
-+
-+ return reg;
-+}
-+
-+static rtx
-+ubicom32_legitimize_fdpic_address (rtx orig, rtx reg, rtx fdpic_reg)
-+{
-+ rtx addr = orig;
-+ rtx new_rtx = orig;
-+
-+ if (GET_CODE (addr) == CONST || GET_CODE (addr) == PLUS)
-+ {
-+ rtx base;
-+
-+ if (GET_CODE (addr) == CONST)
-+ {
-+ addr = XEXP (addr, 0);
-+ gcc_assert (GET_CODE (addr) == PLUS);
-+ }
-+
-+ base = ubicom32_legitimize_fdpic_address_symbol (XEXP (addr, 0), reg, fdpic_reg);
-+ return gen_rtx_PLUS (Pmode, base, XEXP (addr, 1));
-+ }
-+
-+ return new_rtx;
-+}
-+
-+/* Code generation. */
-+
-+void
-+ubicom32_expand_movsi (rtx *operands)
-+{
-+ if (GET_CODE (operands[1]) == SYMBOL_REF
-+ || (GET_CODE (operands[1]) == CONST
-+ && GET_CODE (XEXP (operands[1], 0)) == PLUS
-+ && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
-+ || CONSTANT_ADDRESS_P (operands[1]))
-+ {
-+ if (TARGET_FDPIC)
-+ {
-+ rtx tmp;
-+ rtx fdpic_reg;
-+
-+ gcc_assert (can_create_pseudo_p ());
-+ tmp = gen_reg_rtx (Pmode);
-+ fdpic_reg = get_hard_reg_initial_val (SImode, FDPIC_REGNUM);
-+ if (GET_CODE (operands[1]) == SYMBOL_REF
-+ || GET_CODE (operands[1]) == LABEL_REF)
-+ operands[1] = ubicom32_legitimize_fdpic_address_symbol (operands[1], tmp, fdpic_reg);
-+ else
-+ operands[1] = ubicom32_legitimize_fdpic_address (operands[1], tmp, fdpic_reg);
-+ }
-+ else
-+ {
-+ rtx tmp;
-+ enum machine_mode mode;
-+
-+ /* We want to avoid reusing operand 0 if we can because it limits
-+ our ability to optimize later. */
-+ tmp = ! can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
-+
-+ mode = GET_MODE (operands[0]);
-+ emit_insn (gen_rtx_SET (VOIDmode, tmp,
-+ gen_rtx_HIGH (mode, operands[1])));
-+ operands[1] = gen_rtx_LO_SUM (mode, tmp, operands[1]);
-+ if (can_create_pseudo_p() && ! REG_P (operands[0]))
-+ {
-+ tmp = gen_reg_rtx (mode);
-+ emit_insn (gen_rtx_SET (VOIDmode, tmp, operands[1]));
-+ operands[1] = tmp;
-+ }
-+ }
-+ }
-+}
-+
-+/* Emit code for addsi3. */
-+
-+void
-+ubicom32_expand_addsi3 (rtx *operands)
-+{
-+ rtx op, clob;
-+
-+ if (can_create_pseudo_p ())
-+ {
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (SImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (SImode, operands[2]);
-+ }
-+
-+ /* Emit the instruction. */
-+
-+ op = gen_rtx_SET (VOIDmode, operands[0],
-+ gen_rtx_PLUS (SImode, operands[1], operands[2]));
-+
-+ if (! can_create_pseudo_p ())
-+ {
-+ /* Reload doesn't know about the flags register, and doesn't know that
-+ it doesn't want to clobber it. We can only do this with PLUS. */
-+ emit_insn (op);
-+ }
-+ else
-+ {
-+ clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM));
-+ emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, op, clob)));
-+ }
-+}
-+
-+/* Emit code for mulsi3. Return 1 if we have generated all the code
-+ necessary to do the multiplication. */
-+
-+int
-+ubicom32_emit_mult_sequence (rtx *operands)
-+{
-+ if (! ubicom32_v4)
-+ {
-+ rtx a1, a1_1, a2;
-+ rtx b1, b1_1, b2;
-+ rtx mac_lo_rtx;
-+ rtx t1, t2, t3;
-+
-+ /* Give up if we cannot create new pseudos. */
-+ if (!can_create_pseudo_p())
-+ return 0;
-+
-+ /* Synthesize 32-bit multiplication using 16-bit operations:
-+
-+ a1 = highpart (a)
-+ a2 = lowpart (a)
-+
-+ b1 = highpart (b)
-+ b2 = lowpart (b)
-+
-+ c = (a1 * b1) << 32 + (a1 * b2) << 16 + (a2 * b1) << 16 + a2 * b2
-+ = 0 + (a1 * b2) << 16 + (a2 * b1) << 16 + a2 * b2
-+ ^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^ ^^^^^^^
-+ Signed Signed Unsigned */
-+
-+ if (!ubicom32_data_register_operand (operands[1], GET_MODE (operands[1])))
-+ {
-+ rtx op1;
-+
-+ op1 = gen_reg_rtx (SImode);
-+ emit_move_insn (op1, operands[1]);
-+ operands[1] = op1;
-+ }
-+
-+ if (!ubicom32_data_register_operand (operands[2], GET_MODE (operands[2])))
-+ {
-+ rtx op2;
-+
-+ op2 = gen_reg_rtx (SImode);
-+ emit_move_insn (op2, operands[2]);
-+ operands[2] = op2;
-+ }
-+
-+ /* a1 = highpart (a) */
-+ a1 = gen_reg_rtx (HImode);
-+ a1_1 = gen_reg_rtx (SImode);
-+ emit_insn (gen_ashrsi3 (a1_1, operands[1], GEN_INT (16)));
-+ emit_move_insn (a1, gen_lowpart (HImode, a1_1));
-+
-+ /* a2 = lowpart (a) */
-+ a2 = gen_reg_rtx (HImode);
-+ emit_move_insn (a2, gen_lowpart (HImode, operands[1]));
-+
-+ /* b1 = highpart (b) */
-+ b1 = gen_reg_rtx (HImode);
-+ b1_1 = gen_reg_rtx (SImode);
-+ emit_insn (gen_ashrsi3 (b1_1, operands[2], GEN_INT (16)));
-+ emit_move_insn (b1, gen_lowpart (HImode, b1_1));
-+
-+ /* b2 = lowpart (b) */
-+ b2 = gen_reg_rtx (HImode);
-+ emit_move_insn (b2, gen_lowpart (HImode, operands[2]));
-+
-+ /* t1 = (a1 * b2) << 16 */
-+ t1 = gen_reg_rtx (SImode);
-+ mac_lo_rtx = gen_rtx_REG (SImode, ACC0_LO_REGNUM);
-+ emit_insn (gen_mulhisi3 (mac_lo_rtx, a1, b2));
-+ emit_insn (gen_ashlsi3 (t1, mac_lo_rtx, GEN_INT (16)));
-+
-+ /* t2 = (a2 * b1) << 16 */
-+ t2 = gen_reg_rtx (SImode);
-+ emit_insn (gen_mulhisi3 (mac_lo_rtx, a2, b1));
-+ emit_insn (gen_ashlsi3 (t2, mac_lo_rtx, GEN_INT (16)));
-+
-+ /* mac_lo = a2 * b2 */
-+ emit_insn (gen_umulhisi3 (mac_lo_rtx, a2, b2));
-+
-+ /* t3 = t1 + t2 */
-+ t3 = gen_reg_rtx (SImode);
-+ emit_insn (gen_addsi3 (t3, t1, t2));
-+
-+ /* c = t3 + mac_lo_rtx */
-+ emit_insn (gen_addsi3 (operands[0], mac_lo_rtx, t3));
-+
-+ return 1;
-+ }
-+ else
-+ {
-+ rtx acc_rtx;
-+
-+ /* Give up if we cannot create new pseudos. */
-+ if (!can_create_pseudo_p())
-+ return 0;
-+
-+ if (!ubicom32_data_register_operand (operands[1], GET_MODE (operands[1])))
-+ {
-+ rtx op1;
-+
-+ op1 = gen_reg_rtx (SImode);
-+ emit_move_insn (op1, operands[1]);
-+ operands[1] = op1;
-+ }
-+
-+ if (!ubicom32_data_register_operand (operands[2], GET_MODE (operands[2])))
-+ {
-+ rtx op2;
-+
-+ op2 = gen_reg_rtx (SImode);
-+ emit_move_insn (op2, operands[2]);
-+ operands[2] = op2;
-+ }
-+
-+ acc_rtx = gen_reg_rtx (DImode);
-+ emit_insn (gen_umulsidi3 (acc_rtx, operands[1], operands[2]));
-+ emit_move_insn (operands[0], gen_lowpart (SImode, acc_rtx));
-+
-+ return 1;
-+ }
-+}
-+
-+/* Move the integer value VAL into OPERANDS[0]. */
-+
-+void
-+ubicom32_emit_move_const_int (rtx dest, rtx imm)
-+{
-+ rtx xoperands[2];
-+
-+ xoperands[0] = dest;
-+ xoperands[1] = imm;
-+
-+ /* Treat mem destinations separately. Values must be explicitly sign
-+ extended. */
-+ if (MEM_P (dest))
-+ {
-+ rtx low_hword_mem;
-+ rtx low_hword_addr;
-+
-+ /* Emit shorter sequence for signed 7-bit quantities. */
-+ if (satisfies_constraint_I (imm))
-+ {
-+ output_asm_insn ("move.4\t%0, %1", xoperands);
-+ return;
-+ }
-+
-+ /* Special case for pushing constants. */
-+ if (GET_CODE (XEXP (dest, 0)) == PRE_DEC
-+ && XEXP (XEXP (dest, 0), 0) == stack_pointer_rtx)
-+ {
-+ output_asm_insn ("movei\t-4(sp)++, #%%hi(%E1)", xoperands);
-+ output_asm_insn ("movei\t2(sp), #%%lo(%E1)", xoperands);
-+ return;
-+ }
-+
-+ /* See if we can add 2 to the original address. This is only
-+ possible if the original address is of the form REG or
-+ REG+const. */
-+ low_hword_addr = plus_constant (XEXP (dest, 0), 2);
-+ if (ubicom32_legitimate_address_p (HImode, low_hword_addr, 1))
-+ {
-+ low_hword_mem = gen_rtx_MEM (HImode, low_hword_addr);
-+ MEM_COPY_ATTRIBUTES (low_hword_mem, dest);
-+ output_asm_insn ("movei\t%0, #%%hi(%E1)", xoperands);
-+ xoperands[0] = low_hword_mem;
-+ output_asm_insn ("movei\t%0, #%%lo(%E1)", xoperands);
-+ return;
-+ }
-+
-+ /* The original address is too complex. We need to use a
-+ scratch memory by (sp) and move that to the original
-+ destination. */
-+ if (! reg_mentioned_p (stack_pointer_rtx, dest))
-+ {
-+ output_asm_insn ("movei\t-4(sp)++, #%%hi(%E1)", xoperands);
-+ output_asm_insn ("movei\t2(sp), #%%lo(%E1)", xoperands);
-+ output_asm_insn ("move.4\t%0, (sp)4++", xoperands);
-+ return;
-+ }
-+
-+ /* Our address mentions the stack pointer so we need to
-+ use our scratch data register here as well as scratch
-+ memory. */
-+ output_asm_insn ("movei\t-4(sp)++, #%%hi(%E1)", xoperands);
-+ output_asm_insn ("movei\t2(sp), #%%lo(%E1)", xoperands);
-+ output_asm_insn ("move.4\td15, (sp)4++", xoperands);
-+ output_asm_insn ("move.4\t%0, d15", xoperands);
-+ return;
-+ }
-+
-+ /* Move into registers are zero extended by default. */
-+ if (! REG_P (dest))
-+ abort ();
-+
-+ if (satisfies_constraint_N (imm))
-+ {
-+ output_asm_insn ("movei\t%0, %1", xoperands);
-+ return;
-+ }
-+
-+ if (INTVAL (xoperands[1]) >= 0xff80
-+ && INTVAL (xoperands[1]) < 0x10000)
-+ {
-+ xoperands[1] = GEN_INT (INTVAL (xoperands[1]) - 0x10000);
-+ output_asm_insn ("move.2\t%0, %1", xoperands);
-+ return;
-+ }
-+
-+ if ((REGNO_REG_CLASS (REGNO (xoperands[0])) == ADDRESS_REGS
-+ || REGNO_REG_CLASS (REGNO (xoperands[0])) == FDPIC_REG)
-+ && ((INTVAL (xoperands[1]) & 0x80000000) == 0))
-+ {
-+ output_asm_insn ("moveai\t%0, #%%hi(%E1)", xoperands);
-+ if ((INTVAL (xoperands[1]) & 0x7f) != 0)
-+ output_asm_insn ("lea.1\t%0, %%lo(%E1)(%0)", xoperands);
-+ return;
-+ }
-+
-+ if ((INTVAL (xoperands[1]) & 0xffff0000) == 0)
-+ {
-+ output_asm_insn ("movei\t%0, #%%lo(%E1)", xoperands);
-+ output_asm_insn ("move.2\t%0, %0", xoperands);
-+ return;
-+ }
-+
-+ /* This is very expensive. The constant is so large that we
-+ need to use the stack to do the load. */
-+ output_asm_insn ("movei\t-4(sp)++, #%%hi(%E1)", xoperands);
-+ output_asm_insn ("movei\t2(sp), #%%lo(%E1)", xoperands);
-+ output_asm_insn ("move.4\t%0, (sp)4++", xoperands);
-+}
-+
-+/* Stack layout. Prologue/Epilogue. */
-+
-+static int save_regs_size;
-+
-+static void
-+ubicom32_layout_frame (void)
-+{
-+ int regno;
-+
-+ memset ((char *) &save_regs[0], 0, sizeof (save_regs));
-+ nregs = 0;
-+ frame_size = get_frame_size ();
-+
-+ if (frame_pointer_needed || df_regs_ever_live_p (FRAME_POINTER_REGNUM))
-+ {
-+ save_regs[FRAME_POINTER_REGNUM] = 1;
-+ ++nregs;
-+ }
-+
-+ if (current_function_is_leaf && ! df_regs_ever_live_p (LINK_REGNO))
-+ ubicom32_can_use_calli_to_ret = 1;
-+ else
-+ {
-+ ubicom32_can_use_calli_to_ret = 0;
-+ save_regs[LINK_REGNO] = 1;
-+ ++nregs;
-+ }
-+
-+ /* Figure out which register(s) needs to be saved. */
-+ for (regno = 0; regno <= LAST_ADDRESS_REGNUM; regno++)
-+ if (df_regs_ever_live_p(regno)
-+ && ! call_used_regs[regno]
-+ && ! fixed_regs[regno]
-+ && ! save_regs[regno])
-+ {
-+ save_regs[regno] = 1;
-+ ++nregs;
-+ }
-+
-+ save_regs_size = 4 * nregs;
-+}
-+
-+static void
-+ubicom32_emit_add_movsi (int regno, int adj)
-+{
-+ rtx x;
-+ rtx reg = gen_rtx_REG (SImode, regno);
-+
-+ adj += 4;
-+ if (adj > 8 * 4)
-+ {
-+ x = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
-+ GEN_INT (-adj)));
-+ RTX_FRAME_RELATED_P (x) = 1;
-+ x = emit_move_insn (gen_rtx_MEM (SImode, stack_pointer_rtx), reg);
-+ }
-+ else
-+ {
-+ rtx addr = gen_rtx_PRE_MODIFY (Pmode, stack_pointer_rtx,
-+ gen_rtx_PLUS (Pmode, stack_pointer_rtx,
-+ GEN_INT (-adj)));
-+ x = emit_move_insn (gen_rtx_MEM (SImode, addr), reg);
-+ }
-+ RTX_FRAME_RELATED_P (x) = 1;
-+}
-+
-+void
-+ubicom32_expand_prologue (void)
-+{
-+ rtx x;
-+ int regno;
-+ int outgoing_args_size = crtl->outgoing_args_size;
-+ int adj;
-+
-+ if (ubicom32_naked_function_p ())
-+ return;
-+
-+ ubicom32_builtin_saveregs ();
-+
-+ ubicom32_layout_frame ();
-+ adj = (outgoing_args_size + get_frame_size () + save_regs_size
-+ + crtl->args.pretend_args_size);
-+
-+ if (!adj)
-+ ;
-+ else if (outgoing_args_size + save_regs_size < 508
-+ && get_frame_size () + save_regs_size > 508)
-+ {
-+ int i = 0;
-+ x = gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
-+ GEN_INT (-adj));
-+ x = emit_insn (x);
-+ RTX_FRAME_RELATED_P (x) = 1;
-+
-+ for (regno = LAST_ADDRESS_REGNUM; regno >= 0; --regno)
-+ if (save_regs[regno] && regno != LINK_REGNO)
-+ {
-+ x = gen_rtx_MEM (SImode,
-+ gen_rtx_PLUS (Pmode,
-+ stack_pointer_rtx,
-+ GEN_INT (i * 4 + outgoing_args_size)));
-+ x = emit_move_insn (x, gen_rtx_REG (SImode, regno));
-+ RTX_FRAME_RELATED_P (x) = 1;
-+ ++i;
-+ }
-+ if (save_regs[LINK_REGNO])
-+ {
-+ x = gen_rtx_MEM (SImode,
-+ gen_rtx_PLUS (Pmode,
-+ stack_pointer_rtx,
-+ GEN_INT (i * 4 + outgoing_args_size)));
-+ x = emit_move_insn (x, gen_rtx_REG (SImode, LINK_REGNO));
-+ RTX_FRAME_RELATED_P (x) = 1;
-+ }
-+ }
-+ else
-+ {
-+ int regno;
-+ int adj = get_frame_size () + crtl->args.pretend_args_size;
-+ int i = 0;
-+
-+ if (save_regs[LINK_REGNO])
-+ {
-+ ubicom32_emit_add_movsi (LINK_REGNO, adj);
-+ ++i;
-+ }
-+
-+ for (regno = 0; regno <= LAST_ADDRESS_REGNUM; ++regno)
-+ if (save_regs[regno] && regno != LINK_REGNO)
-+ {
-+ if (i)
-+ {
-+ rtx mem = gen_rtx_MEM (SImode,
-+ gen_rtx_PRE_DEC (Pmode,
-+ stack_pointer_rtx));
-+ x = emit_move_insn (mem, gen_rtx_REG (SImode, regno));
-+ RTX_FRAME_RELATED_P (x) = 1;
-+ }
-+ else
-+ ubicom32_emit_add_movsi (regno, adj);
-+ ++i;
-+ }
-+
-+ if (outgoing_args_size || (!i && adj))
-+ {
-+ x = gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
-+ GEN_INT (-outgoing_args_size - (i ? 0 : adj)));
-+ x = emit_insn (x);
-+ RTX_FRAME_RELATED_P (x) = 1;
-+ }
-+ }
-+
-+ if (frame_pointer_needed)
-+ {
-+ int fp_adj = save_regs_size + outgoing_args_size;
-+ x = gen_addsi3 (frame_pointer_rtx, stack_pointer_rtx,
-+ GEN_INT (fp_adj));
-+ x = emit_insn (x);
-+ RTX_FRAME_RELATED_P (x) = 1;
-+ }
-+}
-+
-+void
-+ubicom32_expand_epilogue (void)
-+{
-+ rtx x;
-+ int regno;
-+ int outgoing_args_size = crtl->outgoing_args_size;
-+ int adj;
-+ int i;
-+
-+ if (ubicom32_naked_function_p ())
-+ {
-+ emit_jump_insn (gen_return_internal (gen_rtx_REG (SImode,
-+ LINK_REGNO)));
-+ return;
-+ }
-+
-+ if (cfun->calls_alloca)
-+ {
-+ x = gen_addsi3 (stack_pointer_rtx, frame_pointer_rtx,
-+ GEN_INT (-save_regs_size));
-+ emit_insn (x);
-+ outgoing_args_size = 0;
-+ }
-+
-+ if (outgoing_args_size)
-+ {
-+ x = gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
-+ GEN_INT (outgoing_args_size));
-+ emit_insn (x);
-+ }
-+
-+ i = 0;
-+ for (regno = LAST_ADDRESS_REGNUM; regno >= 0; --regno)
-+ if (save_regs[regno] && regno != LINK_REGNO)
-+ {
-+ x = gen_rtx_MEM (SImode, gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
-+ emit_move_insn (gen_rtx_REG (SImode, regno), x);
-+ ++i;
-+ }
-+
-+ /* Do we have to adjust the stack after we've finished restoring regs? */
-+ adj = get_frame_size() + crtl->args.pretend_args_size;
-+ if (cfun->stdarg)
-+ adj += UBICOM32_FUNCTION_ARG_REGS * UNITS_PER_WORD;
-+
-+#if 0
-+ if (crtl->calls_eh_return && 0)
-+ {
-+ if (save_regs[LINK_REGNO])
-+ {
-+ x = gen_rtx_MEM (SImode, gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
-+ emit_move_insn (gen_rtx_REG (SImode, LINK_REGNO), x);
-+ }
-+
-+ if (adj)
-+ {
-+ x = gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
-+ GEN_INT (adj));
-+ x = emit_insn (x);
-+ }
-+
-+ /* Perform the additional bump for __throw. */
-+ emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
-+ EH_RETURN_STACKADJ_RTX));
-+ emit_jump_insn (gen_eh_return_internal ());
-+ return;
-+ }
-+#endif
-+
-+ if (save_regs[LINK_REGNO])
-+ {
-+ if (adj >= 4 && adj <= (6 * 4))
-+ {
-+ x = GEN_INT (adj + 4);
-+ emit_jump_insn (gen_return_from_post_modify_sp (x));
-+ return;
-+ }
-+
-+ if (adj == 0)
-+ {
-+ x = gen_rtx_MEM (SImode, gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
-+ emit_jump_insn (gen_return_internal (x));
-+ return;
-+ }
-+
-+ x = gen_rtx_MEM (SImode, gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
-+ emit_move_insn (gen_rtx_REG (SImode, LINK_REGNO), x);
-+ }
-+
-+ if (adj)
-+ {
-+ x = gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
-+ GEN_INT (adj));
-+ x = emit_insn (x);
-+ adj = 0;
-+ }
-+
-+ /* Given that we've just done all the hard work here we may as well use
-+ a calli to return. */
-+ ubicom32_can_use_calli_to_ret = 1;
-+ emit_jump_insn (gen_return_internal (gen_rtx_REG (SImode, LINK_REGNO)));
-+}
-+
-+void
-+ubicom32_expand_call_fdpic (rtx *operands)
-+{
-+ rtx c;
-+ rtx addr;
-+ rtx fdpic_reg = get_hard_reg_initial_val (SImode, FDPIC_REGNUM);
-+
-+ addr = XEXP (operands[0], 0);
-+
-+ c = gen_call_fdpic (addr, operands[1], fdpic_reg);
-+ emit_call_insn (c);
-+}
-+
-+void
-+ubicom32_expand_call_value_fdpic (rtx *operands)
-+{
-+ rtx c;
-+ rtx addr;
-+ rtx fdpic_reg = get_hard_reg_initial_val (SImode, FDPIC_REGNUM);
-+
-+ addr = XEXP (operands[1], 0);
-+
-+ c = gen_call_value_fdpic (operands[0], addr, operands[2], fdpic_reg);
-+ emit_call_insn (c);
-+}
-+
-+void
-+ubicom32_expand_eh_return (rtx *operands)
-+{
-+ if (REG_P (operands[0])
-+ || REGNO (operands[0]) != EH_RETURN_STACKADJ_REGNO)
-+ {
-+ rtx sp = EH_RETURN_STACKADJ_RTX;
-+ emit_move_insn (sp, operands[0]);
-+ operands[0] = sp;
-+ }
-+
-+ if (REG_P (operands[1])
-+ || REGNO (operands[1]) != EH_RETURN_HANDLER_REGNO)
-+ {
-+ rtx ra = EH_RETURN_HANDLER_RTX;
-+ emit_move_insn (ra, operands[1]);
-+ operands[1] = ra;
-+ }
-+}
-+
-+/* Compute the offsets between eliminable registers. */
-+
-+int
-+ubicom32_initial_elimination_offset (int from, int to)
-+{
-+ ubicom32_layout_frame ();
-+ if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
-+ return save_regs_size + crtl->outgoing_args_size;
-+
-+ if (from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
-+ return get_frame_size ()/* + save_regs_size */;
-+
-+ if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
-+ return get_frame_size ()
-+ + crtl->outgoing_args_size
-+ + save_regs_size;
-+
-+ return 0;
-+}
-+
-+/* Return 1 if it is appropriate to emit `ret' instructions in the
-+ body of a function. Do this only if the epilogue is simple, needing a
-+ couple of insns. Prior to reloading, we can't tell how many registers
-+ must be saved, so return 0 then. Return 0 if there is no frame
-+ marker to de-allocate.
-+
-+ If NON_SAVING_SETJMP is defined and true, then it is not possible
-+ for the epilogue to be simple, so return 0. This is a special case
-+ since NON_SAVING_SETJMP will not cause regs_ever_live to change
-+ until final, but jump_optimize may need to know sooner if a
-+ `return' is OK. */
-+
-+int
-+ubicom32_can_use_return_insn_p (void)
-+{
-+ if (! reload_completed || frame_pointer_needed)
-+ return 0;
-+
-+ return 1;
-+}
-+
-+/* Attributes and CC handling. */
-+
-+/* Handle an attribute requiring a FUNCTION_DECL; arguments as in
-+ struct attribute_spec.handler. */
-+static tree
-+ubicom32_handle_fndecl_attribute (tree *node, tree name,
-+ tree args ATTRIBUTE_UNUSED,
-+ int flags ATTRIBUTE_UNUSED,
-+ bool *no_add_attrs)
-+{
-+ if (TREE_CODE (*node) != FUNCTION_DECL)
-+ {
-+ warning ("'%s' attribute only applies to functions",
-+ IDENTIFIER_POINTER (name));
-+ *no_add_attrs = true;
-+ }
-+
-+ return NULL_TREE;
-+}
-+
-+/* A C expression that places additional restrictions on the register class to
-+ use when it is necessary to copy value X into a register in class CLASS.
-+ The value is a register class; perhaps CLASS, or perhaps another, smaller
-+ class. On many machines, the following definition is safe:
-+
-+ #define PREFERRED_RELOAD_CLASS(X,CLASS) CLASS
-+
-+ Sometimes returning a more restrictive class makes better code. For
-+ example, on the 68000, when X is an integer constant that is in range for a
-+ `moveq' instruction, the value of this macro is always `DATA_REGS' as long
-+ as CLASS includes the data registers. Requiring a data register guarantees
-+ that a `moveq' will be used.
-+
-+ If X is a `const_double', by returning `NO_REGS' you can force X into a
-+ memory constant. This is useful on certain machines where immediate
-+ floating values cannot be loaded into certain kinds of registers. */
-+
-+enum reg_class
-+ubicom32_preferred_reload_class (rtx x, enum reg_class class)
-+{
-+ /* If a symbolic constant, HIGH or a PLUS is reloaded,
-+ it is most likely being used as an address, so
-+ prefer ADDRESS_REGS. If 'class' is not a superset
-+ of ADDRESS_REGS, e.g. DATA_REGS, then reject this reload. */
-+ if (GET_CODE (x) == PLUS
-+ || GET_CODE (x) == HIGH
-+ || GET_CODE (x) == LABEL_REF
-+ || GET_CODE (x) == SYMBOL_REF
-+ || GET_CODE (x) == CONST)
-+ {
-+ if (reg_class_subset_p (ALL_ADDRESS_REGS, class))
-+ return ALL_ADDRESS_REGS;
-+
-+ return NO_REGS;
-+ }
-+
-+ return class;
-+}
-+
-+/* Function arguments and varargs. */
-+
-+int
-+ubicom32_reg_parm_stack_space (tree fndecl)
-+{
-+ return 0;
-+
-+ if (fndecl
-+ && TYPE_ARG_TYPES (TREE_TYPE (fndecl)) != 0
-+ && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (TREE_TYPE (fndecl))))
-+ != void_type_node))
-+ return UBICOM32_FUNCTION_ARG_REGS * UNITS_PER_WORD;
-+
-+ return 0;
-+}
-+
-+/* Flush the argument registers to the stack for a stdarg function;
-+ return the new argument pointer. */
-+
-+rtx
-+ubicom32_builtin_saveregs (void)
-+{
-+ int regno;
-+
-+ if (! cfun->stdarg)
-+ return 0;
-+
-+ for (regno = UBICOM32_FUNCTION_ARG_REGS - 1; regno >= 0; --regno)
-+ emit_move_insn (gen_rtx_MEM (SImode,
-+ gen_rtx_PRE_DEC (SImode,
-+ stack_pointer_rtx)),
-+ gen_rtx_REG (SImode, regno));
-+
-+ return stack_pointer_rtx;
-+}
-+
-+void
-+ubicom32_va_start (tree valist, rtx nextarg)
-+{
-+ std_expand_builtin_va_start (valist, nextarg);
-+}
-+
-+rtx
-+ubicom32_va_arg (tree valist, tree type)
-+{
-+ HOST_WIDE_INT size, rsize;
-+ tree addr, incr, tmp;
-+ rtx addr_rtx;
-+ int indirect = 0;
-+
-+ /* Round up sizeof(type) to a word. */
-+ size = int_size_in_bytes (type);
-+ rsize = (size + UNITS_PER_WORD - 1) & -UNITS_PER_WORD;
-+
-+ /* Large types are passed by reference. */
-+ if (size > 8)
-+ {
-+ indirect = 1;
-+ size = rsize = UNITS_PER_WORD;
-+ }
-+
-+ incr = valist;
-+ addr = incr = save_expr (incr);
-+
-+ /* FIXME Nat's version - is it correct? */
-+ tmp = fold_convert (ptr_type_node, size_int (rsize));
-+ tmp = build2 (PLUS_EXPR, ptr_type_node, incr, tmp);
-+ incr = fold (tmp);
-+
-+ /* FIXME Nat's version - is it correct? */
-+ incr = build2 (MODIFY_EXPR, ptr_type_node, valist, incr);
-+
-+ TREE_SIDE_EFFECTS (incr) = 1;
-+ expand_expr (incr, const0_rtx, VOIDmode, EXPAND_NORMAL);
-+
-+ addr_rtx = expand_expr (addr, NULL, Pmode, EXPAND_NORMAL);
-+
-+ if (size < UNITS_PER_WORD)
-+ emit_insn (gen_addsi3 (addr_rtx, addr_rtx,
-+ GEN_INT (UNITS_PER_WORD - size)));
-+
-+ if (indirect)
-+ {
-+ addr_rtx = force_reg (Pmode, addr_rtx);
-+ addr_rtx = gen_rtx_MEM (Pmode, addr_rtx);
-+ set_mem_alias_set (addr_rtx, get_varargs_alias_set ());
-+ }
-+
-+ return addr_rtx;
-+}
-+
-+void
-+init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype, rtx libname,
-+ int indirect ATTRIBUTE_UNUSED)
-+{
-+ cum->nbytes = 0;
-+
-+ if (!libname)
-+ {
-+ cum->stdarg = (TYPE_ARG_TYPES (fntype) != 0
-+ && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
-+ != void_type_node));
-+ }
-+}
-+
-+/* Return an RTX to represent where a value in mode MODE will be passed
-+ to a function. If the result is 0, the argument will be pushed. */
-+
-+rtx
-+function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
-+ int named ATTRIBUTE_UNUSED)
-+{
-+ rtx result = 0;
-+ int size, align;
-+ int nregs = UBICOM32_FUNCTION_ARG_REGS;
-+
-+ /* Figure out the size of the object to be passed. */
-+ if (mode == BLKmode)
-+ size = int_size_in_bytes (type);
-+ else
-+ size = GET_MODE_SIZE (mode);
-+
-+ /* Figure out the alignment of the object to be passed. */
-+ align = size;
-+
-+ cum->nbytes = (cum->nbytes + 3) & ~3;
-+
-+ /* Don't pass this arg via a register if all the argument registers
-+ are used up. */
-+ if (cum->nbytes >= nregs * UNITS_PER_WORD)
-+ return 0;
-+
-+ /* Don't pass this arg via a register if it would be split between
-+ registers and memory. */
-+ result = gen_rtx_REG (mode, cum->nbytes / UNITS_PER_WORD);
-+
-+ return result;
-+}
-+
-+rtx
-+function_incoming_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
-+ int named ATTRIBUTE_UNUSED)
-+{
-+ if (cfun->stdarg)
-+ return 0;
-+
-+ return function_arg (cum, mode, type, named);
-+}
-+
-+
-+/* Implement hook TARGET_ARG_PARTIAL_BYTES.
-+
-+ Returns the number of bytes at the beginning of an argument that
-+ must be put in registers. The value must be zero for arguments
-+ that are passed entirely in registers or that are entirely pushed
-+ on the stack. */
-+static int
-+ubicom32_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
-+ tree type, bool named ATTRIBUTE_UNUSED)
-+{
-+ int size, diff;
-+
-+ int nregs = UBICOM32_FUNCTION_ARG_REGS;
-+
-+ /* round up to full word */
-+ cum->nbytes = (cum->nbytes + 3) & ~3;
-+
-+ if (targetm.calls.pass_by_reference (cum, mode, type, named))
-+ return 0;
-+
-+ /* number of bytes left in registers */
-+ diff = nregs*UNITS_PER_WORD - cum->nbytes;
-+
-+ /* regs all used up */
-+ if (diff <= 0)
-+ return 0;
-+
-+ /* Figure out the size of the object to be passed. */
-+ if (mode == BLKmode)
-+ size = int_size_in_bytes (type);
-+ else
-+ size = GET_MODE_SIZE (mode);
-+
-+ /* enough space left in regs for size */
-+ if (size <= diff)
-+ return 0;
-+
-+ /* put diff bytes in regs and rest on stack */
-+ return diff;
-+
-+}
-+
-+static bool
-+ubicom32_pass_by_reference (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
-+ enum machine_mode mode, const_tree type,
-+ bool named ATTRIBUTE_UNUSED)
-+{
-+ int size;
-+
-+ if (type)
-+ size = int_size_in_bytes (type);
-+ else
-+ size = GET_MODE_SIZE (mode);
-+
-+ return size <= 0 || size > 8;
-+}
-+
-+static bool
-+ubicom32_callee_copies (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
-+ enum machine_mode mode, const_tree type,
-+ bool named ATTRIBUTE_UNUSED)
-+{
-+ int size;
-+
-+ if (type)
-+ size = int_size_in_bytes (type);
-+ else
-+ size = GET_MODE_SIZE (mode);
-+
-+ return size <= 0 || size > 8;
-+}
-+
-+static bool
-+ubicom32_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
-+{
-+ int size, mode;
-+
-+ if (!type)
-+ return true;
-+
-+ size = int_size_in_bytes(type);
-+ if (size > 8)
-+ return true;
-+
-+ mode = TYPE_MODE(type);
-+ if (mode == BLKmode)
-+ return true;
-+
-+ return false;
-+}
-+
-+/* Return true if a given register number REGNO is acceptable for machine
-+ mode MODE. */
-+bool
-+ubicom32_hard_regno_mode_ok (unsigned int regno, enum machine_mode mode)
-+{
-+ /* If we're not at least a v3 ISA then ACC0_HI is only 16 bits. */
-+ if (! ubicom32_v3)
-+ {
-+ if (regno == ACC0_HI_REGNUM)
-+ return (mode == QImode || mode == HImode);
-+ }
-+
-+ /* Only the flags reg can hold CCmode. */
-+ if (GET_MODE_CLASS (mode) == MODE_CC)
-+ return regno == CC_REGNUM;
-+
-+ /* We restrict the choice of DImode registers to only being address,
-+ data or accumulator regs. We also restrict them to only start on
-+ even register numbers so we never have to worry about partial
-+ overlaps between operands in instructions. */
-+ if (GET_MODE_SIZE (mode) > 4)
-+ {
-+ switch (REGNO_REG_CLASS (regno))
-+ {
-+ case ADDRESS_REGS:
-+ case DATA_REGS:
-+ case ACC_REGS:
-+ return (regno & 1) == 0;
-+
-+ default:
-+ return false;
-+ }
-+ }
-+
-+ return true;
-+}
-+
-+/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
-+ and check its validity for a certain class.
-+ We have two alternate definitions for each of them.
-+ The usual definition accepts all pseudo regs; the other rejects
-+ them unless they have been allocated suitable hard regs.
-+ The symbol REG_OK_STRICT causes the latter definition to be used.
-+
-+ Most source files want to accept pseudo regs in the hope that
-+ they will get allocated to the class that the insn wants them to be in.
-+ Source files for reload pass need to be strict.
-+ After reload, it makes no difference, since pseudo regs have
-+ been eliminated by then.
-+
-+ These assume that REGNO is a hard or pseudo reg number.
-+ They give nonzero only if REGNO is a hard reg of the suitable class
-+ or a pseudo reg currently allocated to a suitable hard reg.
-+ Since they use reg_renumber, they are safe only once reg_renumber
-+ has been allocated, which happens in local-alloc.c. */
-+
-+int
-+ubicom32_regno_ok_for_base_p (int regno, int strict)
-+{
-+ if ((regno >= FIRST_ADDRESS_REGNUM && regno <= STACK_POINTER_REGNUM)
-+ || (!strict
-+ && (regno >= FIRST_PSEUDO_REGISTER
-+ || regno == ARG_POINTER_REGNUM))
-+ || (strict && (reg_renumber
-+ && reg_renumber[regno] >= FIRST_ADDRESS_REGNUM
-+ && reg_renumber[regno] <= STACK_POINTER_REGNUM)))
-+ return 1;
-+
-+ return 0;
-+}
-+
-+int
-+ubicom32_regno_ok_for_index_p (int regno, int strict)
-+{
-+ if ((regno >= FIRST_DATA_REGNUM && regno <= LAST_DATA_REGNUM)
-+ || (!strict && regno >= FIRST_PSEUDO_REGISTER)
-+ || (strict && (reg_renumber
-+ && reg_renumber[regno] >= FIRST_DATA_REGNUM
-+ && reg_renumber[regno] <= LAST_DATA_REGNUM)))
-+ return 1;
-+
-+ return 0;
-+}
-+
-+/* Returns 1 if X is a valid index register. STRICT is 1 if only hard
-+ registers should be accepted. Accept either REG or SUBREG where a
-+ register is valid. */
-+
-+static bool
-+ubicom32_is_index_reg (rtx x, int strict)
-+{
-+ if ((REG_P (x) && ubicom32_regno_ok_for_index_p (REGNO (x), strict))
-+ || (GET_CODE (x) == SUBREG && REG_P (SUBREG_REG (x))
-+ && ubicom32_regno_ok_for_index_p (REGNO (SUBREG_REG (x)), strict)))
-+ return true;
-+
-+ return false;
-+}
-+
-+/* Return 1 if X is a valid index for a memory address. */
-+
-+static bool
-+ubicom32_is_index_expr (enum machine_mode mode, rtx x, int strict)
-+{
-+ /* Immediate index must be an unsigned 7-bit offset multiple of 1, 2
-+ or 4 depending on mode. */
-+ if (CONST_INT_P (x))
-+ {
-+ switch (mode)
-+ {
-+ case QImode:
-+ return satisfies_constraint_J (x);
-+
-+ case HImode:
-+ return satisfies_constraint_K (x);
-+
-+ case SImode:
-+ case SFmode:
-+ return satisfies_constraint_L (x);
-+
-+ case DImode:
-+ return satisfies_constraint_L (x)
-+ && satisfies_constraint_L (GEN_INT (INTVAL (x) + 4));
-+
-+ default:
-+ return false;
-+ }
-+ }
-+
-+ if (mode != SImode && mode != HImode && mode != QImode)
-+ return false;
-+
-+ /* Register index scaled by mode of operand: REG + REG * modesize.
-+ Valid scaled index registers are:
-+
-+ SImode (mult (dreg) 4))
-+ HImode (mult (dreg) 2))
-+ QImode (mult (dreg) 1)) */
-+ if (GET_CODE (x) == MULT
-+ && ubicom32_is_index_reg (XEXP (x, 0), strict)
-+ && CONST_INT_P (XEXP (x, 1))
-+ && INTVAL (XEXP (x, 1)) == (HOST_WIDE_INT)GET_MODE_SIZE (mode))
-+ return true;
-+
-+ /* REG + REG addressing is allowed for QImode. */
-+ if (ubicom32_is_index_reg (x, strict) && mode == QImode)
-+ return true;
-+
-+ return false;
-+}
-+
-+static bool
-+ubicom32_is_valid_offset (enum machine_mode mode, HOST_WIDE_INT offs)
-+{
-+ if (offs < 0)
-+ return false;
-+
-+ switch (mode)
-+ {
-+ case QImode:
-+ return offs <= 127;
-+
-+ case HImode:
-+ return offs <= 254;
-+
-+ case SImode:
-+ case SFmode:
-+ return offs <= 508;
-+
-+ case DImode:
-+ return offs <= 504;
-+
-+ default:
-+ return false;
-+ }
-+}
-+
-+static int
-+ubicom32_get_valid_offset_mask (enum machine_mode mode)
-+{
-+ switch (mode)
-+ {
-+ case QImode:
-+ return 127;
-+
-+ case HImode:
-+ return 255;
-+
-+ case SImode:
-+ case SFmode:
-+ return 511;
-+
-+ case DImode:
-+ return 255;
-+
-+ default:
-+ return 0;
-+ }
-+}
-+
-+/* Returns 1 if X is a valid base register. STRICT is 1 if only hard
-+ registers should be accepted. Accept either REG or SUBREG where a
-+ register is valid. */
-+
-+static bool
-+ubicom32_is_base_reg (rtx x, int strict)
-+{
-+ if ((REG_P (x) && ubicom32_regno_ok_for_base_p (REGNO (x), strict))
-+ || (GET_CODE (x) == SUBREG && REG_P (SUBREG_REG (x))
-+ && ubicom32_regno_ok_for_base_p (REGNO (SUBREG_REG (x)), strict)))
-+ return true;
-+
-+ return false;
-+}
-+
-+static bool
-+ubicom32_cannot_force_const_mem (rtx x ATTRIBUTE_UNUSED)
-+{
-+ return TARGET_FDPIC;
-+}
-+
-+/* Determine if X is a legitimate constant. */
-+
-+bool
-+ubicom32_legitimate_constant_p (rtx x)
-+{
-+ /* Among its other duties, LEGITIMATE_CONSTANT_P decides whether
-+ a constant can be entered into reg_equiv_constant[]. If we return true,
-+ reload can create new instances of the constant whenever it likes.
-+
-+ The idea is therefore to accept as many constants as possible (to give
-+ reload more freedom) while rejecting constants that can only be created
-+ at certain times. In particular, anything with a symbolic component will
-+ require use of the pseudo FDPIC register, which is only available before
-+ reload. */
-+ if (TARGET_FDPIC)
-+ {
-+ if (GET_CODE (x) == SYMBOL_REF
-+ || (GET_CODE (x) == CONST
-+ && GET_CODE (XEXP (x, 0)) == PLUS
-+ && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF)
-+ || CONSTANT_ADDRESS_P (x))
-+ return false;
-+
-+ return true;
-+ }
-+
-+ /* For non-PIC code anything goes! */
-+ return true;
-+}
-+
-+/* Address validation. */
-+
-+bool
-+ubicom32_legitimate_address_p (enum machine_mode mode, rtx x, int strict)
-+{
-+ if (TARGET_DEBUG_ADDRESS)
-+ {
-+ fprintf (stderr, "\n==> GO_IF_LEGITIMATE_ADDRESS%s\n",
-+ (strict) ? " (STRICT)" : "");
-+ debug_rtx (x);
-+ }
-+
-+ if (CONSTANT_ADDRESS_P (x))
-+ return false;
-+
-+ if (ubicom32_is_base_reg (x, strict))
-+ return true;
-+
-+ if ((GET_CODE (x) == POST_INC
-+ || GET_CODE (x) == PRE_INC
-+ || GET_CODE (x) == POST_DEC
-+ || GET_CODE (x) == PRE_DEC)
-+ && REG_P (XEXP (x, 0))
-+ && ubicom32_is_base_reg (XEXP (x, 0), strict)
-+ && mode != DImode)
-+ return true;
-+
-+ if ((GET_CODE (x) == PRE_MODIFY || GET_CODE (x) == POST_MODIFY)
-+ && ubicom32_is_base_reg (XEXP (x, 0), strict)
-+ && GET_CODE (XEXP (x, 1)) == PLUS
-+ && rtx_equal_p (XEXP (x, 0), XEXP (XEXP (x, 1), 0))
-+ && CONST_INT_P (XEXP (XEXP (x, 1), 1))
-+ && mode != DImode)
-+ {
-+ HOST_WIDE_INT disp = INTVAL (XEXP (XEXP (x, 1), 1));
-+ switch (mode)
-+ {
-+ case QImode:
-+ return disp >= -8 && disp <= 7;
-+
-+ case HImode:
-+ return disp >= -16 && disp <= 14 && ! (disp & 1);
-+
-+ case SImode:
-+ return disp >= -32 && disp <= 28 && ! (disp & 3);
-+
-+ default:
-+ return false;
-+ }
-+ }
-+
-+ /* Accept base + index * scale. */
-+ if (GET_CODE (x) == PLUS
-+ && ubicom32_is_base_reg (XEXP (x, 0), strict)
-+ && ubicom32_is_index_expr (mode, XEXP (x, 1), strict))
-+ return true;
-+
-+ /* Accept index * scale + base. */
-+ if (GET_CODE (x) == PLUS
-+ && ubicom32_is_base_reg (XEXP (x, 1), strict)
-+ && ubicom32_is_index_expr (mode, XEXP (x, 0), strict))
-+ return true;
-+
-+ if (! TARGET_FDPIC)
-+ {
-+ /* Accept (lo_sum (reg) (symbol_ref)) that can be used as a mem+7bits
-+ displacement operand:
-+
-+ moveai a1, #%hi(SYM)
-+ move.4 d3, %lo(SYM)(a1) */
-+ if (GET_CODE (x) == LO_SUM
-+ && ubicom32_is_base_reg (XEXP (x, 0), strict)
-+ && (GET_CODE (XEXP (x, 1)) == SYMBOL_REF
-+ || GET_CODE (XEXP (x, 1)) == LABEL_REF /* FIXME: wrong */)
-+ && mode != DImode)
-+ return true;
-+ }
-+
-+ if (TARGET_DEBUG_ADDRESS)
-+ fprintf (stderr, "\nNot a legitimate address.\n");
-+
-+ return false;
-+}
-+
-+rtx
-+ubicom32_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
-+ enum machine_mode mode)
-+{
-+ if (mode == BLKmode)
-+ return NULL_RTX;
-+
-+ if (GET_CODE (x) == PLUS
-+ && REG_P (XEXP (x, 0))
-+ && ! REGNO_PTR_FRAME_P (REGNO (XEXP (x, 0)))
-+ && CONST_INT_P (XEXP (x, 1))
-+ && ! ubicom32_is_valid_offset (mode, INTVAL (XEXP (x, 1))))
-+ {
-+ rtx base;
-+ rtx plus;
-+ rtx new_rtx;
-+ HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
-+ HOST_WIDE_INT low = val & ubicom32_get_valid_offset_mask (mode);
-+ HOST_WIDE_INT high = val ^ low;
-+
-+ if (val < 0)
-+ return NULL_RTX;
-+
-+ if (! low)
-+ return NULL_RTX;
-+
-+ /* Reload the high part into a base reg; leave the low part
-+ in the mem directly. */
-+ base = XEXP (x, 0);
-+ if (! ubicom32_is_base_reg (base, 0))
-+ base = copy_to_mode_reg (Pmode, base);
-+
-+ plus = expand_simple_binop (Pmode, PLUS,
-+ gen_int_mode (high, Pmode),
-+ base, NULL, 0, OPTAB_WIDEN);
-+ new_rtx = plus_constant (plus, low);
-+
-+ return new_rtx;
-+ }
-+
-+ return NULL_RTX;
-+}
-+
-+/* Try a machine-dependent way of reloading an illegitimate address AD
-+ operand. If we find one, push the reload and and return the new address.
-+
-+ MODE is the mode of the enclosing MEM. OPNUM is the operand number
-+ and TYPE is the reload type of the current reload. */
-+
-+rtx
-+ubicom32_legitimize_reload_address (rtx ad, enum machine_mode mode,
-+ int opnum, int type)
-+{
-+ /* Is this an address that we've already fixed up? If it is then
-+ recognize it and move on. */
-+ if (GET_CODE (ad) == PLUS
-+ && GET_CODE (XEXP (ad, 0)) == PLUS
-+ && REG_P (XEXP (XEXP (ad, 0), 0))
-+ && CONST_INT_P (XEXP (XEXP (ad, 0), 1))
-+ && CONST_INT_P (XEXP (ad, 1)))
-+ {
-+ push_reload (XEXP (ad, 0), NULL_RTX, &XEXP (ad, 0), NULL,
-+ BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
-+ opnum, (enum reload_type) type);
-+ return ad;
-+ }
-+
-+ /* Have we got an address where the offset is simply out of range? If
-+ yes then reload the range as a high part and smaller offset. */
-+ if (GET_CODE (ad) == PLUS
-+ && REG_P (XEXP (ad, 0))
-+ && REGNO (XEXP (ad, 0)) < FIRST_PSEUDO_REGISTER
-+ && REGNO_OK_FOR_BASE_P (REGNO (XEXP (ad, 0)))
-+ && CONST_INT_P (XEXP (ad, 1))
-+ && ! ubicom32_is_valid_offset (mode, INTVAL (XEXP (ad, 1))))
-+ {
-+ rtx temp;
-+ rtx new_rtx;
-+
-+ HOST_WIDE_INT val = INTVAL (XEXP (ad, 1));
-+ HOST_WIDE_INT low = val & ubicom32_get_valid_offset_mask (mode);
-+ HOST_WIDE_INT high = val ^ low;
-+
-+ /* Reload the high part into a base reg; leave the low part
-+ in the mem directly. */
-+ temp = gen_rtx_PLUS (Pmode, XEXP (ad, 0), GEN_INT (high));
-+ new_rtx = gen_rtx_PLUS (Pmode, temp, GEN_INT (low));
-+
-+ push_reload (XEXP (new_rtx, 0), NULL_RTX, &XEXP (new_rtx, 0), NULL,
-+ BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
-+ opnum, (enum reload_type) type);
-+ return new_rtx;
-+ }
-+
-+ /* If we're presented with an pre/post inc/dec then we must force this
-+ to be done in an address register. The register allocator should
-+ work this out for itself but at times ends up trying to use the wrong
-+ class. If we get the wrong class then reload will end up generating
-+ at least 3 instructions whereas this way we can hopefully keep it to
-+ just 2. */
-+ if ((GET_CODE (ad) == POST_INC
-+ || GET_CODE (ad) == PRE_INC
-+ || GET_CODE (ad) == POST_DEC
-+ || GET_CODE (ad) == PRE_DEC)
-+ && REG_P (XEXP (ad, 0))
-+ && REGNO (XEXP (ad, 0)) < FIRST_PSEUDO_REGISTER
-+ && ! REGNO_OK_FOR_BASE_P (REGNO (XEXP (ad, 0))))
-+ {
-+ push_reload (XEXP (ad, 0), XEXP (ad, 0), &XEXP (ad, 0), &XEXP (ad, 0),
-+ BASE_REG_CLASS, GET_MODE (XEXP (ad, 0)), GET_MODE (XEXP (ad, 0)), 0, 0,
-+ opnum, RELOAD_OTHER);
-+ return ad;
-+ }
-+
-+ return NULL_RTX;
-+}
-+
-+/* Compute a (partial) cost for rtx X. Return true if the complete
-+ cost has been computed, and false if subexpressions should be
-+ scanned. In either case, *TOTAL contains the cost result. */
-+
-+static bool
-+ubicom32_rtx_costs (rtx x, int code, int outer_code, int *total,
-+ bool speed ATTRIBUTE_UNUSED)
-+{
-+ enum machine_mode mode = GET_MODE (x);
-+
-+ switch (code)
-+ {
-+ case CONST_INT:
-+ /* Very short constants often fold into instructions so
-+ we pretend that they don't cost anything! This is
-+ really important as regards zero values as otherwise
-+ the compiler has a nasty habit of wanting to reuse
-+ zeroes that are in regs but that tends to pessimize
-+ the code. */
-+ if (satisfies_constraint_I (x))
-+ {
-+ *total = 0;
-+ return true;
-+ }
-+
-+ /* Bit clearing costs nothing */
-+ if (outer_code == AND
-+ && exact_log2 (~INTVAL (x)) != -1)
-+ {
-+ *total = 0;
-+ return true;
-+ }
-+
-+ /* Masking the lower set of bits costs nothing. */
-+ if (outer_code == AND
-+ && exact_log2 (INTVAL (x) + 1) != -1)
-+ {
-+ *total = 0;
-+ return true;
-+ }
-+
-+ /* Bit setting costs nothing. */
-+ if (outer_code == IOR
-+ && exact_log2 (INTVAL (x)) != -1)
-+ {
-+ *total = 0;
-+ return true;
-+ }
-+
-+ /* Larger constants that can be loaded via movei aren't too
-+ bad. If we're just doing a set they cost nothing extra. */
-+ if (satisfies_constraint_N (x))
-+ {
-+ if (mode == DImode)
-+ *total = COSTS_N_INSNS (2);
-+ else
-+ *total = COSTS_N_INSNS (1);
-+ return true;
-+ }
-+
-+ if (mode == DImode)
-+ *total = COSTS_N_INSNS (5);
-+ else
-+ *total = COSTS_N_INSNS (3);
-+ return true;
-+
-+ case CONST_DOUBLE:
-+ /* We don't optimize CONST_DOUBLEs well nor do we relax them well,
-+ so their cost is very high. */
-+ *total = COSTS_N_INSNS (6);
-+ return true;
-+
-+ case CONST:
-+ case SYMBOL_REF:
-+ case MEM:
-+ *total = 0;
-+ return true;
-+
-+ case IF_THEN_ELSE:
-+ *total = COSTS_N_INSNS (1);
-+ return true;
-+
-+ case LABEL_REF:
-+ case HIGH:
-+ case LO_SUM:
-+ case BSWAP:
-+ case PLUS:
-+ case MINUS:
-+ case AND:
-+ case IOR:
-+ case XOR:
-+ case ASHIFT:
-+ case ASHIFTRT:
-+ case LSHIFTRT:
-+ case NEG:
-+ case NOT:
-+ case SIGN_EXTEND:
-+ case ZERO_EXTEND:
-+ case ZERO_EXTRACT:
-+ if (outer_code == SET)
-+ {
-+ if (mode == DImode)
-+ *total = COSTS_N_INSNS (2);
-+ else
-+ *total = COSTS_N_INSNS (1);
-+ }
-+ return true;
-+
-+ case COMPARE:
-+ if (outer_code == SET)
-+ {
-+ if (GET_MODE (XEXP (x, 0)) == DImode
-+ || GET_MODE (XEXP (x, 1)) == DImode)
-+ *total = COSTS_N_INSNS (2);
-+ else
-+ *total = COSTS_N_INSNS (1);
-+ }
-+ return true;
-+
-+ case UMOD:
-+ case UDIV:
-+ case MOD:
-+ case DIV:
-+ if (outer_code == SET)
-+ {
-+ if (mode == DImode)
-+ *total = COSTS_N_INSNS (600);
-+ else
-+ *total = COSTS_N_INSNS (200);
-+ }
-+ return true;
-+
-+ case MULT:
-+ if (outer_code == SET)
-+ {
-+ if (! ubicom32_v4)
-+ {
-+ if (mode == DImode)
-+ *total = COSTS_N_INSNS (15);
-+ else
-+ *total = COSTS_N_INSNS (5);
-+ }
-+ else
-+ {
-+ if (mode == DImode)
-+ *total = COSTS_N_INSNS (6);
-+ else
-+ *total = COSTS_N_INSNS (2);
-+ }
-+ }
-+ return true;
-+
-+ case UNSPEC:
-+ if (XINT (x, 1) == UNSPEC_FDPIC_GOT
-+ || XINT (x, 1) == UNSPEC_FDPIC_GOT_FUNCDESC)
-+ *total = 0;
-+ return true;
-+
-+ default:
-+ return false;
-+ }
-+}
-+
-+/* Return 1 if ADDR can have different meanings depending on the machine
-+ mode of the memory reference it is used for or if the address is
-+ valid for some modes but not others.
-+
-+ Autoincrement and autodecrement addresses typically have
-+ mode-dependent effects because the amount of the increment or
-+ decrement is the size of the operand being addressed. Some machines
-+ have other mode-dependent addresses. Many RISC machines have no
-+ mode-dependent addresses.
-+
-+ You may assume that ADDR is a valid address for the machine. */
-+
-+int
-+ubicom32_mode_dependent_address_p (rtx addr)
-+{
-+ if (GET_CODE (addr) == POST_INC
-+ || GET_CODE (addr) == PRE_INC
-+ || GET_CODE (addr) == POST_DEC
-+ || GET_CODE (addr) == PRE_DEC
-+ || GET_CODE (addr) == POST_MODIFY
-+ || GET_CODE (addr) == PRE_MODIFY)
-+ return 1;
-+
-+ return 0;
-+}
-+
-+static void
-+ubicom32_function_prologue (FILE *file, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
-+{
-+ fprintf (file, "/* frame/pretend: %ld/%d save_regs: %d out_args: %d %s */\n",
-+ get_frame_size (), crtl->args.pretend_args_size,
-+ save_regs_size, crtl->outgoing_args_size,
-+ current_function_is_leaf ? "leaf" : "nonleaf");
-+}
-+
-+static void
-+ubicom32_function_epilogue (FILE *file ATTRIBUTE_UNUSED,
-+ HOST_WIDE_INT size ATTRIBUTE_UNUSED)
-+{
-+ ubicom32_reorg_completed = 0;
-+}
-+
-+static void
-+ubicom32_machine_dependent_reorg (void)
-+{
-+#if 0 /* Commenting out this optimization until it is fixed */
-+ if (optimize)
-+ {
-+ compute_bb_for_insn ();
-+
-+ /* Do a very simple CSE pass over just the hard registers. */
-+ reload_cse_regs (get_insns ());
-+
-+ /* Reload_cse_regs can eliminate potentially-trapping MEMs.
-+ Remove any EH edges associated with them. */
-+ if (flag_non_call_exceptions)
-+ purge_all_dead_edges ();
-+ }
-+#endif
-+ ubicom32_reorg_completed = 1;
-+}
-+
-+void
-+ubicom32_output_cond_jump (rtx insn, rtx cond, rtx target)
-+{
-+ rtx note;
-+ int mostly_false_jump;
-+ rtx xoperands[2];
-+ rtx cc_reg;
-+
-+ note = find_reg_note (insn, REG_BR_PROB, 0);
-+ mostly_false_jump = !note || (INTVAL (XEXP (note, 0))
-+ <= REG_BR_PROB_BASE / 2);
-+
-+ xoperands[0] = target;
-+ xoperands[1] = cond;
-+ cc_reg = XEXP (cond, 0);
-+
-+ if (GET_MODE (cc_reg) == CCWmode
-+ || GET_MODE (cc_reg) == CCWZmode
-+ || GET_MODE (cc_reg) == CCWZNmode)
-+ {
-+ if (mostly_false_jump)
-+ output_asm_insn ("jmp%b1.w.f\t%0", xoperands);
-+ else
-+ output_asm_insn ("jmp%b1.w.t\t%0", xoperands);
-+ return;
-+ }
-+
-+ if (GET_MODE (cc_reg) == CCSmode
-+ || GET_MODE (cc_reg) == CCSZmode
-+ || GET_MODE (cc_reg) == CCSZNmode)
-+ {
-+ if (mostly_false_jump)
-+ output_asm_insn ("jmp%b1.s.f\t%0", xoperands);
-+ else
-+ output_asm_insn ("jmp%b1.s.t\t%0", xoperands);
-+ return;
-+ }
-+
-+ abort ();
-+}
-+
-+/* Return non-zero if FUNC is a naked function. */
-+
-+static int
-+ubicom32_naked_function_p (void)
-+{
-+ return lookup_attribute ("naked", DECL_ATTRIBUTES (current_function_decl)) != NULL_TREE;
-+}
-+
-+/* Return an RTX indicating where the return address to the
-+ calling function can be found. */
-+rtx
-+ubicom32_return_addr_rtx (int count, rtx frame ATTRIBUTE_UNUSED)
-+{
-+ if (count != 0)
-+ return NULL_RTX;
-+
-+ return get_hard_reg_initial_val (Pmode, LINK_REGNO);
-+}
-+
-+/*
-+ * ubicom32_readonly_data_section: This routtine handles code
-+ * at the start of readonly data sections
-+ */
-+static void
-+ubicom32_readonly_data_section (const void *data ATTRIBUTE_UNUSED)
-+{
-+ static int num = 0;
-+ if (in_section == readonly_data_section){
-+ fprintf (asm_out_file, "%s", DATA_SECTION_ASM_OP);
-+ if (flag_data_sections){
-+ fprintf (asm_out_file, ".rodata%d", num);
-+ fprintf (asm_out_file, ",\"a\"");
-+ }
-+ fprintf (asm_out_file, "\n");
-+ }
-+ num++;
-+}
-+
-+/*
-+ * ubicom32_text_section: not in readonly section
-+ */
-+static void
-+ubicom32_text_section(const void *data ATTRIBUTE_UNUSED)
-+{
-+ fprintf (asm_out_file, "%s\n", TEXT_SECTION_ASM_OP);
-+}
-+
-+/*
-+ * ubicom32_data_section: not in readonly section
-+ */
-+static void
-+ubicom32_data_section(const void *data ATTRIBUTE_UNUSED)
-+{
-+ fprintf (asm_out_file, "%s\n", DATA_SECTION_ASM_OP);
-+}
-+
-+/*
-+ * ubicom32_asm_init_sections: This routine implements special
-+ * section handling
-+ */
-+static void
-+ubicom32_asm_init_sections(void)
-+{
-+ text_section = get_unnamed_section(SECTION_CODE, ubicom32_text_section, NULL);
-+
-+ data_section = get_unnamed_section(SECTION_WRITE, ubicom32_data_section, NULL);
-+
-+ readonly_data_section = get_unnamed_section(0, ubicom32_readonly_data_section, NULL);
-+}
-+
-+/*
-+ * ubicom32_profiler: This routine would call
-+ * mcount to support prof and gprof if mcount
-+ * was supported. Currently, do nothing.
-+ */
-+void
-+ubicom32_profiler(void)
-+{
-+}
-+
-+/* Initialise the builtin functions. Start by initialising
-+ descriptions of different types of functions (e.g., void fn(int),
-+ int fn(void)), and then use these to define the builtins. */
-+static void
-+ubicom32_init_builtins (void)
-+{
-+ tree endlink;
-+ tree short_unsigned_endlink;
-+ tree unsigned_endlink;
-+ tree short_unsigned_ftype_short_unsigned;
-+ tree unsigned_ftype_unsigned;
-+
-+ endlink = void_list_node;
-+
-+ short_unsigned_endlink
-+ = tree_cons (NULL_TREE, short_unsigned_type_node, endlink);
-+
-+ unsigned_endlink
-+ = tree_cons (NULL_TREE, unsigned_type_node, endlink);
-+
-+ short_unsigned_ftype_short_unsigned
-+ = build_function_type (short_unsigned_type_node, short_unsigned_endlink);
-+
-+ unsigned_ftype_unsigned
-+ = build_function_type (unsigned_type_node, unsigned_endlink);
-+
-+ /* Initialise the byte swap function. */
-+ add_builtin_function ("__builtin_ubicom32_swapb_2",
-+ short_unsigned_ftype_short_unsigned,
-+ UBICOM32_BUILTIN_UBICOM32_SWAPB_2,
-+ BUILT_IN_MD, NULL,
-+ NULL_TREE);
-+
-+ /* Initialise the byte swap function. */
-+ add_builtin_function ("__builtin_ubicom32_swapb_4",
-+ unsigned_ftype_unsigned,
-+ UBICOM32_BUILTIN_UBICOM32_SWAPB_4,
-+ BUILT_IN_MD, NULL,
-+ NULL_TREE);
-+}
-+
-+/* Given a builtin function taking 2 operands (i.e., target + source),
-+ emit the RTL for the underlying instruction. */
-+static rtx
-+ubicom32_expand_builtin_2op (enum insn_code icode, tree arglist, rtx target)
-+{
-+ tree arg0;
-+ rtx op0, pat;
-+ enum machine_mode tmode, mode0;
-+
-+ /* Grab the incoming argument and emit its RTL. */
-+ arg0 = TREE_VALUE (arglist);
-+ op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
-+
-+ /* Determine the modes of the instruction operands. */
-+ tmode = insn_data[icode].operand[0].mode;
-+ mode0 = insn_data[icode].operand[1].mode;
-+
-+ /* Ensure that the incoming argument RTL is in a register of the
-+ correct mode. */
-+ if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
-+ op0 = copy_to_mode_reg (mode0, op0);
-+
-+ /* If there isn't a suitable target, emit a target register. */
-+ if (target == 0
-+ || GET_MODE (target) != tmode
-+ || !(*insn_data[icode].operand[0].predicate) (target, tmode))
-+ target = gen_reg_rtx (tmode);
-+
-+ /* Emit and return the new instruction. */
-+ pat = GEN_FCN (icode) (target, op0);
-+ if (!pat)
-+ return 0;
-+ emit_insn (pat);
-+
-+ return target;
-+}
-+
-+/* Expand a call to a builtin function. */
-+static rtx
-+ubicom32_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
-+ enum machine_mode mode ATTRIBUTE_UNUSED,
-+ int ignore ATTRIBUTE_UNUSED)
-+{
-+ tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
-+ tree arglist = CALL_EXPR_ARGS(exp);
-+ int fcode = DECL_FUNCTION_CODE (fndecl);
-+
-+ switch (fcode)
-+ {
-+ case UBICOM32_BUILTIN_UBICOM32_SWAPB_2:
-+ return ubicom32_expand_builtin_2op (CODE_FOR_bswaphi, arglist, target);
-+
-+ case UBICOM32_BUILTIN_UBICOM32_SWAPB_4:
-+ return ubicom32_expand_builtin_2op (CODE_FOR_bswapsi, arglist, target);
-+
-+ default:
-+ gcc_unreachable();
-+ }
-+
-+ /* Should really do something sensible here. */
-+ return NULL_RTX;
-+}
-+
-+/* Fold any constant argument for a swapb.2 instruction. */
-+static tree
-+ubicom32_fold_builtin_ubicom32_swapb_2 (tree fndecl, tree arglist)
-+{
-+ tree arg0;
-+
-+ arg0 = TREE_VALUE (arglist);
-+
-+ /* Optimize constant value. */
-+ if (TREE_CODE (arg0) == INTEGER_CST)
-+ {
-+ HOST_WIDE_INT v;
-+ HOST_WIDE_INT res;
-+
-+ v = TREE_INT_CST_LOW (arg0);
-+ res = ((v >> 8) & 0xff)
-+ | ((v & 0xff) << 8);
-+
-+ return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), res);
-+ }
-+
-+ return NULL_TREE;
-+}
-+
-+/* Fold any constant argument for a swapb.4 instruction. */
-+static tree
-+ubicom32_fold_builtin_ubicom32_swapb_4 (tree fndecl, tree arglist)
-+{
-+ tree arg0;
-+
-+ arg0 = TREE_VALUE (arglist);
-+
-+ /* Optimize constant value. */
-+ if (TREE_CODE (arg0) == INTEGER_CST)
-+ {
-+ unsigned HOST_WIDE_INT v;
-+ unsigned HOST_WIDE_INT res;
-+
-+ v = TREE_INT_CST_LOW (arg0);
-+ res = ((v >> 24) & 0xff)
-+ | (((v >> 16) & 0xff) << 8)
-+ | (((v >> 8) & 0xff) << 16)
-+ | ((v & 0xff) << 24);
-+
-+ return build_int_cst_wide (TREE_TYPE (TREE_TYPE (fndecl)), res, 0);
-+ }
-+
-+ return NULL_TREE;
-+}
-+
-+/* Fold any constant arguments for builtin functions. */
-+static tree
-+ubicom32_fold_builtin (tree fndecl, tree arglist, bool ignore ATTRIBUTE_UNUSED)
-+{
-+ switch (DECL_FUNCTION_CODE (fndecl))
-+ {
-+ case UBICOM32_BUILTIN_UBICOM32_SWAPB_2:
-+ return ubicom32_fold_builtin_ubicom32_swapb_2 (fndecl, arglist);
-+
-+ case UBICOM32_BUILTIN_UBICOM32_SWAPB_4:
-+ return ubicom32_fold_builtin_ubicom32_swapb_4 (fndecl, arglist);
-+
-+ default:
-+ return NULL;
-+ }
-+}
-+
-+/* Implementation of TARGET_ASM_INTEGER. When using FD-PIC, we need to
-+ tell the assembler to generate pointers to function descriptors in
-+ some cases. */
-+static bool
-+ubicom32_assemble_integer (rtx value, unsigned int size, int aligned_p)
-+{
-+ if (TARGET_FDPIC && size == UNITS_PER_WORD)
-+ {
-+ if (GET_CODE (value) == SYMBOL_REF
-+ && SYMBOL_REF_FUNCTION_P (value))
-+ {
-+ fputs ("\t.picptr\t%funcdesc(", asm_out_file);
-+ output_addr_const (asm_out_file, value);
-+ fputs (")\n", asm_out_file);
-+ return true;
-+ }
-+
-+ if (!aligned_p)
-+ {
-+ /* We've set the unaligned SI op to NULL, so we always have to
-+ handle the unaligned case here. */
-+ assemble_integer_with_op ("\t.4byte\t", value);
-+ return true;
-+ }
-+ }
-+
-+ return default_assemble_integer (value, size, aligned_p);
-+}
-+
-+/* If the constant I can be constructed by shifting a source-1 immediate
-+ by a constant number of bits then return the bit count. If not
-+ return 0. */
-+
-+int
-+ubicom32_shiftable_const_int (int i)
-+{
-+ int shift = 0;
-+
-+ /* Note that any constant that can be represented as an immediate to
-+ a movei instruction is automatically ignored here in the interests
-+ of the clarity of the output asm code. */
-+ if (i >= -32768 && i <= 32767)
-+ return 0;
-+
-+ /* Find the number of trailing zeroes. We could use __builtin_ctz
-+ here but it's not obvious if this is supported on all build
-+ compilers so we err on the side of caution. */
-+ if ((i & 0xffff) == 0)
-+ {
-+ shift += 16;
-+ i >>= 16;
-+ }
-+
-+ if ((i & 0xff) == 0)
-+ {
-+ shift += 8;
-+ i >>= 8;
-+ }
-+
-+ if ((i & 0xf) == 0)
-+ {
-+ shift += 4;
-+ i >>= 4;
-+ }
-+
-+ if ((i & 0x3) == 0)
-+ {
-+ shift += 2;
-+ i >>= 2;
-+ }
-+
-+ if ((i & 0x1) == 0)
-+ {
-+ shift += 1;
-+ i >>= 1;
-+ }
-+
-+ if (i >= -128 && i <= 127)
-+ return shift;
-+
-+ return 0;
-+}
-+
---- /dev/null
-+++ b/gcc/config/ubicom32/ubicom32.h
-@@ -0,0 +1,1564 @@
-+/* Definitions of target machine for Ubicom32
-+
-+ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
-+ 2009 Free Software Foundation, Inc.
-+ Contributed by Ubicom, Inc.
-+
-+ This file is part of GCC.
-+
-+ GCC is free software; you can redistribute it and/or modify it
-+ under the terms of the GNU General Public License as published
-+ by the Free Software Foundation; either version 3, or (at your
-+ option) any later version.
-+
-+ GCC is distributed in the hope that it will be useful, but WITHOUT
-+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
-+ License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with GCC; see the file COPYING3. If not see
-+ <http://www.gnu.org/licenses/>. */
-+
-+\f
-+
-+#define OBJECT_FORMAT_ELF
-+
-+/* Run-time target specifications. */
-+
-+/* Target CPU builtins. */
-+#define TARGET_CPU_CPP_BUILTINS() \
-+ do \
-+ { \
-+ builtin_define_std ("__UBICOM32__"); \
-+ builtin_define_std ("__ubicom32__"); \
-+ \
-+ if (TARGET_FDPIC) \
-+ { \
-+ builtin_define ("__UBICOM32_FDPIC__"); \
-+ builtin_define ("__FDPIC__"); \
-+ } \
-+ } \
-+ while (0)
-+
-+#ifndef TARGET_DEFAULT
-+#define TARGET_DEFAULT 0
-+#endif
-+
-+extern int ubicom32_case_values_threshold;
-+
-+/* Nonzero if this chip supports the Ubicom32 v3 ISA. */
-+extern int ubicom32_v3;
-+
-+/* Nonzero if this chip supports the Ubicom32 v4 ISA. */
-+extern int ubicom32_v4;
-+
-+extern int ubicom32_stack_size;
-+
-+/* Flag for whether we can use calli instead of ret in returns. */
-+extern int ubicom32_can_use_calli_to_ret;
-+
-+/* This macro is a C statement to print on `stderr' a string describing the
-+ particular machine description choice. Every machine description should
-+ define `TARGET_VERSION'. */
-+#define TARGET_VERSION fprintf (stderr, " (UBICOM32)");
-+
-+/* We don't need a frame pointer to debug things. Doing this means
-+ that gcc can turn on -fomit-frame-pointer when '-O' is specified. */
-+#define CAN_DEBUG_WITHOUT_FP
-+
-+/* We need to handle processor-specific options. */
-+#define OVERRIDE_OPTIONS ubicom32_override_options ()
-+
-+#define OPTIMIZATION_OPTIONS(LEVEL, SIZE) \
-+ ubicom32_optimization_options (LEVEL, SIZE)
-+
-+/* For Ubicom32 the least significant bit has the lowest bit number
-+ so we define this to be 0. */
-+#define BITS_BIG_ENDIAN 0
-+
-+/* For Ubicom32 the most significant byte in a word has the lowest
-+ number. */
-+#define BYTES_BIG_ENDIAN 1
-+
-+/* For Ubicom32, in a multiword object, the most signifant word has the
-+ lowest number. */
-+#define WORDS_BIG_ENDIAN 1
-+
-+/* Ubicom32 has 8 bits per byte. */
-+#define BITS_PER_UNIT 8
-+
-+/* Ubicom32 has 32 bits per word. */
-+#define BITS_PER_WORD 32
-+
-+/* Width of a word, in units (bytes). */
-+#define UNITS_PER_WORD 4
-+
-+/* Width of a pointer, in bits. */
-+#define POINTER_SIZE 32
-+
-+/* Alias for pointers. Ubicom32 is a 32-bit architecture so we use
-+ SImode. */
-+#define Pmode SImode
-+
-+/* Normal alignment required for function parameters on the stack, in
-+ bits. */
-+#define PARM_BOUNDARY 32
-+
-+/* We need to maintain the stack on a 32-bit boundary. */
-+#define STACK_BOUNDARY 32
-+
-+/* Alignment required for a function entry point, in bits. */
-+#define FUNCTION_BOUNDARY 32
-+
-+/* Alias for the machine mode used for memory references to functions being
-+ called, in `call' RTL expressions. We use byte-oriented addresses
-+ here. */
-+#define FUNCTION_MODE QImode
-+
-+/* Biggest alignment that any data type can require on this machine,
-+ in bits. */
-+#define BIGGEST_ALIGNMENT 32
-+
-+/* this default to BIGGEST_ALIGNMENT unless defined */
-+/* ART: What's the correct value here? Default is (((unsigned int)1<<28)*8)*/
-+#undef MAX_OFILE_ALIGNMENT
-+#define MAX_OFILE_ALIGNMENT (128 * 8)
-+
-+/* Alignment in bits to be given to a structure bit field that follows an empty
-+ field such as `int : 0;'. */
-+#define EMPTY_FIELD_BOUNDARY 32
-+
-+/* All structures must be a multiple of 32 bits in size. */
-+#define STRUCTURE_SIZE_BOUNDARY 32
-+
-+/* A bit-field declared as `int' forces `int' alignment for the struct. */
-+#define PCC_BITFIELD_TYPE_MATTERS 1
-+
-+/* For Ubicom32 we absolutely require that data be aligned with nominal
-+ alignment. */
-+#define STRICT_ALIGNMENT 1
-+
-+/* Make strcpy of constants fast. */
-+#define CONSTANT_ALIGNMENT(EXP, ALIGN) \
-+ (TREE_CODE (EXP) == STRING_CST \
-+ && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
-+
-+/* Define this macro as an expression for the alignment of a structure
-+ (given by STRUCT as a tree node) if the alignment computed in the
-+ usual way is COMPUTED and the alignment explicitly specified was
-+ SPECIFIED. */
-+#define DATA_ALIGNMENT(TYPE, ALIGN) \
-+ ((((ALIGN) < BITS_PER_WORD) \
-+ && (TREE_CODE (TYPE) == ARRAY_TYPE \
-+ || TREE_CODE (TYPE) == UNION_TYPE \
-+ || TREE_CODE (TYPE) == RECORD_TYPE)) ? BITS_PER_WORD : (ALIGN))
-+
-+#define LOCAL_ALIGNMENT(TYPE,ALIGN) DATA_ALIGNMENT(TYPE,ALIGN)
-+
-+/* For Ubicom32 we default to unsigned chars. */
-+#define DEFAULT_SIGNED_CHAR 0
-+
-+/* Machine-specific data register numbers. */
-+#define FIRST_DATA_REGNUM 0
-+#define D10_REGNUM 10
-+#define D11_REGNUM 11
-+#define D12_REGNUM 12
-+#define D13_REGNUM 13
-+#define LAST_DATA_REGNUM 15
-+
-+/* Machine-specific address register numbers. */
-+#define FIRST_ADDRESS_REGNUM 16
-+#define LAST_ADDRESS_REGNUM 22
-+
-+/* Register numbers used for passing a function's static chain pointer. If
-+ register windows are used, the register number as seen by the called
-+ function is `STATIC_CHAIN_INCOMING_REGNUM', while the register number as
-+ seen by the calling function is `STATIC_CHAIN_REGNUM'. If these registers
-+ are the same, `STATIC_CHAIN_INCOMING_REGNUM' need not be defined.
-+
-+ The static chain register need not be a fixed register.
-+
-+ If the static chain is passed in memory, these macros should not be defined;
-+ instead, the next two macros should be defined. */
-+#define STATIC_CHAIN_REGNUM (FIRST_ADDRESS_REGNUM + 1)
-+
-+/* The register number of the frame pointer register, which is used to access
-+ automatic variables in the stack frame. We generally eliminate this anyway
-+ for Ubicom32 but we make it A6 by default. */
-+#define FRAME_POINTER_REGNUM (LAST_ADDRESS_REGNUM)
-+
-+/* The register number of the stack pointer register, which is also be a
-+ fixed register according to `FIXED_REGISTERS'. For Ubicom32 we don't
-+ have a hardware requirement about which register this is, but by convention
-+ we use A7. */
-+#define STACK_POINTER_REGNUM (LAST_ADDRESS_REGNUM + 1)
-+
-+/* Machine-specific accumulator register numbers. */
-+#define ACC0_HI_REGNUM 24
-+#define ACC0_LO_REGNUM 25
-+#define ACC1_HI_REGNUM 26
-+#define ACC1_LO_REGNUM 27
-+
-+/* source3 register number */
-+#define SOURCE3_REGNUM 28
-+
-+/* The register number of the arg pointer register, which is used to access the
-+ function's argument list. On some machines, this is the same as the frame
-+ pointer register. On some machines, the hardware determines which register
-+ this is. On other machines, you can choose any register you wish for this
-+ purpose. If this is not the same register as the frame pointer register,
-+ then you must mark it as a fixed register according to `FIXED_REGISTERS', or
-+ arrange to be able to eliminate it. */
-+#define ARG_POINTER_REGNUM 29
-+
-+/* Pseudo-reg for condition code. */
-+#define CC_REGNUM 30
-+
-+/* Interrupt set/clear registers. */
-+#define INT_SET0_REGNUM 31
-+#define INT_SET1_REGNUM 32
-+#define INT_CLR0_REGNUM 33
-+#define INT_CLR1_REGNUM 34
-+
-+/* Scratchpad registers. */
-+#define SCRATCHPAD0_REGNUM 35
-+#define SCRATCHPAD1_REGNUM 36
-+#define SCRATCHPAD2_REGNUM 37
-+#define SCRATCHPAD3_REGNUM 38
-+
-+/* FDPIC register. */
-+#define FDPIC_REGNUM 16
-+
-+/* Number of hardware registers known to the compiler. They receive numbers 0
-+ through `FIRST_PSEUDO_REGISTER-1'; thus, the first pseudo register's number
-+ really is assigned the number `FIRST_PSEUDO_REGISTER'. */
-+#define FIRST_PSEUDO_REGISTER 39
-+
-+/* An initializer that says which registers are used for fixed purposes all
-+ throughout the compiled code and are therefore not available for general
-+ allocation. These would include the stack pointer, the frame pointer
-+ (except on machines where that can be used as a general register when no
-+ frame pointer is needed), the program counter on machines where that is
-+ considered one of the addressable registers, and any other numbered register
-+ with a standard use.
-+
-+ This information is expressed as a sequence of numbers, separated by commas
-+ and surrounded by braces. The Nth number is 1 if register N is fixed, 0
-+ otherwise.
-+
-+ The table initialized from this macro, and the table initialized by the
-+ following one, may be overridden at run time either automatically, by the
-+ actions of the macro `CONDITIONAL_REGISTER_USAGE', or by the user with the
-+ command options `-ffixed-REG', `-fcall-used-REG' and `-fcall-saved-REG'. */
-+#define FIXED_REGISTERS \
-+ { \
-+ 0, 0, 0, 0, 0, 0, 0, 0, /* d0 - d7 */ \
-+ 0, 0, 0, 0, 0, 0, 0, 1, /* d8 - d15 */ \
-+ 0, 0, 0, 0, 0, 0, 0, 1, /* a0 - a7 */ \
-+ 0, 0, /* acc0 hi/lo */ \
-+ 0, 0, /* acc1 hi/lo */ \
-+ 0, /* source3 */ \
-+ 1, /* arg */ \
-+ 1, /* cc */ \
-+ 1, 1, /* int_set[01] */ \
-+ 1, 1, /* int_clr[01] */ \
-+ 1, 1, 1, 1 /* scratchpad[0123] */ \
-+ }
-+
-+/* Like `FIXED_REGISTERS' but has 1 for each register that is clobbered (in
-+ general) by function calls as well as for fixed registers. This macro
-+ therefore identifies the registers that are not available for general
-+ allocation of values that must live across function calls.
-+
-+ If a register has 0 in `CALL_USED_REGISTERS', the compiler automatically
-+ saves it on function entry and restores it on function exit, if the register
-+ is used within the function. */
-+#define CALL_USED_REGISTERS \
-+ { \
-+ 1, 1, 1, 1, 1, 1, 1, 1, /* d0 - d7 */ \
-+ 1, 1, 0, 0, 0, 0, 1, 1, /* d8 - d15 */ \
-+ 1, 0, 0, 1, 1, 1, 0, 1, /* a0 - a7 */ \
-+ 1, 1, /* acc0 hi/lo */ \
-+ 1, 1, /* acc1 hi/lo */ \
-+ 1, /* source3 */ \
-+ 1, /* arg */ \
-+ 1, /* cc */ \
-+ 1, 1, /* int_set[01] */ \
-+ 1, 1, /* int_clr[01] */ \
-+ 1, 1, 1, 1 /* scratchpad[0123] */ \
-+ }
-+
-+/* How to refer to registers in assembler output.
-+ This sequence is indexed by compiler's hard-register-number (see above). */
-+
-+/* A C initializer containing the assembler's names for the machine registers,
-+ each one as a C string constant. This is what translates register numbers
-+ in the compiler into assembler language. */
-+#define REGISTER_NAMES \
-+ { \
-+ "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", \
-+ "d8", "d9", "d10", "d11", "d12", "d13", "d14", "d15", \
-+ "a0", "a1", "a2", "a3", "a4", "a5", "a6", "sp", \
-+ "acc0_hi", "acc0_lo", \
-+ "acc1_hi", "acc1_lo", \
-+ "source3", \
-+ "arg", \
-+ "cc", \
-+ "int_set0", "int_set1", \
-+ "int_clr0", "int_clr1", \
-+ "scratchpad0", "scratchpad1", "scratchpad2", "scratchpad3" \
-+ }
-+
-+#define CONDITIONAL_REGISTER_USAGE \
-+ ubicom32_conditional_register_usage ();
-+
-+/* Order of allocation of registers. */
-+
-+/* If defined, an initializer for a vector of integers, containing the numbers
-+ of hard registers in the order in which GNU CC should prefer to use them
-+ (from most preferred to least).
-+
-+ For Ubicom32 we try using caller-clobbered data registers first, then
-+ callee-saved data registers, then caller-clobbered address registers,
-+ then callee-saved address registers and finally everything else.
-+
-+ The caller-clobbered registers are usually slightly cheaper to use because
-+ there's no need to save/restore. */
-+#define REG_ALLOC_ORDER \
-+ { \
-+ 0, 1, 2, 3, 4, /* d0 - d4 */ \
-+ 5, 6, 7, 8, 9, /* d5 - d9 */ \
-+ 14, /* d14 */ \
-+ 10, 11, 12, 13, /* d10 - d13 */ \
-+ 19, 20, 16, 21, /* a3, a4, a0, a5 */ \
-+ 17, 18, 22, /* a1, a2, a6 */ \
-+ 24, 25, /* acc0 hi/lo */ \
-+ 26, 27, /* acc0 hi/lo */ \
-+ 28 /* source3 */ \
-+ }
-+
-+/* C expression for the number of consecutive hard registers, starting at
-+ register number REGNO, required to hold a value of mode MODE. */
-+#define HARD_REGNO_NREGS(REGNO, MODE) \
-+ ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
-+
-+/* Most registers can hold QImode, HImode and SImode values but we have to
-+ be able to indicate any hard registers that cannot hold values with some
-+ modes. */
-+#define HARD_REGNO_MODE_OK(REGNO, MODE) \
-+ ubicom32_hard_regno_mode_ok(REGNO, MODE)
-+
-+/* We can rename most registers aside from the FDPIC register if we're using
-+ FDPIC. */
-+#define HARD_REGNO_RENAME_OK(from, to) (TARGET_FDPIC ? ((to) != FDPIC_REGNUM) : 1)
-+
-+/* A C expression that is nonzero if it is desirable to choose register
-+ allocation so as to avoid move instructions between a value of mode MODE1
-+ and a value of mode MODE2.
-+
-+ If `HARD_REGNO_MODE_OK (R, MODE1)' and `HARD_REGNO_MODE_OK (R, MODE2)' are
-+ ever different for any R, then `MODES_TIEABLE_P (MODE1, MODE2)' must be
-+ zero. */
-+#define MODES_TIEABLE_P(MODE1, MODE2) 1
-+
-+/* An enumeral type that must be defined with all the register class names as
-+ enumeral values. `NO_REGS' must be first. `ALL_REGS' must be the last
-+ register class, followed by one more enumeral value, `LIM_REG_CLASSES',
-+ which is not a register class but rather tells how many classes there are.
-+
-+ Each register class has a number, which is the value of casting the class
-+ name to type `int'. The number serves as an index in many of the tables
-+ described below. */
-+
-+enum reg_class
-+{
-+ NO_REGS,
-+ DATA_REGS,
-+ FDPIC_REG,
-+ ADDRESS_REGS,
-+ ALL_ADDRESS_REGS,
-+ ACC_LO_REGS,
-+ ACC_REGS,
-+ CC_REG,
-+ DATA_ACC_REGS,
-+ SOURCE3_REG,
-+ SPECIAL_REGS,
-+ GENERAL_REGS,
-+ ALL_REGS,
-+ LIM_REG_CLASSES
-+};
-+
-+/* The number of distinct register classes. */
-+#define N_REG_CLASSES (int) LIM_REG_CLASSES
-+
-+/* An initializer containing the names of the register classes as C string
-+ constants. These names are used in writing some of the debugging dumps. */
-+
-+#define REG_CLASS_NAMES \
-+{ \
-+ "NO_REGS", \
-+ "DATA_REGS", \
-+ "FDPIC_REG", \
-+ "ADDRESS_REGS", \
-+ "ALL_ADDRESS_REGS", \
-+ "ACC_LO_REGS", \
-+ "ACC_REGS", \
-+ "CC_REG", \
-+ "DATA_ACC_REGS", \
-+ "SOURCE3_REG", \
-+ "SPECIAL_REGS", \
-+ "GENERAL_REGS", \
-+ "ALL_REGS", \
-+ "LIM_REGS" \
-+}
-+
-+/* An initializer containing the contents of the register classes, as integers
-+ which are bit masks. The Nth integer specifies the contents of class N.
-+ The way the integer MASK is interpreted is that register R is in the class
-+ if `MASK & (1 << R)' is 1.
-+
-+ When the machine has more than 32 registers, an integer does not suffice.
-+ Then the integers are replaced by sub-initializers, braced groupings
-+ containing several integers. Each sub-initializer must be suitable as an
-+ initializer for the type `HARD_REG_SET' which is defined in
-+ `hard-reg-set.h'. */
-+#define REG_CLASS_CONTENTS \
-+{ \
-+ {0x00000000, 0x00000000}, /* No regs */ \
-+ {0x0000ffff, 0x00000000}, /* DATA_REGS */ \
-+ {0x00010000, 0x00000000}, /* FDPIC_REG */ \
-+ {0x20fe0000, 0x00000000}, /* ADDRESS_REGS */ \
-+ {0x20ff0000, 0x00000000}, /* ALL_ADDRESS_REGS */ \
-+ {0x0a000000, 0x00000000}, /* ACC_LO_REGS */ \
-+ {0x0f000000, 0x00000000}, /* ACC_REGS */ \
-+ {0x40000000, 0x00000000}, /* CC_REG */ \
-+ {0x0f00ffff, 0x00000000}, /* DATA_ACC_REGS */ \
-+ {0x10000000, 0x00000000}, /* SOURGE3_REG */ \
-+ {0x80000000, 0x0000007f}, /* SPECIAL_REGS */ \
-+ {0xbfffffff, 0x0000007f}, /* GENERAL_REGS */ \
-+ {0xbfffffff, 0x0000007f} /* ALL_REGS */ \
-+}
-+
-+extern enum reg_class const ubicom32_regclass_map[FIRST_PSEUDO_REGISTER];
-+
-+/* A C expression whose value is a register class containing hard register
-+ REGNO. In general there is more than one such class; choose a class which
-+ is "minimal", meaning that no smaller class also contains the register. */
-+#define REGNO_REG_CLASS(REGNO) (ubicom32_regclass_map[REGNO])
-+
-+#define IRA_COVER_CLASSES \
-+{ \
-+ GENERAL_REGS, \
-+ LIM_REG_CLASSES \
-+}
-+
-+/* Ubicom32 base registers must be address registers since addresses can
-+ only be reached via address registers. */
-+#define BASE_REG_CLASS ALL_ADDRESS_REGS
-+
-+/* Ubicom32 index registers must be data registers since we cannot add
-+ two address registers together to form an address. */
-+#define INDEX_REG_CLASS DATA_REGS
-+
-+/* A C expression which is nonzero if register number NUM is suitable for use
-+ as a base register in operand addresses. It may be either a suitable hard
-+ register or a pseudo register that has been allocated such a hard register. */
-+
-+#ifndef REG_OK_STRICT
-+#define REGNO_OK_FOR_BASE_P(regno) \
-+ ubicom32_regno_ok_for_base_p (regno, 0)
-+#else
-+#define REGNO_OK_FOR_BASE_P(regno) \
-+ ubicom32_regno_ok_for_base_p (regno, 1)
-+#endif
-+
-+/* A C expression which is nonzero if register number NUM is suitable for use
-+ as an index register in operand addresses. It may be either a suitable hard
-+ register or a pseudo register that has been allocated such a hard register.
-+
-+ The difference between an index register and a base register is that the
-+ index register may be scaled. If an address involves the sum of two
-+ registers, neither one of them scaled, then either one may be labeled the
-+ "base" and the other the "index"; but whichever labeling is used must fit
-+ the machine's constraints of which registers may serve in each capacity.
-+ The compiler will try both labelings, looking for one that is valid, and
-+ will reload one or both registers only if neither labeling works. */
-+#ifndef REG_OK_STRICT
-+#define REGNO_OK_FOR_INDEX_P(regno) \
-+ ubicom32_regno_ok_for_index_p (regno, 0)
-+#else
-+#define REGNO_OK_FOR_INDEX_P(regno) \
-+ ubicom32_regno_ok_for_index_p (regno, 1)
-+#endif
-+
-+/* Attempt to restrict the register class we need to copy value X intoto the
-+ would-be register class CLASS. Most things are fine for Ubicom32 but we
-+ have to restrict certain types of address loads. */
-+#define PREFERRED_RELOAD_CLASS(X, CLASS) \
-+ ubicom32_preferred_reload_class (X, CLASS)
-+
-+/* A C expression for the maximum number of consecutive registers of
-+ class CLASS needed to hold a value of mode MODE. For Ubicom32 this
-+ is pretty much identical to HARD_REGNO_NREGS. */
-+#define CLASS_MAX_NREGS(CLASS, MODE) \
-+ ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
-+
-+/* For Ubicom32 the stack grows downwards when we push a word onto the stack
-+ - i.e. it moves to a smaller address. */
-+#define STACK_GROWS_DOWNWARD 1
-+
-+/* Offset from the frame pointer to the first local variable slot to
-+ be allocated. */
-+#define STARTING_FRAME_OFFSET 0
-+
-+/* Offset from the argument pointer register to the first argument's
-+ address. */
-+#define FIRST_PARM_OFFSET(FNDECL) 0
-+
-+/* A C expression whose value is RTL representing the value of the return
-+ address for the frame COUNT steps up from the current frame, after the
-+ prologue. FRAMEADDR is the frame pointer of the COUNT frame, or the frame
-+ pointer of the COUNT - 1 frame if `RETURN_ADDR_IN_PREVIOUS_FRAME' is
-+ defined.
-+
-+ The value of the expression must always be the correct address when COUNT is
-+ zero, but may be `NULL_RTX' if there is not way to determine the return
-+ address of other frames. */
-+#define RETURN_ADDR_RTX(COUNT, FRAME) \
-+ ubicom32_return_addr_rtx (COUNT, FRAME)
-+
-+/* Register That Address the Stack Frame. */
-+
-+/* We don't actually require a frame pointer in most functions with the
-+ Ubicom32 architecture so we allow it to be eliminated. */
-+#define FRAME_POINTER_REQUIRED 0
-+
-+/* Macro that defines a table of register pairs used to eliminate unecessary
-+ registers that point into the stack frame.
-+
-+ For Ubicom32 we don't generally need an arg pointer of a frame pointer
-+ so we allow the arg pointer to be replaced by either the frame pointer or
-+ the stack pointer. We also allow the frame pointer to be replaced by
-+ the stack pointer. */
-+#define ELIMINABLE_REGS \
-+{ \
-+ {ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
-+ {ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM}, \
-+ {FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM} \
-+}
-+
-+/* Let the compiler know that we want to use the ELIMINABLE_REGS macro
-+ above. */
-+#define CAN_ELIMINATE(FROM, TO) 1
-+
-+/* This macro is similar to `INITIAL_FRAME_POINTER_OFFSET'. It specifies the
-+ initial difference between the specified pair of registers. This macro must
-+ be defined if `ELIMINABLE_REGS' is defined. */
-+#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
-+ (OFFSET) = ubicom32_initial_elimination_offset (FROM, TO)
-+
-+/* If defined, the maximum amount of space required for outgoing arguments will
-+ be computed and placed into the variable
-+ `current_function_outgoing_args_size'. No space will be pushed onto the
-+ stack for each call; instead, the function prologue should increase the
-+ stack frame size by this amount.
-+
-+ Defining both `PUSH_ROUNDING' and `ACCUMULATE_OUTGOING_ARGS' is not
-+ proper. */
-+#define ACCUMULATE_OUTGOING_ARGS 1
-+
-+/* Define this macro if functions should assume that stack space has been
-+ allocated for arguments even when their values are passed in registers.
-+
-+ The value of this macro is the size, in bytes, of the area reserved for
-+ arguments passed in registers for the function represented by FNDECL.
-+
-+ This space can be allocated by the caller, or be a part of the
-+ machine-dependent stack frame: `OUTGOING_REG_PARM_STACK_SPACE' says
-+ which. */
-+#define REG_PARM_STACK_SPACE(FNDECL) ubicom32_reg_parm_stack_space(FNDECL)
-+
-+/* A C expression that should indicate the number of bytes of its own arguments
-+ that a function pops on returning, or 0 if the function pops no arguments
-+ and the caller must therefore pop them all after the function returns.
-+
-+ FUNDECL is a C variable whose value is a tree node that describes the
-+ function in question. Normally it is a node of type `FUNCTION_DECL' that
-+ describes the declaration of the function. From this it is possible to
-+ obtain the DECL_MACHINE_ATTRIBUTES of the function.
-+
-+ FUNTYPE is a C variable whose value is a tree node that describes the
-+ function in question. Normally it is a node of type `FUNCTION_TYPE' that
-+ describes the data type of the function. From this it is possible to obtain
-+ the data types of the value and arguments (if known).
-+
-+ When a call to a library function is being considered, FUNTYPE will contain
-+ an identifier node for the library function. Thus, if you need to
-+ distinguish among various library functions, you can do so by their names.
-+ Note that "library function" in this context means a function used to
-+ perform arithmetic, whose name is known specially in the compiler and was
-+ not mentioned in the C code being compiled.
-+
-+ STACK-SIZE is the number of bytes of arguments passed on the stack. If a
-+ variable number of bytes is passed, it is zero, and argument popping will
-+ always be the responsibility of the calling function.
-+
-+ On the Vax, all functions always pop their arguments, so the definition of
-+ this macro is STACK-SIZE. On the 68000, using the standard calling
-+ convention, no functions pop their arguments, so the value of the macro is
-+ always 0 in this case. But an alternative calling convention is available
-+ in which functions that take a fixed number of arguments pop them but other
-+ functions (such as `printf') pop nothing (the caller pops all). When this
-+ convention is in use, FUNTYPE is examined to determine whether a function
-+ takes a fixed number of arguments. */
-+#define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, STACK_SIZE) 0
-+
-+/* A C expression that controls whether a function argument is passed in a
-+ register, and which register.
-+
-+ The arguments are CUM, of type CUMULATIVE_ARGS, which summarizes (in a way
-+ defined by INIT_CUMULATIVE_ARGS and FUNCTION_ARG_ADVANCE) all of the previous
-+ arguments so far passed in registers; MODE, the machine mode of the argument;
-+ TYPE, the data type of the argument as a tree node or 0 if that is not known
-+ (which happens for C support library functions); and NAMED, which is 1 for an
-+ ordinary argument and 0 for nameless arguments that correspond to `...' in the
-+ called function's prototype.
-+
-+ The value of the expression should either be a `reg' RTX for the hard
-+ register in which to pass the argument, or zero to pass the argument on the
-+ stack.
-+
-+ For machines like the Vax and 68000, where normally all arguments are
-+ pushed, zero suffices as a definition.
-+
-+ The usual way to make the ANSI library `stdarg.h' work on a machine where
-+ some arguments are usually passed in registers, is to cause nameless
-+ arguments to be passed on the stack instead. This is done by making
-+ `FUNCTION_ARG' return 0 whenever NAMED is 0.
-+
-+ You may use the macro `MUST_PASS_IN_STACK (MODE, TYPE)' in the definition of
-+ this macro to determine if this argument is of a type that must be passed in
-+ the stack. If `REG_PARM_STACK_SPACE' is not defined and `FUNCTION_ARG'
-+ returns non-zero for such an argument, the compiler will abort. If
-+ `REG_PARM_STACK_SPACE' is defined, the argument will be computed in the
-+ stack and then loaded into a register. */
-+#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
-+ function_arg (&CUM, MODE, TYPE, NAMED)
-+
-+#define FUNCTION_INCOMING_ARG(CUM, MODE, TYPE, NAMED) \
-+ function_incoming_arg (&CUM, MODE, TYPE, NAMED)
-+
-+/* A C expression for the number of words, at the beginning of an argument,
-+ must be put in registers. The value must be zero for arguments that are
-+ passed entirely in registers or that are entirely pushed on the stack.
-+
-+ On some machines, certain arguments must be passed partially in registers
-+ and partially in memory. On these machines, typically the first N words of
-+ arguments are passed in registers, and the rest on the stack. If a
-+ multi-word argument (a `double' or a structure) crosses that boundary, its
-+ first few words must be passed in registers and the rest must be pushed.
-+ This macro tells the compiler when this occurs, and how many of the words
-+ should go in registers.
-+
-+ `FUNCTION_ARG' for these arguments should return the first register to be
-+ used by the caller for this argument; likewise `FUNCTION_INCOMING_ARG', for
-+ the called function. */
-+
-+/* A C expression that indicates when an argument must be passed by reference.
-+ If nonzero for an argument, a copy of that argument is made in memory and a
-+ pointer to the argument is passed instead of the argument itself. The
-+ pointer is passed in whatever way is appropriate for passing a pointer to
-+ that type.
-+
-+ On machines where `REG_PARM_STACK_SPACE' is not defined, a suitable
-+ definition of this macro might be
-+ #define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \
-+ MUST_PASS_IN_STACK (MODE, TYPE) */
-+
-+/* If defined, a C expression that indicates when it is the called function's
-+ responsibility to make a copy of arguments passed by invisible reference.
-+ Normally, the caller makes a copy and passes the address of the copy to the
-+ routine being called. When FUNCTION_ARG_CALLEE_COPIES is defined and is
-+ nonzero, the caller does not make a copy. Instead, it passes a pointer to
-+ the "live" value. The called function must not modify this value. If it
-+ can be determined that the value won't be modified, it need not make a copy;
-+ otherwise a copy must be made. */
-+
-+/* 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
-+ `int' suffices and can hold the number of bytes of argument so far.
-+
-+ There is no need to record in `CUMULATIVE_ARGS' anything about the arguments
-+ that have been passed on the stack. The compiler has other variables to
-+ keep track of that. For target machines on which all arguments are passed
-+ on the stack, there is no need to store anything in `CUMULATIVE_ARGS';
-+ however, the data structure must exist and should not be empty, so use
-+ `int'. */
-+struct cum_arg
-+{
-+ int nbytes;
-+ int reg;
-+ int stdarg;
-+};
-+#define CUMULATIVE_ARGS struct cum_arg
-+
-+/* A C statement (sans semicolon) for initializing the variable CUM for the
-+ state at the beginning of the argument list. The variable has type
-+ `CUMULATIVE_ARGS'. The value of FNTYPE is the tree node for the data type
-+ of the function which will receive the args, or 0 if the args are to a
-+ compiler support library function. The value of INDIRECT is nonzero when
-+ processing an indirect call, for example a call through a function pointer.
-+ The value of INDIRECT is zero for a call to an explicitly named function, a
-+ library function call, or when `INIT_CUMULATIVE_ARGS' is used to find
-+ arguments for the function being compiled.
-+
-+ When processing a call to a compiler support library function, LIBNAME
-+ identifies which one. It is a `symbol_ref' rtx which contains the name of
-+ the function, as a string. LIBNAME is 0 when an ordinary C function call is
-+ being processed. Thus, each time this macro is called, either LIBNAME or
-+ FNTYPE is nonzero, but never both of them at once. */
-+
-+#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT, NAMED_ARGS) \
-+ init_cumulative_args (&(CUM), FNTYPE, LIBNAME, INDIRECT);
-+
-+/* A C statement (sans semicolon) to update the summarizer variable CUM to
-+ advance past an argument in the argument list. The values MODE, TYPE and
-+ NAMED describe that argument. Once this is done, the variable CUM is
-+ suitable for analyzing the *following* argument with `FUNCTION_ARG', etc.
-+
-+ This macro need not do anything if the argument in question was passed on
-+ the stack. The compiler knows how to track the amount of stack space used
-+ for arguments without any special help. */
-+#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
-+ ((CUM).nbytes += ((MODE) != BLKmode \
-+ ? (GET_MODE_SIZE (MODE) + 3) & ~3 \
-+ : (int_size_in_bytes (TYPE) + 3) & ~3))
-+
-+/* For the Ubicom32 we define the upper function argument register here. */
-+#define UBICOM32_FUNCTION_ARG_REGS 10
-+
-+/* A C expression that is nonzero if REGNO is the number of a hard register in
-+ which function arguments are sometimes passed. This does *not* include
-+ implicit arguments such as the static chain and the structure-value address.
-+ On many machines, no registers can be used for this purpose since all
-+ function arguments are pushed on the stack. */
-+#define FUNCTION_ARG_REGNO_P(N) ((N) < UBICOM32_FUNCTION_ARG_REGS)
-+
-+\f
-+/* How Scalar Function Values are Returned. */
-+
-+/* The number of the hard register that is used to return a scalar value from a
-+ function call. */
-+#define RETURN_VALUE_REGNUM 0
-+
-+/* A C expression to create an RTX representing the place where a function
-+ returns a value of data type VALTYPE. VALTYPE is a tree node representing a
-+ data type. Write `TYPE_MODE (VALTYPE)' to get the machine mode used to
-+ represent that type. On many machines, only the mode is relevant.
-+ (Actually, on most machines, scalar values are returned in the same place
-+ regardless of mode).
-+
-+ If `PROMOTE_FUNCTION_RETURN' is defined, you must apply the same promotion
-+ rules specified in `PROMOTE_MODE' if VALTYPE is a scalar type.
-+
-+ If the precise function being called is known, FUNC is a tree node
-+ (`FUNCTION_DECL') for it; otherwise, FUNC is a null pointer. This makes it
-+ possible to use a different value-returning convention for specific
-+ functions when all their calls are known.
-+
-+ `FUNCTION_VALUE' is not used for return vales with aggregate data types,
-+ because these are returned in another way. See `STRUCT_VALUE_REGNUM' and
-+ related macros, below. */
-+#define FUNCTION_VALUE(VALTYPE, FUNC) \
-+ gen_rtx_REG (TYPE_MODE (VALTYPE), FIRST_DATA_REGNUM)
-+
-+/* A C expression to create an RTX representing the place where a library
-+ function returns a value of mode MODE.
-+
-+ Note that "library function" in this context means a compiler support
-+ routine, used to perform arithmetic, whose name is known specially by the
-+ compiler and was not mentioned in the C code being compiled.
-+
-+ The definition of `LIBRARY_VALUE' need not be concerned aggregate data
-+ types, because none of the library functions returns such types. */
-+#define LIBCALL_VALUE(MODE) gen_rtx_REG (MODE, FIRST_DATA_REGNUM)
-+
-+/* A C expression that is nonzero if REGNO is the number of a hard register in
-+ which the values of called function may come back.
-+
-+ A register whose use for returning values is limited to serving as the
-+ second of a pair (for a value of type `double', say) need not be recognized
-+ by this macro. So for most machines, this definition suffices:
-+
-+ #define FUNCTION_VALUE_REGNO_P(N) ((N) == RETURN)
-+
-+ If the machine has register windows, so that the caller and the called
-+ function use different registers for the return value, this macro should
-+ recognize only the caller's register numbers. */
-+#define FUNCTION_VALUE_REGNO_P(N) ((N) == FIRST_DATA_REGNUM)
-+
-+\f
-+/* How Large Values are Returned. */
-+
-+/* A C expression which can inhibit the returning of certain function values in
-+ registers, based on the type of value. A nonzero value says to return the
-+ function value in memory, just as large structures are always returned.
-+ Here TYPE will be a C expression of type `tree', representing the data type
-+ of the value.
-+
-+ Note that values of mode `BLKmode' must be explicitly handled by this macro.
-+ Also, the option `-fpcc-struct-return' takes effect regardless of this
-+ macro. On most systems, it is possible to leave the macro undefined; this
-+ causes a default definition to be used, whose value is the constant 1 for
-+ `BLKmode' values, and 0 otherwise.
-+
-+ Do not use this macro to indicate that structures and unions should always
-+ be returned in memory. You should instead use `DEFAULT_PCC_STRUCT_RETURN'
-+ to indicate this. */
-+#define RETURN_IN_MEMORY(TYPE) \
-+ (int_size_in_bytes (TYPE) > 8 || TYPE_MODE (TYPE) == BLKmode)
-+
-+/* Define this macro to be 1 if all structure and union return values must be
-+ in memory. Since this results in slower code, this should be defined only
-+ if needed for compatibility with other compilers or with an ABI. If you
-+ define this macro to be 0, then the conventions used for structure and union
-+ return values are decided by the `RETURN_IN_MEMORY' macro.
-+
-+ If not defined, this defaults to the value 1. */
-+#define DEFAULT_PCC_STRUCT_RETURN 0
-+
-+/* If the structure value address is not passed in a register, define
-+ `STRUCT_VALUE' as an expression returning an RTX for the place
-+ where the address is passed. If it returns 0, the address is
-+ passed as an "invisible" first argument. */
-+#define STRUCT_VALUE 0
-+
-+/* Define this macro as a C expression that is nonzero if the return
-+ instruction or the function epilogue ignores the value of the stack pointer;
-+ in other words, if it is safe to delete an instruction to adjust the stack
-+ pointer before a return from the function.
-+
-+ Note that this macro's value is relevant only for functions for which frame
-+ pointers are maintained. It is never safe to delete a final stack
-+ adjustment in a function that has no frame pointer, and the compiler knows
-+ this regardless of `EXIT_IGNORE_STACK'. */
-+#define EXIT_IGNORE_STACK 1
-+
-+/* A C statement or compound statement to output to FILE some assembler code to
-+ call the profiling subroutine `mcount'. Before calling, the assembler code
-+ must load the address of a counter variable into a register where `mcount'
-+ expects to find the address. The name of this variable is `LP' followed by
-+ the number LABELNO, so you would generate the name using `LP%d' in a
-+ `fprintf'.
-+
-+ The details of how the address should be passed to `mcount' are determined
-+ by your operating system environment, not by GNU CC. To figure them out,
-+ compile a small program for profiling using the system's installed C
-+ compiler and look at the assembler code that results.
-+
-+ This declaration must be present, but it can be an abort if profiling is
-+ not implemented. */
-+
-+#define FUNCTION_PROFILER(file, labelno) ubicom32_profiler(file, labelno)
-+
-+/* A C statement to output, on the stream FILE, assembler code for a block of
-+ data that contains the constant parts of a trampoline. This code should not
-+ include a label--the label is taken care of automatically. */
-+#if 0
-+#define TRAMPOLINE_TEMPLATE(FILE) \
-+ do { \
-+ fprintf (FILE, "\tadd -4,sp\n"); \
-+ fprintf (FILE, "\t.long 0x0004fffa\n"); \
-+ fprintf (FILE, "\tmov (0,sp),a0\n"); \
-+ fprintf (FILE, "\tadd 4,sp\n"); \
-+ fprintf (FILE, "\tmov (13,a0),a1\n"); \
-+ fprintf (FILE, "\tmov (17,a0),a0\n"); \
-+ fprintf (FILE, "\tjmp (a0)\n"); \
-+ fprintf (FILE, "\t.long 0\n"); \
-+ fprintf (FILE, "\t.long 0\n"); \
-+ } while (0)
-+#endif
-+
-+/* A C expression for the size in bytes of the trampoline, as an integer. */
-+#define TRAMPOLINE_SIZE 0x1b
-+
-+/* Alignment required for trampolines, in bits.
-+
-+ If you don't define this macro, the value of `BIGGEST_ALIGNMENT' is used for
-+ aligning trampolines. */
-+#define TRAMPOLINE_ALIGNMENT 32
-+
-+/* A C statement to initialize the variable parts of a trampoline. ADDR is an
-+ RTX for the address of the trampoline; FNADDR is an RTX for the address of
-+ the nested function; STATIC_CHAIN is an RTX for the static chain value that
-+ should be passed to the function when it is called. */
-+#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
-+{ \
-+ emit_move_insn (gen_rtx_MEM (SImode, plus_constant ((TRAMP), 0x14)), \
-+ (CXT)); \
-+ emit_move_insn (gen_rtx_MEM (SImode, plus_constant ((TRAMP), 0x18)), \
-+ (FNADDR)); \
-+}
-+
-+/* Ubicom32 supports pre and post increment/decrement addressing. */
-+#define HAVE_POST_INCREMENT 1
-+#define HAVE_PRE_INCREMENT 1
-+#define HAVE_POST_DECREMENT 1
-+#define HAVE_PRE_DECREMENT 1
-+
-+/* Ubicom32 supports pre and post address side-effects with constants
-+ other than the size of the memory operand. */
-+#define HAVE_PRE_MODIFY_DISP 1
-+#define HAVE_POST_MODIFY_DISP 1
-+
-+/* A C expression that is 1 if the RTX X is a constant which is a valid
-+ address. On most machines, this can be defined as `CONSTANT_P (X)',
-+ but a few machines are more restrictive in which constant addresses
-+ are supported.
-+
-+ `CONSTANT_P' accepts integer-values expressions whose values are not
-+ explicitly known, such as `symbol_ref', `label_ref', and `high'
-+ expressions and `const' arithmetic expressions, in addition to
-+ `const_int' and `const_double' expressions. */
-+#define CONSTANT_ADDRESS_P(X) \
-+ (GET_CODE (X) == LABEL_REF \
-+ || (GET_CODE (X) == CONST \
-+ && GET_CODE (XEXP (X, 0)) == PLUS \
-+ && GET_CODE (XEXP (XEXP (X, 0), 0)) == LABEL_REF))
-+
-+/* Ubicom32 supports a maximum of 2 registers in a valid memory address.
-+ One is always an address register while a second, optional, one may be a
-+ data register. */
-+#define MAX_REGS_PER_ADDRESS 2
-+
-+/* A C compound statement with a conditional `goto LABEL;' executed if X (an
-+ RTX) is a legitimate memory address on the target machine for a memory
-+ operand of mode MODE.
-+
-+ It usually pays to define several simpler macros to serve as subroutines for
-+ this one. Otherwise it may be too complicated to understand.
-+
-+ This macro must exist in two variants: a strict variant and a non-strict
-+ one. The strict variant is used in the reload pass. It must be defined so
-+ that any pseudo-register that has not been allocated a hard register is
-+ considered a memory reference. In contexts where some kind of register is
-+ required, a pseudo-register with no hard register must be rejected.
-+
-+ The non-strict variant is used in other passes. It must be defined to
-+ accept all pseudo-registers in every context where some kind of register is
-+ required.
-+
-+ Compiler source files that want to use the strict variant of this macro
-+ define the macro `REG_OK_STRICT'. You should use an `#ifdef REG_OK_STRICT'
-+ conditional to define the strict variant in that case and the non-strict
-+ variant otherwise.
-+
-+ Subroutines to check for acceptable registers for various purposes (one for
-+ base registers, one for index registers, and so on) are typically among the
-+ subroutines used to define `GO_IF_LEGITIMATE_ADDRESS'. Then only these
-+ subroutine macros need have two variants; the higher levels of macros may be
-+ the same whether strict or not.
-+
-+ Normally, constant addresses which are the sum of a `symbol_ref' and an
-+ integer are stored inside a `const' RTX to mark them as constant.
-+ Therefore, there is no need to recognize such sums specifically as
-+ legitimate addresses. Normally you would simply recognize any `const' as
-+ legitimate.
-+
-+ Usually `PRINT_OPERAND_ADDRESS' is not prepared to handle constant sums that
-+ are not marked with `const'. It assumes that a naked `plus' indicates
-+ indexing. If so, then you *must* reject such naked constant sums as
-+ illegitimate addresses, so that none of them will be given to
-+ `PRINT_OPERAND_ADDRESS'.
-+
-+ On some machines, whether a symbolic address is legitimate depends on the
-+ section that the address refers to. On these machines, define the macro
-+ `ENCODE_SECTION_INFO' to store the information into the `symbol_ref', and
-+ then check for it here. When you see a `const', you will have to look
-+ inside it to find the `symbol_ref' in order to determine the section.
-+
-+ The best way to modify the name string is by adding text to the beginning,
-+ with suitable punctuation to prevent any ambiguity. Allocate the new name
-+ in `saveable_obstack'. You will have to modify `ASM_OUTPUT_LABELREF' to
-+ remove and decode the added text and output the name accordingly, and define
-+ `STRIP_NAME_ENCODING' to access the original name string.
-+
-+ You can check the information stored here into the `symbol_ref' in the
-+ definitions of the macros `GO_IF_LEGITIMATE_ADDRESS' and
-+ `PRINT_OPERAND_ADDRESS'. */
-+/* On the ubicom32, the value in the address register must be
-+ in the same memory space/segment as the effective address.
-+
-+ This is problematical for reload since it does not understand
-+ that base+index != index+base in a memory reference. */
-+
-+#ifdef REG_OK_STRICT
-+#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
-+ if (ubicom32_legitimate_address_p (MODE, X, 1)) goto ADDR;
-+#else
-+#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
-+ if (ubicom32_legitimate_address_p (MODE, X, 0)) goto ADDR;
-+#endif
-+
-+/* Try machine-dependent ways of modifying an illegitimate address
-+ to be legitimate. If we find one, return the new, valid address.
-+ This macro is used in only one place: `memory_address' in explow.c.
-+
-+ OLDX is the address as it was before break_out_memory_refs was called.
-+ In some cases it is useful to look at this to decide what needs to be done.
-+
-+ MODE and WIN are passed so that this macro can use
-+ GO_IF_LEGITIMATE_ADDRESS.
-+
-+ It is always safe for this macro to do nothing. It exists to recognize
-+ opportunities to optimize the output.
-+
-+ On RS/6000, first check for the sum of a register with a constant
-+ integer that is out of range. If so, generate code to add the
-+ constant with the low-order 16 bits masked to the register and force
-+ this result into another register (this can be done with `cau').
-+ Then generate an address of REG+(CONST&0xffff), allowing for the
-+ possibility of bit 16 being a one.
-+
-+ Then check for the sum of a register and something not constant, try to
-+ load the other things into a register and return the sum. */
-+
-+#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \
-+{ \
-+ rtx result = ubicom32_legitimize_address ((X), (OLDX), (MODE)); \
-+ if (result != NULL_RTX) \
-+ { \
-+ (X) = result; \
-+ goto WIN; \
-+ } \
-+}
-+
-+/* Try a machine-dependent way of reloading an illegitimate address
-+ operand. If we find one, push the reload and jump to WIN. This
-+ macro is used in only one place: `find_reloads_address' in reload.c. */
-+#define LEGITIMIZE_RELOAD_ADDRESS(AD, MODE, OPNUM, TYPE, IND, WIN) \
-+{ \
-+ rtx new_rtx = ubicom32_legitimize_reload_address ((AD), (MODE), (OPNUM), (int)(TYPE)); \
-+ if (new_rtx) \
-+ { \
-+ (AD) = new_rtx; \
-+ goto WIN; \
-+ } \
-+}
-+
-+/* A C statement or compound statement with a conditional `goto LABEL;'
-+ executed if memory address X (an RTX) can have different meanings depending
-+ on the machine mode of the memory reference it is used for or if the address
-+ is valid for some modes but not others.
-+
-+ Autoincrement and autodecrement addresses typically have mode-dependent
-+ effects because the amount of the increment or decrement is the size of the
-+ operand being addressed. Some machines have other mode-dependent addresses.
-+ Many RISC machines have no mode-dependent addresses.
-+
-+ You may assume that ADDR is a valid address for the machine. */
-+#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL) \
-+ if (ubicom32_mode_dependent_address_p (ADDR)) \
-+ goto LABEL;
-+
-+/* A C expression that is nonzero if X is a legitimate constant for an
-+ immediate operand on the target machine. You can assume that X
-+ satisfies `CONSTANT_P', so you need not check this. In fact, `1' is
-+ a suitable definition for this macro on machines where anything
-+ `CONSTANT_P' is valid. */
-+#define LEGITIMATE_CONSTANT_P(X) \
-+ ubicom32_legitimate_constant_p ((X))
-+
-+/* Moves between registers are pretty-much single instructions for
-+ Ubicom32. We make this the default "2" that gcc likes. */
-+#define REGISTER_MOVE_COST(MODE, FROM, TO) 2
-+
-+/* This is a little bit of magic from the S390 port that wins 2% on code
-+ size when building the Linux kernel! Unfortunately while it wins on
-+ that size the user-space apps built using FD-PIC don't improve and the
-+ performance is lower because we put more pressure on the caches. We may
-+ want this back on some future CPU that has higher cache performance. */
-+/* #define IRA_HARD_REGNO_ADD_COST_MULTIPLIER(regno) 0.5 */
-+
-+/* Moves between registers and memory are more expensive than between
-+ registers because we have caches and write buffers that slow things
-+ down! */
-+#define MEMORY_MOVE_COST(MODE, CLASS, IN) 2
-+
-+/* A fall-through branch is very low cost but anything that changes the PC
-+ incurs a major pipeline hazard. We don't make the full extent of this
-+ hazard visible because we hope that multiple threads will absorb much
-+ of the cost and so we don't want a jump being replaced with, say, 7
-+ instructions. */
-+#define BRANCH_COST(SPEED_P, PREDICTABLE_P) \
-+ ((PREDICTABLE_P) ? 1 : 3)
-+
-+/* Define this macro as a C expression which is nonzero if accessing less than
-+ a word of memory (i.e. a `char' or a `short') is no faster than accessing a
-+ word of memory, i.e., if such access require more than one instruction or if
-+ there is no difference in cost between byte and (aligned) word loads.
-+
-+ When this macro is not defined, the compiler will access a field by finding
-+ the smallest containing object; when it is defined, a fullword load will be
-+ used if alignment permits. Unless bytes accesses are faster than word
-+ accesses, using word accesses is preferable since it may eliminate
-+ subsequent memory access if subsequent accesses occur to other fields in the
-+ same word of the structure, but to different bytes. */
-+#define SLOW_BYTE_ACCESS 0
-+
-+/* The number of scalar move insns which should be generated instead of a
-+ string move insn or a library call. Increasing the value will always make
-+ code faster, but eventually incurs high cost in increased code size.
-+
-+ If you don't define this, a reasonable default is used. */
-+/* According to expr.c, a value of around 6 should minimize code size. */
-+#define MOVE_RATIO(SPEED) 6
-+
-+/* We're much better off calling a constant function address with the
-+ Ubicom32 architecture because we have an opcode for doing so. Don't
-+ let the compiler extract function addresses as common subexpressions
-+ into an address register. */
-+#define NO_FUNCTION_CSE
-+
-+#define SELECT_CC_MODE(OP, X, Y) ubicom32_select_cc_mode (OP, X, Y)
-+
-+#define REVERSIBLE_CC_MODE(MODE) 1
-+
-+/* Canonicalize a comparison from one we don't have to one we do have. */
-+#define CANONICALIZE_COMPARISON(CODE, OP0, OP1) \
-+ ubicom32_canonicalize_comparison (&(CODE), &(OP0), &(OP1))
-+
-+/* Dividing the output into sections. */
-+
-+/* A C expression whose value is a string containing the assembler operation
-+ that should precede instructions and read-only data. Normally `".text"' is
-+ right. */
-+#define TEXT_SECTION_ASM_OP "\t.section .text"
-+
-+/* A C expression whose value is a string containing the assembler operation to
-+ identify the following data as writable initialized data. Normally
-+ `".data"' is right. */
-+#define DATA_SECTION_ASM_OP "\t.section .data"
-+
-+
-+/* If defined, a C expression whose value is a string containing the
-+ assembler operation to identify the following data as
-+ uninitialized global data. If not defined, and neither
-+ `ASM_OUTPUT_BSS' nor `ASM_OUTPUT_ALIGNED_BSS' are defined,
-+ uninitialized global data will be output in the data section if
-+ `-fno-common' is passed, otherwise `ASM_OUTPUT_COMMON' will be
-+ used. */
-+#define BSS_SECTION_ASM_OP "\t.section .bss"
-+
-+/* This is how we tell the assembler that a symbol is weak. */
-+
-+#define ASM_WEAKEN_LABEL(FILE, NAME) \
-+ do \
-+ { \
-+ fputs ("\t.weak\t", (FILE)); \
-+ assemble_name ((FILE), (NAME)); \
-+ fputc ('\n', (FILE)); \
-+ } \
-+ while (0)
-+
-+/* The Overall Framework of an Assembler File. */
-+
-+#undef SET_ASM_OP
-+#define SET_ASM_OP "\t.set\t"
-+
-+/* A C string constant describing how to begin a comment in the target
-+ assembler language. The compiler assumes that the comment will end at the
-+ end of the line. */
-+#define ASM_COMMENT_START ";"
-+
-+/* A C string constant for text to be output before each `asm' statement or
-+ group of consecutive ones. Normally this is `"#APP"', which is a comment
-+ that has no effect on most assemblers but tells the GNU assembler that it
-+ must check the lines that follow for all valid assembler constructs. */
-+#define ASM_APP_ON "#APP\n"
-+
-+/* A C string constant for text to be output after each `asm' statement or
-+ group of consecutive ones. Normally this is `"#NO_APP"', which tells the
-+ GNU assembler to resume making the time-saving assumptions that are valid
-+ for ordinary compiler output. */
-+#define ASM_APP_OFF "#NO_APP\n"
-+
-+/* Like `ASM_OUTPUT_BSS' except takes the required alignment as a separate,
-+ explicit argument. If you define this macro, it is used in place of
-+ `ASM_OUTPUT_BSS', and gives you more flexibility in handling the required
-+ alignment of the variable. The alignment is specified as the number of
-+ bits.
-+
-+ Try to use function `asm_output_aligned_bss' defined in file `varasm.c' when
-+ defining this macro. */
-+#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
-+ asm_output_aligned_bss ((FILE), (DECL), (NAME), (SIZE), (ALIGN))
-+
-+/* A C expression to assign to OUTVAR (which is a variable of type `char *') a
-+ newly allocated string made from the string NAME and the number NUMBER, with
-+ some suitable punctuation added. Use `alloca' to get space for the string.
-+
-+ The string will be used as an argument to `ASM_OUTPUT_LABELREF' to produce
-+ an assembler label for an internal static variable whose name is NAME.
-+ Therefore, the string must be such as to result in valid assembler code.
-+ The argument NUMBER is different each time this macro is executed; it
-+ prevents conflicts between similarly-named internal static variables in
-+ different scopes.
-+
-+ Ideally this string should not be a valid C identifier, to prevent any
-+ conflict with the user's own symbols. Most assemblers allow periods or
-+ percent signs in assembler symbols; putting at least one of these between
-+ the name and the number will suffice. */
-+#define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \
-+ ((OUTPUT) = (char *) alloca (strlen ((NAME)) + 10), \
-+ sprintf ((OUTPUT), "%s___%d", (NAME), (LABELNO)))
-+
-+#define ASM_GENERATE_INTERNAL_LABEL(STRING, PREFIX, NUM) \
-+ sprintf (STRING, "*.%s%ld", PREFIX, (long)(NUM))
-+/* A C statement to store into the string STRING a label whose name
-+ is made from the string PREFIX and the number NUM.
-+
-+ This string, when output subsequently by `assemble_name', should
-+ produce the output that `(*targetm.asm_out.internal_label)' would produce
-+ with the same PREFIX and NUM.
-+
-+ If the string begins with `*', then `assemble_name' will output
-+ the rest of the string unchanged. It is often convenient for
-+ `ASM_GENERATE_INTERNAL_LABEL' to use `*' in this way. If the
-+ string doesn't start with `*', then `ASM_OUTPUT_LABELREF' gets to
-+ output the string, and may change it. (Of course,
-+ `ASM_OUTPUT_LABELREF' is also part of your machine description, so
-+ you should know what it does on your machine.) */
-+
-+/* This says how to output assembler code to declare an
-+ uninitialized external linkage data object. Under SVR4,
-+ the linker seems to want the alignment of data objects
-+ to depend on their types. We do exactly that here. */
-+
-+#define COMMON_ASM_OP "\t.comm\t"
-+
-+#undef ASM_OUTPUT_COMMON
-+#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \
-+ do \
-+ { \
-+ fprintf ((FILE), "%s", COMMON_ASM_OP); \
-+ assemble_name ((FILE), (NAME)); \
-+ fprintf ((FILE), ", %u\n", (SIZE)); \
-+ } \
-+ while (0)
-+
-+/* This says how to output assembler code to declare an
-+ uninitialized internal linkage data object. Under SVR4,
-+ the linker seems to want the alignment of data objects
-+ to depend on their types. We do exactly that here. */
-+#define LOCAL_ASM_OP "\t.lcomm\t"
-+
-+#undef ASM_OUTPUT_LOCAL
-+#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \
-+ do \
-+ { \
-+ fprintf ((FILE), "%s", LOCAL_ASM_OP); \
-+ assemble_name ((FILE), (NAME)); \
-+ fprintf ((FILE), ", %u\n", (SIZE)); \
-+ } \
-+ while (0)
-+
-+/* Globalizing directive for a label. */
-+#define GLOBAL_ASM_OP ".global\t"
-+
-+/* Output the operand of an instruction. */
-+#define PRINT_OPERAND(FILE, X, CODE) \
-+ ubicom32_print_operand(FILE, X, CODE)
-+
-+/* Output the address of an operand. */
-+#define PRINT_OPERAND_ADDRESS(FILE, ADDR) \
-+ ubicom32_print_operand_address (FILE, ADDR)
-+
-+/* A C expression to output to STREAM some assembler code which will push hard
-+ register number REGNO onto the stack. The code need not be optimal, since
-+ this macro is used only when profiling. */
-+#define ASM_OUTPUT_REG_PUSH(FILE, REGNO)
-+
-+/* A C expression to output to STREAM some assembler code which will pop hard
-+ register number REGNO off of the stack. The code need not be optimal, since
-+ this macro is used only when profiling. */
-+#define ASM_OUTPUT_REG_POP(FILE, REGNO)
-+
-+/* This macro should be provided on machines where the addresses in a dispatch
-+ table are relative to the table's own address.
-+
-+ The definition should be a C statement to output to the stdio stream STREAM
-+ an assembler pseudo-instruction to generate a difference between two labels.
-+ VALUE and REL are the numbers of two internal labels. The definitions of
-+ these labels are output using `ASM_OUTPUT_INTERNAL_LABEL', and they must be
-+ printed in the same way here. For example,
-+
-+ fprintf (STREAM, "\t.word L%d-L%d\n", VALUE, REL) */
-+#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
-+ fprintf (FILE, "\t%s .L%d-.L%d\n", ".long", VALUE, REL)
-+
-+/* This macro should be provided on machines where the addresses in a dispatch
-+ table are absolute.
-+
-+ The definition should be a C statement to output to the stdio stream STREAM
-+ an assembler pseudo-instruction to generate a reference to a label. VALUE
-+ is the number of an internal label whose definition is output using
-+ `ASM_OUTPUT_INTERNAL_LABEL'. For example,
-+
-+ fprintf (STREAM, "\t.word L%d\n", VALUE) */
-+#define ASM_OUTPUT_ADDR_VEC_ELT(STREAM, VALUE) \
-+ fprintf (STREAM, "\t.word .L%d\n", VALUE)
-+
-+/* Switch into a generic section. */
-+#define TARGET_ASM_NAMED_SECTION default_elf_asm_named_section
-+
-+/* Assembler Commands for Alignment. */
-+
-+#define ASM_OUTPUT_SKIP(STREAM, N) fprintf (STREAM, "\t.skip %d,0\n", N)
-+/* A C statement to output to the stdio stream STREAM an assembler
-+ instruction to advance the location counter by NBYTES bytes.
-+ Those bytes should be zero when loaded. NBYTES will be a C
-+ expression of type `int'. */
-+
-+/* A C statement to output to the stdio stream STREAM an assembler command to
-+ advance the location counter to a multiple of 2 to the POWER bytes. POWER
-+ will be a C expression of type `int'. */
-+#define ASM_OUTPUT_ALIGN(FILE, LOG) \
-+ if ((LOG) != 0) \
-+ fprintf (FILE, "\t.align %d\n", (LOG))
-+
-+/* A C expression that returns the DBX register number for the compiler
-+ register number REGNO. In simple cases, the value of this expression may be
-+ REGNO itself. But sometimes there are some registers that the compiler
-+ knows about and DBX does not, or vice versa. In such cases, some register
-+ may need to have one number in the compiler and another for DBX.
-+
-+ If two registers have consecutive numbers inside GNU CC, and they can be
-+ used as a pair to hold a multiword value, then they *must* have consecutive
-+ numbers after renumbering with `DBX_REGISTER_NUMBER'. Otherwise, debuggers
-+ will be unable to access such a pair, because they expect register pairs to
-+ be consecutive in their own numbering scheme.
-+
-+ If you find yourself defining `DBX_REGISTER_NUMBER' in way that does not
-+ preserve register pairs, then what you must do instead is redefine the
-+ actual register numbering scheme.
-+
-+ This declaration is required. */
-+#define DBX_REGISTER_NUMBER(REGNO) REGNO
-+
-+/* A C expression that returns the integer offset value for an automatic
-+ variable having address X (an RTL expression). The default computation
-+ assumes that X is based on the frame-pointer and gives the offset from the
-+ frame-pointer. This is required for targets that produce debugging output
-+ for DBX or COFF-style debugging output for SDB and allow the frame-pointer
-+ to be eliminated when the `-g' options is used. */
-+#define DEBUGGER_AUTO_OFFSET(X) \
-+ ((GET_CODE (X) == PLUS ? INTVAL (XEXP (X, 1)) : 0) \
-+ + (frame_pointer_needed \
-+ ? 0 : -initial_elimination_offset (FRAME_POINTER_REGNUM, \
-+ STACK_POINTER_REGNUM)))
-+
-+/* A C expression that returns the integer offset value for an argument having
-+ address X (an RTL expression). The nominal offset is OFFSET. */
-+#define DEBUGGER_ARG_OFFSET(OFFSET, X) \
-+ ((GET_CODE (X) == PLUS ? OFFSET : 0) \
-+ + (frame_pointer_needed \
-+ ? 0 : -initial_elimination_offset (ARG_POINTER_REGNUM, \
-+ STACK_POINTER_REGNUM)))
-+
-+/* A C expression that returns the type of debugging output GNU CC produces
-+ when the user specifies `-g' or `-ggdb'. Define this if you have arranged
-+ for GNU CC to support more than one format of debugging output. Currently,
-+ the allowable values are `DBX_DEBUG', `SDB_DEBUG', `DWARF_DEBUG',
-+ `DWARF2_DEBUG', and `XCOFF_DEBUG'.
-+
-+ The value of this macro only affects the default debugging output; the user
-+ can always get a specific type of output by using `-gstabs', `-gcoff',
-+ `-gdwarf-1', `-gdwarf-2', or `-gxcoff'.
-+
-+ Defined in svr4.h.
-+*/
-+#undef PREFERRED_DEBUGGING_TYPE
-+#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
-+
-+/* Define this macro if GNU CC should produce dwarf version 2 format debugging
-+ output in response to the `-g' option.
-+
-+ To support optional call frame debugging information, you must also define
-+ `INCOMING_RETURN_ADDR_RTX' and either set `RTX_FRAME_RELATED_P' on the
-+ prologue insns if you use RTL for the prologue, or call `dwarf2out_def_cfa'
-+ and `dwarf2out_reg_save' as appropriate from `FUNCTION_PROLOGUE' if you
-+ don't.
-+
-+ Defined in svr4.h. */
-+
-+#define DWARF2_DEBUGGING_INFO 1
-+/*#define DWARF2_UNWIND_INFO 1*/
-+#define DWARF2_UNWIND_INFO 0
-+#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (Pmode, LINK_REGNO)
-+#define INCOMING_FRAME_SP_OFFSET 0
-+#define DWARF_FRAME_RETURN_COLUMN DWARF_FRAME_REGNUM (LINK_REGNO)
-+#define EH_RETURN_FIRST 9
-+#define EH_RETURN_DATA_REGNO(N) ((N) < 2 ? (N) + EH_RETURN_FIRST : INVALID_REGNUM)
-+
-+/* The EH_RETURN_STACKADJ_RTX macro returns RTL which describes the
-+ location used to store the amount to ajdust the stack. This is
-+ usually a registers that is available from end of the function's body
-+ to the end of the epilogue. Thus, this cannot be a register used as a
-+ temporary by the epilogue.
-+
-+ This must be an integer register. */
-+#define EH_RETURN_STACKADJ_REGNO 11
-+#define EH_RETURN_STACKADJ_RTX \
-+ gen_rtx_REG (Pmode, EH_RETURN_STACKADJ_REGNO)
-+
-+/* The EH_RETURN_HANDLER_RTX macro returns RTL which describes the
-+ location used to store the address the processor should jump to
-+ catch exception. This is usually a registers that is available from
-+ end of the function's body to the end of the epilogue. Thus, this
-+ cannot be a register used as a temporary by the epilogue.
-+
-+ This must be an address register. */
-+#define EH_RETURN_HANDLER_REGNO 18
-+#define EH_RETURN_HANDLER_RTX \
-+ gen_rtx_REG (Pmode, EH_RETURN_HANDLER_REGNO)
-+
-+/* #define DWARF2_DEBUGGING_INFO */
-+
-+/* Define this macro if GNU CC should produce dwarf version 2-style
-+ line numbers. This usually requires extending the assembler to
-+ support them, and #defining DWARF2_LINE_MIN_INSN_LENGTH in the
-+ assembler configuration header files. */
-+/* #define DWARF2_ASM_LINE_DEBUG_INFO 1 */
-+
-+
-+/* An alias for a machine mode name. This is the machine mode that elements
-+ of a jump-table have. */
-+#define CASE_VECTOR_MODE Pmode
-+
-+/* Smallest number of different values for which it is best to use a
-+ jump-table instead of a tree of conditional branches. For most Ubicom32
-+ targets this is quite small, but for the v1 architecture implementations
-+ we had very little data memory and so heavily prefer the tree approach
-+ rather than the jump tables. */
-+#define CASE_VALUES_THRESHOLD ubicom32_case_values_threshold
-+
-+/* Register operations within the Ubicom32 architecture always operate on
-+ the whole register word and not just the sub-bits required for the opcode
-+ mode size. */
-+#define WORD_REGISTER_OPERATIONS
-+
-+/* The maximum number of bytes that a single instruction can move quickly from
-+ memory to memory. */
-+#define MOVE_MAX 4
-+
-+/* A C expression that is nonzero if on this machine the number of bits
-+ actually used for the count of a shift operation is equal to the number of
-+ bits needed to represent the size of the object being shifted. When this
-+ macro is non-zero, the compiler will assume that it is safe to omit a
-+ sign-extend, zero-extend, and certain bitwise `and' instructions that
-+ truncates the count of a shift operation. On machines that have
-+ instructions that act on bitfields at variable positions, which may include
-+ `bit test' instructions, a nonzero `SHIFT_COUNT_TRUNCATED' also enables
-+ deletion of truncations of the values that serve as arguments to bitfield
-+ instructions.
-+
-+ If both types of instructions truncate the count (for shifts) and position
-+ (for bitfield operations), or if no variable-position bitfield instructions
-+ exist, you should define this macro.
-+
-+ However, on some machines, such as the 80386 and the 680x0, truncation only
-+ applies to shift operations and not the (real or pretended) bitfield
-+ operations. Define `SHIFT_COUNT_TRUNCATED' to be zero on such machines.
-+ Instead, add patterns to the `md' file that include the implied truncation
-+ of the shift instructions.
-+
-+ You need not define this macro if it would always have the value of zero. */
-+#define SHIFT_COUNT_TRUNCATED 1
-+
-+/* A C expression which is nonzero if on this machine it is safe to "convert"
-+ an integer of INPREC bits to one of OUTPREC bits (where OUTPREC is smaller
-+ than INPREC) by merely operating on it as if it had only OUTPREC bits.
-+
-+ On many machines, this expression can be 1.
-+
-+ When `TRULY_NOOP_TRUNCATION' returns 1 for a pair of sizes for modes for
-+ which `MODES_TIEABLE_P' is 0, suboptimal code can result. If this is the
-+ case, making `TRULY_NOOP_TRUNCATION' return 0 in such cases may improve
-+ things. */
-+#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
-+
-+/* A C string constant that tells the GNU CC driver program options to pass
-+ to the assembler. It can also specify how to translate options you give
-+ to GNU CC into options for GNU CC to pass to the assembler. See the
-+ file `sun3.h' for an example of this.
-+
-+ Defined in svr4.h. */
-+#undef ASM_SPEC
-+#define ASM_SPEC \
-+ "%{march=*:-m%*} %{!march=*:-mubicom32v4} %{mfdpic:-mfdpic}"
-+
-+#define LINK_SPEC "\
-+%{h*} %{v:-V} \
-+%{b} \
-+%{mfdpic:-melf32ubicom32fdpic -z text} \
-+%{static:-dn -Bstatic} \
-+%{shared:-G -Bdynamic} \
-+%{symbolic:-Bsymbolic} \
-+%{G*} \
-+%{YP,*} \
-+%{Qy:} %{!Qn:-Qy}"
-+
-+#undef STARTFILE_SPEC
-+#undef ENDFILE_SPEC
-+
-+/* The svr4.h LIB_SPEC with -leval and --*group tacked on */
-+
-+#undef LIB_SPEC
-+#define LIB_SPEC "%{!shared:%{!symbolic:--start-group -lc -leval -lgcc --end-group}}"
-+
-+#undef HAVE_GAS_SHF_MERGE
-+#define HAVE_GAS_SHF_MERGE 0
-+
-+#define HANDLE_SYSV_PRAGMA 1
-+#undef HANDLE_PRAGMA_PACK
-+
-+typedef void (*ubicom32_func_ptr) (void);
-+
-+/* Define builtins for selected special-purpose instructions. */
-+enum ubicom32_builtins
-+{
-+ UBICOM32_BUILTIN_UBICOM32_SWAPB_2,
-+ UBICOM32_BUILTIN_UBICOM32_SWAPB_4
-+};
-+
-+extern rtx ubicom32_compare_op0;
-+extern rtx ubicom32_compare_op1;
-+
-+#define TYPE_ASM_OP "\t.type\t"
-+#define TYPE_OPERAND_FMT "@%s"
-+
-+#ifndef ASM_DECLARE_RESULT
-+#define ASM_DECLARE_RESULT(FILE, RESULT)
-+#endif
-+
-+/* These macros generate the special .type and .size directives which
-+ are used to set the corresponding fields of the linker symbol table
-+ entries in an ELF object file under SVR4. These macros also output
-+ the starting labels for the relevant functions/objects. */
-+
-+/* Write the extra assembler code needed to declare a function properly.
-+ Some svr4 assemblers need to also have something extra said about the
-+ function's return value. We allow for that here. */
-+
-+#ifndef ASM_DECLARE_FUNCTION_NAME
-+#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \
-+ do \
-+ { \
-+ ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "function"); \
-+ ASM_DECLARE_RESULT (FILE, DECL_RESULT (DECL)); \
-+ ASM_OUTPUT_LABEL (FILE, NAME); \
-+ } \
-+ while (0)
-+#endif
---- /dev/null
-+++ b/gcc/config/ubicom32/ubicom32.md
-@@ -0,0 +1,3753 @@
-+; GCC machine description for Ubicom32
-+;
-+; Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Free Software
-+; Foundation, Inc.
-+; Contributed by Ubicom, Inc.
-+;
-+; This file is part of GCC.
-+;
-+; GCC is free software; you can redistribute it and/or modify
-+; it under the terms of the GNU General Public License as published by
-+; the Free Software Foundation; either version 3, or (at your option)
-+; any later version.
-+;
-+; GCC is distributed in the hope that it will be useful,
-+; but WITHOUT ANY WARRANTY; without even the implied warranty of
-+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+; GNU General Public License for more details.
-+;
-+; You should have received a copy of the GNU General Public License
-+; along with GCC; see the file COPYING3. If not see
-+; <http://www.gnu.org/licenses/>.
-+
-+(define_constants
-+ [(AUX_DATA_REGNO 15)
-+ (LINK_REGNO 21)
-+ (SP_REGNO 23)
-+ (ACC0_HI_REGNO 24)
-+ (ACC1_HI_REGNO 26)
-+ (CC_REGNO 30)])
-+
-+(define_constants
-+ [(UNSPEC_FDPIC_GOT 0)
-+ (UNSPEC_FDPIC_GOT_FUNCDESC 1)])
-+
-+(define_constants
-+ [(UNSPEC_VOLATILE_LOAD_FDPIC_FUNCDESC 0)])
-+
-+;; Types of instructions (for scheduling purposes).
-+
-+(define_attr "type" "mul,addr,other"
-+ (const_string "other"))
-+
-+; Define instruction scheduling characteristics. We can only issue
-+; one instruction per clock so we don't need to define CPU units.
-+;
-+(define_automaton "ubicom32")
-+
-+(define_cpu_unit "i_pipeline" "ubicom32");
-+
-+; We have a 4 cycle hazard associated with address calculations which
-+; seems rather tricky to avoid so we go with a defensive assumption
-+; that almost anything can be used to generate addresses.
-+;
-+;(define_insn_reservation "ubicom32_other" 4
-+; (eq_attr "type" "other")
-+; "i_pipeline")
-+
-+; Some moves don't generate hazards.
-+;
-+;(define_insn_reservation "ubicom32_addr" 1
-+; (eq_attr "type" "addr")
-+; "i_pipeline")
-+
-+; We need 3 cycles between a multiply instruction and any use of the
-+; matching accumulator register(s).
-+;
-+(define_insn_reservation "ubicom32_mul" 4
-+ (eq_attr "type" "mul")
-+ "i_pipeline")
-+
-+(define_attr "length" ""
-+ (const_int 4))
-+
-+(include "predicates.md")
-+(include "constraints.md")
-+
-+; 8-bit move with no change to the flags reg.
-+;
-+(define_insn "movqi"
-+ [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
-+ (match_operand:QI 1 "ubicom32_move_operand" "g"))]
-+ ""
-+ "move.1\\t%0, %1")
-+
-+; Combiner-generated 8-bit move with the zero flag set accordingly.
-+;
-+(define_insn "movqi_ccszn"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:QI 0 "nonimmediate_operand" "rm")
-+ (const_int 0)))
-+ (set (match_operand:QI 1 "nonimmediate_operand" "=rm")
-+ (match_dup 0))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "ext.1\\t%1, %0")
-+
-+; Combine isn't very good at merging some types of operations so we
-+; have to make do with a peephole. It's not as effective but it's better
-+; than doing nothing.
-+;
-+(define_peephole2
-+ [(set (match_operand:QI 0 "nonimmediate_operand" "")
-+ (match_operand:QI 1 "nonimmediate_operand" ""))
-+ (set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (match_operator 3 "ubicom32_compare_operator"
-+ [(match_dup 0)
-+ (const_int 0)]))]
-+ "(GET_MODE (operands[2]) == CCSZNmode
-+ || GET_MODE (operands[2]) == CCSZmode)"
-+ [(parallel
-+ [(set (match_dup 2)
-+ (match_op_dup 3
-+ [(match_dup 1)
-+ (const_int 0)]))
-+ (set (match_dup 0)
-+ (match_dup 1))])]
-+ "")
-+
-+; Combine isn't very good at merging some types of operations so we
-+; have to make do with a peephole. It's not as effective but it's better
-+; than doing nothing.
-+;
-+(define_peephole2
-+ [(set (match_operand:QI 0 "nonimmediate_operand" "")
-+ (match_operand:QI 1 "nonimmediate_operand" ""))
-+ (set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (match_operator 3 "ubicom32_compare_operator"
-+ [(match_dup 1)
-+ (const_int 0)]))]
-+ "(GET_MODE (operands[2]) == CCSZNmode
-+ || GET_MODE (operands[2]) == CCSZmode)"
-+ [(parallel
-+ [(set (match_dup 2)
-+ (match_op_dup 3
-+ [(match_dup 1)
-+ (const_int 0)]))
-+ (set (match_dup 0)
-+ (match_dup 1))])]
-+ "")
-+
-+; 16-bit move with no change to the flags reg.
-+;
-+(define_insn "movhi"
-+ [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
-+ (match_operand:HI 1 "ubicom32_move_operand" "g"))]
-+ ""
-+ "*
-+ {
-+ if (CONST_INT_P (operands[1]))
-+ return \"movei\\t%0, %1\";
-+
-+ return \"move.2\\t%0, %1\";
-+ }")
-+
-+; Combiner-generated 16-bit move with the zero flag set accordingly.
-+;
-+(define_insn "movhi_ccszn"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:HI 0 "nonimmediate_operand" "rm")
-+ (const_int 0)))
-+ (set (match_operand:HI 1 "nonimmediate_operand" "=rm")
-+ (match_dup 0))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "ext.2\\t%1, %0")
-+
-+; Combine isn't very good at merging some types of operations so we
-+; have to make do with a peephole. It's not as effective but it's better
-+; than doing nothing.
-+;
-+(define_peephole2
-+ [(set (match_operand:HI 0 "nonimmediate_operand" "")
-+ (match_operand:HI 1 "nonimmediate_operand" ""))
-+ (set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (match_operator 3 "ubicom32_compare_operator"
-+ [(match_dup 0)
-+ (const_int 0)]))]
-+ "(GET_MODE (operands[2]) == CCSZNmode
-+ || GET_MODE (operands[2]) == CCSZmode)"
-+ [(parallel
-+ [(set (match_dup 2)
-+ (match_op_dup 3
-+ [(match_dup 1)
-+ (const_int 0)]))
-+ (set (match_dup 0)
-+ (match_dup 1))])]
-+ "")
-+
-+; Combine isn't very good at merging some types of operations so we
-+; have to make do with a peephole. It's not as effective but it's better
-+; than doing nothing.
-+;
-+(define_peephole2
-+ [(set (match_operand:HI 0 "nonimmediate_operand" "")
-+ (match_operand:HI 1 "nonimmediate_operand" ""))
-+ (set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (match_operator 3 "ubicom32_compare_operator"
-+ [(match_dup 1)
-+ (const_int 0)]))]
-+ "(GET_MODE (operands[2]) == CCSZNmode
-+ || GET_MODE (operands[2]) == CCSZmode)"
-+ [(parallel
-+ [(set (match_dup 2)
-+ (match_op_dup 3
-+ [(match_dup 1)
-+ (const_int 0)]))
-+ (set (match_dup 0)
-+ (match_dup 1))])]
-+ "")
-+
-+; 32-bit move with no change to the flags reg.
-+;
-+(define_expand "movsi"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
-+ (match_operand:SI 1 "general_operand" ""))]
-+ ""
-+ "{
-+ /* Convert any complexities in operand 1 into something that can just
-+ fall into the default expander code. */
-+ ubicom32_expand_movsi (operands);
-+ }")
-+
-+(define_insn "movsi_high"
-+ [(set (match_operand:SI 0 "ubicom32_address_register_operand" "=a")
-+ (high:SI (match_operand:SI 1 "ubicom32_symbolic_address_operand" "s")))]
-+ ""
-+ "moveai\\t%0, #%%hi(%E1)")
-+
-+(define_insn "movsi_lo_sum"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (lo_sum:SI (match_operand:SI 1 "ubicom32_address_register_operand" "a")
-+ (match_operand:SI 2 "immediate_operand" "s")))]
-+ ""
-+ "lea.1\\t%0, %%lo(%E2)(%1)")
-+
-+(define_insn "movsi_internal"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (match_operand:SI 1 "ubicom32_move_operand" "rmnY"))]
-+ ""
-+ "*
-+ {
-+ if (CONST_INT_P (operands[1]))
-+ {
-+ ubicom32_emit_move_const_int (operands[0], operands[1]);
-+ return \"\";
-+ }
-+
-+ if (GET_CODE (operands[1]) == CONST_DOUBLE)
-+ {
-+ HOST_WIDE_INT i = CONST_DOUBLE_LOW (operands[1]);
-+
-+ ubicom32_emit_move_const_int (operands[0], GEN_INT (i));
-+ return \"\";
-+ }
-+
-+ if (ubicom32_address_register_operand (operands[0], VOIDmode)
-+ && register_operand (operands[1], VOIDmode))
-+ {
-+ if (ubicom32_address_register_operand (operands[1], VOIDmode))
-+ return \"lea.1\\t%0, 0(%1)\";
-+
-+ /* Use movea here to utilize the hazard bypass in the >= v4 ISA. */
-+ if (ubicom32_v4)
-+ return \"movea\\t%0, %1\";
-+
-+ return \"move.4\\t%0, %1\";
-+ }
-+
-+ return \"move.4\\t%0, %1\";
-+ }")
-+
-+; If we're not dependent on the state of the condition codes we can construct
-+; constants of value 2^n by using a bset.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(exact_log2 (INTVAL (operands[1])) > 14
-+ && peep2_regno_dead_p (0, CC_REGNO))"
-+ [(parallel
-+ [(set (match_dup 0)
-+ (ior:SI (const_int 0)
-+ (match_dup 1)))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "")
-+
-+; If we're not dependent on the state of the condition codes we can construct
-+; constants of value ~(2^n) by using a bclr.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(exact_log2 (~INTVAL (operands[1])) > 14
-+ && peep2_regno_dead_p (0, CC_REGNO))"
-+ [(parallel
-+ [(set (match_dup 0)
-+ (and:SI (const_int -1)
-+ (match_dup 1)))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "")
-+
-+; For 32-bit constants that have bits 0 through 24 and bit 31 set the same
-+; we can use swapb.4!
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(ubicom32_v4
-+ && (INTVAL (operands[1]) & 0xffffffff) != 0xffffffff
-+ && (INTVAL (operands[1]) & 0xffffffff) != 0
-+ && ((INTVAL (operands[1]) & 0x80ffffff) == 0
-+ || (INTVAL (operands[1]) & 0x80ffffff) == 0x80ffffff))"
-+ [(set (match_dup 0)
-+ (bswap:SI (match_dup 2)))]
-+ "{
-+ operands[2] = GEN_INT (INTVAL (operands[1]) >> 24);
-+ }")
-+
-+; If this is a write of a constant to memory look to see if we can usefully
-+; transform this into 2 smaller writes.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "memory_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "! satisfies_constraint_I (operands[1])
-+ && ubicom32_legitimate_address_p (HImode, plus_constant (XEXP (operands[0], 0), 2), 1)"
-+ [(set (match_dup 4) (match_dup 2))
-+ (set (match_dup 5) (match_dup 3))]
-+ "{
-+ rtx low_hword_addr;
-+
-+ operands[2] = gen_highpart_mode (HImode, SImode, operands[1]);
-+ operands[3] = gen_lowpart (HImode, operands[1]);
-+
-+ operands[4] = gen_rtx_MEM (HImode, XEXP (operands[0], 0));
-+ MEM_COPY_ATTRIBUTES (operands[4], operands[0]);
-+
-+ low_hword_addr = plus_constant (XEXP (operands[0], 0), 2);
-+ operands[5] = gen_rtx_MEM (HImode, low_hword_addr);
-+ MEM_COPY_ATTRIBUTES (operands[5], operands[0]);
-+ }")
-+
-+; If we're writing memory and we've not found a better way to do this then
-+; try loading into a D register and then copying to memory. This will
-+; perform the fewest possible memory read/writes.
-+;
-+(define_peephole2
-+ [(match_scratch:SI 2 "d")
-+ (set (match_operand:SI 0 "memory_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "! satisfies_constraint_I (operands[1])"
-+ [(set (match_dup 2) (match_dup 1))
-+ (set (match_dup 0) (match_dup 2))]
-+ "")
-+
-+; If we're not dependent on the state of the condition codes we can construct
-+; constants of value (2^n - 1) by using an lsr.4.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(exact_log2 (INTVAL (operands[1]) + 1) > 14
-+ && peep2_regno_dead_p (0, CC_REGNO))"
-+ [(parallel
-+ [(set (match_dup 0)
-+ (lshiftrt:SI (const_int -1)
-+ (match_dup 2)))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "{
-+ operands[2] = GEN_INT (32 - exact_log2 (INTVAL (operands[1]) + 1));
-+ }")
-+
-+; If we're not dependent on the state of the condition codes we can construct
-+; constants of value (2^n - 1) by using an lsr.4.
-+;
-+(define_peephole2
-+ [(match_scratch:SI 2 "d")
-+ (set (match_operand:SI 0 "nonimmediate_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(exact_log2 (INTVAL (operands[1]) + 1) > 14
-+ && peep2_regno_dead_p (0, CC_REGNO))"
-+ [(parallel
-+ [(set (match_dup 2)
-+ (lshiftrt:SI (const_int -1)
-+ (match_dup 3)))
-+ (clobber (reg:CC CC_REGNO))])
-+ (set (match_dup 0)
-+ (match_dup 2))]
-+ "{
-+ operands[3] = GEN_INT (32 - exact_log2 (INTVAL (operands[1]) + 1));
-+ }")
-+
-+; If we're not dependent on the state of the condition codes we can construct
-+; some other constants by using an lsl.4 to shift 7 bits left by some
-+; constant.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(ubicom32_shiftable_const_int (INTVAL (operands[1]))
-+ && peep2_regno_dead_p (0, CC_REGNO))"
-+ [(parallel
-+ [(set (match_dup 0)
-+ (ashift:SI (match_dup 2)
-+ (match_dup 3)))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "{
-+ int shift = ubicom32_shiftable_const_int (INTVAL (operands[1]));
-+ operands[2] = GEN_INT (INTVAL (operands[1]) >> shift);
-+ operands[3] = GEN_INT (shift);
-+ }")
-+
-+; If we're not dependent on the state of the condition codes we can construct
-+; some other constants by using an lsl.4 to shift 7 bits left by some
-+; constant.
-+;
-+(define_peephole2
-+ [(match_scratch:SI 2 "d")
-+ (set (match_operand:SI 0 "nonimmediate_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(ubicom32_shiftable_const_int (INTVAL (operands[1]))
-+ && peep2_regno_dead_p (0, CC_REGNO))"
-+ [(parallel
-+ [(set (match_dup 2)
-+ (ashift:SI (match_dup 3)
-+ (match_dup 4)))
-+ (clobber (reg:CC CC_REGNO))])
-+ (set (match_dup 0)
-+ (match_dup 2))]
-+ "{
-+ int shift = ubicom32_shiftable_const_int (INTVAL (operands[1]));
-+ operands[3] = GEN_INT (INTVAL (operands[1]) >> shift);
-+ operands[4] = GEN_INT (shift);
-+ }")
-+
-+; For some 16-bit unsigned constants that have bit 15 set we can use
-+; swapb.2!
-+;
-+; Note that the movsi code emits the same sequence but by using a peephole2
-+; we split the pattern early enough to allow instruction scheduling to
-+; occur.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(ubicom32_v4
-+ && (INTVAL (operands[1]) & 0xffff80ff) == 0x80ff)"
-+ [(set (match_dup 0)
-+ (zero_extend:SI (bswap:HI (match_dup 2))))]
-+ "{
-+ HOST_WIDE_INT i = INTVAL (operands[1]) >> 8;
-+ if (i >= 0x80)
-+ i -= 0x100;
-+ operands[2] = GEN_INT (i);
-+ }")
-+
-+; In general for a 16-bit unsigned constant that has bit 15 set
-+; then we need a movei/move.2 pair unless we can represent it
-+; via just a move.2.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(INTVAL (operands[1]) & 0xffff8000) == 0x8000
-+ && (INTVAL (operands[1]) & 0xffff) < 0xff80"
-+ [(set (match_dup 2)
-+ (match_dup 1))
-+ (set (match_dup 0)
-+ (zero_extend:SI (match_dup 2)))]
-+ "{
-+ operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));
-+ }")
-+
-+; If we're not dependent on the state of the condition codes we can construct
-+; 32-bit constants that have bits 16 through 31 set to arbitrary values
-+; and have bits 0 through 15 set to something representable as a default
-+; source-1 immediate - we use movei/shmrg.2
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(((INTVAL (operands[1]) >= 0x8000
-+ && INTVAL (operands[1]) < 0xff80)
-+ || INTVAL (operands[1]) >= 0x10000
-+ || INTVAL (operands[1]) < -0x8000)
-+ && ((INTVAL (operands[1]) & 0xffff) >= 0xff80
-+ || (INTVAL (operands[1]) & 0xffff) < 0x80)
-+ && peep2_regno_dead_p (0, CC_REGNO))"
-+ [(set (match_dup 0)
-+ (match_dup 2))
-+ (parallel
-+ [(set (match_dup 0)
-+ (ior:SI
-+ (ashift:SI (match_dup 0)
-+ (const_int 16))
-+ (zero_extend:SI
-+ (match_dup 3))))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "{
-+ operands[2] = gen_highpart_mode (HImode, SImode, operands[1]);
-+ operands[3] = gen_lowpart (HImode, operands[1]);
-+ }")
-+
-+; Exactly the same as the peephole2 preceding except that this targets a
-+; general register instead of D register. Hopefully the later optimization
-+; passes will notice that the value ended up in a D register first here
-+; and eliminate away the other register!
-+;
-+(define_peephole2
-+ [(match_scratch:SI 2 "d")
-+ (set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(((INTVAL (operands[1]) >= 0x8000
-+ && INTVAL (operands[1]) < 0xff80)
-+ || INTVAL (operands[1]) >= 0x10000
-+ || INTVAL (operands[1]) < -0x8000)
-+ && ((INTVAL (operands[1]) & 0xffff) >= 0xff80
-+ || (INTVAL (operands[1]) & 0xffff) < 0x80)
-+ && peep2_regno_dead_p (0, CC_REGNO))"
-+ [(set (match_dup 2)
-+ (match_dup 3))
-+ (parallel
-+ [(set (match_dup 2)
-+ (ior:SI
-+ (ashift:SI (match_dup 2)
-+ (const_int 16))
-+ (zero_extend:SI
-+ (match_dup 4))))
-+ (clobber (reg:CC CC_REGNO))])
-+ (set (match_dup 0)
-+ (match_dup 2))]
-+ "{
-+ operands[3] = gen_highpart_mode (HImode, SImode, operands[1]);
-+ operands[4] = gen_lowpart (HImode, operands[1]);
-+ }")
-+
-+; If we have a load of a large integer constant which does not have bit 31
-+; set and we have a spare A reg then construct it with a moveai/lea.1 pair
-+; instead. This avoids constructing it in 3 instructions on the stack.
-+;
-+; Note that we have to be careful not to match anything that matches
-+; something we can do in a single instruction! There aren't many such
-+; constants but there are some.
-+;
-+(define_peephole2
-+ [(match_scratch:SI 2 "a")
-+ (set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(! (INTVAL (operands[1]) & 0x80000000)
-+ && ((INTVAL (operands[1]) >= 0x8000
-+ && INTVAL (operands[1]) < 0xff80)
-+ || INTVAL (operands[1]) >= 0x10000))"
-+ [(set (match_dup 2)
-+ (match_dup 3))
-+ (set (match_dup 0)
-+ (plus:SI (match_dup 2)
-+ (match_dup 4)))]
-+ "{
-+ HOST_WIDE_INT i = INTVAL (operands[1]);
-+ operands[3] = GEN_INT (i & 0xffffff80);
-+ operands[4] = GEN_INT (i & 0x7f);
-+ }")
-+
-+; If we're not dependent on the state of the condition codes we can construct
-+; a 32-bit constant with a movei/movei/shmrg.2 sequence if possible.
-+;
-+(define_peephole2
-+ [(match_scratch:HI 2 "d")
-+ (set (match_operand:SI 0 "ubicom32_data_register_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))
-+ (match_dup 2)]
-+ "(INTVAL (operands[1]) & 0x80000000
-+ && INTVAL (operands[1]) < -0x8000
-+ && peep2_regno_dead_p (0, CC_REGNO))"
-+ [(set (match_dup 0)
-+ (match_dup 3))
-+ (set (match_dup 2)
-+ (match_dup 4))
-+ (parallel
-+ [(set (match_dup 0)
-+ (ior:SI
-+ (ashift:SI (match_dup 0)
-+ (const_int 16))
-+ (zero_extend:SI
-+ (match_dup 2))))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "{
-+ operands[3] = gen_highpart_mode (HImode, SImode, operands[1]);
-+ operands[4] = gen_lowpart (HImode, operands[1]);
-+ }")
-+
-+; Exactly the same as the peephole2 preceding except that this targets a
-+; general register instead of D register. Hopefully the later optimization
-+; passes will notice that the value ended up in a D register first here
-+; and eliminate away the other register!
-+;
-+(define_peephole2
-+ [(match_scratch:SI 2 "d")
-+ (match_scratch:HI 3 "d")
-+ (set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))
-+ (match_dup 3)]
-+ "(INTVAL (operands[1]) & 0x80000000
-+ && INTVAL (operands[1]) < -0x8000
-+ && peep2_regno_dead_p (0, CC_REGNO))"
-+ [(set (match_dup 2)
-+ (match_dup 4))
-+ (set (match_dup 3)
-+ (match_dup 5))
-+ (parallel
-+ [(set (match_dup 2)
-+ (ior:SI
-+ (ashift:SI (match_dup 2)
-+ (const_int 16))
-+ (zero_extend:SI
-+ (match_dup 3))))
-+ (clobber (reg:CC CC_REGNO))])
-+ (set (match_dup 0)
-+ (match_dup 2))]
-+ "{
-+ operands[4] = gen_highpart_mode (HImode, SImode, operands[1]);
-+ operands[5] = gen_lowpart (HImode, operands[1]);
-+ }")
-+
-+(define_insn "movsi_fdpic_got_offset"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (match_operand:SI 1 "ubicom32_fdpic_got_offset_operand" "Y"))]
-+ ""
-+ "movei\\t%0, %1")
-+
-+; The explicit MEM inside the UNSPEC prevents the compiler from moving
-+; the load before a branch after a NULL test, or before a store that
-+; initializes a function descriptor.
-+
-+(define_insn_and_split "load_fdpic_funcdesc"
-+ [(set (match_operand:SI 0 "ubicom32_address_register_operand" "=a")
-+ (unspec_volatile:SI [(mem:SI (match_operand:SI 1 "address_operand" "p"))]
-+ UNSPEC_VOLATILE_LOAD_FDPIC_FUNCDESC))]
-+ ""
-+ "#"
-+ "reload_completed"
-+ [(set (match_dup 0)
-+ (mem:SI (match_dup 1)))])
-+
-+; Combiner-generated 32-bit move with the zero flag set accordingly.
-+;
-+(define_insn "movsi_ccwzn"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:SI 0 "nonimmediate_operand" "rm, d")
-+ (const_int 0)))
-+ (set (match_operand:SI 1 "nonimmediate_operand" "=d,rm")
-+ (match_dup 0))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "@
-+ lsl.4\\t%1, %0, #0
-+ add.4\\t%1, #0, %0")
-+
-+; Combiner-generated 32-bit move with all flags set accordingly.
-+;
-+(define_insn "movsi_ccw"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:SI 0 "ubicom32_data_register_operand" "d")
-+ (const_int 0)))
-+ (set (match_operand:SI 1 "nonimmediate_operand" "=rm")
-+ (match_dup 0))]
-+ "ubicom32_match_cc_mode(insn, CCWmode)"
-+ "add.4\\t%1, #0, %0")
-+
-+; Combine isn't very good at merging some types of operations so we
-+; have to make do with a peephole. It's not as effective but it's better
-+; than doing nothing.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "")
-+ (match_operand:SI 1 "nonimmediate_operand" ""))
-+ (parallel
-+ [(set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (match_operator 3 "ubicom32_compare_operator"
-+ [(match_dup 0)
-+ (const_int 0)]))
-+ (clobber (match_operand:SI 4 "ubicom32_data_register_operand" ""))])]
-+ "(GET_MODE (operands[2]) == CCWZNmode
-+ || GET_MODE (operands[2]) == CCWZmode)"
-+ [(parallel
-+ [(set (match_dup 2)
-+ (match_op_dup 3
-+ [(match_dup 1)
-+ (const_int 0)]))
-+ (set (match_dup 0)
-+ (match_dup 1))])]
-+ "")
-+
-+; Combine isn't very good at merging some types of operations so we
-+; have to make do with a peephole. It's not as effective but it's better
-+; than doing nothing.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
-+ (match_operand:SI 1 "ubicom32_data_register_operand" ""))
-+ (parallel
-+ [(set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (match_operator 3 "ubicom32_compare_operator"
-+ [(match_dup 1)
-+ (const_int 0)]))
-+ (clobber (match_operand:SI 4 "ubicom32_data_register_operand" ""))])]
-+ "(GET_MODE (operands[2]) == CCWZNmode
-+ || GET_MODE (operands[2]) == CCWZmode)"
-+ [(parallel
-+ [(set (match_dup 2)
-+ (match_op_dup 3
-+ [(match_dup 1)
-+ (const_int 0)]))
-+ (set (match_dup 0)
-+ (match_dup 1))])]
-+ "")
-+
-+; Combine isn't very good at merging some types of operations so we
-+; have to make do with a peephole. It's not as effective but it's better
-+; than doing nothing.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "nonimmediate_operand" ""))
-+ (parallel
-+ [(set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (match_operator 3 "ubicom32_compare_operator"
-+ [(match_dup 0)
-+ (const_int 0)]))
-+ (set (match_operand:SI 4 "ubicom32_data_register_operand" "")
-+ (match_dup 0))])]
-+ "(peep2_reg_dead_p (2, operands[0])
-+ && (GET_MODE (operands[2]) == CCWZNmode
-+ || GET_MODE (operands[2]) == CCWZmode))"
-+ [(parallel
-+ [(set (match_dup 2)
-+ (match_op_dup 3
-+ [(match_dup 1)
-+ (const_int 0)]))
-+ (set (match_dup 4)
-+ (match_dup 1))])]
-+ "")
-+
-+; Register renaming may make a general reg into a D reg in which case
-+; we may be able to simplify a compare.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "nonimmediate_operand" ""))
-+ (parallel
-+ [(set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (match_operator 3 "ubicom32_compare_operator"
-+ [(match_dup 0)
-+ (const_int 0)]))
-+ (clobber (match_operand:SI 4 "ubicom32_data_register_operand" ""))])]
-+ "(peep2_reg_dead_p (2, operands[0])
-+ && (GET_MODE (operands[2]) == CCWZNmode
-+ || GET_MODE (operands[2]) == CCWZmode))"
-+ [(parallel
-+ [(set (match_dup 2)
-+ (match_op_dup 3
-+ [(match_dup 1)
-+ (const_int 0)]))
-+ (clobber (match_dup 4))])]
-+ "")
-+
-+(define_insn_and_split "movdi"
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
-+ (match_operand:DI 1 "general_operand" "rmi,ri"))]
-+ ""
-+ "#"
-+ "reload_completed"
-+ [(set (match_dup 2) (match_dup 3))
-+ (set (match_dup 4) (match_dup 5))]
-+ "{
-+ rtx dest_low;
-+ rtx src_low;
-+
-+ dest_low = gen_lowpart (SImode, operands[0]);
-+ src_low = gen_lowpart (SImode, operands[1]);
-+
-+ if (REG_P (operands[0])
-+ && REG_P (operands[1])
-+ && REGNO (operands[0]) < REGNO (operands[1]))
-+ {
-+ operands[2] = gen_highpart (SImode, operands[0]);
-+ operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
-+ operands[4] = dest_low;
-+ operands[5] = src_low;
-+ }
-+ else if (reg_mentioned_p (dest_low, src_low))
-+ {
-+ operands[2] = gen_highpart (SImode, operands[0]);
-+ operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
-+ operands[4] = dest_low;
-+ operands[5] = src_low;
-+ }
-+ else
-+ {
-+ operands[2] = dest_low;
-+ operands[3] = src_low;
-+ operands[4] = gen_highpart (SImode, operands[0]);
-+ operands[5] = gen_highpart_mode (SImode, DImode, operands[1]);
-+ }
-+ }"
-+ [(set_attr "length" "8")])
-+
-+; Combiner-generated 64-bit move with all flags set accordingly.
-+;
-+(define_insn "movdi_ccwzn"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:DI 0 "nonimmediate_operand" "d, m, r")
-+ (const_int 0)))
-+ (set (match_operand:DI 1 "nonimmediate_operand" "=&rm,rm,!&rm")
-+ (match_dup 0))
-+ (clobber (match_scratch:SI 2 "=X, d, d"))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "*
-+ {
-+ operands[3] = gen_lowpart (SImode, operands[0]);
-+ operands[4] = gen_lowpart (SImode, operands[1]);
-+ operands[5] = gen_highpart (SImode, operands[0]);
-+ operands[6] = gen_highpart (SImode, operands[1]);
-+
-+ if (ubicom32_data_register_operand (operands[0], VOIDmode))
-+ return \"add.4\\t%4, #0, %3\;addc\\t%6, #0, %5\";
-+
-+ return \"movei\\t%2, #0\;add.4\\t%4, %3, %2\;addc\\t%6, %5, %2\";
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_insn "movdi_ccw"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:DI 0 "nonimmediate_operand" "d, m, r")
-+ (const_int 0)))
-+ (set (match_operand:DI 1 "nonimmediate_operand" "=&rm,rm,!&rm")
-+ (match_dup 0))
-+ (clobber (match_scratch:SI 2 "=X, d, d"))]
-+ "ubicom32_match_cc_mode(insn, CCWmode)"
-+ "*
-+ {
-+ operands[3] = gen_lowpart (SImode, operands[0]);
-+ operands[4] = gen_lowpart (SImode, operands[1]);
-+ operands[5] = gen_highpart (SImode, operands[0]);
-+ operands[6] = gen_highpart (SImode, operands[1]);
-+
-+ if (ubicom32_data_register_operand (operands[0], VOIDmode))
-+ return \"add.4\\t%4, #0, %3\;addc\\t%6, #0, %5\";
-+
-+ return \"movei\\t%2, #0\;add.4\\t%4, %3, %2\;addc\\t%6, %5, %2\";
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_insn "movsf"
-+ [(set (match_operand:SF 0 "nonimmediate_operand" "=!d,*rm")
-+ (match_operand:SF 1 "ubicom32_move_operand" "rmF,rmF"))]
-+ ""
-+ "*
-+ {
-+ if (GET_CODE (operands[1]) == CONST_DOUBLE)
-+ {
-+ HOST_WIDE_INT val;
-+ REAL_VALUE_TYPE rv;
-+
-+ REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
-+ REAL_VALUE_TO_TARGET_SINGLE (rv, val);
-+
-+ ubicom32_emit_move_const_int (operands[0], GEN_INT (val));
-+ return \"\";
-+ }
-+
-+ return \"move.4\\t%0, %1\";
-+ }")
-+
-+(define_insn "zero_extendqihi2"
-+ [(set (match_operand:HI 0 "register_operand" "=r")
-+ (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
-+ ""
-+ "move.1\\t%0, %1")
-+
-+(define_insn "zero_extendqisi2"
-+ [(set (match_operand:SI 0 "register_operand" "=r")
-+ (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
-+ ""
-+ "move.1\\t%0, %1")
-+
-+(define_insn "zero_extendqisi2_ccwz_1"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "rm"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (zero_extend:SI (match_dup 1)))]
-+ "ubicom32_match_cc_mode(insn, CCWZmode)"
-+ "shmrg.1\\t%0, %1, #0")
-+
-+(define_insn "zero_extendhisi2"
-+ [(set (match_operand:SI 0 "register_operand" "=r")
-+ (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
-+ ""
-+ "move.2\\t%0, %1")
-+
-+(define_insn "zero_extendhisi2_ccwz_1"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (zero_extend:SI (match_dup 1)))]
-+ "ubicom32_match_cc_mode(insn, CCWZmode)"
-+ "shmrg.2\\t%0, %1, #0")
-+
-+(define_insn_and_split "zero_extendqidi2"
-+ [(set (match_operand:DI 0 "register_operand" "=r")
-+ (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
-+ ""
-+ "#"
-+ "reload_completed"
-+ [(set (match_dup 2)
-+ (zero_extend:SI (match_dup 1)))
-+ (set (match_dup 3)
-+ (const_int 0))]
-+ "{
-+ operands[2] = gen_lowpart (SImode, operands[0]);
-+ operands[3] = gen_highpart (SImode, operands[0]);
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_insn_and_split "zero_extendhidi2"
-+ [(set (match_operand:DI 0 "register_operand" "=r")
-+ (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
-+ ""
-+ "#"
-+ "reload_completed"
-+ [(set (match_dup 2)
-+ (zero_extend:SI (match_dup 1)))
-+ (set (match_dup 3)
-+ (const_int 0))]
-+ "{
-+ operands[2] = gen_lowpart (SImode, operands[0]);
-+ operands[3] = gen_highpart (SImode, operands[0]);
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_insn_and_split "zero_extendsidi2"
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
-+ (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
-+ ""
-+ "#"
-+ "reload_completed"
-+ [(set (match_dup 2)
-+ (match_dup 1))
-+ (set (match_dup 3)
-+ (const_int 0))]
-+ "{
-+ operands[2] = gen_lowpart (SImode, operands[0]);
-+ operands[3] = gen_highpart (SImode, operands[0]);
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_insn "extendqihi2"
-+ [(set (match_operand:HI 0 "register_operand" "=r")
-+ (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "rm")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "ext.1\\t%0, %1")
-+
-+(define_insn "extendqisi2"
-+ [(set (match_operand:SI 0 "register_operand" "=r")
-+ (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "rm")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "ext.1\\t%0, %1")
-+
-+(define_insn "extendhisi2"
-+ [(set (match_operand:SI 0 "register_operand" "=r")
-+ (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "ext.2\\t%0, %1")
-+
-+(define_insn_and_split "extendsidi2"
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "=d")
-+ (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "#"
-+ "reload_completed"
-+ [(set (match_dup 2)
-+ (match_dup 1))
-+ (parallel
-+ [(set (match_dup 3)
-+ (ashiftrt:SI (match_dup 2)
-+ (const_int 31)))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "{
-+ operands[2] = gen_lowpart (SImode, operands[0]);
-+ operands[3] = gen_highpart (SImode, operands[0]);
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_insn "bswaphi"
-+ [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
-+ (bswap:HI (match_operand:HI 1 "ubicom32_arith_operand" "rmI")))]
-+ "(ubicom32_v4)"
-+ "swapb.2\\t%0, %1");
-+
-+(define_insn "bswaphisi"
-+ [(set (match_operand:SI 0 "register_operand" "=r")
-+ (zero_extend:SI
-+ (bswap:HI (match_operand:HI 1 "ubicom32_arith_operand" "rmI"))))]
-+ "(ubicom32_v4)"
-+ "swapb.2\\t%0, %1");
-+
-+(define_insn "bswapsi"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (bswap:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")))]
-+ "(ubicom32_v4)"
-+ "swapb.4\\t%0, %1");
-+
-+(define_insn "tstqi_ext1"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:QI 0 "nonimmediate_operand" "rm")
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "ext.1\\t#0, %0")
-+
-+(define_expand "cmpqi"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:QI 0 "ubicom32_arith_operand" "")
-+ (match_operand:QI 1 "ubicom32_data_register_operand" "")))]
-+ "(ubicom32_v4)"
-+ "{
-+ ubicom32_compare_op0 = operands[0];
-+ ubicom32_compare_op1 = operands[1];
-+ DONE;
-+ }")
-+
-+(define_insn "sub1_ccs"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:QI 0 "ubicom32_arith_operand" "rmI")
-+ (match_operand:QI 1 "ubicom32_data_register_operand" "d")))]
-+ "(ubicom32_v4)"
-+ "sub.1\\t#0, %0, %1")
-+
-+; If we're testing for equality we don't have to worry about reversing conditions.
-+;
-+(define_insn "sub1_ccsz_1"
-+ [(set (reg:CCSZ CC_REGNO)
-+ (compare:CCSZ (match_operand:QI 0 "nonimmediate_operand" "rm")
-+ (match_operand:QI 1 "ubicom32_data_register_operand" "d")))]
-+ "(ubicom32_v4)"
-+ "sub.1\\t#0, %0, %1")
-+
-+(define_insn "sub1_ccsz_2"
-+ [(set (reg:CCSZ CC_REGNO)
-+ (compare:CCSZ (match_operand:QI 0 "ubicom32_data_register_operand" "d")
-+ (match_operand:QI 1 "ubicom32_arith_operand" "rmI")))]
-+ "(ubicom32_v4)"
-+ "sub.1\\t#0, %1, %0")
-+
-+; When the combiner runs it doesn't have any insight into whether or not an argument
-+; to a compare is spilled to the stack and therefore can't swap the comparison in
-+; an attempt to use sub.1 more effectively. We peephole this case here.
-+;
-+(define_peephole2
-+ [(set (match_operand:QI 0 "register_operand" "")
-+ (match_operand:QI 1 "ubicom32_arith_operand" ""))
-+ (set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (compare (match_operand:QI 3 "ubicom32_data_register_operand" "")
-+ (match_dup 0)))
-+ (set (pc)
-+ (if_then_else (match_operator 4 "comparison_operator"
-+ [(match_dup 2)
-+ (const_int 0)])
-+ (label_ref (match_operand 5 "" ""))
-+ (pc)))]
-+ "(peep2_reg_dead_p (2, operands[0])
-+ && peep2_regno_dead_p (3, CC_REGNO))"
-+ [(set (match_dup 2)
-+ (compare (match_dup 1)
-+ (match_dup 3)))
-+ (set (pc)
-+ (if_then_else (match_op_dup 6
-+ [(match_dup 2)
-+ (const_int 0)])
-+ (label_ref (match_dup 5))
-+ (pc)))]
-+ "{
-+ rtx cc_reg;
-+
-+ cc_reg = gen_rtx_REG (GET_MODE (operands[2]), CC_REGNO);
-+ operands[6] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[4])),
-+ GET_MODE (operands[4]),
-+ cc_reg,
-+ const0_rtx);
-+ }")
-+
-+(define_insn "tsthi_ext2"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:HI 0 "nonimmediate_operand" "rm")
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "ext.2\\t#0, %0")
-+
-+(define_expand "cmphi"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:HI 0 "ubicom32_arith_operand" "")
-+ (match_operand:HI 1 "ubicom32_compare_operand" "")))]
-+ ""
-+ "{
-+ do
-+ {
-+ /* Is this a cmpi? */
-+ if (CONST_INT_P (operands[1]))
-+ break;
-+
-+ /* Must be a sub.2 - if necessary copy an operand into a reg. */
-+ if (! ubicom32_data_register_operand (operands[1], HImode))
-+ operands[1] = copy_to_mode_reg (HImode, operands[1]);
-+ }
-+ while (0);
-+
-+ ubicom32_compare_op0 = operands[0];
-+ ubicom32_compare_op1 = operands[1];
-+ DONE;
-+ }")
-+
-+(define_insn "cmpi"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:HI 0 "nonimmediate_operand" "rm")
-+ (match_operand 1 "const_int_operand" "N")))]
-+ ""
-+ "cmpi\\t%0, %1")
-+
-+(define_insn "sub2_ccs"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:HI 0 "ubicom32_arith_operand" "rmI")
-+ (match_operand:HI 1 "ubicom32_data_register_operand" "d")))]
-+ ""
-+ "sub.2\\t#0, %0, %1")
-+
-+; If we're testing for equality we don't have to worry about reversing conditions.
-+;
-+(define_insn "sub2_ccsz_1"
-+ [(set (reg:CCSZ CC_REGNO)
-+ (compare:CCSZ (match_operand:HI 0 "nonimmediate_operand" "rm")
-+ (match_operand:HI 1 "ubicom32_data_register_operand" "d")))]
-+ ""
-+ "sub.2\\t#0, %0, %1")
-+
-+(define_insn "sub2_ccsz_2"
-+ [(set (reg:CCSZ CC_REGNO)
-+ (compare:CCSZ (match_operand:HI 0 "ubicom32_data_register_operand" "d")
-+ (match_operand:HI 1 "ubicom32_arith_operand" "rmI")))]
-+ ""
-+ "sub.2\\t#0, %1, %0")
-+
-+; When the combiner runs it doesn't have any insight into whether or not an argument
-+; to a compare is spilled to the stack and therefore can't swap the comparison in
-+; an attempt to use sub.2 more effectively. We peephole this case here.
-+;
-+(define_peephole2
-+ [(set (match_operand:HI 0 "register_operand" "")
-+ (match_operand:HI 1 "ubicom32_arith_operand" ""))
-+ (set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (compare (match_operand:HI 3 "ubicom32_data_register_operand" "")
-+ (match_dup 0)))
-+ (set (pc)
-+ (if_then_else (match_operator 4 "comparison_operator"
-+ [(match_dup 2)
-+ (const_int 0)])
-+ (label_ref (match_operand 5 "" ""))
-+ (pc)))]
-+ "(peep2_reg_dead_p (2, operands[0])
-+ && peep2_regno_dead_p (3, CC_REGNO))"
-+ [(set (match_dup 2)
-+ (compare (match_dup 1)
-+ (match_dup 3)))
-+ (set (pc)
-+ (if_then_else (match_op_dup 6
-+ [(match_dup 2)
-+ (const_int 0)])
-+ (label_ref (match_dup 5))
-+ (pc)))]
-+ "{
-+ rtx cc_reg;
-+
-+ cc_reg = gen_rtx_REG (GET_MODE (operands[2]), CC_REGNO);
-+ operands[6] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[4])),
-+ GET_MODE (operands[4]),
-+ cc_reg,
-+ const0_rtx);
-+ }")
-+
-+(define_insn_and_split "tstsi_lsl4"
-+ [(set (match_operand 0 "ubicom32_cc_register_operand" "=r")
-+ (match_operator 1 "ubicom32_compare_operator"
-+ [(match_operand:SI 2 "nonimmediate_operand" "rm")
-+ (const_int 0)]))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "#"
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ [(parallel
-+ [(set (match_dup 0)
-+ (match_op_dup 1
-+ [(match_dup 2)
-+ (const_int 0)]))
-+ (clobber (match_dup 3))])]
-+ "{
-+ operands[3] = gen_reg_rtx (SImode);
-+ }")
-+
-+(define_insn "tstsi_lsl4_d"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:SI 0 "nonimmediate_operand" "rm")
-+ (const_int 0)))
-+ (clobber (match_operand:SI 1 "ubicom32_data_register_operand" "=d"))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "lsl.4\\t%1, %0, #0")
-+
-+; Comparison for equality with -1.
-+;
-+(define_insn "cmpsi_not4_ccwz"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:SI 0 "nonimmediate_operand" "rm")
-+ (const_int -1)))]
-+ "ubicom32_match_cc_mode(insn, CCWZmode)"
-+ "not.4\\t#0, %0")
-+
-+(define_expand "cmpsi"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:SI 0 "ubicom32_arith_operand" "")
-+ (match_operand:SI 1 "ubicom32_compare_operand" "")))]
-+ ""
-+ "{
-+ do
-+ {
-+ /* Is this a cmpi? We can't take a memory address as cmpi takes
-+ 16-bit operands. */
-+ if (register_operand (operands[0], SImode)
-+ && CONST_INT_P (operands[1])
-+ && satisfies_constraint_N (operands[1]))
-+ break;
-+
-+ /* Must be a sub.4 - if necessary copy an operand into a reg. */
-+ if (! ubicom32_data_register_operand (operands[1], SImode))
-+ operands[1] = copy_to_mode_reg (SImode, operands[1]);
-+ }
-+ while (0);
-+
-+ ubicom32_compare_op0 = operands[0];
-+ ubicom32_compare_op1 = operands[1];
-+ DONE;
-+ }")
-+
-+(define_insn "cmpsi_cmpi"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:SI 0 "register_operand" "r")
-+ (match_operand 1 "const_int_operand" "N")))]
-+ "(satisfies_constraint_N (operands[1]))"
-+ "cmpi\\t%0, %1")
-+
-+(define_insn "cmpsi_sub4"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:SI 0 "ubicom32_arith_operand" "rmI")
-+ (match_operand:SI 1 "ubicom32_data_register_operand" "d")))]
-+ ""
-+ "sub.4\\t#0, %0, %1")
-+
-+; If we're testing for equality we don't have to worry about reversing conditions.
-+;
-+(define_insn "cmpsi_sub4_ccwz_1"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:SI 0 "nonimmediate_operand" "rm")
-+ (match_operand:SI 1 "ubicom32_data_register_operand" "d")))]
-+ "ubicom32_match_cc_mode(insn, CCWZmode)"
-+ "sub.4\\t#0, %0, %1")
-+
-+(define_insn "cmpsi_sub4_ccwz_2"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:SI 0 "ubicom32_data_register_operand" "d")
-+ (match_operand:SI 1 "nonimmediate_operand" "rm")))]
-+ "ubicom32_match_cc_mode(insn, CCWZmode)"
-+ "sub.4\\t#0, %1, %0")
-+
-+; When the combiner runs it doesn't have any insight into whether or not an argument
-+; to a compare is spilled to the stack and therefore can't swap the comparison in
-+; an attempt to use sub.4 more effectively. We peephole this case here.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "ubicom32_arith_operand" ""))
-+ (set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (compare (match_operand:SI 3 "ubicom32_data_register_operand" "")
-+ (match_dup 0)))
-+ (set (pc)
-+ (if_then_else (match_operator 4 "comparison_operator"
-+ [(match_dup 2)
-+ (const_int 0)])
-+ (label_ref (match_operand 5 "" ""))
-+ (pc)))]
-+ "(peep2_reg_dead_p (2, operands[0])
-+ && peep2_regno_dead_p (3, CC_REGNO))"
-+ [(set (match_dup 2)
-+ (compare (match_dup 1)
-+ (match_dup 3)))
-+ (set (pc)
-+ (if_then_else (match_op_dup 6
-+ [(match_dup 2)
-+ (const_int 0)])
-+ (label_ref (match_dup 5))
-+ (pc)))]
-+ "{
-+ rtx cc_reg;
-+
-+ cc_reg = gen_rtx_REG (GET_MODE (operands[2]), CC_REGNO);
-+ operands[6] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[4])),
-+ GET_MODE (operands[4]),
-+ cc_reg,
-+ const0_rtx);
-+ }")
-+
-+(define_insn_and_split "tstdi_or4"
-+ [(set (reg:CCWZ CC_REGNO)
-+ (compare:CCWZ (match_operand:DI 0 "nonimmediate_operand" "rm")
-+ (const_int 0)))]
-+ ""
-+ "#"
-+ ""
-+ [(parallel
-+ [(set (reg:CCWZ CC_REGNO)
-+ (compare:CCWZ (match_dup 0)
-+ (const_int 0)))
-+ (clobber (match_dup 1))])]
-+ "{
-+ operands[1] = gen_reg_rtx (SImode);
-+ }")
-+
-+(define_insn "tstdi_or4_d"
-+ [(set (reg:CCWZ CC_REGNO)
-+ (compare:CCWZ (match_operand:DI 0 "nonimmediate_operand" "rm")
-+ (const_int 0)))
-+ (clobber (match_operand:SI 1 "ubicom32_data_register_operand" "=d"))]
-+ ""
-+ "*
-+ {
-+ operands[2] = gen_lowpart (SImode, operands[0]);
-+ operands[3] = gen_highpart_mode (SImode, DImode, operands[0]);
-+
-+ if (ubicom32_data_register_operand (operands[0], GET_MODE (operands[0])))
-+ return \"or.4\\t#0, %2, %3\";
-+
-+ return \"move.4\\t%1, %2\;or.4\\t%1, %3, %1\";
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_expand "cmpdi"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:DI 0 "ubicom32_arith_operand" "")
-+ (match_operand:DI 1 "ubicom32_data_register_operand" "")))]
-+ ""
-+ "{
-+ ubicom32_compare_op0 = operands[0];
-+ ubicom32_compare_op1 = operands[1];
-+ DONE;
-+ }")
-+
-+(define_insn "cmpdi_sub4subc"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:DI 0 "ubicom32_arith_operand" "rmI")
-+ (match_operand:DI 1 "ubicom32_data_register_operand" "d")))]
-+ ""
-+ "*
-+ {
-+ operands[2] = gen_lowpart (SImode, operands[0]);
-+ operands[3] = gen_lowpart (SImode, operands[1]);
-+ operands[4] = gen_highpart_mode (SImode, DImode, operands[0]);
-+ operands[5] = gen_highpart_mode (SImode, DImode, operands[1]);
-+
-+ return \"sub.4\\t#0, %2, %3\;subc\\t#0, %4, %5\";
-+ }"
-+ [(set_attr "length" "8")])
-+
-+; When the combiner runs it doesn't have any insight into whether or not an argument
-+; to a compare is spilled to the stack and therefore can't swap the comparison in
-+; an attempt to use sub.4/subc more effectively. We peephole this case here.
-+;
-+(define_peephole2
-+ [(set (match_operand:DI 0 "register_operand" "")
-+ (match_operand:DI 1 "ubicom32_arith_operand" ""))
-+ (set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (compare (match_operand:DI 3 "ubicom32_data_register_operand" "")
-+ (match_dup 0)))
-+ (set (pc)
-+ (if_then_else (match_operator 4 "comparison_operator"
-+ [(match_dup 2)
-+ (const_int 0)])
-+ (label_ref (match_operand 5 "" ""))
-+ (pc)))]
-+ "(peep2_reg_dead_p (2, operands[0])
-+ && peep2_regno_dead_p (3, CC_REGNO))"
-+ [(set (match_dup 2)
-+ (compare (match_dup 1)
-+ (match_dup 3)))
-+ (set (pc)
-+ (if_then_else (match_op_dup 6
-+ [(match_dup 2)
-+ (const_int 0)])
-+ (label_ref (match_dup 5))
-+ (pc)))]
-+ "{
-+ rtx cc_reg;
-+
-+ cc_reg = gen_rtx_REG (GET_MODE (operands[2]), CC_REGNO);
-+ operands[6] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[4])),
-+ GET_MODE (operands[4]),
-+ cc_reg,
-+ const0_rtx);
-+ }")
-+
-+(define_insn "btst"
-+ [(set (reg:CCWZ CC_REGNO)
-+ (compare:CCWZ
-+ (zero_extract:SI
-+ (match_operand:SI 0 "nonimmediate_operand" "rm")
-+ (const_int 1)
-+ (match_operand:SI 1 "ubicom32_arith_operand" "dM"))
-+ (const_int 0)))]
-+ ""
-+ "btst\\t%0, %1")
-+
-+(define_insn "bfextu_ccwz_null"
-+ [(set (reg:CCWZ CC_REGNO)
-+ (compare:CCWZ
-+ (zero_extract:SI
-+ (match_operand:SI 0 "nonimmediate_operand" "rm")
-+ (match_operand 1 "const_int_operand" "M")
-+ (const_int 0))
-+ (const_int 0)))
-+ (clobber (match_scratch:SI 2 "=d"))]
-+ ""
-+ "bfextu\\t%2, %0, %1")
-+
-+(define_expand "addqi3"
-+ [(parallel
-+ [(set (match_operand:QI 0 "memory_operand" "")
-+ (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
-+ (match_operand:QI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "(ubicom32_v4)"
-+ "{
-+ if (!memory_operand (operands[0], QImode))
-+ FAIL;
-+
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (QImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (QImode, operands[2]);
-+ }")
-+
-+(define_insn "addqi3_add1"
-+ [(set (match_operand:QI 0 "memory_operand" "=m, m")
-+ (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:QI 2 "ubicom32_arith_operand" "rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4)"
-+ "@
-+ add.1\\t%0, %2, %1
-+ add.1\\t%0, %1, %2")
-+
-+(define_insn "addqi3_add1_ccszn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (neg:QI (match_operand:QI 0 "nonimmediate_operand" "%d,rm"))
-+ (match_operand:QI 1 "ubicom32_arith_operand" "rmI, d")))]
-+ "(ubicom32_v4
-+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
-+ "@
-+ add.1\\t#0, %1, %0
-+ add.1\\t#0, %0, %1")
-+
-+(define_expand "addhi3"
-+ [(parallel
-+ [(set (match_operand:HI 0 "memory_operand" "")
-+ (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
-+ (match_operand:HI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ ""
-+ "{
-+ if (!memory_operand (operands[0], HImode))
-+ FAIL;
-+
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (HImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (HImode, operands[2]);
-+ }")
-+
-+(define_insn "addhi3_add2"
-+ [(set (match_operand:HI 0 "memory_operand" "=m, m")
-+ (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:HI 2 "ubicom32_arith_operand" "rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "@
-+ add.2\\t%0, %2, %1
-+ add.2\\t%0, %1, %2")
-+
-+(define_insn "addhi3_add2_ccszn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (neg:HI (match_operand:HI 0 "nonimmediate_operand" "%d,rm"))
-+ (match_operand:HI 1 "ubicom32_arith_operand" "rmI, d")))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "@
-+ add.2\\t#0, %1, %0
-+ add.2\\t#0, %0, %1")
-+
-+(define_expand "addsi3"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
-+ (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
-+ (match_operand:SI 2 "ubicom32_move_operand" "")))]
-+ ""
-+ "{
-+ ubicom32_expand_addsi3 (operands);
-+ DONE;
-+ }")
-+
-+; We start with an instruction pattern that can do all sorts of interesting
-+; things but we split out any uses of lea or pdec instructions because
-+; those instructions don't clobber the condition codes.
-+;
-+(define_insn_and_split "addsi3_1"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm,rm,rm,rm, rm,rm")
-+ (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%a, a, a, a, a, d,rm")
-+ (match_operand:SI 2 "ubicom32_move_operand" "L, K, J, P, d,rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "@
-+ #
-+ #
-+ #
-+ #
-+ #
-+ add.4\\t%0, %2, %1
-+ add.4\\t%0, %1, %2"
-+ "(reload_completed
-+ && ubicom32_address_register_operand (operands[1], GET_MODE (operands[1])))"
-+ [(set (match_dup 0)
-+ (plus:SI (match_dup 1)
-+ (match_dup 2)))]
-+ ""
-+)
-+
-+(define_insn "addsi3_1_ccwzn"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
-+ (plus:SI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "@
-+ add.4\\t%0, %2, %1
-+ add.4\\t%0, %1, %2")
-+
-+(define_insn "addsi3_1_ccwzn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (neg:SI (match_operand:SI 0 "nonimmediate_operand" "%d,rm"))
-+ (match_operand:SI 1 "ubicom32_arith_operand" "rmI, d")))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "@
-+ add.4\\t#0, %1, %0
-+ add.4\\t#0, %0, %1")
-+
-+(define_insn_and_split "addsi3_2"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm,rm,rm,rm,rm")
-+ (plus:SI (match_operand:SI 1 "ubicom32_address_register_operand" "%a, a, a, a, a, a")
-+ (match_operand:SI 2 "ubicom32_move_operand" "L, K, J, P, d, n")))]
-+ ""
-+ "@
-+ lea.4\\t%0, %E2(%1)
-+ lea.2\\t%0, %E2(%1)
-+ lea.1\\t%0, %E2(%1)
-+ pdec\\t%0, %n2(%1)
-+ lea.1\\t%0, (%1,%2)
-+ #"
-+ "(reload_completed
-+ && ! satisfies_constraint_L (operands[2])
-+ && ! satisfies_constraint_K (operands[2])
-+ && ! satisfies_constraint_J (operands[2])
-+ && ! satisfies_constraint_P (operands[2])
-+ && ! ubicom32_data_register_operand (operands[2], GET_MODE (operands[2])))"
-+ [(set (reg:SI AUX_DATA_REGNO)
-+ (match_dup 2))
-+ (set (match_dup 0)
-+ (plus:SI (match_dup 1)
-+ (reg:SI AUX_DATA_REGNO)))]
-+ ""
-+)
-+
-+(define_insn "lea_2"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (plus:SI (mult:SI (match_operand:SI 1 "ubicom32_data_register_operand" "d")
-+ (const_int 2))
-+ (match_operand:SI 2 "ubicom32_address_register_operand" "a")))]
-+ ""
-+ "lea.2\\t%0, (%2,%1)")
-+
-+(define_insn "lea_4"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (plus:SI (mult:SI (match_operand:SI 1 "ubicom32_data_register_operand" "d")
-+ (const_int 4))
-+ (match_operand:SI 2 "ubicom32_address_register_operand" "a")))]
-+ ""
-+ "lea.4\\t%0, (%2,%1)")
-+
-+(define_expand "adddi3"
-+ [(parallel
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "")
-+ (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
-+ (match_operand:DI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ ""
-+ "{
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (DImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (DImode, operands[2]);
-+ }")
-+
-+; We construct a 64-bit add from 32-bit operations. Note that we use the
-+; & constraint to prevent overlapping registers being allocated. We do
-+; allow identical registers though as that won't break anything.
-+;
-+(define_insn "adddi3_add4addc"
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,&r,rm, d, m, m")
-+ (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%d,rm, 0, 0, d,rm")
-+ (match_operand:DI 2 "ubicom32_arith_operand" "rmI, d, d,rmI,rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "*
-+ {
-+ operands[3] = gen_lowpart (SImode, operands[0]);
-+ operands[4] = gen_lowpart (SImode, operands[1]);
-+ operands[5] = gen_lowpart (SImode, operands[2]);
-+ operands[6] = gen_highpart (SImode, operands[0]);
-+ operands[7] = gen_highpart (SImode, operands[1]);
-+ operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
-+
-+ if (ubicom32_data_register_operand (operands[2], GET_MODE (operands[2])))
-+ return \"add.4\\t%3, %4, %5\;addc\\t%6, %7, %8\";
-+
-+ return \"add.4\\t%3, %5, %4\;addc\\t%6, %8, %7\";
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_insn "adddi3_ccwz"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%d,rm, 0, 0, d,rm")
-+ (match_operand:DI 2 "ubicom32_arith_operand" "rmI, d, d,rmI,rmI, d"))
-+ (const_int 0)))
-+ (set (match_operand:DI 0 "nonimmediate_operand" "=&r,&r,rm, d, m, m")
-+ (plus:DI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "*
-+ {
-+ operands[3] = gen_lowpart (SImode, operands[0]);
-+ operands[6] = gen_highpart (SImode, operands[0]);
-+
-+ if (ubicom32_data_register_operand (operands[1], GET_MODE (operands[1])))
-+ {
-+ operands[4] = gen_lowpart (SImode, operands[1]);
-+ operands[5] = gen_lowpart (SImode, operands[2]);
-+ operands[7] = gen_highpart (SImode, operands[1]);
-+ operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
-+ }
-+ else
-+ {
-+ operands[4] = gen_lowpart (SImode, operands[2]);
-+ operands[5] = gen_lowpart (SImode, operands[1]);
-+ operands[7] = gen_highpart (SImode, operands[2]);
-+ operands[8] = gen_highpart (SImode, operands[1]);
-+ }
-+
-+ return \"add.4\\t%3, %5, %4\;addc\\t%6, %8, %7\";
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_insn "adddi3_ccwz_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (neg:DI (match_operand:DI 0 "nonimmediate_operand" "%d,rm"))
-+ (match_operand:DI 1 "ubicom32_arith_operand" "rmI, d")))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "*
-+ {
-+ if (ubicom32_data_register_operand (operands[0], GET_MODE (operands[0])))
-+ {
-+ operands[2] = gen_lowpart (SImode, operands[0]);
-+ operands[3] = gen_lowpart (SImode, operands[1]);
-+ operands[4] = gen_highpart (SImode, operands[0]);
-+ operands[5] = gen_highpart_mode (SImode, DImode, operands[1]);
-+ }
-+ else
-+ {
-+ operands[2] = gen_lowpart (SImode, operands[1]);
-+ operands[3] = gen_lowpart (SImode, operands[0]);
-+ operands[4] = gen_highpart (SImode, operands[1]);
-+ operands[5] = gen_highpart (SImode, operands[0]);
-+ }
-+
-+ return \"add.4\\t#0, %3, %2\;addc\\t#0, %5, %4\";
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_expand "subqi3"
-+ [(parallel
-+ [(set (match_operand:QI 0 "memory_operand" "")
-+ (minus:QI (match_operand:QI 1 "ubicom32_arith_operand" "")
-+ (match_operand:QI 2 "ubicom32_data_register_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "(ubicom32_v4)"
-+ "{
-+ if (!memory_operand (operands[0], QImode))
-+ FAIL;
-+ }")
-+
-+(define_insn "subqi3_sub1"
-+ [(set (match_operand:QI 0 "memory_operand" "=m")
-+ (minus:QI (match_operand:QI 1 "ubicom32_arith_operand" "rmI")
-+ (match_operand:QI 2 "ubicom32_data_register_operand" "d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4)"
-+ "sub.1\\t%0, %1, %2")
-+
-+(define_expand "subhi3"
-+ [(parallel
-+ [(set (match_operand:HI 0 "memory_operand" "")
-+ (minus:HI (match_operand:HI 1 "ubicom32_arith_operand" "")
-+ (match_operand:HI 2 "ubicom32_data_register_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "(ubicom32_v4)"
-+ "{
-+ if (!memory_operand (operands[0], HImode))
-+ FAIL;
-+ }")
-+
-+(define_insn "subhi3_sub2"
-+ [(set (match_operand:HI 0 "memory_operand" "=m")
-+ (minus:HI (match_operand:HI 1 "ubicom32_arith_operand" "rmI")
-+ (match_operand:HI 2 "ubicom32_data_register_operand" "d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "sub.2\\t%0, %1, %2")
-+
-+(define_insn "subsi3"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (minus:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")
-+ (match_operand:SI 2 "ubicom32_data_register_operand" "d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "sub.4\\t%0, %1, %2")
-+
-+(define_insn "subsi3_ccwz"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (minus:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")
-+ (match_operand:SI 2 "ubicom32_data_register_operand" "d"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (minus:SI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "sub.4\\t%0, %1, %2")
-+
-+; We construct a 64-bit add from 32-bit operations. Note that we use the
-+; & constraint to prevent overlapping registers being allocated. We do
-+; allow identical registers though as that won't break anything.
-+;
-+(define_insn "subdi3"
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,r, d, m")
-+ (minus:DI (match_operand:DI 1 "ubicom32_arith_operand" "rmI,0,rmI,rmI")
-+ (match_operand:DI 2 "ubicom32_data_register_operand" "d,d, 0, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "*
-+ {
-+ operands[3] = gen_lowpart (SImode, operands[0]);
-+ operands[4] = gen_lowpart (SImode, operands[1]);
-+ operands[5] = gen_lowpart (SImode, operands[2]);
-+ operands[6] = gen_highpart (SImode, operands[0]);
-+ operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
-+ operands[8] = gen_highpart (SImode, operands[2]);
-+
-+ return \"sub.4\\t%3, %4, %5\;subc\\t%6, %7, %8\";
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_insn "subdi3_ccwz"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (minus:DI (match_operand:DI 1 "ubicom32_arith_operand" "rmI,rmI")
-+ (match_operand:DI 2 "ubicom32_data_register_operand" "d, d"))
-+ (const_int 0)))
-+ (set (match_operand:DI 0 "nonimmediate_operand" "=&r, m")
-+ (minus:DI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "*
-+ {
-+ operands[3] = gen_lowpart (SImode, operands[0]);
-+ operands[4] = gen_lowpart (SImode, operands[1]);
-+ operands[5] = gen_lowpart (SImode, operands[2]);
-+ operands[6] = gen_highpart (SImode, operands[0]);
-+ operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
-+ operands[8] = gen_highpart (SImode, operands[2]);
-+
-+ return \"sub.4\\t%3, %4, %5\;subc\\t%6, %7, %8\";
-+ }"
-+ [(set_attr "length" "8")])
-+
-+;(define_insn "negqi2"
-+; [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
-+; (neg:QI (match_operand:QI 1 "ubicom32_data_register_operand" "d")))
-+; (clobber (reg:CC CC_REGNO))]
-+; "(ubicom32_v4)"
-+; "sub.1\\t%0, #0, %1")
-+
-+;(define_insn "neghi2"
-+; [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
-+; (neg:HI (match_operand:HI 1 "ubicom32_data_register_operand" "d")))
-+; (clobber (reg:CC CC_REGNO))]
-+; ""
-+; "sub.2\\t%0, #0, %1")
-+
-+(define_insn "negsi2"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (neg:SI (match_operand:SI 1 "ubicom32_data_register_operand" "d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "sub.4\\t%0, #0, %1")
-+
-+(define_insn_and_split "negdi2"
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "=&rm")
-+ (neg:DI (match_operand:DI 1 "ubicom32_data_register_operand" "d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "#"
-+ "reload_completed"
-+ [(parallel [(set (match_dup 0)
-+ (minus:DI (const_int 0)
-+ (match_dup 1)))
-+ (clobber (reg:CC CC_REGNO))])]
-+ ""
-+ [(set_attr "length" "8")])
-+
-+(define_insn "umulhisi3"
-+ [(set (match_operand:SI 0 "ubicom32_acc_lo_register_operand" "=l, l")
-+ (mult:SI
-+ (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "%d,rm"))
-+ (zero_extend:SI (match_operand:HI 2 "nonimmediate_operand" "rm, d"))))
-+ (clobber (reg:HI ACC0_HI_REGNO))
-+ (clobber (reg:HI ACC1_HI_REGNO))]
-+ ""
-+ "@
-+ mulu\\t%A0, %2, %1
-+ mulu\\t%A0, %1, %2"
-+ [(set_attr "type" "mul,mul")])
-+
-+(define_insn "mulhisi3"
-+ [(set (match_operand:SI 0 "ubicom32_acc_lo_register_operand" "=l, l")
-+ (mult:SI
-+ (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "%d,rm"))
-+ (sign_extend:SI (match_operand:HI 2 "nonimmediate_operand" "rm, d"))))
-+ (clobber (reg:HI ACC0_HI_REGNO))
-+ (clobber (reg:HI ACC1_HI_REGNO))]
-+ ""
-+ "@
-+ muls\\t%A0, %2, %1
-+ muls\\t%A0, %1, %2"
-+ [(set_attr "type" "mul,mul")])
-+
-+(define_expand "mulsi3"
-+ [(set (match_operand:SI 0 "ubicom32_acc_hi_register_operand" "")
-+ (mult:SI (match_operand:SI 1 "ubicom32_arith_operand" "")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "")))]
-+ ""
-+ "{
-+ if (ubicom32_emit_mult_sequence (operands))
-+ DONE;
-+ }")
-+
-+(define_insn "umulsidi3"
-+ [(set (match_operand:DI 0 "ubicom32_acc_hi_register_operand" "=h, h")
-+ (mult:DI
-+ (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%d,rm"))
-+ (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm, d"))))]
-+ "(ubicom32_v4)"
-+ "@
-+ mulu.4\\t%A0, %2, %1
-+ mulu.4\\t%A0, %1, %2"
-+ [(set_attr "type" "mul,mul")])
-+
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "nonimmediate_operand" ""))
-+ (set (match_operand:DI 2 "ubicom32_acc_hi_register_operand" "")
-+ (mult:DI
-+ (zero_extend:DI (match_dup 0))
-+ (zero_extend:DI (match_operand:SI 3 "ubicom32_data_register_operand" ""))))]
-+ "(peep2_reg_dead_p (2, operands[0])
-+ || REGNO (operands[0]) == REGNO (operands[2])
-+ || REGNO (operands[0]) == REGNO (operands[2]) + 1)
-+ && ! rtx_equal_p (operands[0], operands[3])"
-+ [(set (match_dup 2)
-+ (mult:DI
-+ (zero_extend:DI (match_dup 1))
-+ (zero_extend:DI (match_dup 3))))]
-+ "")
-+
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "nonimmediate_operand" ""))
-+ (set (match_operand:DI 2 "ubicom32_acc_hi_register_operand" "")
-+ (mult:DI
-+ (zero_extend:DI (match_operand:SI 3 "ubicom32_data_register_operand" ""))
-+ (zero_extend:DI (match_dup 0))))]
-+ "(peep2_reg_dead_p (2, operands[0])
-+ || REGNO (operands[0]) == REGNO (operands[2])
-+ || REGNO (operands[0]) == REGNO (operands[2]) + 1)
-+ && ! rtx_equal_p (operands[0], operands[3])"
-+ [(set (match_dup 2)
-+ (mult:DI
-+ (zero_extend:DI (match_dup 1))
-+ (zero_extend:DI (match_dup 3))))]
-+ "")
-+
-+(define_insn "umulsidi3_const"
-+ [(set (match_operand:DI 0 "ubicom32_acc_hi_register_operand" "=h")
-+ (mult:DI
-+ (zero_extend:DI (match_operand:SI 1 "ubicom32_data_register_operand" "%d"))
-+ (match_operand 2 "const_int_operand" "I")))]
-+ "(ubicom32_v4 && satisfies_constraint_I (operands[2]))"
-+ "mulu.4\\t%A0, %2, %1"
-+ [(set_attr "type" "mul")])
-+
-+(define_insn "mulsidi3"
-+ [(set (match_operand:DI 0 "ubicom32_acc_hi_register_operand" "=h, h")
-+ (mult:DI
-+ (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%d,rm"))
-+ (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm, d"))))]
-+ "(ubicom32_v4)"
-+ "@
-+ muls.4\\t%A0, %2, %1
-+ muls.4\\t%A0, %1, %2"
-+ [(set_attr "type" "mul,mul")])
-+
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "nonimmediate_operand" ""))
-+ (set (match_operand:DI 2 "ubicom32_acc_hi_register_operand" "")
-+ (mult:DI
-+ (sign_extend:DI (match_dup 0))
-+ (sign_extend:DI (match_operand:SI 3 "ubicom32_data_register_operand" ""))))]
-+ "(peep2_reg_dead_p (2, operands[0])
-+ || REGNO (operands[0]) == REGNO (operands[2])
-+ || REGNO (operands[0]) == REGNO (operands[2]) + 1)
-+ && ! rtx_equal_p (operands[0], operands[3])"
-+ [(set (match_dup 2)
-+ (mult:DI
-+ (sign_extend:DI (match_dup 1))
-+ (sign_extend:DI (match_dup 3))))]
-+ "")
-+
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "nonimmediate_operand" ""))
-+ (set (match_operand:DI 2 "ubicom32_acc_hi_register_operand" "")
-+ (mult:DI
-+ (sign_extend:DI (match_operand:SI 3 "ubicom32_data_register_operand" ""))
-+ (sign_extend:DI (match_dup 0))))]
-+ "(peep2_reg_dead_p (2, operands[0])
-+ || REGNO (operands[0]) == REGNO (operands[2])
-+ || REGNO (operands[0]) == REGNO (operands[2]) + 1)
-+ && ! rtx_equal_p (operands[0], operands[3])"
-+ [(set (match_dup 2)
-+ (mult:DI
-+ (sign_extend:DI (match_dup 1))
-+ (sign_extend:DI (match_dup 3))))]
-+ "")
-+
-+(define_insn "mulsidi3_const"
-+ [(set (match_operand:DI 0 "ubicom32_acc_hi_register_operand" "=h")
-+ (mult:DI
-+ (sign_extend:DI (match_operand:SI 1 "ubicom32_data_register_operand" "%d"))
-+ (match_operand 2 "const_int_operand" "I")))]
-+ "(ubicom32_v4 && satisfies_constraint_I (operands[2]))"
-+ "muls.4\\t%A0, %2, %1"
-+ [(set_attr "type" "mul")])
-+
-+(define_expand "andqi3"
-+ [(parallel
-+ [(set (match_operand:QI 0 "memory_operand" "")
-+ (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
-+ (match_operand:QI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "(ubicom32_v4)"
-+ "{
-+ if (!memory_operand (operands[0], QImode))
-+ FAIL;
-+
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (QImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (QImode, operands[2]);
-+ }")
-+
-+(define_insn "andqi3_and1"
-+ [(set (match_operand:QI 0 "memory_operand" "=m, m")
-+ (and:QI (match_operand:QI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:QI 2 "ubicom32_arith_operand" "rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4)"
-+ "@
-+ and.1\\t%0, %2, %1
-+ and.1\\t%0, %1, %2")
-+
-+(define_insn "andqi3_and1_ccszn"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (and:QI (match_operand:QI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:QI 2 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))
-+ (set (match_operand:QI 0 "memory_operand" "=m, m")
-+ (and:QI (match_dup 1)
-+ (match_dup 2)))]
-+ "(ubicom32_v4
-+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
-+ "@
-+ and.1\\t%0, %2, %1
-+ and.1\\t%0, %1, %2")
-+
-+(define_insn "andqi3_and1_ccszn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (and:QI (match_operand:QI 0 "nonimmediate_operand" "%d,rm")
-+ (match_operand:QI 1 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))]
-+ "(ubicom32_v4
-+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
-+ "@
-+ and.1\\t#0, %1, %0
-+ and.1\\t#0, %0, %1")
-+
-+(define_insn "and1_ccszn_null_1"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:QI
-+ (and:SI (match_operand:SI 0 "ubicom32_data_register_operand" "%d")
-+ (match_operand:SI 1 "ubicom32_arith_operand" "rI"))
-+ 3)
-+ (const_int 0)))]
-+ "(ubicom32_v4
-+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
-+ "and.1\\t#0, %1, %0")
-+
-+(define_insn "and1_ccszn_null_2"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:QI
-+ (and:SI (match_operand:SI 0 "ubicom32_data_register_operand" "d")
-+ (subreg:SI
-+ (match_operand:QI 1 "memory_operand" "m")
-+ 0))
-+ 3)
-+ (const_int 0)))]
-+ "(ubicom32_v4
-+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
-+ "and.1\\t#0, %1, %0")
-+
-+(define_insn "and1_ccszn_null_3"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:QI
-+ (and:SI (subreg:SI
-+ (match_operand:QI 0 "memory_operand" "m")
-+ 0)
-+ (match_operand:SI 1 "ubicom32_data_register_operand" "d"))
-+ 3)
-+ (const_int 0)))]
-+ "(ubicom32_v4
-+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
-+ "and.1\\t#0, %0, %1")
-+
-+(define_expand "andhi3"
-+ [(parallel
-+ [(set (match_operand:HI 0 "memory_operand" "")
-+ (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
-+ (match_operand:HI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ ""
-+ "{
-+ if (!memory_operand (operands[0], HImode))
-+ FAIL;
-+
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (HImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (HImode, operands[2]);
-+ }")
-+
-+(define_insn "andhi3_and2"
-+ [(set (match_operand:HI 0 "memory_operand" "=m, m")
-+ (and:HI (match_operand:HI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:HI 2 "ubicom32_arith_operand" "rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "@
-+ and.2\\t%0, %2, %1
-+ and.2\\t%0, %1, %2")
-+
-+(define_insn "andhi3_and2_ccszn"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (and:HI (match_operand:HI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:HI 2 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))
-+ (set (match_operand:HI 0 "memory_operand" "=m, m")
-+ (and:HI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "@
-+ and.2\\t%0, %2, %1
-+ and.2\\t%0, %1, %2")
-+
-+(define_insn "andhi3_and2_ccszn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (and:HI (match_operand:HI 0 "nonimmediate_operand" "%d,rm")
-+ (match_operand:HI 1 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "@
-+ and.2\\t#0, %1, %0
-+ and.2\\t#0, %0, %1")
-+
-+(define_insn "and2_ccszn_null_1"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:HI
-+ (and:SI (match_operand:SI 0 "ubicom32_data_register_operand" "%d")
-+ (match_operand:SI 1 "ubicom32_arith_operand" "rI"))
-+ 2)
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "and.2\\t#0, %1, %0")
-+
-+(define_insn "and2_ccszn_null_2"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:HI
-+ (and:SI (match_operand:SI 0 "ubicom32_data_register_operand" "d")
-+ (subreg:SI
-+ (match_operand:HI 1 "memory_operand" "m")
-+ 0))
-+ 2)
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "and.2\\t#0, %1, %0")
-+
-+(define_insn "and2_ccszn_null_3"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:HI
-+ (and:SI (subreg:SI
-+ (match_operand:HI 0 "memory_operand" "m")
-+ 0)
-+ (match_operand:SI 1 "ubicom32_data_register_operand" "d"))
-+ 2)
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "and.2\\t#0, %0, %1")
-+
-+(define_expand "andsi3"
-+ [(parallel
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
-+ (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
-+ (match_operand:SI 2 "ubicom32_and_or_si3_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ ""
-+ "{
-+ do
-+ {
-+ /* Is this a bfextu? */
-+ if (ubicom32_data_register_operand (operands[0], SImode)
-+ && CONST_INT_P (operands[2])
-+ && exact_log2 (INTVAL (operands[2]) + 1) != -1)
-+ break;
-+
-+ /* Is this a bclr? */
-+ if (CONST_INT_P (operands[2])
-+ && exact_log2 (~INTVAL (operands[2])) != -1)
-+ break;
-+
-+ /* Must be an and.4 */
-+ if (!ubicom32_data_register_operand (operands[1], SImode))
-+ operands[1] = copy_to_mode_reg (SImode, operands[1]);
-+
-+ if (!ubicom32_arith_operand (operands[2], SImode))
-+ operands[2] = copy_to_mode_reg (SImode, operands[2]);
-+ }
-+ while (0);
-+ }")
-+
-+(define_insn "andsi3_bfextu"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (and:SI (match_operand:SI 1 "nonimmediate_operand" "%rm")
-+ (match_operand:SI 2 "const_int_operand" "O")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(satisfies_constraint_O (operands[2]))"
-+ "*
-+ {
-+ operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2]) + 1));
-+
-+ return \"bfextu\\t%0, %1, %3\";
-+ }")
-+
-+(define_insn "andsi3_bfextu_ccwz"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (and:SI (match_operand:SI 1 "nonimmediate_operand" "%rm")
-+ (match_operand:SI 2 "const_int_operand" "O"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (and:SI (match_dup 1)
-+ (match_dup 2)))]
-+ "(satisfies_constraint_O (operands[2])
-+ && ubicom32_match_cc_mode(insn, CCWZmode))"
-+ "*
-+ {
-+ operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2]) + 1));
-+
-+ return \"bfextu\\t%0, %1, %3\";
-+ }")
-+
-+(define_insn "andsi3_bfextu_ccwz_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (and:SI (match_operand:SI 0 "nonimmediate_operand" "%rm")
-+ (match_operand:SI 1 "const_int_operand" "O"))
-+ (const_int 0)))
-+ (clobber (match_scratch:SI 2 "=d"))]
-+ "(satisfies_constraint_O (operands[1])
-+ && ubicom32_match_cc_mode(insn, CCWZmode))"
-+ "*
-+ {
-+ operands[3] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1));
-+
-+ return \"bfextu\\t%2, %0, %3\";
-+ }")
-+
-+(define_insn "andsi3_bclr"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (and:SI (match_operand:SI 1 "ubicom32_arith_operand" "%rmI")
-+ (match_operand:SI 2 "const_int_operand" "n")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(exact_log2 (~INTVAL (operands[2])) != -1)"
-+ "bclr\\t%0, %1, #%D2")
-+
-+(define_insn "andsi3_and4"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
-+ (and:SI (match_operand:SI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "@
-+ and.4\\t%0, %2, %1
-+ and.4\\t%0, %1, %2")
-+
-+(define_insn "andsi3_and4_ccwzn"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (and:SI (match_operand:SI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
-+ (and:SI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "@
-+ and.4\\t%0, %2, %1
-+ and.4\\t%0, %1, %2")
-+
-+(define_insn "andsi3_and4_ccwzn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (and:SI (match_operand:SI 0 "nonimmediate_operand" "%d,rm")
-+ (match_operand:SI 1 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "@
-+ and.4\\t#0, %1, %0
-+ and.4\\t#0, %0, %1")
-+
-+(define_insn "andsi3_lsr4_ccwz_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (and:SI (match_operand:SI 0 "nonimmediate_operand" "%rm")
-+ (match_operand:SI 1 "const_int_operand" "n"))
-+ (const_int 0)))
-+ (clobber (match_scratch:SI 2 "=d"))]
-+ "(exact_log2 ((~(INTVAL (operands[1]))) + 1) != -1
-+ && ubicom32_match_cc_mode(insn, CCWZmode))"
-+ "*
-+ {
-+ operands[3] = GEN_INT (exact_log2 ((~(INTVAL (operands[1]))) + 1));
-+
-+ return \"lsr.4\\t%2, %0, %3\";
-+ }")
-+
-+; We really would like the combiner to recognize this scenario and deal with
-+; it but unfortunately it tries to canonicalize zero_extract ops on MEMs
-+; into QImode operations and we can't match them in any useful way.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))
-+ (set (reg:CCWZ CC_REGNO)
-+ (compare:CCWZ
-+ (and:SI (match_operand:SI 2 "nonimmediate_operand" "")
-+ (match_dup 0))
-+ (const_int 0)))]
-+ "(exact_log2 (INTVAL (operands[1])) != -1
-+ && peep2_reg_dead_p (2, operands[0]))"
-+ [(set (reg:CCWZ CC_REGNO)
-+ (compare:CCWZ
-+ (zero_extract:SI
-+ (match_dup 2)
-+ (const_int 1)
-+ (match_dup 3))
-+ (const_int 0)))]
-+ "{
-+ operands[3] = GEN_INT (exact_log2 (INTVAL (operands[1])));
-+ }")
-+
-+(define_expand "anddi3"
-+ [(parallel
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "")
-+ (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
-+ (match_operand:DI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ ""
-+ "{
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (DImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (DImode, operands[2]);
-+ }")
-+
-+(define_insn_and_split "anddi3_and4"
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,&r, d,rm, m, m")
-+ (and:DI (match_operand:DI 1 "nonimmediate_operand" "%d,rm, 0, 0, d,rm")
-+ (match_operand:DI 2 "ubicom32_arith_operand" "rmI, d,rmI, d,rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "#"
-+ "reload_completed"
-+ [(parallel [(set (match_dup 3)
-+ (and:SI (match_dup 4)
-+ (match_dup 5)))
-+ (clobber (reg:CC CC_REGNO))])
-+ (parallel [(set (match_dup 6)
-+ (and:SI (match_dup 7)
-+ (match_dup 8)))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "{
-+ operands[3] = gen_lowpart (SImode, operands[0]);
-+ operands[4] = gen_lowpart (SImode, operands[1]);
-+ operands[5] = gen_lowpart (SImode, operands[2]);
-+ operands[6] = gen_highpart (SImode, operands[0]);
-+ operands[7] = gen_highpart (SImode, operands[1]);
-+ operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_expand "iorqi3"
-+ [(parallel
-+ [(set (match_operand:QI 0 "memory_operand" "")
-+ (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
-+ (match_operand:QI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "(ubicom32_v4)"
-+ "{
-+ if (!memory_operand (operands[0], QImode))
-+ FAIL;
-+
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (QImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (QImode, operands[2]);
-+ }")
-+
-+(define_insn "iorqi3_or1"
-+ [(set (match_operand:QI 0 "memory_operand" "=m, m")
-+ (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:QI 2 "ubicom32_arith_operand" "rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4)"
-+ "@
-+ or.1\\t%0, %2, %1
-+ or.1\\t%0, %1, %2")
-+
-+(define_expand "iorhi3"
-+ [(parallel
-+ [(set (match_operand:HI 0 "memory_operand" "")
-+ (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
-+ (match_operand:HI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ ""
-+ "{
-+ if (!memory_operand (operands[0], HImode))
-+ FAIL;
-+
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (HImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (HImode, operands[2]);
-+ }")
-+
-+(define_insn "iorhi3_or2"
-+ [(set (match_operand:HI 0 "memory_operand" "=m, m")
-+ (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:HI 2 "ubicom32_arith_operand" "rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "@
-+ or.2\\t%0, %2, %1
-+ or.2\\t%0, %1, %2")
-+
-+(define_expand "iorsi3"
-+ [(parallel
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
-+ (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
-+ (match_operand:SI 2 "ubicom32_and_or_si3_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ ""
-+ "{
-+ do
-+ {
-+ /* Is this a bset? */
-+ if (CONST_INT_P (operands[2])
-+ && exact_log2 (INTVAL (operands[2])) != -1)
-+ break;
-+
-+ /* Must be an or.4 */
-+ if (!ubicom32_data_register_operand (operands[1], SImode))
-+ operands[1] = copy_to_mode_reg (SImode, operands[1]);
-+
-+ if (!ubicom32_arith_operand (operands[2], SImode))
-+ operands[2] = copy_to_mode_reg (SImode, operands[2]);
-+ }
-+ while (0);
-+ }")
-+
-+(define_insn "iorsi3_bset"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (ior:SI (match_operand:SI 1 "ubicom32_arith_operand" "%rmI")
-+ (match_operand 2 "const_int_operand" "n")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(exact_log2 (INTVAL (operands[2])) != -1)"
-+ "bset\\t%0, %1, #%d2")
-+
-+(define_insn "iorsi3_or4"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
-+ (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "@
-+ or.4\\t%0, %2, %1
-+ or.4\\t%0, %1, %2")
-+
-+(define_insn "iorsi3_ccwzn"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
-+ (ior:SI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "@
-+ or.4\\t%0, %2, %1
-+ or.4\\t%0, %1, %2")
-+
-+(define_insn "iorsi3_ccwzn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (ior:SI (match_operand:SI 0 "nonimmediate_operand" "%d,rm")
-+ (match_operand:SI 1 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "@
-+ or.4\\t#0, %1, %0
-+ or.4\\t#0, %0, %1")
-+
-+(define_expand "iordi3"
-+ [(parallel
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "")
-+ (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
-+ (match_operand:DI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ ""
-+ "{
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (DImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (DImode, operands[2]);
-+ }")
-+
-+(define_insn_and_split "iordi3_or4"
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,&r, d,rm, m, m")
-+ (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%d,rm, 0, 0, d,rm")
-+ (match_operand:DI 2 "ubicom32_arith_operand" "rmI, d,rmI, d,rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "#"
-+ "reload_completed"
-+ [(parallel [(set (match_dup 3)
-+ (ior:SI (match_dup 4)
-+ (match_dup 5)))
-+ (clobber (reg:CC CC_REGNO))])
-+ (parallel [(set (match_dup 6)
-+ (ior:SI (match_dup 7)
-+ (match_dup 8)))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "{
-+ operands[3] = gen_lowpart (SImode, operands[0]);
-+ operands[4] = gen_lowpart (SImode, operands[1]);
-+ operands[5] = gen_lowpart (SImode, operands[2]);
-+ operands[6] = gen_highpart (SImode, operands[0]);
-+ operands[7] = gen_highpart (SImode, operands[1]);
-+ operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_expand "xorqi3"
-+ [(parallel
-+ [(set (match_operand:QI 0 "memory_operand" "")
-+ (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
-+ (match_operand:QI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "(ubicom32_v4)"
-+ "{
-+ if (!memory_operand (operands[0], QImode))
-+ FAIL;
-+
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (QImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (QImode, operands[2]);
-+ }")
-+
-+(define_insn "xorqi3_xor1"
-+ [(set (match_operand:QI 0 "memory_operand" "=m, m")
-+ (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:QI 2 "ubicom32_arith_operand" "rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4)"
-+ "@
-+ xor.1\\t%0, %2, %1
-+ xor.1\\t%0, %1, %2")
-+
-+(define_insn "xorqi3_xor1_ccszn"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:QI 2 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))
-+ (set (match_operand:QI 0 "memory_operand" "=m, m")
-+ (xor:QI (match_dup 1)
-+ (match_dup 2)))]
-+ "(ubicom32_v4
-+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
-+ "@
-+ xor.1\\t%0, %2, %1
-+ xor.1\\t%0, %1, %2")
-+
-+(define_insn "xorqi3_xor1_ccszn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (xor:QI (match_operand:QI 0 "nonimmediate_operand" "%d,rm")
-+ (match_operand:QI 1 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))]
-+ "(ubicom32_v4
-+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
-+ "@
-+ xor.1\\t#0, %1, %0
-+ xor.1\\t#0, %0, %1")
-+
-+(define_insn "xor1_ccszn_null_1"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:QI
-+ (xor:SI (match_operand:SI 0 "ubicom32_data_register_operand" "%d")
-+ (match_operand:SI 1 "ubicom32_arith_operand" "rI"))
-+ 3)
-+ (const_int 0)))]
-+ "(ubicom32_v4
-+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
-+ "xor.1\\t#0, %1, %0")
-+
-+(define_insn "xor1_ccszn_null_2"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:QI
-+ (xor:SI (match_operand:SI 0 "ubicom32_data_register_operand" "d")
-+ (subreg:SI
-+ (match_operand:QI 1 "memory_operand" "m")
-+ 0))
-+ 3)
-+ (const_int 0)))]
-+ "(ubicom32_v4
-+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
-+ "xor.1\\t#0, %1, %0")
-+
-+(define_insn "xor1_ccwzn_null_3"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:QI
-+ (xor:SI (subreg:SI
-+ (match_operand:QI 0 "memory_operand" "m")
-+ 0)
-+ (match_operand:SI 1 "ubicom32_data_register_operand" "d"))
-+ 3)
-+ (const_int 0)))]
-+ "(ubicom32_v4
-+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
-+ "xor.1\\t#0, %0, %1")
-+
-+(define_expand "xorhi3"
-+ [(parallel
-+ [(set (match_operand:HI 0 "memory_operand" "")
-+ (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
-+ (match_operand:HI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ ""
-+ "{
-+ if (!memory_operand (operands[0], HImode))
-+ FAIL;
-+
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (HImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (HImode, operands[2]);
-+ }")
-+
-+(define_insn "xorhi3_xor2"
-+ [(set (match_operand:HI 0 "memory_operand" "=m, m")
-+ (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:HI 2 "ubicom32_arith_operand" "rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "@
-+ xor.2\\t%0, %2, %1
-+ xor.2\\t%0, %1, %2")
-+
-+(define_insn "xorhi3_xor2_ccszn"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:HI 2 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))
-+ (set (match_operand:HI 0 "memory_operand" "=m, m")
-+ (xor:HI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "@
-+ xor.2\\t%0, %2, %1
-+ xor.2\\t%0, %1, %2")
-+
-+(define_insn "xorhi3_xor2_ccszn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (xor:HI (match_operand:HI 0 "nonimmediate_operand" "%d,rm")
-+ (match_operand:HI 1 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "@
-+ xor.2\\t#0, %1, %0
-+ xor.2\\t#0, %0, %1")
-+
-+(define_insn "xor2_ccszn_null_1"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:HI
-+ (xor:SI (match_operand:SI 0 "ubicom32_data_register_operand" "%d")
-+ (match_operand:SI 1 "ubicom32_arith_operand" "rI"))
-+ 2)
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "xor.2\\t#0, %1, %0")
-+
-+(define_insn "xor2_ccszn_null_2"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:HI
-+ (xor:SI (match_operand:SI 0 "ubicom32_data_register_operand" "d")
-+ (subreg:SI
-+ (match_operand:HI 1 "memory_operand" "m")
-+ 0))
-+ 2)
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "xor.2\\t#0, %1, %0")
-+
-+(define_insn "xor2_ccszn_null_3"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:HI
-+ (xor:SI (subreg:SI
-+ (match_operand:HI 0 "memory_operand" "m")
-+ 0)
-+ (match_operand:SI 1 "ubicom32_data_register_operand" "d"))
-+ 2)
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "xor.2\\t#0, %0, %1")
-+
-+(define_insn "xorsi3"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
-+ (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "@
-+ xor.4\\t%0, %2, %1
-+ xor.4\\t%0, %1, %2")
-+
-+(define_insn "xorsi3_ccwzn"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
-+ (xor:SI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "@
-+ xor.4\\t%0, %2, %1
-+ xor.4\\t%0, %1, %2")
-+
-+(define_insn "xorsi3_ccwzn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (xor:SI (match_operand:SI 0 "nonimmediate_operand" "%d,rm")
-+ (match_operand:SI 1 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "@
-+ xor.4\\t#0, %1, %0
-+ xor.4\\t#0, %0, %1")
-+
-+(define_expand "xordi3"
-+ [(parallel
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "")
-+ (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
-+ (match_operand:DI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ ""
-+ "{
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (DImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (DImode, operands[2]);
-+ }")
-+
-+(define_insn_and_split "xordi3_xor4"
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,&r, d,rm, m, m")
-+ (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%d,rm, 0, 0, d,rm")
-+ (match_operand:DI 2 "ubicom32_arith_operand" "rmI, d,rmI, d,rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "#"
-+ "reload_completed"
-+ [(parallel [(set (match_dup 3)
-+ (xor:SI (match_dup 4)
-+ (match_dup 5)))
-+ (clobber (reg:CC CC_REGNO))])
-+ (parallel [(set (match_dup 6)
-+ (xor:SI (match_dup 7)
-+ (match_dup 8)))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "{
-+ operands[3] = gen_lowpart (SImode, operands[0]);
-+ operands[4] = gen_lowpart (SImode, operands[1]);
-+ operands[5] = gen_lowpart (SImode, operands[2]);
-+ operands[6] = gen_highpart (SImode, operands[0]);
-+ operands[7] = gen_highpart (SImode, operands[1]);
-+ operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_insn "not2_2"
-+ [(set (match_operand:HI 0 "memory_operand" "=m")
-+ (subreg:HI
-+ (not:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI"))
-+ 2))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "not.2\\t%0, %1")
-+
-+(define_insn "one_cmplsi2"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (not:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "not.4\\t%0, %1")
-+
-+(define_insn "one_cmplsi2_ccwzn"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (not:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (not:SI (match_dup 1)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "not.4\\t%0, %1")
-+
-+(define_insn "one_cmplsi2_ccwzn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (not:SI (match_operand:SI 0 "ubicom32_arith_operand" "rmI"))
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "not.4\\t#0, %0")
-+
-+(define_insn_and_split "one_cmpldi2"
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "=&rm")
-+ (not:DI (match_operand:DI 1 "nonimmediate_operand" "rmI0")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "#"
-+ ""
-+ [(parallel [(set (match_dup 2)
-+ (not:SI (match_dup 3)))
-+ (clobber (reg:CC CC_REGNO))])
-+ (parallel [(set (match_dup 4)
-+ (not:SI (match_dup 5)))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "{
-+ operands[2] = gen_lowpart (SImode, operands[0]);
-+ operands[3] = gen_lowpart (SImode, operands[1]);
-+ operands[4] = gen_highpart (SImode, operands[0]);
-+ operands[5] = gen_highpart (SImode, operands[1]);
-+ }"
-+ [(set_attr "length" "8")])
-+
-+; Conditional jump instructions
-+
-+(define_expand "beq"
-+ [(set (pc)
-+ (if_then_else (eq (match_dup 1)
-+ (const_int 0))
-+ (label_ref (match_operand 0 "" ""))
-+ (pc)))]
-+ ""
-+ "{
-+ operands[1] = ubicom32_gen_compare_reg (EQ, ubicom32_compare_op0,
-+ ubicom32_compare_op1);
-+ }")
-+
-+(define_expand "bne"
-+ [(set (pc)
-+ (if_then_else (ne (match_dup 1)
-+ (const_int 0))
-+ (label_ref (match_operand 0 "" ""))
-+ (pc)))]
-+ ""
-+ "{
-+ operands[1] = ubicom32_gen_compare_reg (NE, ubicom32_compare_op0,
-+ ubicom32_compare_op1);
-+ }")
-+
-+(define_expand "bgt"
-+ [(set (pc)
-+ (if_then_else (gt (match_dup 1)
-+ (const_int 0))
-+ (label_ref (match_operand 0 "" ""))
-+ (pc)))]
-+ ""
-+ "{
-+ operands[1] = ubicom32_gen_compare_reg (GT, ubicom32_compare_op0,
-+ ubicom32_compare_op1);
-+ }")
-+
-+(define_expand "ble"
-+ [(set (pc)
-+ (if_then_else (le (match_dup 1)
-+ (const_int 0))
-+ (label_ref (match_operand 0 "" ""))
-+ (pc)))]
-+ ""
-+ "{
-+ operands[1] = ubicom32_gen_compare_reg (LE, ubicom32_compare_op0,
-+ ubicom32_compare_op1);
-+ }")
-+
-+(define_expand "bge"
-+ [(set (pc)
-+ (if_then_else (ge (match_dup 1)
-+ (const_int 0))
-+ (label_ref (match_operand 0 "" ""))
-+ (pc)))]
-+ ""
-+ "{
-+ operands[1] = ubicom32_gen_compare_reg (GE, ubicom32_compare_op0,
-+ ubicom32_compare_op1);
-+ }")
-+
-+(define_expand "blt"
-+ [(set (pc)
-+ (if_then_else (lt (match_dup 1)
-+ (const_int 0))
-+ (label_ref (match_operand 0 "" ""))
-+ (pc)))]
-+ ""
-+ "{
-+ operands[1] = ubicom32_gen_compare_reg (LT, ubicom32_compare_op0,
-+ ubicom32_compare_op1);
-+ }")
-+
-+(define_expand "bgtu"
-+ [(set (pc)
-+ (if_then_else (gtu (match_dup 1)
-+ (const_int 0))
-+ (label_ref (match_operand 0 "" ""))
-+ (pc)))]
-+ ""
-+ "{
-+ operands[1] = ubicom32_gen_compare_reg (GTU, ubicom32_compare_op0,
-+ ubicom32_compare_op1);
-+ }")
-+
-+(define_expand "bleu"
-+ [(set (pc)
-+ (if_then_else (leu (match_dup 1)
-+ (const_int 0))
-+ (label_ref (match_operand 0 "" ""))
-+ (pc)))]
-+ ""
-+ "{
-+ operands[1] = ubicom32_gen_compare_reg (LEU, ubicom32_compare_op0,
-+ ubicom32_compare_op1);
-+ }")
-+
-+(define_expand "bgeu"
-+ [(set (pc)
-+ (if_then_else (geu (match_dup 1)
-+ (const_int 0))
-+ (label_ref (match_operand 0 "" ""))
-+ (pc)))]
-+ ""
-+ "{
-+ operands[1] = ubicom32_gen_compare_reg (GEU, ubicom32_compare_op0,
-+ ubicom32_compare_op1);
-+ }")
-+
-+(define_expand "bltu"
-+ [(set (pc)
-+ (if_then_else (ltu (match_dup 1)
-+ (const_int 0))
-+ (label_ref (match_operand 0 "" ""))
-+ (pc)))]
-+ ""
-+ "{
-+ operands[1] = ubicom32_gen_compare_reg (LTU, ubicom32_compare_op0,
-+ ubicom32_compare_op1);
-+ }")
-+
-+(define_insn "jcc"
-+ [(set (pc)
-+ (if_then_else (match_operator 1 "comparison_operator"
-+ [(match_operand 2 "ubicom32_cc_register_operand" "")
-+ (const_int 0)])
-+ (label_ref (match_operand 0 "" ""))
-+ (pc)))]
-+ ""
-+ "*
-+ {
-+ ubicom32_output_cond_jump (insn, operands[1], operands[0]);
-+ return \"\";
-+ }")
-+
-+; Reverse branch - reverse our comparison condition so that we can
-+; branch in the opposite sense.
-+;
-+(define_insn_and_split "jcc_reverse"
-+ [(set (pc)
-+ (if_then_else (match_operator 1 "comparison_operator"
-+ [(match_operand 2 "ubicom32_cc_register_operand" "")
-+ (const_int 0)])
-+ (pc)
-+ (label_ref (match_operand 0 "" ""))))]
-+ ""
-+ "#"
-+ "reload_completed"
-+ [(set (pc)
-+ (if_then_else (match_dup 3)
-+ (label_ref (match_dup 0))
-+ (pc)))]
-+ "{
-+ rtx cc_reg;
-+
-+ cc_reg = gen_rtx_REG (GET_MODE (operands[2]), CC_REGNO);
-+ operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[1])),
-+ GET_MODE (operands[1]),
-+ cc_reg,
-+ const0_rtx);
-+ }")
-+
-+(define_insn "jump"
-+ [(set (pc)
-+ (label_ref (match_operand 0 "" "")))]
-+ ""
-+ "jmpt\\t%l0")
-+
-+(define_expand "indirect_jump"
-+ [(parallel [(set (pc)
-+ (match_operand:SI 0 "register_operand" ""))
-+ (clobber (match_dup 0))])]
-+ ""
-+ "")
-+
-+(define_insn "indirect_jump_internal"
-+ [(set (pc)
-+ (match_operand:SI 0 "register_operand" "a"))
-+ (clobber (match_dup 0))]
-+ ""
-+ "calli\\t%0,0(%0)")
-+
-+; Program Space: The table contains instructions, typically jumps.
-+; CALL An,TABLE_SIZE(PC) ;An = Jump Table Base Address.
-+; <Jump Table is Here> ;An -> Here.
-+; LEA Ak, (An,Dn) ;Ak -> Table Entry
-+; JMP/CALL (Ak)
-+
-+(define_expand "tablejump"
-+ [(parallel [(set (pc)
-+ (match_operand:SI 0 "nonimmediate_operand" ""))
-+ (use (label_ref (match_operand 1 "" "")))])]
-+ ""
-+ "")
-+
-+(define_insn "tablejump_internal"
-+ [(set (pc)
-+ (match_operand:SI 0 "nonimmediate_operand" "rm"))
-+ (use (label_ref (match_operand 1 "" "")))]
-+ ""
-+ "ret\\t%0")
-+
-+; Call subroutine with no return value.
-+;
-+(define_expand "call"
-+ [(call (match_operand:QI 0 "general_operand" "")
-+ (match_operand:SI 1 "general_operand" ""))]
-+ ""
-+ "{
-+ if (TARGET_FDPIC)
-+ {
-+ ubicom32_expand_call_fdpic (operands);
-+ DONE;
-+ }
-+
-+ if (! ubicom32_call_address_operand (XEXP (operands[0], 0), VOIDmode))
-+ XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
-+ }")
-+
-+; We expand to a simple form that doesn't clobber the link register and
-+; then split to a form that does. This allows the RTL optimizers that
-+; run before the splitter to have the opportunity to eliminate the call
-+; without marking A5 as being clobbered and this in turn avoids saves
-+; and returns in a number of cases.
-+;
-+(define_insn_and_split "call_1"
-+ [(call (mem:QI (match_operand:SI 0 "ubicom32_call_address_operand" "a,S"))
-+ (match_operand:SI 1 "general_operand" "g,g"))]
-+ "! TARGET_FDPIC"
-+ "#"
-+ ""
-+ [(parallel
-+ [(call (mem:QI (match_dup 0))
-+ (match_dup 1))
-+ (clobber (reg:SI LINK_REGNO))])]
-+ "")
-+
-+(define_insn "call_slow"
-+ [(call (mem:QI (match_operand:SI 0 "ubicom32_call_address_operand" "a,S"))
-+ (match_operand:SI 1 "general_operand" "g,g"))
-+ (clobber (reg:SI LINK_REGNO))]
-+ "(! TARGET_FDPIC && ! TARGET_FASTCALL)"
-+ "@
-+ calli\\ta5, 0(%0)
-+ moveai\\ta5, #%%hi(%C0)\;calli\\ta5, %%lo(%C0)(a5)")
-+
-+(define_insn "call_fast"
-+ [(call (mem:QI (match_operand:SI 0 "ubicom32_call_address_operand" "a,S"))
-+ (match_operand:SI 1 "general_operand" "g,g"))
-+ (clobber (reg:SI LINK_REGNO))]
-+ "(! TARGET_FDPIC && TARGET_FASTCALL)"
-+ "@
-+ calli\\ta5, 0(%0)
-+ call\\ta5, %C0")
-+
-+; We expand to a simple form that doesn't clobber the link register and
-+; then split to a form that does. This allows the RTL optimizers that
-+; run before the splitter to have the opportunity to eliminate the call
-+; without marking A5 as being clobbered and this in turn avoids saves
-+; and returns in a number of cases.
-+;
-+(define_insn_and_split "call_fdpic"
-+ [(call (mem:QI (match_operand:SI 0 "ubicom32_call_address_operand" "a,S"))
-+ (match_operand:SI 1 "general_operand" "g,g"))
-+ (use (match_operand:SI 2 "ubicom32_fdpic_operand" "Z,Z"))]
-+ "TARGET_FDPIC"
-+ "#"
-+ ""
-+ [(parallel
-+ [(call (mem:QI (match_dup 0))
-+ (match_dup 1))
-+ (use (match_dup 2))
-+ (clobber (reg:SI LINK_REGNO))])]
-+ "")
-+
-+(define_insn "call_fdpic_clobber"
-+ [(call (mem:QI (match_operand:SI 0 "ubicom32_call_address_operand" "a,S"))
-+ (match_operand:SI 1 "general_operand" "g,g"))
-+ (use (match_operand:SI 2 "ubicom32_fdpic_operand" "Z,Z"))
-+ (clobber (reg:SI LINK_REGNO))]
-+ "TARGET_FDPIC"
-+ "@
-+ move.4\\ta5, 0(%0)\;move.4\\t%2, 4(%0)\;calli\\ta5, 0(a5)
-+ call\\ta5, %C0")
-+
-+; Call subroutine, returning value in operand 0
-+; (which must be a hard register).
-+;
-+(define_expand "call_value"
-+ [(set (match_operand 0 "" "")
-+ (call (match_operand:QI 1 "general_operand" "")
-+ (match_operand:SI 2 "general_operand" "")))]
-+ ""
-+ "{
-+ if (TARGET_FDPIC)
-+ {
-+ ubicom32_expand_call_value_fdpic (operands);
-+ DONE;
-+ }
-+
-+ if (! ubicom32_call_address_operand (XEXP (operands[1], 0), VOIDmode))
-+ XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
-+ }")
-+
-+; We expand to a simple form that doesn't clobber the link register and
-+; then split to a form that does. This allows the RTL optimizers that
-+; run before the splitter to have the opportunity to eliminate the call
-+; without marking A5 as being clobbered and this in turn avoids saves
-+; and returns in a number of cases.
-+;
-+(define_insn_and_split "call_value_1"
-+ [(set (match_operand 0 "register_operand" "=r,r")
-+ (call (mem:QI (match_operand:SI 1 "ubicom32_call_address_operand" "a,S"))
-+ (match_operand:SI 2 "general_operand" "g,g")))]
-+ "! TARGET_FDPIC"
-+ "#"
-+ ""
-+ [(parallel
-+ [(set (match_dup 0)
-+ (call (mem:QI (match_dup 1))
-+ (match_dup 2)))
-+ (clobber (reg:SI LINK_REGNO))])]
-+ "")
-+
-+(define_insn "call_value_slow"
-+ [(set (match_operand 0 "register_operand" "=r,r")
-+ (call (mem:QI (match_operand:SI 1 "ubicom32_call_address_operand" "a,S"))
-+ (match_operand:SI 2 "general_operand" "g,g")))
-+ (clobber (reg:SI LINK_REGNO))]
-+ "(! TARGET_FDPIC && ! TARGET_FASTCALL)"
-+ "@
-+ calli\\ta5, 0(%1)
-+ moveai\\ta5, #%%hi(%C1)\;calli\\ta5, %%lo(%C1)(a5)")
-+
-+(define_insn "call_value_fast"
-+ [(set (match_operand 0 "register_operand" "=r,r")
-+ (call (mem:QI (match_operand:SI 1 "ubicom32_call_address_operand" "a,S"))
-+ (match_operand:SI 2 "general_operand" "g,g")))
-+ (clobber (reg:SI LINK_REGNO))]
-+ "(! TARGET_FDPIC && TARGET_FASTCALL)"
-+ "@
-+ calli\\ta5, 0(%1)
-+ call\\ta5, %C1")
-+
-+; We expand to a simple form that doesn't clobber the link register and
-+; then split to a form that does. This allows the RTL optimizers that
-+; run before the splitter to have the opportunity to eliminate the call
-+; without marking A5 as being clobbered and this in turn avoids saves
-+; and returns in a number of cases.
-+;
-+(define_insn_and_split "call_value_fdpic"
-+ [(set (match_operand 0 "register_operand" "=r,r")
-+ (call (mem:QI (match_operand:SI 1 "ubicom32_call_address_operand" "a,S"))
-+ (match_operand:SI 2 "general_operand" "g,g")))
-+ (use (match_operand:SI 3 "ubicom32_fdpic_operand" "Z,Z"))]
-+ "TARGET_FDPIC"
-+ "#"
-+ ""
-+ [(parallel
-+ [(set (match_dup 0)
-+ (call (mem:QI (match_dup 1))
-+ (match_dup 2)))
-+ (use (match_dup 3))
-+ (clobber (reg:SI LINK_REGNO))])]
-+ "")
-+
-+(define_insn "call_value_fdpic_clobber"
-+ [(set (match_operand 0 "register_operand" "=r,r")
-+ (call (mem:QI (match_operand:SI 1 "ubicom32_call_address_operand" "a,S"))
-+ (match_operand:SI 2 "general_operand" "g,g")))
-+ (use (match_operand:SI 3 "ubicom32_fdpic_operand" "Z,Z"))
-+ (clobber (reg:SI LINK_REGNO))]
-+ "TARGET_FDPIC"
-+ "@
-+ move.4\\ta5, 0(%1)\;move.4\\t%3, 4(%1)\;calli\\ta5, 0(a5)
-+ call\\ta5, %C1")
-+
-+(define_expand "untyped_call"
-+ [(parallel [(call (match_operand 0 "" "")
-+ (const_int 0))
-+ (match_operand 1 "" "")
-+ (match_operand 2 "" "")])]
-+ ""
-+ "{
-+ int i;
-+
-+ emit_call_insn (gen_call (operands[0], const0_rtx));
-+
-+ for (i = 0; i < XVECLEN (operands[2], 0); i++)
-+ {
-+ rtx set = XVECEXP (operands[2], 0, i);
-+ emit_move_insn (SET_DEST (set), SET_SRC (set));
-+ }
-+ DONE;
-+ }")
-+
-+(define_insn "lsl1_1"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (ashift:SI (subreg:SI
-+ (match_operand:QI 1 "memory_operand" "m")
-+ 0)
-+ (match_operand:SI 2 "ubicom32_arith_operand" "dM")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4)"
-+ "lsl.1\\t%0, %1, %2")
-+
-+; The combiner gets rather creative about left shifts of sub-word memory
-+; operands because it's uncertain about whether the memory is sign or
-+; zero extended. It only wants zero-extended behaviour and so throws
-+; in an extra and operation.
-+;
-+(define_insn "lsl1_2"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (and:SI
-+ (ashift:SI (subreg:SI
-+ (match_operand:QI 1 "memory_operand" "m")
-+ 0)
-+ (match_operand:SI 2 "const_int_operand" "M"))
-+ (match_operand:SI 3 "const_int_operand" "n")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4
-+ && INTVAL (operands[3]) == (0xff << INTVAL (operands[2])))"
-+ "lsl.1\\t%0, %1, %2")
-+
-+(define_insn "lsl2_1"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (ashift:SI (subreg:SI
-+ (match_operand:HI 1 "memory_operand" "m")
-+ 0)
-+ (match_operand:SI 2 "ubicom32_arith_operand" "dM")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4)"
-+ "lsl.2\\t%0, %1, %2")
-+
-+; The combiner gets rather creative about left shifts of sub-word memory
-+; operands because it's uncertain about whether the memory is sign or
-+; zero extended. It only wants zero-extended behaviour and so throws
-+; in an extra and operation.
-+;
-+(define_insn "lsl2_2"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (and:SI
-+ (ashift:SI (subreg:SI
-+ (match_operand:HI 1 "memory_operand" "m")
-+ 0)
-+ (match_operand:SI 2 "const_int_operand" "M"))
-+ (match_operand:SI 3 "const_int_operand" "n")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4
-+ && INTVAL (operands[3]) == (0xffff << INTVAL (operands[2])))"
-+ "lsl.2\\t%0, %1, %2")
-+
-+(define_insn "ashlsi3"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (ashift:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "dM")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "lsl.4\\t%0, %1, %2")
-+
-+(define_insn "lshlsi3_ccwz"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (ashift:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "dM"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (ashift:SI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCWZmode)"
-+ "lsl.4\\t%0, %1, %2")
-+
-+(define_insn "lshlsi3_ccwz_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (ashift:SI (match_operand:SI 0 "ubicom32_arith_operand" "rmI")
-+ (match_operand:SI 1 "ubicom32_arith_operand" "dM"))
-+ (const_int 0)))
-+ (clobber (match_scratch:SI 2 "=d"))]
-+ "ubicom32_match_cc_mode(insn, CCWZmode)"
-+ "lsl.4\\t%2, %0, %1")
-+
-+; The combiner finds this canonical form for what is in essence a right
-+; shift.
-+;
-+(define_insn "asr1_2"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (sign_extract:SI (match_operand:QI 1 "memory_operand" "m")
-+ (match_operand:SI 2 "const_int_operand" "M")
-+ (match_operand:SI 3 "const_int_operand" "M")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4
-+ && (INTVAL (operands[2]) + INTVAL (operands[3]) == 8))"
-+ "asr.1\\t%0, %1, %3")
-+
-+; The combiner finds this canonical form for what is in essence a right
-+; shift.
-+;
-+(define_insn "asr2_2"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (sign_extract:SI (match_operand:HI 1 "memory_operand" "m")
-+ (match_operand:SI 2 "const_int_operand" "M")
-+ (match_operand:SI 3 "const_int_operand" "M")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4
-+ && (INTVAL (operands[2]) + INTVAL (operands[3]) == 16))"
-+ "asr.2\\t%0, %1, %3")
-+
-+(define_insn "ashrsi3"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (ashiftrt:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmJ")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "dM")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "asr.4\\t%0, %1, %2")
-+
-+(define_insn "ashrsi3_ccwzn"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (ashiftrt:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmJ")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "dM"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (ashiftrt:SI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "asr.4\\t%0, %1, %2")
-+
-+(define_insn "ashrsi3_ccwzn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (ashiftrt:SI (match_operand:SI 0 "ubicom32_arith_operand" "rmJ")
-+ (match_operand:SI 1 "ubicom32_arith_operand" "dM"))
-+ (const_int 0)))
-+ (clobber (match_scratch:SI 2 "=d"))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "asr.4\\t%2, %0, %1")
-+
-+(define_insn "lsr1_1"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (lshiftrt:SI (subreg:SI
-+ (match_operand:QI 1 "memory_operand" "m")
-+ 0)
-+ (match_operand:SI 2 "ubicom32_arith_operand" "dM")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4)"
-+ "lsr.1\\t%0, %1, %2")
-+
-+; The combiner finds this canonical form for what is in essence a right
-+; shift.
-+;
-+(define_insn "lsr1_2"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (zero_extract:SI (match_operand:QI 1 "memory_operand" "m")
-+ (match_operand:SI 2 "const_int_operand" "M")
-+ (match_operand:SI 3 "const_int_operand" "M")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4
-+ && (INTVAL (operands[2]) + INTVAL (operands[3]) == 8))"
-+ "lsr.1\\t%0, %1, %3")
-+
-+(define_insn "lsr2_1"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (lshiftrt:SI (subreg:SI
-+ (match_operand:HI 1 "memory_operand" "m")
-+ 0)
-+ (match_operand:SI 2 "ubicom32_arith_operand" "dM")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4)"
-+ "lsr.2\\t%0, %1, %2")
-+
-+; The combiner finds this canonical form for what is in essence a right
-+; shift.
-+;
-+(define_insn "lsr2_2"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (zero_extract:SI (match_operand:HI 1 "memory_operand" "m")
-+ (match_operand:SI 2 "const_int_operand" "M")
-+ (match_operand:SI 3 "const_int_operand" "M")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4
-+ && (INTVAL (operands[2]) + INTVAL (operands[3]) == 16))"
-+ "lsr.2\\t%0, %1, %3")
-+
-+(define_insn "lshrsi3"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (lshiftrt:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "dM")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "lsr.4\\t%0, %1, %2")
-+
-+(define_insn "lshrsi3_ccwz"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (lshiftrt:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "dM"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (lshiftrt:SI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCWZmode)"
-+ "lsr.4\\t%0, %1, %2")
-+
-+(define_insn "lshrsi3_ccwz_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (lshiftrt:SI (match_operand:SI 0 "ubicom32_arith_operand" "rmI")
-+ (match_operand:SI 1 "ubicom32_arith_operand" "dM"))
-+ (const_int 0)))
-+ (clobber (match_scratch:SI 2 "=d"))]
-+ "ubicom32_match_cc_mode(insn, CCWZmode)"
-+ "lsr.4\\t%2, %0, %1")
-+
-+(define_expand "prologue"
-+ [(const_int 0)]
-+ ""
-+ "{
-+ ubicom32_expand_prologue ();
-+ DONE;
-+ }")
-+
-+(define_expand "epilogue"
-+ [(return)]
-+ ""
-+ "{
-+ ubicom32_expand_epilogue ();
-+ DONE;
-+ }")
-+
-+(define_expand "return"
-+ [(return)]
-+ ""
-+ "{
-+ ubicom32_expand_epilogue ();
-+ DONE;
-+ }")
-+
-+(define_expand "_eh_return"
-+ [(use (match_operand:SI 0 "register_operand" "r"))
-+ (use (match_operand:SI 1 "register_operand" "r"))]
-+ ""
-+ "{
-+ ubicom32_expand_eh_return (operands);
-+ DONE;
-+ }")
-+
-+; XXX - it looks almost certain that we could make return_internal use a Dn
-+; register too. In that instance we'd have to use a ret instruction
-+; rather than a calli but it might save cycles.
-+;
-+(define_insn "return_internal"
-+ [(const_int 2)
-+ (return)
-+ (use (match_operand:SI 0 "ubicom32_mem_or_address_register_operand" "rm"))]
-+ ""
-+ "*
-+ {
-+ if (REG_P (operands[0]) && REGNO (operands[0]) == LINK_REGNO
-+ && ubicom32_can_use_calli_to_ret)
-+ return \"calli\\t%0, 0(%0)\";
-+
-+ return \"ret\\t%0\";
-+ }")
-+
-+(define_insn "return_from_post_modify_sp"
-+ [(parallel
-+ [(const_int 2)
-+ (return)
-+ (use (mem:SI (post_modify:SI
-+ (reg:SI SP_REGNO)
-+ (plus:SI (reg:SI SP_REGNO)
-+ (match_operand:SI 0 "const_int_operand" "n")))))])]
-+ "INTVAL (operands[0]) >= 4 && INTVAL (operands[0]) <= 7 * 4"
-+ "ret\\t(sp)%E0++")
-+
-+;(define_insn "eh_return_internal"
-+; [(const_int 4)
-+; (return)
-+; (use (reg:SI 34))]
-+; ""
-+; "ret\\ta2")
-+
-+; No operation, needed in case the user uses -g but not -O.
-+(define_expand "nop"
-+ [(const_int 0)]
-+ ""
-+ "")
-+
-+(define_insn "nop_internal"
-+ [(const_int 0)]
-+ ""
-+ "nop")
-+
-+; The combiner will generate this pattern given shift and add operations.
-+; The canonical form that the combiner wants to use appears to be multiplies
-+; instead of shifts even if the compiled sources use shifts.
-+;
-+(define_insn "shmrg1_add"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (plus:SI
-+ (mult:SI (match_operand:SI 1 "ubicom32_data_register_operand" "d")
-+ (const_int 256))
-+ (zero_extend:SI
-+ (match_operand:QI 2 "ubicom32_arith_operand" "rmI"))))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "shmrg.1\\t%0, %2, %1")
-+
-+; The combiner will generate this pattern given shift and or operations.
-+;
-+(define_insn "shmrg1_ior"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (ior:SI
-+ (ashift:SI (match_operand:SI 1 "ubicom32_data_register_operand" "d")
-+ (const_int 8))
-+ (zero_extend:SI
-+ (match_operand:QI 2 "ubicom32_arith_operand" "rmI"))))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "shmrg.1\\t%0, %2, %1")
-+
-+; The combiner will generate this pattern given shift and add operations.
-+; The canonical form that the combiner wants to use appears to be multiplies
-+; instead of shifts even if the compiled sources use shifts.
-+;
-+(define_insn "shmrg2_add"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (plus:SI
-+ (mult:SI (match_operand:SI 1 "ubicom32_data_register_operand" "d")
-+ (const_int 65536))
-+ (zero_extend:SI
-+ (match_operand:HI 2 "ubicom32_arith_operand" "rmI"))))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "shmrg.2\\t%0, %2, %1")
-+
-+; The combiner will generate this pattern given shift and or operations.
-+;
-+(define_insn "shmrg2_ior"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (ior:SI
-+ (ashift:SI (match_operand:SI 1 "ubicom32_data_register_operand" "d")
-+ (const_int 16))
-+ (zero_extend:SI
-+ (match_operand:HI 2 "ubicom32_arith_operand" "rmI"))))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "shmrg.2\\t%0, %2, %1")
-+
-+; Match the case where we load a word from the stack but then discard the
-+; upper 16 bits. We turn this into a zero-extended load of that useful
-+; 16 bits direct from the stack where possible.
-+;
-+
-+; XXX - do these peephole2 ops actually work after the CCmode conversion?
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (mem:SI (plus:SI (reg:SI SP_REGNO)
-+ (match_operand:SI 1 "const_int_operand" ""))))
-+ (set (match_operand:SI 2 "nonimmediate_operand" "")
-+ (zero_extend:SI (match_operand:HI 3 "register_operand" "")))]
-+ "(INTVAL (operands[1]) <= 252
-+ && REGNO (operands[3]) == REGNO (operands[0])
-+ && ((peep2_reg_dead_p (2, operands[0])
-+ && ! reg_mentioned_p (operands[0], operands[2]))
-+ || rtx_equal_p (operands[0], operands[2])))"
-+ [(set (match_dup 2)
-+ (zero_extend:SI (mem:HI (plus:SI (reg:SI SP_REGNO)
-+ (match_dup 4)))))]
-+ "{
-+ operands[4] = GEN_INT (INTVAL (operands[1]) + 2);
-+ }")
-+
-+; Match the case where we load a word from the stack but then discard the
-+; upper 16 bits. We turn this into a 16-bit load of that useful
-+; 16 bits direct from the stack where possible.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (mem:SI (plus:SI (reg:SI SP_REGNO)
-+ (match_operand:SI 1 "const_int_operand" ""))))
-+ (set (match_operand:HI 2 "nonimmediate_operand" "")
-+ (match_operand:HI 3 "register_operand" ""))]
-+ "(INTVAL (operands[1]) <= 252
-+ && REGNO (operands[3]) == REGNO (operands[0])
-+ && ((peep2_reg_dead_p (2, operands[0])
-+ && ! reg_mentioned_p (operands[0], operands[2]))
-+ || rtx_equal_p (operands[0], operands[2])))"
-+ [(set (match_dup 2)
-+ (mem:HI (plus:SI (reg:SI SP_REGNO)
-+ (match_dup 4))))]
-+ "{
-+ operands[4] = GEN_INT (INTVAL (operands[1]) + 2);
-+ }")
-+
-+; Match the case where we load a word from the stack but then discard the
-+; upper 24 bits. We turn this into a zero-extended load of that useful
-+; 8 bits direct from the stack where possible.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (mem:SI (plus:SI (reg:SI SP_REGNO)
-+ (match_operand:SI 1 "const_int_operand" ""))))
-+ (set (match_operand:SI 2 "nonimmediate_operand" "")
-+ (zero_extend:SI (match_operand:QI 3 "register_operand" "")))]
-+ "(INTVAL (operands[1]) <= 124
-+ && REGNO (operands[3]) == REGNO (operands[0])
-+ && ((peep2_reg_dead_p (2, operands[0])
-+ && ! reg_mentioned_p (operands[0], operands[2]))
-+ || rtx_equal_p (operands[0], operands[2])))"
-+ [(set (match_dup 2)
-+ (zero_extend:SI (mem:QI (plus:SI (reg:SI SP_REGNO)
-+ (match_dup 4)))))]
-+ "{
-+ operands[4] = GEN_INT (INTVAL (operands[1]) + 3);
-+ }")
-+
-+; Match the case where we load a word from the stack but then discard the
-+; upper 24 bits. We turn this into an 8-bit load of that useful
-+; 8 bits direct from the stack where possible.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (mem:SI (plus:SI (reg:SI SP_REGNO)
-+ (match_operand:SI 1 "const_int_operand" ""))))
-+ (set (match_operand:QI 2 "nonimmediate_operand" "")
-+ (match_operand:QI 3 "register_operand" ""))]
-+ "(INTVAL (operands[1]) <= 124
-+ && REGNO (operands[3]) == REGNO (operands[0])
-+ && ((peep2_reg_dead_p (2, operands[0])
-+ && ! reg_mentioned_p (operands[0], operands[2]))
-+ || rtx_equal_p (operands[0], operands[2])))"
-+ [(set (match_dup 2)
-+ (mem:QI (plus:SI (reg:SI SP_REGNO)
-+ (match_dup 4))))]
-+ "{
-+ operands[4] = GEN_INT (INTVAL (operands[1]) + 3);
-+ }")
-+
---- /dev/null
-+++ b/gcc/config/ubicom32/ubicom32.opt
-@@ -0,0 +1,27 @@
-+mdebug-address
-+Target RejectNegative Report Undocumented Mask(DEBUG_ADDRESS)
-+Debug addresses
-+
-+mdebug-context
-+Target RejectNegative Report Undocumented Mask(DEBUG_CONTEXT)
-+Debug contexts
-+
-+march=
-+Target Report Var(ubicom32_arch_name) Init("ubicom32v4") Joined
-+Specify the name of the target architecture
-+
-+mfdpic
-+Target Report Mask(FDPIC)
-+Enable Function Descriptor PIC mode
-+
-+minline-plt
-+Target Report Mask(INLINE_PLT)
-+Enable inlining of PLT in function calls
-+
-+mfastcall
-+Target Report Mask(FASTCALL)
-+Enable default fast (call) calling sequence for smaller applications
-+
-+mipos-abi
-+Target Report Mask(IPOS_ABI)
-+Enable the ipOS ABI in which D10-D13 are caller-clobbered
---- /dev/null
-+++ b/gcc/config/ubicom32/uclinux.h
-@@ -0,0 +1,67 @@
-+/* Definitions of target machine for Ubicom32-uclinux
-+
-+ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
-+ 2009 Free Software Foundation, Inc.
-+ Contributed by Ubicom, Inc.
-+
-+ This file is part of GCC.
-+
-+ GCC is free software; you can redistribute it and/or modify it
-+ under the terms of the GNU General Public License as published
-+ by the Free Software Foundation; either version 3, or (at your
-+ option) any later version.
-+
-+ GCC is distributed in the hope that it will be useful, but WITHOUT
-+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
-+ License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with GCC; see the file COPYING3. If not see
-+ <http://www.gnu.org/licenses/>. */
-+
-+/* Don't assume anything about the header files. */
-+#define NO_IMPLICIT_EXTERN_C
-+
-+#undef LIB_SPEC
-+#define LIB_SPEC \
-+ "%{pthread:-lpthread} " \
-+ "%{!shared:%{!symbolic: -lc}} "
-+
-+
-+#undef LINK_GCC_C_SEQUENCE_SPEC
-+#define LINK_GCC_C_SEQUENCE_SPEC \
-+ "%{!shared:--start-group} %G %L %{!shared:--end-group}%{shared:%G} "
-+
-+#undef STARTFILE_SPEC
-+#define STARTFILE_SPEC \
-+ "%{!shared: crt1%O%s}" \
-+ " crti%O%s crtbegin%O%s"
-+
-+#undef ENDFILE_SPEC
-+#define ENDFILE_SPEC "crtend%O%s crtn%O%s"
-+
-+/* This macro applies on top of OBJECT_FORMAT_ELF and indicates that
-+ we want to support both flat and ELF output. */
-+#define OBJECT_FORMAT_FLAT
-+
-+#undef DRIVER_SELF_SPECS
-+#define DRIVER_SELF_SPECS \
-+ "%{!mno-fastcall:-mfastcall}"
-+
-+/* taken from linux.h */
-+/* The GNU C++ standard library requires that these macros be defined. */
-+#undef CPLUSPLUS_CPP_SPEC
-+#define CPLUSPLUS_CPP_SPEC "-D_GNU_SOURCE %(cpp)"
-+
-+#define TARGET_OS_CPP_BUILTINS() \
-+ do { \
-+ builtin_define_std ("__UBICOM32__"); \
-+ builtin_define_std ("__ubicom32__"); \
-+ builtin_define ("__gnu_linux__"); \
-+ builtin_define_std ("linux"); \
-+ builtin_define_std ("unix"); \
-+ builtin_assert ("system=linux"); \
-+ builtin_assert ("system=unix"); \
-+ builtin_assert ("system=posix"); \
-+ } while (0)
---- /dev/null
-+++ b/gcc/config/ubicom32/xm-ubicom32.h
-@@ -0,0 +1,36 @@
-+/* Configuration for Ubicom's Ubicom32 architecture.
-+ Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Free Software
-+ Foundation, Inc.
-+ Contributed by Ubicom Inc.
-+
-+This file is part of GNU CC.
-+
-+GNU CC is free software; you can redistribute it and/or modify
-+it under the terms of the GNU General Public License as published by
-+the Free Software Foundation; either version 2, or (at your option)
-+any later version.
-+
-+GNU CC is distributed in the hope that it will be useful,
-+but WITHOUT ANY WARRANTY; without even the implied warranty of
-+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+GNU General Public License for more details.
-+
-+You should have received a copy of the GNU General Public License
-+along with GNU CC; see the file COPYING. If not, write to
-+the Free Software Foundation, 59 Temple Place - Suite 330,
-+Boston, MA 02111-1307, USA. */
-+
-+/* #defines that need visibility everywhere. */
-+#define FALSE 0
-+#define TRUE 1
-+
-+/* This describes the machine the compiler is hosted on. */
-+#define HOST_BITS_PER_CHAR 8
-+#define HOST_BITS_PER_SHORT 16
-+#define HOST_BITS_PER_INT 32
-+#define HOST_BITS_PER_LONG 32
-+#define HOST_BITS_PER_LONGLONG 64
-+
-+/* Arguments to use with `exit'. */
-+#define SUCCESS_EXIT_CODE 0
-+#define FATAL_EXIT_CODE 33
---- a/gcc/config.gcc
-+++ b/gcc/config.gcc
-@@ -2314,6 +2314,34 @@ spu-*-elf*)
- c_target_objs="${c_target_objs} spu-c.o"
- cxx_target_objs="${cxx_target_objs} spu-c.o"
- ;;
-+ubicom32-*-elf)
-+ xm_file=ubicom32/xm-ubicom32.h
-+ tm_file="${tm_file} ubicom32/elf.h" # still need dbxelf.h elfos.h
-+ tmake_file=ubicom32/t-ubicom32
-+ ;;
-+ubicom32-*-uclinux*)
-+ xm_file=ubicom32/xm-ubicom32.h
-+ tm_file="${tm_file} ubicom32/elf.h ubicom32/uclinux.h" # still need dbxelf.h elfos.h linux.h
-+ tm_defines="${tm_defines} UCLIBC_DEFAULT=1"
-+ extra_options="${extra_options} linux.opt"
-+ tmake_file=ubicom32/t-ubicom32-uclinux
-+ use_collect2=no
-+ ;;
-+ubicom32-*-linux-uclibc)
-+ xm_file=ubicom32/xm-ubicom32.h
-+ tm_file="${tm_file} ubicom32/elf.h linux.h ubicom32/linux.h" # still need dbxelf.h elfos.h
-+ tmake_file="t-slibgcc-elf-ver ubicom32/t-ubicom32-linux"
-+ extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
-+ use_collect2=no
-+ ;;
-+ubicom32-*-linux*)
-+ xm_file=ubicom32/xm-ubicom32.h
-+ tm_file="${tm_file} ubicom32/elf.h linux.h ubicom32/linux.h" # still need dbxelf.h elfos.h
-+ tmake_file="t-slibgcc-elf-ver ubicom32/t-ubicom32-linux"
-+ tm_defines="${tm_defines} UCLIBC_DEFAULT=1"
-+ extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
-+ use_collect2=no
-+ ;;
- v850e1-*-*)
- target_cpu_default="TARGET_CPU_v850e1"
- tm_file="dbxelf.h elfos.h svr4.h v850/v850.h"
---- a/libgcc/config.host
-+++ b/libgcc/config.host
-@@ -551,6 +551,15 @@ sparc64-*-netbsd*)
- ;;
- spu-*-elf*)
- ;;
-+ubicom32*-*-elf*)
-+ ;;
-+ubicom32*-*-uclinux*)
-+ ;;
-+ubicom32*-*-linux*)
-+ # No need to build crtbeginT.o on uClibc systems. Should probably
-+ # be moved to the OS specific section above.
-+ extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
-+ ;;
- v850e1-*-*)
- ;;
- v850e-*-*)
+++ /dev/null
---- a/gcc/config/arm/linux-elf.h
-+++ b/gcc/config/arm/linux-elf.h
-@@ -60,7 +60,7 @@
- %{shared:-lc} \
- %{!shared:%{profile:-lc_p}%{!profile:-lc}}"
-
--#define LIBGCC_SPEC "%{msoft-float:-lfloat} %{mfloat-abi=soft*:-lfloat} -lgcc"
-+#define LIBGCC_SPEC "-lgcc"
-
- #define GLIBC_DYNAMIC_LINKER "/lib/ld-linux.so.2"
-
---- a/gcc/config/arm/t-linux
-+++ b/gcc/config/arm/t-linux
-@@ -4,7 +4,10 @@
-
- LIB1ASMSRC = arm/lib1funcs.asm
- LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_lnx _clzsi2 _clzdi2 \
-- _arm_addsubdf3 _arm_addsubsf3
-+ _arm_addsubdf3 _arm_addsubsf3 \
-+ _negdf2 _addsubdf3 _muldivdf3 _cmpdf2 _unorddf2 _fixdfsi _fixunsdfsi \
-+ _truncdfsf2 _negsf2 _addsubsf3 _muldivsf3 _cmpsf2 _unordsf2 \
-+ _fixsfsi _fixunssfsi _floatdidf _floatundidf _floatdisf _floatundisf
-
- # MULTILIB_OPTIONS = mhard-float/msoft-float
- # MULTILIB_DIRNAMES = hard-float soft-float
+++ /dev/null
---- a/libgcc/Makefile.in
-+++ b/libgcc/Makefile.in
-@@ -729,11 +729,12 @@ $(libgcov-objects): %$(objext): $(gcc_sr
-
- # Static libraries.
- libgcc.a: $(libgcc-objects)
-+libgcc_pic.a: $(libgcc-s-objects)
- libgcov.a: $(libgcov-objects)
- libunwind.a: $(libunwind-objects)
- libgcc_eh.a: $(libgcc-eh-objects)
-
--libgcc.a libgcov.a libunwind.a libgcc_eh.a:
-+libgcc.a libgcov.a libunwind.a libgcc_eh.a libgcc_pic.a:
- -rm -f $@
-
- objects="$(objects)"; \
-@@ -755,7 +756,7 @@ libgcc_s$(SHLIB_EXT): libunwind$(SHLIB_E
- endif
-
- ifeq ($(enable_shared),yes)
--all: libgcc_eh.a libgcc_s$(SHLIB_EXT)
-+all: libgcc_eh.a libgcc_pic.a libgcc_s$(SHLIB_EXT)
- ifneq ($(LIBUNWIND),)
- all: libunwind$(SHLIB_EXT)
- endif
-@@ -928,6 +929,10 @@ install-shared:
- chmod 644 $(DESTDIR)$(inst_libdir)/libgcc_eh.a
- $(RANLIB) $(DESTDIR)$(inst_libdir)/libgcc_eh.a
-
-+ $(INSTALL_DATA) libgcc_pic.a $(mapfile) $(DESTDIR)$(inst_libdir)/
-+ chmod 644 $(DESTDIR)$(inst_libdir)/libgcc_pic.a
-+ $(RANLIB) $(DESTDIR)$(inst_libdir)/libgcc_pic.a
-+
- $(subst @multilib_dir@,$(MULTIDIR),$(subst \
- @shlib_base_name@,libgcc_s,$(subst \
- @shlib_slibdir_qual@,$(MULTIOSSUBDIR),$(SHLIB_INSTALL))))
+++ /dev/null
-
- This patch brings over a few features from MirBSD:
- * -fhonour-copts
- If this option is not given, it's warned (depending
- on environment variables). This is to catch errors
- of misbuilt packages which override CFLAGS themselves.
- * Make -fno-strict-aliasing and -fno-delete-null-pointer-checks
- the default for -O2/-Os, because they trigger gcc bugs
- and can delete code with security implications.
-
- This patch was authored by Thorsten Glaser <tg at mirbsd.de>
- with copyright assignment to the FSF in effect.
-
---- a/gcc/c-opts.c
-+++ b/gcc/c-opts.c
-@@ -105,6 +105,9 @@
- /* Number of deferred options scanned for -include. */
- static size_t include_cursor;
-
-+/* Check if a port honours COPTS. */
-+static int honour_copts = 0;
-+
- static void set_Wimplicit (int);
- static void handle_OPT_d (const char *);
- static void set_std_cxx98 (int);
-@@ -690,6 +701,12 @@
- flag_exceptions = value;
- break;
-
-+ case OPT_fhonour_copts:
-+ if (c_language == clk_c) {
-+ honour_copts++;
-+ }
-+ break;
-+
- case OPT_fimplement_inlines:
- flag_implement_inlines = value;
- break;
-@@ -1209,6 +1226,47 @@
- return false;
- }
-
-+ if (c_language == clk_c) {
-+ char *ev = getenv ("GCC_HONOUR_COPTS");
-+ int evv;
-+ if (ev == NULL)
-+ evv = -1;
-+ else if ((*ev == '0') || (*ev == '\0'))
-+ evv = 0;
-+ else if (*ev == '1')
-+ evv = 1;
-+ else if (*ev == '2')
-+ evv = 2;
-+ else if (*ev == 's')
-+ evv = -1;
-+ else {
-+ warning (0, "unknown GCC_HONOUR_COPTS value, assuming 1");
-+ evv = 1; /* maybe depend this on something like MIRBSD_NATIVE? */
-+ }
-+ if (evv == 1) {
-+ if (honour_copts == 0) {
-+ error ("someone does not honour COPTS at all in lenient mode");
-+ return false;
-+ } else if (honour_copts != 1) {
-+ warning (0, "someone does not honour COPTS correctly, passed %d times",
-+ honour_copts);
-+ }
-+ } else if (evv == 2) {
-+ if (honour_copts == 0) {
-+ error ("someone does not honour COPTS at all in strict mode");
-+ return false;
-+ } else if (honour_copts != 1) {
-+ error ("someone does not honour COPTS correctly, passed %d times",
-+ honour_copts);
-+ return false;
-+ }
-+ } else if (evv == 0) {
-+ if (honour_copts != 1)
-+ inform (0, "someone does not honour COPTS correctly, passed %d times",
-+ honour_copts);
-+ }
-+ }
-+
- return true;
- }
-
---- a/gcc/c.opt
-+++ b/gcc/c.opt
-@@ -609,6 +613,9 @@
- fhonor-std
- C++ ObjC++
-
-+fhonour-copts
-+C ObjC C++ ObjC++ RejectNegative
-+
- fhosted
- C ObjC
- Assume normal C execution environment
---- a/gcc/common.opt
-+++ b/gcc/common.opt
-@@ -573,6 +577,9 @@
- Common Report Var(flag_guess_branch_prob) Optimization
- Enable guessing of branch probabilities
-
-+fhonour-copts
-+Common RejectNegative
-+
- ; Nonzero means ignore `#ident' directives. 0 means handle them.
- ; Generate position-independent code for executables if possible
- ; On SVR4 targets, it also controls whether or not to emit a
---- a/gcc/opts.c
-+++ b/gcc/opts.c
-@@ -896,9 +896,6 @@
- flag_schedule_insns_after_reload = opt2;
- #endif
- flag_regmove = opt2;
-- flag_strict_aliasing = opt2;
-- flag_strict_overflow = opt2;
-- flag_delete_null_pointer_checks = opt2;
- flag_reorder_blocks = opt2;
- flag_reorder_functions = opt2;
- flag_tree_vrp = opt2;
-@@ -922,6 +919,9 @@
-
- /* -O3 optimizations. */
- opt3 = (optimize >= 3);
-+ flag_strict_aliasing = opt3;
-+ flag_strict_overflow = opt3;
-+ flag_delete_null_pointer_checks = opt3;
- flag_predictive_commoning = opt3;
- flag_inline_functions = opt3;
- flag_unswitch_loops = opt3;
-@@ -1607,6 +1607,9 @@
- enable_warning_as_error (arg, value, lang_mask);
- break;
-
-+ case OPT_fhonour_copts:
-+ break;
-+
- case OPT_Wextra:
- set_Wextra (value);
- break;
---- a/gcc/doc/invoke.texi
-+++ b/gcc/doc/invoke.texi
-@@ -5699,7 +5715,7 @@
- second branch or a point immediately following it, depending on whether
- the condition is known to be true or false.
-
--Enabled at levels @option{-O2}, @option{-O3}, @option{-Os}.
-+Enabled at levels @option{-O3}.
-
- @item -fsplit-wide-types
- @opindex fsplit-wide-types
-@@ -5844,7 +5860,7 @@
- @option{-fno-delete-null-pointer-checks} to disable this optimization
- for programs which depend on that behavior.
-
--Enabled at levels @option{-O2}, @option{-O3}, @option{-Os}.
-+Enabled at levels @option{-O3}.
-
- @item -fexpensive-optimizations
- @opindex fexpensive-optimizations
---- a/gcc/java/jvspec.c
-+++ b/gcc/java/jvspec.c
-@@ -670,6 +670,7 @@
- class name. Append dummy `.c' that can be stripped by set_input so %b
- is correct. */
- set_input (concat (main_class_name, "main.c", NULL));
-+ putenv ("GCC_HONOUR_COPTS=s"); /* XXX hack! */
- err = do_spec (jvgenmain_spec);
- if (err == 0)
- {
+++ /dev/null
---- gcc-4.4.0/gcc/config/arm/arm-protos.h 2009-02-20 16:20:38.000000000 +0100
-+++ gcc-4.4.0.new/gcc/config/arm/arm-protos.h 2009-04-22 16:00:58.000000000 +0200
-@@ -43,10 +43,10 @@
- extern void arm_output_fn_unwind (FILE *, bool);
-
-
--#ifdef RTX_CODE
- extern bool arm_vector_mode_supported_p (enum machine_mode);
- extern int arm_hard_regno_mode_ok (unsigned int, enum machine_mode);
- extern int const_ok_for_arm (HOST_WIDE_INT);
-+#ifdef RTX_CODE
- extern int arm_split_constant (RTX_CODE, enum machine_mode, rtx,
- HOST_WIDE_INT, rtx, rtx, int);
- extern RTX_CODE arm_canonicalize_comparison (RTX_CODE, enum machine_mode,
+++ /dev/null
-Index: gcc-4.4.2/gcc/config.gcc
-===================================================================
---- gcc-4.4.2.orig/gcc/config.gcc 2009-10-21 16:19:39.000000000 +0200
-+++ gcc-4.4.2/gcc/config.gcc 2009-10-21 16:19:40.000000000 +0200
-@@ -1506,6 +1506,7 @@
- if test x$sjlj != x1; then
- tmake_file="$tmake_file m68k/t-slibgcc-elf-ver"
- fi
-+ tmake_file="m68k/t-floatlib m68k/t-m68kbare m68k/t-m68kelf"
- ;;
- m68k-*-rtems*)
- default_m68k_cpu=68020
+++ /dev/null
---- a/contrib/regression/objs-gcc.sh
-+++ b/contrib/regression/objs-gcc.sh
-@@ -106,6 +106,10 @@
- then
- make all-gdb all-dejagnu all-ld || exit 1
- make install-gdb install-dejagnu install-ld || exit 1
-+elif [ $H_REAL_TARGET = $H_REAL_HOST -a $H_REAL_TARGET = i686-pc-linux-uclibc ]
-+ then
-+ make all-gdb all-dejagnu all-ld || exit 1
-+ make install-gdb install-dejagnu install-ld || exit 1
- elif [ $H_REAL_TARGET = $H_REAL_HOST ] ; then
- make bootstrap || exit 1
- make install || exit 1
---- a/libjava/classpath/ltconfig
-+++ b/libjava/classpath/ltconfig
-@@ -603,7 +603,7 @@
-
- # Transform linux* to *-*-linux-gnu*, to support old configure scripts.
- case $host_os in
--linux-gnu*) ;;
-+linux-gnu*|linux-uclibc*) ;;
- linux*) host=`echo $host | sed 's/^\(.*-.*-linux\)\(.*\)$/\1-gnu\2/'`
- esac
-
-@@ -1251,7 +1251,7 @@
- ;;
-
- # This must be Linux ELF.
--linux-gnu*)
-+linux*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
+++ /dev/null
---- a/boehm-gc/include/gc.h
-+++ b/boehm-gc/include/gc.h
-@@ -503,7 +503,7 @@
- #if defined(__linux__) || defined(__GLIBC__)
- # include <features.h>
- # if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1 || __GLIBC__ > 2) \
-- && !defined(__ia64__)
-+ && !defined(__ia64__) && !defined(__UCLIBC__)
- # ifndef GC_HAVE_BUILTIN_BACKTRACE
- # define GC_HAVE_BUILTIN_BACKTRACE
- # endif
+++ /dev/null
---- a/libstdc++-v3/include/c_global/cstdio
-+++ b/libstdc++-v3/include/c_global/cstdio
-@@ -139,7 +139,7 @@
-
- _GLIBCXX_END_NAMESPACE
-
--#if _GLIBCXX_USE_C99
-+#if _GLIBCXX_USE_C99 || defined __UCLIBC__
-
- #undef snprintf
- #undef vfscanf
+++ /dev/null
---- a/libmudflap/mf-hooks2.c
-+++ b/libmudflap/mf-hooks2.c
-@@ -421,7 +421,7 @@
- {
- TRACE ("%s\n", __PRETTY_FUNCTION__);
- MF_VALIDATE_EXTENT(s, n, __MF_CHECK_WRITE, "bzero region");
-- bzero (s, n);
-+ memset (s, 0, n);
- }
-
-
-@@ -431,7 +431,7 @@
- TRACE ("%s\n", __PRETTY_FUNCTION__);
- MF_VALIDATE_EXTENT(src, n, __MF_CHECK_READ, "bcopy src");
- MF_VALIDATE_EXTENT(dest, n, __MF_CHECK_WRITE, "bcopy dest");
-- bcopy (src, dest, n);
-+ memmove (dest, src, n);
- }
-
-
-@@ -441,7 +441,7 @@
- TRACE ("%s\n", __PRETTY_FUNCTION__);
- MF_VALIDATE_EXTENT(s1, n, __MF_CHECK_READ, "bcmp 1st arg");
- MF_VALIDATE_EXTENT(s2, n, __MF_CHECK_READ, "bcmp 2nd arg");
-- return bcmp (s1, s2, n);
-+ return n == 0 ? 0 : memcmp (s1, s2, n);
- }
-
-
-@@ -450,7 +450,7 @@
- size_t n = strlen (s);
- TRACE ("%s\n", __PRETTY_FUNCTION__);
- MF_VALIDATE_EXTENT(s, CLAMPADD(n, 1), __MF_CHECK_READ, "index region");
-- return index (s, c);
-+ return strchr (s, c);
- }
-
-
-@@ -459,7 +459,7 @@
- size_t n = strlen (s);
- TRACE ("%s\n", __PRETTY_FUNCTION__);
- MF_VALIDATE_EXTENT(s, CLAMPADD(n, 1), __MF_CHECK_READ, "rindex region");
-- return rindex (s, c);
-+ return strrchr (s, c);
- }
-
- /* XXX: stpcpy, memccpy */
+++ /dev/null
---- a/configure
-+++ b/configure
-@@ -2688,6 +2688,9 @@ case "${target}" in
- ip2k-*-*)
- noconfigdirs="$noconfigdirs target-libiberty target-libstdc++-v3 ${libgcj}"
- ;;
-+ ubicom32-*-*)
-+ noconfigdirs="$noconfigdirs target-libffi"
-+ ;;
- *-*-linux* | *-*-gnu* | *-*-k*bsd*-gnu | *-*-kopensolaris*-gnu)
- noconfigdirs="$noconfigdirs target-newlib target-libgloss"
- ;;
---- /dev/null
-+++ b/gcc/config/ubicom32/constraints.md
-@@ -0,0 +1,149 @@
-+; Constraint definitions for Ubicom32
-+
-+; Copyright (C) 2009 Free Software Foundation, Inc.
-+; Contributed by Ubicom, Inc.
-+
-+; This file is part of GCC.
-+
-+; GCC is free software; you can redistribute it and/or modify it
-+; under the terms of the GNU General Public License as published
-+; by the Free Software Foundation; either version 3, or (at your
-+; option) any later version.
-+
-+; GCC is distributed in the hope that it will be useful, but WITHOUT
-+; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-+; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
-+; License for more details.
-+
-+; You should have received a copy of the GNU General Public License
-+; along with GCC; see the file COPYING3. If not see
-+; <http://www.gnu.org/licenses/>.
-+
-+(define_register_constraint "a" "ALL_ADDRESS_REGS"
-+ "An An register.")
-+
-+(define_register_constraint "d" "DATA_REGS"
-+ "A Dn register.")
-+
-+(define_register_constraint "h" "ACC_REGS"
-+ "An accumulator register.")
-+
-+(define_register_constraint "l" "ACC_LO_REGS"
-+ "An accn_lo register.")
-+
-+(define_register_constraint "Z" "FDPIC_REG"
-+ "The FD-PIC GOT pointer: A0.")
-+
-+(define_constraint "I"
-+ "An 8-bit signed constant value."
-+ (and (match_code "const_int")
-+ (match_test "(ival >= -128) && (ival <= 127)")))
-+
-+(define_constraint "Q"
-+ "An 8-bit signed constant value represented as unsigned."
-+ (and (match_code "const_int")
-+ (match_test "(ival >= 0x00) && (ival <= 0xff)")))
-+
-+(define_constraint "R"
-+ "An 8-bit signed constant value represented as unsigned."
-+ (and (match_code "const_int")
-+ (match_test "((ival >= 0x0000) && (ival <= 0x007f)) || ((ival >= 0xff80) && (ival <= 0xffff))")))
-+
-+(define_constraint "J"
-+ "A 7-bit unsigned constant value."
-+ (and (match_code "const_int")
-+ (match_test "(ival >= 0) && (ival <= 127)")))
-+
-+(define_constraint "K"
-+ "A 7-bit unsigned constant value shifted << 1."
-+ (and (match_code "const_int")
-+ (match_test "(ival >= 0) && (ival <= 254) && ((ival & 1) == 0)")))
-+
-+(define_constraint "L"
-+ "A 7-bit unsigned constant value shifted << 2."
-+ (and (match_code "const_int")
-+ (match_test "(ival >= 0) && (ival <= 508) && ((ival & 3) == 0)")))
-+
-+(define_constraint "M"
-+ "A 5-bit unsigned constant value."
-+ (and (match_code "const_int")
-+ (match_test "(ival >= 0) && (ival <= 31)")))
-+
-+(define_constraint "N"
-+ "A signed 16 bit constant value."
-+ (and (match_code "const_int")
-+ (match_test "(ival >= -32768) && (ival <= 32767)")))
-+
-+(define_constraint "O"
-+ "An exact bitmask of contiguous 1 bits starting at bit 0."
-+ (and (match_code "const_int")
-+ (match_test "exact_log2 (ival + 1) != -1")))
-+
-+(define_constraint "P"
-+ "A 7-bit negative constant value shifted << 2."
-+ (and (match_code "const_int")
-+ (match_test "(ival >= -504) && (ival <= 0) && ((ival & 3) == 0)")))
-+
-+(define_constraint "S"
-+ "A symbolic reference."
-+ (match_code "symbol_ref"))
-+
-+(define_constraint "Y"
-+ "An FD-PIC symbolic reference."
-+ (and (match_test "TARGET_FDPIC")
-+ (match_test "GET_CODE (op) == UNSPEC")
-+ (ior (match_test "XINT (op, 1) == UNSPEC_FDPIC_GOT")
-+ (match_test "XINT (op, 1) == UNSPEC_FDPIC_GOT_FUNCDESC"))))
-+
-+(define_memory_constraint "T1"
-+ "A memory operand that can be used for .1 instruction."
-+ (and (match_test "memory_operand (op, GET_MODE(op))")
-+ (match_test "GET_MODE (op) == QImode")))
-+
-+(define_memory_constraint "T2"
-+ "A memory operand that can be used for .2 instruction."
-+ (and (match_test "memory_operand (op, GET_MODE(op))")
-+ (match_test "GET_MODE (op) == HImode")))
-+
-+(define_memory_constraint "T4"
-+ "A memory operand that can be used for .4 instruction."
-+ (and (match_test "memory_operand (op, GET_MODE(op))")
-+ (ior (match_test "GET_MODE (op) == SImode")
-+ (match_test "GET_MODE (op) == DImode")
-+ (match_test "GET_MODE (op) == SFmode"))))
-+
-+(define_memory_constraint "U1"
-+ "An offsettable memory operand that can be used for .1 instruction."
-+ (and (match_test "memory_operand (op, GET_MODE(op))")
-+ (match_test "GET_MODE (op) == QImode")
-+ (match_test "GET_CODE (XEXP (op, 0)) != POST_INC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_INC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != POST_DEC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_DEC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != POST_MODIFY")
-+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_MODIFY")))
-+
-+(define_memory_constraint "U2"
-+ "An offsettable memory operand that can be used for .2 instruction."
-+ (and (match_test "memory_operand (op, GET_MODE(op))")
-+ (match_test "GET_MODE (op) == HImode")
-+ (match_test "GET_CODE (XEXP (op, 0)) != POST_INC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_INC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != POST_DEC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_DEC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != POST_MODIFY")
-+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_MODIFY")))
-+
-+(define_memory_constraint "U4"
-+ "An offsettable memory operand that can be used for .4 instruction."
-+ (and (match_test "memory_operand (op, GET_MODE(op))")
-+ (ior (match_test "GET_MODE (op) == SImode")
-+ (match_test "GET_MODE (op) == DImode")
-+ (match_test "GET_MODE (op) == SFmode"))
-+ (match_test "GET_CODE (XEXP (op, 0)) != POST_INC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_INC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != POST_DEC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_DEC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != POST_MODIFY")
-+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_MODIFY")))
-+
---- /dev/null
-+++ b/gcc/config/ubicom32/crti.S
-@@ -0,0 +1,54 @@
-+/* Specialized code needed to support construction and destruction of
-+ file-scope objects in C++ and Java code, and to support exception handling.
-+ Copyright (C) 1999 Free Software Foundation, Inc.
-+ Contributed by Charles-Antoine Gauthier (charles.gauthier@iit.nrc.ca).
-+
-+This file is part of GCC.
-+
-+GCC is free software; you can redistribute it and/or modify
-+it under the terms of the GNU General Public License as published by
-+the Free Software Foundation; either version 2, or (at your option)
-+any later version.
-+
-+GCC is distributed in the hope that it will be useful,
-+but WITHOUT ANY WARRANTY; without even the implied warranty of
-+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+GNU General Public License for more details.
-+
-+You should have received a copy of the GNU General Public License
-+along with GCC; see the file COPYING. If not, write to
-+the Free Software Foundation, 59 Temple Place - Suite 330,
-+Boston, MA 02111-1307, USA. */
-+
-+/* As a special exception, if you link this library with files
-+ compiled with GCC to produce an executable, this does not cause
-+ the resulting executable to be covered by the GNU General Public License.
-+ This exception does not however invalidate any other reasons why
-+ the executable file might be covered by the GNU General Public License. */
-+
-+/*
-+ * This file just supplies function prologues for the .init and .fini
-+ * sections. It is linked in before crtbegin.o.
-+ */
-+ .file "crti.o"
-+ .ident "GNU C crti.o"
-+
-+ .section .init
-+ .align 2
-+ .globl _init
-+ .type _init, @function
-+_init:
-+ move.4 -4(sp)++, a5
-+#ifdef __UBICOM32_FDPIC__
-+ move.4 -4(sp)++, a0
-+#endif
-+
-+ .section .fini
-+ .align 2
-+ .globl _fini
-+ .type _fini, @function
-+_fini:
-+ move.4 -4(sp)++, a5
-+#ifdef __UBICOM32_FDPIC__
-+ move.4 -4(sp)++, a0
-+#endif
---- /dev/null
-+++ b/gcc/config/ubicom32/crtn.S
-@@ -0,0 +1,47 @@
-+/* Specialized code needed to support construction and destruction of
-+ file-scope objects in C++ and Java code, and to support exception handling.
-+ Copyright (C) 1999 Free Software Foundation, Inc.
-+ Contributed by Charles-Antoine Gauthier (charles.gauthier@iit.nrc.ca).
-+
-+This file is part of GCC.
-+
-+GCC is free software; you can redistribute it and/or modify
-+it under the terms of the GNU General Public License as published by
-+the Free Software Foundation; either version 2, or (at your option)
-+any later version.
-+
-+GCC is distributed in the hope that it will be useful,
-+but WITHOUT ANY WARRANTY; without even the implied warranty of
-+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+GNU General Public License for more details.
-+
-+You should have received a copy of the GNU General Public License
-+along with GCC; see the file COPYING. If not, write to
-+the Free Software Foundation, 59 Temple Place - Suite 330,
-+Boston, MA 02111-1307, USA. */
-+
-+/* As a special exception, if you link this library with files
-+ compiled with GCC to produce an executable, this does not cause
-+ the resulting executable to be covered by the GNU General Public License.
-+ This exception does not however invalidate any other reasons why
-+ the executable file might be covered by the GNU General Public License. */
-+
-+/*
-+ * This file supplies function epilogues for the .init and .fini sections.
-+ * It is linked in after all other files.
-+ */
-+
-+ .file "crtn.o"
-+ .ident "GNU C crtn.o"
-+
-+ .section .init
-+#ifdef __UBICOM32_FDPIC__
-+ move.4 a0, (sp)4++
-+#endif
-+ ret (sp)4++
-+
-+ .section .fini
-+#ifdef __UBICOM32_FDPIC__
-+ move.4 a0, (sp)4++
-+#endif
-+ ret (sp)4++
---- /dev/null
-+++ b/gcc/config/ubicom32/elf.h
-@@ -0,0 +1,29 @@
-+#undef STARTFILE_SPEC
-+#define STARTFILE_SPEC "\
-+%{msim:%{!shared:crt0%O%s}} \
-+crti%O%s crtbegin%O%s"
-+
-+#undef ENDFILE_SPEC
-+#define ENDFILE_SPEC "crtend%O%s crtn%O%s"
-+
-+#ifdef __UBICOM32_FDPIC__
-+#define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC) \
-+ asm (SECTION_OP); \
-+ asm ("move.4 a0, 0(sp);\n\t" \
-+ "call a5," USER_LABEL_PREFIX #FUNC ";"); \
-+ asm (TEXT_SECTION_ASM_OP);
-+#endif
-+
-+#undef SUBTARGET_DRIVER_SELF_SPECS
-+#define SUBTARGET_DRIVER_SELF_SPECS \
-+ "%{mfdpic:-msim} "
-+
-+#define NO_IMPLICIT_EXTERN_C
-+
-+/*
-+ * We need this to compile crtbegin/crtend. This should really be picked
-+ * up from elfos.h but at the moment including elfos.h causes other more
-+ * serous linker issues.
-+ */
-+#define INIT_SECTION_ASM_OP "\t.section\t.init"
-+#define FINI_SECTION_ASM_OP "\t.section\t.fini"
---- /dev/null
-+++ b/gcc/config/ubicom32/linux.h
-@@ -0,0 +1,80 @@
-+/* Definitions of target machine for Ubicom32-uclinux
-+
-+ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
-+ 2009 Free Software Foundation, Inc.
-+ Contributed by Ubicom, Inc.
-+
-+ This file is part of GCC.
-+
-+ GCC is free software; you can redistribute it and/or modify it
-+ under the terms of the GNU General Public License as published
-+ by the Free Software Foundation; either version 3, or (at your
-+ option) any later version.
-+
-+ GCC is distributed in the hope that it will be useful, but WITHOUT
-+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
-+ License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with GCC; see the file COPYING3. If not see
-+ <http://www.gnu.org/licenses/>. */
-+
-+/* Don't assume anything about the header files. */
-+#define NO_IMPLICIT_EXTERN_C
-+
-+#undef LIB_SPEC
-+#define LIB_SPEC \
-+ "%{pthread:-lpthread} " \
-+ "-lc"
-+
-+#undef LINK_GCC_C_SEQUENCE_SPEC
-+#define LINK_GCC_C_SEQUENCE_SPEC \
-+ "%{static:--start-group} %G %L %{static:--end-group} " \
-+ "%{!static: %G}"
-+
-+#undef STARTFILE_SPEC
-+#define STARTFILE_SPEC \
-+ "%{!shared: %{pg|p|profile:gcrt1%O%s;pie:Scrt1%O%s;:crt1%O%s}} " \
-+ "crtreloc%O%s crti%O%s %{shared|pie:crtbeginS%O%s;:crtbegin%O%s}"
-+
-+#undef ENDFILE_SPEC
-+#define ENDFILE_SPEC \
-+ "%{shared|pie:crtendS%O%s;:crtend%O%s} crtn%O%s"
-+
-+/* taken from linux.h */
-+/* The GNU C++ standard library requires that these macros be defined. */
-+#undef CPLUSPLUS_CPP_SPEC
-+#define CPLUSPLUS_CPP_SPEC "-D_GNU_SOURCE %(cpp)"
-+
-+#define TARGET_OS_CPP_BUILTINS() \
-+ do { \
-+ builtin_define_std ("__UBICOM32__"); \
-+ builtin_define_std ("__ubicom32__"); \
-+ builtin_define ("__gnu_linux__"); \
-+ builtin_define_std ("linux"); \
-+ builtin_define_std ("unix"); \
-+ builtin_assert ("system=linux"); \
-+ builtin_assert ("system=unix"); \
-+ builtin_assert ("system=posix"); \
-+ } while (0)
-+
-+#define OBJECT_FORMAT_ELF
-+
-+
-+#undef DRIVER_SELF_SPECS
-+#define DRIVER_SELF_SPECS \
-+ "%{!mno-fdpic:-mfdpic}"
-+
-+#undef LINK_SPEC
-+#define LINK_SPEC "%{mfdpic: -m elf32ubicom32fdpic -z text } %{shared} %{pie} \
-+ %{static:-dn -Bstatic} \
-+ %{shared:-G -Bdynamic} \
-+ %{!shared: %{!static: \
-+ %{rdynamic:-export-dynamic} \
-+ %{!dynamic-linker:-dynamic-linker /lib/ld-uClibc.so.0}} \
-+ %{static}} "
-+
-+/*
-+#define MD_UNWIND_SUPPORT "config/bfin/linux-unwind.h"
-+*/
---- /dev/null
-+++ b/gcc/config/ubicom32/predicates.md
-@@ -0,0 +1,327 @@
-+; Predicate definitions for Ubicom32.
-+
-+; Copyright (C) 2009 Free Software Foundation, Inc.
-+; Contributed by Ubicom, Inc.
-+
-+; This file is part of GCC.
-+
-+; GCC is free software; you can redistribute it and/or modify it
-+; under the terms of the GNU General Public License as published
-+; by the Free Software Foundation; either version 3, or (at your
-+; option) any later version.
-+
-+; GCC is distributed in the hope that it will be useful, but WITHOUT
-+; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-+; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
-+; License for more details.
-+
-+; You should have received a copy of the GNU General Public License
-+; along with GCC; see the file COPYING3. If not see
-+; <http://www.gnu.org/licenses/>.
-+
-+(define_predicate "ubicom32_move_operand"
-+ (match_code "const_int, const_double, const, mem, subreg, reg, lo_sum")
-+{
-+ if (CONST_INT_P (op))
-+ return true;
-+
-+ if (GET_CODE (op) == CONST_DOUBLE)
-+ return true;
-+
-+ if (GET_CODE (op) == CONST)
-+ return memory_address_p (mode, op);
-+
-+ if (GET_MODE (op) != mode)
-+ return false;
-+
-+ if (MEM_P (op))
-+ return memory_address_p (mode, XEXP (op, 0));
-+
-+ if (GET_CODE (op) == SUBREG) {
-+ op = SUBREG_REG (op);
-+
-+ if (REG_P (op))
-+ return true;
-+
-+ if (! MEM_P (op))
-+ return false;
-+
-+ /* Paradoxical SUBREG. */
-+ if (GET_MODE_SIZE (mode) > GET_MODE_SIZE (GET_MODE (op)))
-+ return false;
-+
-+ return memory_address_p (GET_MODE (op), XEXP (op, 0));
-+ }
-+
-+ return register_operand (op, mode);
-+})
-+
-+;; Returns true if OP is either a symbol reference or a sum of a
-+;; symbol reference and a constant.
-+
-+(define_predicate "ubicom32_symbolic_address_operand"
-+ (match_code "symbol_ref, label_ref, const")
-+{
-+ switch (GET_CODE (op))
-+ {
-+ case SYMBOL_REF:
-+ case LABEL_REF:
-+ return true;
-+
-+ case CONST:
-+ op = XEXP (op, 0);
-+ return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
-+ || GET_CODE (XEXP (op, 0)) == LABEL_REF)
-+ && CONST_INT_P (XEXP (op, 1)));
-+
-+ default:
-+ return false;
-+ }
-+})
-+
-+;; Return true if operand is the uClinux FD-PIC register.
-+
-+(define_predicate "ubicom32_fdpic_operand"
-+ (match_code "reg")
-+{
-+ if (! TARGET_FDPIC)
-+ return false;
-+
-+ if (!REG_P (op))
-+ return false;
-+
-+ if (GET_MODE (op) != mode && mode != VOIDmode)
-+ return false;
-+
-+ if (REGNO (op) != FDPIC_REGNUM && REGNO (op) < FIRST_PSEUDO_REGISTER)
-+ return false;
-+
-+ return true;
-+})
-+
-+(define_predicate "ubicom32_fdpic_got_offset_operand"
-+ (match_code "unspec")
-+{
-+ if (! TARGET_FDPIC)
-+ return false;
-+
-+ if (GET_CODE (op) != UNSPEC)
-+ return false;
-+
-+ if (XINT (op, 1) != UNSPEC_FDPIC_GOT
-+ && XINT (op, 1) != UNSPEC_FDPIC_GOT_FUNCDESC)
-+ return false;
-+
-+ return true;
-+})
-+
-+(define_predicate "ubicom32_arith_operand"
-+ (match_code "subreg, reg, const_int, lo_sum, mem")
-+{
-+ return (ubicom32_move_operand (op, mode)
-+ && ! ubicom32_symbolic_address_operand (op, mode)
-+ && (! CONST_INT_P (op)
-+ || satisfies_constraint_I (op)));
-+})
-+
-+(define_predicate "ubicom32_arith_operand_dot1"
-+ (match_code "subreg, reg, const_int, lo_sum, mem")
-+{
-+ return (ubicom32_move_operand (op, mode)
-+ && ! ubicom32_symbolic_address_operand (op, mode)
-+ && (! CONST_INT_P (op)
-+ || satisfies_constraint_Q (op)));
-+})
-+
-+(define_predicate "ubicom32_arith_operand_dot2"
-+ (match_code "subreg, reg, const_int, lo_sum, mem")
-+{
-+ return (ubicom32_move_operand (op, mode)
-+ && ! ubicom32_symbolic_address_operand (op, mode)
-+ && (! CONST_INT_P (op)
-+ || satisfies_constraint_R (op)));
-+})
-+
-+(define_predicate "ubicom32_compare_operand"
-+ (match_code "subreg, reg, const_int, lo_sum, mem")
-+{
-+ return (ubicom32_move_operand (op, mode)
-+ && ! ubicom32_symbolic_address_operand (op, mode)
-+ && (! CONST_INT_P (op)
-+ || satisfies_constraint_N (op)));
-+})
-+
-+(define_predicate "ubicom32_compare_operator"
-+ (match_code "compare"))
-+
-+(define_predicate "ubicom32_and_or_si3_operand"
-+ (match_code "subreg, reg, const_int, lo_sum, mem")
-+{
-+ return (ubicom32_arith_operand (op, mode)
-+ || (CONST_INT_P (op)
-+ && ((exact_log2 (INTVAL (op) + 1) != -1
-+ && exact_log2 (INTVAL (op) + 1) <= 31)
-+ || (exact_log2 (INTVAL (op)) != -1
-+ && exact_log2 (INTVAL (op)) <= 31)
-+ || (exact_log2 (~INTVAL (op)) != -1
-+ && exact_log2 (~INTVAL (op)) <= 31))));
-+})
-+
-+(define_predicate "ubicom32_and_or_hi3_operand"
-+ (match_code "subreg, reg, const_int, lo_sum, mem")
-+{
-+ return (ubicom32_arith_operand (op, mode)
-+ || (CONST_INT_P (op)
-+ && exact_log2 (INTVAL (op) + 1) != -1
-+ && exact_log2 (INTVAL (op) + 1) <= 15));
-+})
-+
-+(define_predicate "ubicom32_mem_or_address_register_operand"
-+ (match_code "subreg, reg, mem")
-+{
-+ unsigned int regno;
-+
-+ if (MEM_P (op)
-+ && memory_operand (op, mode))
-+ return true;
-+
-+ if (REG_P (op))
-+ regno = REGNO (op);
-+ else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
-+ {
-+ int offset;
-+ if (REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER)
-+ offset = SUBREG_BYTE (op) / (GET_MODE_SIZE (GET_MODE (op)));
-+ else
-+ offset = subreg_regno_offset (REGNO (SUBREG_REG (op)),
-+ GET_MODE (SUBREG_REG (op)),
-+ SUBREG_BYTE (op),
-+ GET_MODE (op));
-+ regno = REGNO (SUBREG_REG (op)) + offset;
-+ }
-+ else
-+ return false;
-+
-+ return (regno >= FIRST_PSEUDO_REGISTER
-+ || REGNO_REG_CLASS (regno) == FDPIC_REG
-+ || REGNO_REG_CLASS (regno) == ADDRESS_REGS);
-+})
-+
-+(define_predicate "ubicom32_data_register_operand"
-+ (match_code "subreg, reg")
-+{
-+ unsigned int regno;
-+
-+ if (REG_P (op))
-+ regno = REGNO (op);
-+ else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
-+ {
-+ int offset;
-+ if (REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER)
-+ offset = SUBREG_BYTE (op) / (GET_MODE_SIZE (GET_MODE (op)));
-+ else
-+ offset = subreg_regno_offset (REGNO (SUBREG_REG (op)),
-+ GET_MODE (SUBREG_REG (op)),
-+ SUBREG_BYTE (op),
-+ GET_MODE (op));
-+ regno = REGNO (SUBREG_REG (op)) + offset;
-+ }
-+ else
-+ return false;
-+
-+ return ((regno >= FIRST_PSEUDO_REGISTER
-+ && regno != REGNO (virtual_stack_vars_rtx))
-+ || REGNO_REG_CLASS (regno) == DATA_REGS);
-+})
-+
-+(define_predicate "ubicom32_address_register_operand"
-+ (match_code "subreg, reg")
-+{
-+ unsigned int regno;
-+
-+ if (REG_P (op))
-+ regno = REGNO (op);
-+ else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
-+ {
-+ int offset;
-+ if (REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER)
-+ offset = SUBREG_BYTE (op) / (GET_MODE_SIZE (GET_MODE (op)));
-+ else
-+ offset = subreg_regno_offset (REGNO (SUBREG_REG (op)),
-+ GET_MODE (SUBREG_REG (op)),
-+ SUBREG_BYTE (op),
-+ GET_MODE (op));
-+ regno = REGNO (SUBREG_REG (op)) + offset;
-+ }
-+ else
-+ return false;
-+
-+ return (regno >= FIRST_PSEUDO_REGISTER
-+ || REGNO_REG_CLASS (regno) == FDPIC_REG
-+ || REGNO_REG_CLASS (regno) == ADDRESS_REGS);
-+})
-+
-+(define_predicate "ubicom32_acc_lo_register_operand"
-+ (match_code "subreg, reg")
-+{
-+ unsigned int regno;
-+
-+ if (REG_P (op))
-+ regno = REGNO (op);
-+ else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
-+ {
-+ int offset;
-+ if (REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER)
-+ offset = SUBREG_BYTE (op) / (GET_MODE_SIZE (GET_MODE (op)));
-+ else
-+ offset = subreg_regno_offset (REGNO (SUBREG_REG (op)),
-+ GET_MODE (SUBREG_REG (op)),
-+ SUBREG_BYTE (op),
-+ GET_MODE (op));
-+ regno = REGNO (SUBREG_REG (op)) + offset;
-+ }
-+ else
-+ return false;
-+
-+ return ((regno >= FIRST_PSEUDO_REGISTER
-+ && regno != REGNO (virtual_stack_vars_rtx))
-+ || REGNO_REG_CLASS (regno) == ACC_LO_REGS);
-+})
-+
-+(define_predicate "ubicom32_acc_hi_register_operand"
-+ (match_code "subreg, reg")
-+{
-+ unsigned int regno;
-+
-+ if (REG_P (op))
-+ regno = REGNO (op);
-+ else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
-+ {
-+ int offset;
-+ if (REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER)
-+ offset = SUBREG_BYTE (op) / (GET_MODE_SIZE (GET_MODE (op)));
-+ else
-+ offset = subreg_regno_offset (REGNO (SUBREG_REG (op)),
-+ GET_MODE (SUBREG_REG (op)),
-+ SUBREG_BYTE (op),
-+ GET_MODE (op));
-+ regno = REGNO (SUBREG_REG (op)) + offset;
-+ }
-+ else
-+ return false;
-+
-+ return ((regno >= FIRST_PSEUDO_REGISTER
-+ && regno != REGNO (virtual_stack_vars_rtx))
-+ || REGNO_REG_CLASS (regno) == ACC_REGS);
-+})
-+
-+(define_predicate "ubicom32_call_address_operand"
-+ (match_code "symbol_ref, subreg, reg")
-+{
-+ return (GET_CODE (op) == SYMBOL_REF || REG_P (op));
-+})
-+
-+(define_special_predicate "ubicom32_cc_register_operand"
-+ (and (match_code "reg")
-+ (match_test "REGNO (op) == CC_REGNUM")))
-+
---- /dev/null
-+++ b/gcc/config/ubicom32/t-ubicom32
-@@ -0,0 +1,52 @@
-+# Name of assembly file containing libgcc1 functions.
-+# This entry must be present, but it can be empty if the target does
-+# not need any assembler functions to support its code generation.
-+CROSS_LIBGCC1 =
-+
-+# Alternatively if assembler functions *are* needed then define the
-+# entries below:
-+# CROSS_LIBGCC1 = libgcc1-asm.a
-+
-+LIB2FUNCS_EXTRA = \
-+ $(srcdir)/config/udivmodsi4.c \
-+ $(srcdir)/config/divmod.c \
-+ $(srcdir)/config/udivmod.c
-+
-+# If any special flags are necessary when building libgcc2 put them here.
-+#
-+# TARGET_LIBGCC2_CFLAGS =
-+
-+# 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
-+
-+fp-bit.c: $(srcdir)/config/fp-bit.c
-+ echo '#define FLOAT' > fp-bit.c
-+ cat $(srcdir)/config/fp-bit.c >> fp-bit.c
-+
-+dp-bit.c: $(srcdir)/config/fp-bit.c
-+ cat $(srcdir)/config/fp-bit.c > dp-bit.c
-+
-+# Commented out to speed up compiler development!
-+#
-+# MULTILIB_OPTIONS = march=ubicom32v1/march=ubicom32v2/march=ubicom32v3/march=ubicom32v4
-+# MULTILIB_DIRNAMES = ubicom32v1 ubicom32v2 ubicom32v3 ubicom32v4
-+
-+MULTILIB_OPTIONS = march=ubicom32v3/march=ubicom32v4
-+MULTILIB_OPTIONS += mfdpic
-+MULTILIB_OPTIONS += mno-ipos-abi/mipos-abi
-+MULTILIB_OPTIONS += fno-leading-underscore/fleading-underscore
-+
-+# Assemble startup files.
-+$(T)crti.o: $(srcdir)/config/ubicom32/crti.S $(GCC_PASSES)
-+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) \
-+ -c -o $(T)crti.o -x assembler-with-cpp $(srcdir)/config/ubicom32/crti.S
-+
-+$(T)crtn.o: $(srcdir)/config/ubicom32/crtn.S $(GCC_PASSES)
-+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) \
-+ -c -o $(T)crtn.o -x assembler-with-cpp $(srcdir)/config/ubicom32/crtn.S
-+
-+# these parts are required because uClibc ldso needs them to link.
-+# they are not in the specfile so they will not be included automatically.
-+EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o crtbeginS.o crtendS.o crti.o crtn.o
---- /dev/null
-+++ b/gcc/config/ubicom32/t-ubicom32-linux
-@@ -0,0 +1,35 @@
-+# Name of assembly file containing libgcc1 functions.
-+# This entry must be present, but it can be empty if the target does
-+# not need any assembler functions to support its code generation.
-+CROSS_LIBGCC1 =
-+
-+# Alternatively if assembler functions *are* needed then define the
-+# entries below:
-+# CROSS_LIBGCC1 = libgcc1-asm.a
-+
-+LIB2FUNCS_EXTRA = \
-+ $(srcdir)/config/udivmodsi4.c \
-+ $(srcdir)/config/divmod.c \
-+ $(srcdir)/config/udivmod.c
-+
-+# If any special flags are necessary when building libgcc2 put them here.
-+#
-+# TARGET_LIBGCC2_CFLAGS =
-+
-+# 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
-+
-+fp-bit.c: $(srcdir)/config/fp-bit.c
-+ echo '#define FLOAT' > fp-bit.c
-+ cat $(srcdir)/config/fp-bit.c >> fp-bit.c
-+
-+dp-bit.c: $(srcdir)/config/fp-bit.c
-+ cat $(srcdir)/config/fp-bit.c > dp-bit.c
-+
-+# We only support v3 and v4 ISAs for uClinux.
-+
-+MULTILIB_OPTIONS = march=ubicom32v3/march=ubicom32v4
-+
-+#EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o crtbeginS.o crtendS.o
---- /dev/null
-+++ b/gcc/config/ubicom32/t-ubicom32-uclinux
-@@ -0,0 +1,35 @@
-+# Name of assembly file containing libgcc1 functions.
-+# This entry must be present, but it can be empty if the target does
-+# not need any assembler functions to support its code generation.
-+CROSS_LIBGCC1 =
-+
-+# Alternatively if assembler functions *are* needed then define the
-+# entries below:
-+# CROSS_LIBGCC1 = libgcc1-asm.a
-+
-+LIB2FUNCS_EXTRA = \
-+ $(srcdir)/config/udivmodsi4.c \
-+ $(srcdir)/config/divmod.c \
-+ $(srcdir)/config/udivmod.c
-+
-+# If any special flags are necessary when building libgcc2 put them here.
-+#
-+# TARGET_LIBGCC2_CFLAGS =
-+
-+# 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
-+
-+fp-bit.c: $(srcdir)/config/fp-bit.c
-+ echo '#define FLOAT' > fp-bit.c
-+ cat $(srcdir)/config/fp-bit.c >> fp-bit.c
-+
-+dp-bit.c: $(srcdir)/config/fp-bit.c
-+ cat $(srcdir)/config/fp-bit.c > dp-bit.c
-+
-+# We only support v3 and v4 ISAs for uClinux.
-+
-+MULTILIB_OPTIONS = march=ubicom32v3/march=ubicom32v4
-+
-+EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o # crtbeginS.o crtendS.o
---- /dev/null
-+++ b/gcc/config/ubicom32/ubicom32-modes.def
-@@ -0,0 +1,30 @@
-+/* Definitions of target machine for GNU compiler, Ubicom32 architecture.
-+ Copyright (C) 2009 Free Software Foundation, Inc.
-+ Contributed by Ubicom, Inc.
-+
-+ This file is part of GCC.
-+
-+ GCC is free software; you can redistribute it and/or modify it
-+ under the terms of the GNU General Public License as published
-+ by the Free Software Foundation; either version 3, or (at your
-+ option) any later version.
-+
-+ GCC is distributed in the hope that it will be useful, but WITHOUT
-+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
-+ License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with GCC; see the file COPYING3. If not see
-+ <http://www.gnu.org/licenses/>. */
-+
-+/* Some insns set all condition code flags, some only set the Z and N flags, and
-+ some only set the Z flag. */
-+
-+CC_MODE (CCW);
-+CC_MODE (CCWZN);
-+CC_MODE (CCWZ);
-+CC_MODE (CCS);
-+CC_MODE (CCSZN);
-+CC_MODE (CCSZ);
-+
---- /dev/null
-+++ b/gcc/config/ubicom32/ubicom32-protos.h
-@@ -0,0 +1,84 @@
-+/* Function prototypes for Ubicom IP3000.
-+
-+ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
-+ 2009 Free Software Foundation, Inc.
-+ Contributed by Ubicom, Inc.
-+
-+ This file is part of GNU CC.
-+
-+ GNU CC is free software; you can redistribute it and/or modify it under
-+ the terms of the GNU General Public License as published by the Free
-+ Software Foundation; either version 2, or (at your option) any later
-+ version.
-+
-+ GNU CC is distributed in the hope that it will be useful, but WITHOUT
-+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-+ for more details.
-+
-+ You should have received a copy of the GNU General Public License along
-+ with GNU CC; see the file COPYING. If not, write to the Free Software
-+ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-+
-+#ifdef RTX_CODE
-+
-+#ifdef TREE_CODE
-+extern void ubicom32_va_start (tree, rtx);
-+#endif /* TREE_CODE */
-+
-+extern void ubicom32_print_operand (FILE *, rtx, int);
-+extern void ubicom32_print_operand_address (FILE *, rtx);
-+
-+extern void ubicom32_conditional_register_usage (void);
-+extern enum reg_class ubicom32_preferred_reload_class (rtx, enum reg_class);
-+extern int ubicom32_regno_ok_for_index_p (int, int);
-+extern void ubicom32_expand_movsi (rtx *);
-+extern void ubicom32_expand_addsi3 (rtx *);
-+extern int ubicom32_emit_mult_sequence (rtx *);
-+extern void ubicom32_emit_move_const_int (rtx, rtx);
-+extern bool ubicom32_legitimate_constant_p (rtx);
-+extern bool ubicom32_legitimate_address_p (enum machine_mode, rtx, int);
-+extern rtx ubicom32_legitimize_address (rtx, rtx, enum machine_mode);
-+extern rtx ubicom32_legitimize_reload_address (rtx, enum machine_mode, int, int);
-+extern void ubicom32_canonicalize_comparison (enum rtx_code *code, rtx *op0, rtx *op1);
-+extern int ubicom32_mode_dependent_address_p (rtx);
-+extern void ubicom32_output_cond_jump (rtx, rtx, rtx);
-+extern void ubicom32_expand_eh_return (rtx *);
-+extern void ubicom32_expand_call_fdpic (rtx *);
-+extern void ubicom32_expand_call_value_fdpic (rtx *);
-+extern enum machine_mode ubicom32_select_cc_mode (RTX_CODE, rtx, rtx);
-+extern rtx ubicom32_gen_compare_reg (RTX_CODE, rtx, rtx);
-+extern int ubicom32_shiftable_const_int (int);
-+#endif /* RTX_CODE */
-+
-+#ifdef TREE_CODE
-+extern void init_cumulative_args (CUMULATIVE_ARGS *cum,
-+ tree fntype,
-+ struct rtx_def *libname,
-+ int indirect);
-+extern struct rtx_def *function_arg (CUMULATIVE_ARGS *,
-+ enum machine_mode, tree, int);
-+extern struct rtx_def *function_incoming_arg (CUMULATIVE_ARGS *,
-+ enum machine_mode,
-+ tree, int);
-+extern int function_arg_partial_nregs (CUMULATIVE_ARGS *,
-+ enum machine_mode, tree, int);
-+extern struct rtx_def *ubicom32_va_arg (tree, tree);
-+extern int ubicom32_reg_parm_stack_space (tree);
-+#endif /* TREE_CODE */
-+
-+extern struct rtx_def * ubicom32_builtin_saveregs (void);
-+extern void asm_file_start (FILE *);
-+extern void ubicom32_expand_prologue (void);
-+extern void ubicom32_expand_epilogue (void);
-+extern int ubicom32_initial_elimination_offset (int, int);
-+extern int ubicom32_regno_ok_for_base_p (int, int);
-+extern bool ubicom32_hard_regno_mode_ok (unsigned int, enum machine_mode);
-+extern int ubicom32_can_use_return_insn_p (void);
-+extern rtx ubicom32_return_addr_rtx (int, rtx);
-+extern void ubicom32_optimization_options (int, int);
-+extern void ubicom32_override_options (void);
-+extern bool ubicom32_match_cc_mode (rtx, enum machine_mode);
-+
-+extern int ubicom32_reorg_completed;
-+
---- /dev/null
-+++ b/gcc/config/ubicom32/ubicom32.c
-@@ -0,0 +1,2881 @@
-+/* Subroutines for insn-output.c for Ubicom32
-+
-+ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
-+ 2009 Free Software Foundation, Inc.
-+ Contributed by Ubicom, Inc.
-+
-+ This file is part of GCC.
-+
-+ GCC is free software; you can redistribute it and/or modify it
-+ under the terms of the GNU General Public License as published
-+ by the Free Software Foundation; either version 3, or (at your
-+ option) any later version.
-+
-+ GCC is distributed in the hope that it will be useful, but WITHOUT
-+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
-+ License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with GCC; see the file COPYING3. If not see
-+ <http://www.gnu.org/licenses/>. */
-+
-+#include "config.h"
-+#include "system.h"
-+#include "coretypes.h"
-+#include "tm.h"
-+#include "rtl.h"
-+#include "tree.h"
-+#include "regs.h"
-+#include "hard-reg-set.h"
-+#include "real.h"
-+#include "insn-config.h"
-+#include "conditions.h"
-+#include "insn-flags.h"
-+#include "output.h"
-+#include "insn-attr.h"
-+#include "insn-codes.h"
-+#include "flags.h"
-+#include "recog.h"
-+#include "expr.h"
-+#include "function.h"
-+#include "obstack.h"
-+#include "toplev.h"
-+#include "tm_p.h"
-+#include "tm-constrs.h"
-+#include "basic-block.h"
-+#include "integrate.h"
-+#include "target.h"
-+#include "target-def.h"
-+#include "reload.h"
-+#include "df.h"
-+#include "langhooks.h"
-+#include "optabs.h"
-+
-+static tree ubicom32_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
-+static void ubicom32_layout_frame (void);
-+static void ubicom32_function_prologue (FILE *, HOST_WIDE_INT);
-+static void ubicom32_function_epilogue (FILE *, HOST_WIDE_INT);
-+static bool ubicom32_rtx_costs (rtx, int, int, int *, bool speed);
-+static bool ubicom32_fixed_condition_code_regs (unsigned int *,
-+ unsigned int *);
-+static enum machine_mode ubicom32_cc_modes_compatible (enum machine_mode,
-+ enum machine_mode);
-+static int ubicom32_naked_function_p (void);
-+static void ubicom32_machine_dependent_reorg (void);
-+static bool ubicom32_assemble_integer (rtx, unsigned int, int);
-+static void ubicom32_asm_init_sections (void);
-+static int ubicom32_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,tree,
-+ bool);
-+static bool ubicom32_pass_by_reference (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
-+ enum machine_mode mode, const_tree type,
-+ bool named ATTRIBUTE_UNUSED);
-+static bool ubicom32_callee_copies (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
-+ enum machine_mode mode, const_tree type,
-+ bool named ATTRIBUTE_UNUSED);
-+
-+static bool ubicom32_return_in_memory (const_tree type,
-+ const_tree fntype ATTRIBUTE_UNUSED);
-+static bool ubicom32_is_base_reg (rtx, int);
-+static void ubicom32_init_builtins (void);
-+static rtx ubicom32_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
-+static tree ubicom32_fold_builtin (tree, tree, bool);
-+static int ubicom32_get_valid_offset_mask (enum machine_mode);
-+static bool ubicom32_cannot_force_const_mem (rtx);
-+
-+/* Case values threshold */
-+int ubicom32_case_values_threshold = 6;
-+
-+/* Nonzero if this chip supports the Ubicom32 v3 ISA. */
-+int ubicom32_v3 = 1;
-+
-+/* Nonzero if this chip supports the Ubicom32 v4 ISA. */
-+int ubicom32_v4 = 1;
-+
-+/* Valid attributes:
-+ naked - don't generate function prologue/epilogue and `ret' command. */
-+const struct attribute_spec ubicom32_attribute_table[] =
-+{
-+ /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
-+ { "naked", 0, 0, true, false, false, ubicom32_handle_fndecl_attribute },
-+ { NULL, 0, 0, false, false, false, NULL }
-+};
-+
-+#undef TARGET_ASM_FUNCTION_PROLOGUE
-+#define TARGET_ASM_FUNCTION_PROLOGUE ubicom32_function_prologue
-+
-+#undef TARGET_ASM_FUNCTION_EPILOGUE
-+#define TARGET_ASM_FUNCTION_EPILOGUE ubicom32_function_epilogue
-+
-+#undef TARGET_ATTRIBUTE_TABLE
-+#define TARGET_ATTRIBUTE_TABLE ubicom32_attribute_table
-+
-+/* All addresses cost the same amount. */
-+#undef TARGET_ADDRESS_COST
-+#define TARGET_ADDRESS_COST hook_int_rtx_bool_0
-+
-+#undef TARGET_RTX_COSTS
-+#define TARGET_RTX_COSTS ubicom32_rtx_costs
-+
-+#undef TARGET_FIXED_CONDITION_CODE_REGS
-+#define TARGET_FIXED_CONDITION_CODE_REGS ubicom32_fixed_condition_code_regs
-+
-+#undef TARGET_CC_MODES_COMPATIBLE
-+#define TARGET_CC_MODES_COMPATIBLE ubicom32_cc_modes_compatible
-+
-+#undef TARGET_MACHINE_DEPENDENT_REORG
-+#define TARGET_MACHINE_DEPENDENT_REORG ubicom32_machine_dependent_reorg
-+
-+#undef TARGET_ASM_INTEGER
-+#define TARGET_ASM_INTEGER ubicom32_assemble_integer
-+
-+#undef TARGET_ASM_INIT_SECTIONS
-+#define TARGET_ASM_INIT_SECTIONS ubicom32_asm_init_sections
-+
-+#undef TARGET_ARG_PARTIAL_BYTES
-+#define TARGET_ARG_PARTIAL_BYTES ubicom32_arg_partial_bytes
-+
-+#undef TARGET_PASS_BY_REFERENCE
-+#define TARGET_PASS_BY_REFERENCE ubicom32_pass_by_reference
-+
-+#undef TARGET_CALLEE_COPIES
-+#define TARGET_CALLEE_COPIES ubicom32_callee_copies
-+
-+#undef TARGET_RETURN_IN_MEMORY
-+#define TARGET_RETURN_IN_MEMORY ubicom32_return_in_memory
-+
-+#undef TARGET_INIT_BUILTINS
-+#define TARGET_INIT_BUILTINS ubicom32_init_builtins
-+
-+#undef TARGET_EXPAND_BUILTIN
-+#define TARGET_EXPAND_BUILTIN ubicom32_expand_builtin
-+
-+#undef TARGET_FOLD_BUILTIN
-+#define TARGET_FOLD_BUILTIN ubicom32_fold_builtin
-+
-+#undef TARGET_CANNOT_FORCE_CONST_MEM
-+#define TARGET_CANNOT_FORCE_CONST_MEM ubicom32_cannot_force_const_mem
-+
-+struct gcc_target targetm = TARGET_INITIALIZER;
-+
-+static char save_regs[FIRST_PSEUDO_REGISTER];
-+static int nregs;
-+static int frame_size;
-+int ubicom32_stack_size = 0; /* size of allocated stack (including frame) */
-+int ubicom32_can_use_calli_to_ret;
-+
-+#define STACK_UNIT_BOUNDARY (STACK_BOUNDARY / BITS_PER_UNIT)
-+#define ROUND_CALL_BLOCK_SIZE(BYTES) \
-+ (((BYTES) + (STACK_UNIT_BOUNDARY - 1)) & ~(STACK_UNIT_BOUNDARY - 1))
-+
-+/* In case of a PRE_INC, POST_INC, PRE_DEC, POST_DEC memory reference, we
-+ must report the mode of the memory reference from PRINT_OPERAND to
-+ PRINT_OPERAND_ADDRESS. */
-+enum machine_mode output_memory_reference_mode;
-+
-+/* Flag for some split insns from the ubicom32.md. */
-+int ubicom32_reorg_completed;
-+
-+enum reg_class const ubicom32_regclass_map[FIRST_PSEUDO_REGISTER] =
-+{
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ FDPIC_REG,
-+ ADDRESS_REGS,
-+ ADDRESS_REGS,
-+ ADDRESS_REGS,
-+ ADDRESS_REGS,
-+ ADDRESS_REGS,
-+ ADDRESS_REGS,
-+ ADDRESS_REGS,
-+ ACC_REGS,
-+ ACC_LO_REGS,
-+ ACC_REGS,
-+ ACC_LO_REGS,
-+ SOURCE3_REG,
-+ ADDRESS_REGS,
-+ NO_REGS, /* CC_REG must be NO_REGS */
-+ SPECIAL_REGS,
-+ SPECIAL_REGS,
-+ SPECIAL_REGS,
-+ SPECIAL_REGS,
-+ SPECIAL_REGS,
-+ SPECIAL_REGS,
-+ SPECIAL_REGS,
-+ SPECIAL_REGS
-+};
-+
-+rtx ubicom32_compare_op0;
-+rtx ubicom32_compare_op1;
-+
-+/* Handle command line option overrides. */
-+
-+void
-+ubicom32_override_options (void)
-+{
-+ flag_pic = 0;
-+
-+ if (strcmp (ubicom32_arch_name, "ubicom32v1") == 0) {
-+ /* If we have a version 1 architecture then we want to avoid using jump
-+ tables. */
-+ ubicom32_case_values_threshold = 30000;
-+ ubicom32_v3 = 0;
-+ ubicom32_v4 = 0;
-+ } else if (strcmp (ubicom32_arch_name, "ubicom32v2") == 0) {
-+ ubicom32_v3 = 0;
-+ ubicom32_v4 = 0;
-+ } else if (strcmp (ubicom32_arch_name, "ubicom32v3") == 0) {
-+ ubicom32_v3 = 1;
-+ ubicom32_v4 = 0;
-+ } else if (strcmp (ubicom32_arch_name, "ubicom32v4") == 0) {
-+ ubicom32_v3 = 1;
-+ ubicom32_v4 = 1;
-+ }
-+
-+ /* There is no single unaligned SI op for PIC code. Sometimes we
-+ need to use ".4byte" and sometimes we need to use ".picptr".
-+ See ubicom32_assemble_integer for details. */
-+ if (TARGET_FDPIC)
-+ targetm.asm_out.unaligned_op.si = 0;
-+}
-+
-+void
-+ubicom32_conditional_register_usage (void)
-+{
-+ /* If we're using the old ipOS ABI we need to make D10 through D13
-+ caller-clobbered. */
-+ if (TARGET_IPOS_ABI)
-+ {
-+ call_used_regs[D10_REGNUM] = 1;
-+ call_used_regs[D11_REGNUM] = 1;
-+ call_used_regs[D12_REGNUM] = 1;
-+ call_used_regs[D13_REGNUM] = 1;
-+ }
-+}
-+
-+/* We have some number of optimizations that don't really work for the Ubicom32
-+ architecture so we deal with them here. */
-+
-+void
-+ubicom32_optimization_options (int level ATTRIBUTE_UNUSED,
-+ int size ATTRIBUTE_UNUSED)
-+{
-+ /* The tree IVOPTs pass seems to do really bad things for the Ubicom32
-+ architecture - it tends to turn things that would happily use pre/post
-+ increment/decrement into operations involving unecessary loop
-+ indicies. */
-+ flag_ivopts = 0;
-+
-+ /* We have problems where DSE at the RTL level misses partial stores
-+ to the stack. For now we disable it to avoid this. */
-+ flag_dse = 0;
-+}
-+
-+/* Print operand X using operand code CODE to assembly language output file
-+ FILE. */
-+
-+void
-+ubicom32_print_operand (FILE *file, rtx x, int code)
-+{
-+ switch (code)
-+ {
-+ case 'A':
-+ /* Identify the correct accumulator to use. */
-+ if (REGNO (x) == ACC0_HI_REGNUM || REGNO (x) == ACC0_LO_REGNUM)
-+ fprintf (file, "acc0");
-+ else if (REGNO (x) == ACC1_HI_REGNUM || REGNO (x) == ACC1_LO_REGNUM)
-+ fprintf (file, "acc1");
-+ else
-+ abort ();
-+ break;
-+
-+ case 'b':
-+ case 'B':
-+ {
-+ enum machine_mode mode;
-+
-+ mode = GET_MODE (XEXP (x, 0));
-+
-+ /* These are normal and reversed branches. */
-+ switch (code == 'b' ? GET_CODE (x) : reverse_condition (GET_CODE (x)))
-+ {
-+ case NE:
-+ fprintf (file, "ne");
-+ break;
-+
-+ case EQ:
-+ fprintf (file, "eq");
-+ break;
-+
-+ case GE:
-+ if (mode == CCSZNmode || mode == CCWZNmode)
-+ fprintf (file, "pl");
-+ else
-+ fprintf (file, "ge");
-+ break;
-+
-+ case GT:
-+ fprintf (file, "gt");
-+ break;
-+
-+ case LE:
-+ fprintf (file, "le");
-+ break;
-+
-+ case LT:
-+ if (mode == CCSZNmode || mode == CCWZNmode)
-+ fprintf (file, "mi");
-+ else
-+ fprintf (file, "lt");
-+ break;
-+
-+ case GEU:
-+ fprintf (file, "cs");
-+ break;
-+
-+ case GTU:
-+ fprintf (file, "hi");
-+ break;
-+
-+ case LEU:
-+ fprintf (file, "ls");
-+ break;
-+
-+ case LTU:
-+ fprintf (file, "cc");
-+ break;
-+
-+ default:
-+ abort ();
-+ }
-+ }
-+ break;
-+
-+ case 'C':
-+ /* This is used for the operand to a call instruction;
-+ if it's a REG, enclose it in parens, else output
-+ the operand normally. */
-+ if (REG_P (x))
-+ {
-+ fputc ('(', file);
-+ ubicom32_print_operand (file, x, 0);
-+ fputc (')', file);
-+ }
-+ else
-+ ubicom32_print_operand (file, x, 0);
-+ break;
-+
-+ case 'd':
-+ /* Bit operations we need bit numbers. */
-+ fprintf (file, "%d", exact_log2 (INTVAL (x)));
-+ break;
-+
-+ case 'D':
-+ /* Bit operations we need bit numbers. */
-+ fprintf (file, "%d", exact_log2 (~ INTVAL (x)));
-+ break;
-+
-+ case 'E':
-+ /* For lea, which we use to add address registers.
-+ We don't want the '#' on a constant. */
-+ if (CONST_INT_P (x))
-+ {
-+ fprintf (file, "%ld", INTVAL (x));
-+ break;
-+ }
-+ /* FALL THROUGH */
-+
-+ default:
-+ switch (GET_CODE (x))
-+ {
-+ case MEM:
-+ output_memory_reference_mode = GET_MODE (x);
-+ output_address (XEXP (x, 0));
-+ break;
-+
-+ case PLUS:
-+ output_address (x);
-+ break;
-+
-+ case REG:
-+ fprintf (file, "%s", reg_names[REGNO (x)]);
-+ break;
-+
-+ case SUBREG:
-+ fprintf (file, "%s", reg_names[subreg_regno (x)]);
-+ break;
-+
-+ /* This will only be single precision.... */
-+ case CONST_DOUBLE:
-+ {
-+ unsigned long val;
-+ REAL_VALUE_TYPE rv;
-+
-+ REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
-+ REAL_VALUE_TO_TARGET_SINGLE (rv, val);
-+ fprintf (file, "0x%lx", val);
-+ break;
-+ }
-+
-+ case CONST_INT:
-+ case SYMBOL_REF:
-+ case CONST:
-+ case LABEL_REF:
-+ case CODE_LABEL:
-+ case LO_SUM:
-+ ubicom32_print_operand_address (file, x);
-+ break;
-+
-+ case HIGH:
-+ fprintf (file, "#%%hi(");
-+ ubicom32_print_operand_address (file, XEXP (x, 0));
-+ fprintf (file, ")");
-+ break;
-+
-+ case UNSPEC:
-+ switch (XINT (x, 1))
-+ {
-+ case UNSPEC_FDPIC_GOT:
-+ fprintf (file, "#%%got_lo(");
-+ ubicom32_print_operand_address (file, XVECEXP (x, 0, 0));
-+ fprintf (file, ")");
-+ break;
-+
-+ case UNSPEC_FDPIC_GOT_FUNCDESC:
-+ fprintf (file, "#%%got_funcdesc_lo(");
-+ ubicom32_print_operand_address (file, XVECEXP (x, 0, 0));
-+ fprintf (file, ")");
-+ break;
-+
-+ default:
-+ abort ();
-+ }
-+ break;
-+
-+ default:
-+ abort ();
-+ }
-+ break;
-+ }
-+}
-+
-+/* Output assembly language output for the address ADDR to FILE. */
-+
-+void
-+ubicom32_print_operand_address (FILE *file, rtx addr)
-+{
-+ switch (GET_CODE (addr))
-+ {
-+ case POST_INC:
-+ ubicom32_print_operand_address (file, XEXP (addr, 0));
-+ fprintf (file, "%d++", GET_MODE_SIZE (output_memory_reference_mode));
-+ break;
-+
-+ case PRE_INC:
-+ fprintf (file, "%d", GET_MODE_SIZE (output_memory_reference_mode));
-+ ubicom32_print_operand_address (file, XEXP (addr, 0));
-+ fprintf (file, "++");
-+ break;
-+
-+ case POST_DEC:
-+ ubicom32_print_operand_address (file, XEXP (addr, 0));
-+ fprintf (file, "%d++", -GET_MODE_SIZE (output_memory_reference_mode));
-+ break;
-+
-+ case PRE_DEC:
-+ fprintf (file, "%d", -GET_MODE_SIZE (output_memory_reference_mode));
-+ ubicom32_print_operand_address (file, XEXP (addr, 0));
-+ fprintf (file, "++");
-+ break;
-+
-+ case POST_MODIFY:
-+ ubicom32_print_operand_address (file, XEXP (addr, 0));
-+ fprintf (file, "%ld++", INTVAL (XEXP (XEXP (addr,1), 1)));
-+ break;
-+
-+ case PRE_MODIFY:
-+ fprintf (file, "%ld", INTVAL (XEXP (XEXP (addr,1), 1)));
-+ ubicom32_print_operand_address (file, XEXP (addr, 0));
-+ fprintf (file, "++");
-+ break;
-+
-+ case REG:
-+ fputc ('(', file);
-+ fprintf (file, "%s", reg_names[REGNO (addr)]);
-+ fputc (')', file);
-+ break;
-+
-+ case PLUS:
-+ {
-+ rtx base = XEXP (addr, 0);
-+ rtx index = XEXP (addr, 1);
-+
-+ /* Switch around addresses of the form index * scaling + base. */
-+ if (! ubicom32_is_base_reg (base, 1))
-+ {
-+ rtx tmp = base;
-+ base = index;
-+ index = tmp;
-+ }
-+
-+ if (CONST_INT_P (index))
-+ {
-+ fprintf (file, "%ld", INTVAL (index));
-+ fputc ('(', file);
-+ fputs (reg_names[REGNO (base)], file);
-+ }
-+ else if (GET_CODE (index) == MULT
-+ || REG_P (index))
-+ {
-+ if (GET_CODE (index) == MULT)
-+ index = XEXP (index, 0);
-+ fputc ('(', file);
-+ fputs (reg_names[REGNO (base)], file);
-+ fputc (',', file);
-+ fputs (reg_names[REGNO (index)], file);
-+ }
-+ else
-+ abort ();
-+
-+ fputc (')', file);
-+ break;
-+ }
-+
-+ case LO_SUM:
-+ fprintf (file, "%%lo(");
-+ ubicom32_print_operand (file, XEXP (addr, 1), 'L');
-+ fprintf (file, ")(");
-+ ubicom32_print_operand (file, XEXP (addr, 0), 0);
-+ fprintf (file, ")");
-+ break;
-+
-+ case CONST_INT:
-+ fputc ('#', file);
-+ output_addr_const (file, addr);
-+ break;
-+
-+ default:
-+ output_addr_const (file, addr);
-+ break;
-+ }
-+}
-+
-+/* X and Y are two things to compare using CODE. Emit the compare insn and
-+ return the rtx for the cc reg in the proper mode. */
-+
-+rtx
-+ubicom32_gen_compare_reg (enum rtx_code code, rtx x, rtx y)
-+{
-+ enum machine_mode mode = SELECT_CC_MODE (code, x, y);
-+ rtx cc_reg;
-+
-+ cc_reg = gen_rtx_REG (mode, CC_REGNUM);
-+
-+ emit_insn (gen_rtx_SET (VOIDmode, cc_reg,
-+ gen_rtx_COMPARE (mode, x, y)));
-+
-+ return cc_reg;
-+}
-+
-+/* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
-+ return the mode to be used for the comparison. */
-+
-+enum machine_mode
-+ubicom32_select_cc_mode (enum rtx_code op, rtx x, rtx y)
-+{
-+ /* Is this a short compare? */
-+ if (GET_MODE (x) == QImode
-+ || GET_MODE (x) == HImode
-+ || GET_MODE (y) == QImode
-+ || GET_MODE (y) == HImode)
-+ {
-+ switch (op)
-+ {
-+ case EQ :
-+ case NE :
-+ return CCSZmode;
-+
-+ case GE:
-+ case LT:
-+ if (y == const0_rtx)
-+ return CCSZNmode;
-+
-+ default :
-+ return CCSmode;
-+ }
-+ }
-+
-+ /* We have a word compare. */
-+ switch (op)
-+ {
-+ case EQ :
-+ case NE :
-+ return CCWZmode;
-+
-+ case GE :
-+ case LT :
-+ if (y == const0_rtx)
-+ return CCWZNmode;
-+
-+ default :
-+ return CCWmode;
-+ }
-+}
-+
-+/* Return TRUE or FALSE depending on whether the first SET in INSN
-+ has source and destination with matching CC modes, and that the
-+ CC mode is at least as constrained as REQ_MODE. */
-+bool
-+ubicom32_match_cc_mode (rtx insn, enum machine_mode req_mode)
-+{
-+ rtx set;
-+ enum machine_mode set_mode;
-+
-+ set = PATTERN (insn);
-+ if (GET_CODE (set) == PARALLEL)
-+ set = XVECEXP (set, 0, 0);
-+ gcc_assert (GET_CODE (set) == SET);
-+ gcc_assert (GET_CODE (SET_SRC (set)) == COMPARE);
-+
-+ /* SET_MODE is the mode we have in the instruction. This must either
-+ be the same or less restrictive that the required mode REQ_MODE. */
-+ set_mode = GET_MODE (SET_DEST (set));
-+
-+ switch (req_mode)
-+ {
-+ case CCSZmode:
-+ if (set_mode != CCSZmode)
-+ return 0;
-+ break;
-+
-+ case CCSZNmode:
-+ if (set_mode != CCSZmode
-+ && set_mode != CCSZNmode)
-+ return 0;
-+ break;
-+
-+ case CCSmode:
-+ if (set_mode != CCSmode
-+ && set_mode != CCSZmode
-+ && set_mode != CCSZNmode)
-+ return 0;
-+ break;
-+
-+ case CCWZmode:
-+ if (set_mode != CCWZmode)
-+ return 0;
-+ break;
-+
-+ case CCWZNmode:
-+ if (set_mode != CCWZmode
-+ && set_mode != CCWZNmode)
-+ return 0;
-+ break;
-+
-+ case CCWmode:
-+ if (set_mode != CCWmode
-+ && set_mode != CCWZmode
-+ && set_mode != CCWZNmode)
-+ return 0;
-+ break;
-+
-+ default:
-+ gcc_unreachable ();
-+ }
-+
-+ return (GET_MODE (SET_SRC (set)) == set_mode);
-+}
-+
-+/* Replace the comparison OP0 CODE OP1 by a semantically equivalent one
-+ that we can implement more efficiently. */
-+
-+void
-+ubicom32_canonicalize_comparison (enum rtx_code *code, rtx *op0, rtx *op1)
-+{
-+ /* If we have a REG and a MEM then compare the MEM with the REG and not
-+ the other way round. */
-+ if (REG_P (*op0) && MEM_P (*op1))
-+ {
-+ rtx tem = *op0;
-+ *op0 = *op1;
-+ *op1 = tem;
-+ *code = swap_condition (*code);
-+ return;
-+ }
-+
-+ /* If we have a REG and a CONST_INT then we may want to reverse things
-+ if the constant can be represented as an "I" constraint. */
-+ if (REG_P (*op0) && CONST_INT_P (*op1) && satisfies_constraint_I (*op1))
-+ {
-+ rtx tem = *op0;
-+ *op0 = *op1;
-+ *op1 = tem;
-+ *code = swap_condition (*code);
-+ return;
-+ }
-+}
-+
-+/* Return the fixed registers used for condition codes. */
-+
-+static bool
-+ubicom32_fixed_condition_code_regs (unsigned int *p1, unsigned int *p2)
-+{
-+ *p1 = CC_REGNUM;
-+ *p2 = INVALID_REGNUM;
-+
-+ return true;
-+}
-+
-+/* If two condition code modes are compatible, return a condition code
-+ mode which is compatible with both. Otherwise, return
-+ VOIDmode. */
-+
-+static enum machine_mode
-+ubicom32_cc_modes_compatible (enum machine_mode m1, enum machine_mode m2)
-+{
-+ if (m1 == m2)
-+ return m1;
-+
-+ if (GET_MODE_CLASS (m1) != MODE_CC || GET_MODE_CLASS (m2) != MODE_CC)
-+ return VOIDmode;
-+
-+ switch (m1)
-+ {
-+ case CCWmode:
-+ if (m2 == CCWZNmode || m2 == CCWZmode)
-+ return m1;
-+
-+ return VOIDmode;
-+
-+ case CCWZNmode:
-+ if (m2 == CCWmode)
-+ return m2;
-+
-+ if (m2 == CCWZmode)
-+ return m1;
-+
-+ return VOIDmode;
-+
-+ case CCWZmode:
-+ if (m2 == CCWmode || m2 == CCWZNmode)
-+ return m2;
-+
-+ return VOIDmode;
-+
-+ case CCSmode:
-+ if (m2 == CCSZNmode || m2 == CCSZmode)
-+ return m1;
-+
-+ return VOIDmode;
-+
-+ case CCSZNmode:
-+ if (m2 == CCSmode)
-+ return m2;
-+
-+ if (m2 == CCSZmode)
-+ return m1;
-+
-+ return VOIDmode;
-+
-+ case CCSZmode:
-+ if (m2 == CCSmode || m2 == CCSZNmode)
-+ return m2;
-+
-+ return VOIDmode;
-+
-+ default:
-+ gcc_unreachable ();
-+ }
-+}
-+
-+static rtx
-+ubicom32_legitimize_fdpic_address_symbol (rtx orig, rtx reg, rtx fdpic_reg)
-+{
-+ int unspec;
-+ rtx got_offs;
-+ rtx got_offs_scaled;
-+ rtx plus_scaled;
-+ rtx tmp;
-+ rtx new_rtx;
-+
-+ gcc_assert (reg != 0);
-+
-+ if (GET_CODE (orig) == SYMBOL_REF
-+ && SYMBOL_REF_FUNCTION_P (orig))
-+ unspec = UNSPEC_FDPIC_GOT_FUNCDESC;
-+ else
-+ unspec = UNSPEC_FDPIC_GOT;
-+
-+ got_offs = gen_reg_rtx (SImode);
-+ tmp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, orig), unspec);
-+ emit_move_insn (got_offs, tmp);
-+
-+ got_offs_scaled = gen_rtx_MULT (SImode, got_offs, GEN_INT (4));
-+ plus_scaled = gen_rtx_PLUS (Pmode, fdpic_reg, got_offs_scaled);
-+ new_rtx = gen_const_mem (Pmode, plus_scaled);
-+ emit_move_insn (reg, new_rtx);
-+
-+ return reg;
-+}
-+
-+static rtx
-+ubicom32_legitimize_fdpic_address (rtx orig, rtx reg, rtx fdpic_reg)
-+{
-+ rtx addr = orig;
-+ rtx new_rtx = orig;
-+
-+ if (GET_CODE (addr) == CONST || GET_CODE (addr) == PLUS)
-+ {
-+ rtx base;
-+
-+ if (GET_CODE (addr) == CONST)
-+ {
-+ addr = XEXP (addr, 0);
-+ gcc_assert (GET_CODE (addr) == PLUS);
-+ }
-+
-+ base = ubicom32_legitimize_fdpic_address_symbol (XEXP (addr, 0), reg, fdpic_reg);
-+ return gen_rtx_PLUS (Pmode, base, XEXP (addr, 1));
-+ }
-+
-+ return new_rtx;
-+}
-+
-+/* Code generation. */
-+
-+void
-+ubicom32_expand_movsi (rtx *operands)
-+{
-+ if (GET_CODE (operands[1]) == SYMBOL_REF
-+ || (GET_CODE (operands[1]) == CONST
-+ && GET_CODE (XEXP (operands[1], 0)) == PLUS
-+ && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
-+ || CONSTANT_ADDRESS_P (operands[1]))
-+ {
-+ if (TARGET_FDPIC)
-+ {
-+ rtx tmp;
-+ rtx fdpic_reg;
-+
-+ gcc_assert (can_create_pseudo_p ());
-+ tmp = gen_reg_rtx (Pmode);
-+ fdpic_reg = get_hard_reg_initial_val (SImode, FDPIC_REGNUM);
-+ if (GET_CODE (operands[1]) == SYMBOL_REF
-+ || GET_CODE (operands[1]) == LABEL_REF)
-+ operands[1] = ubicom32_legitimize_fdpic_address_symbol (operands[1], tmp, fdpic_reg);
-+ else
-+ operands[1] = ubicom32_legitimize_fdpic_address (operands[1], tmp, fdpic_reg);
-+ }
-+ else
-+ {
-+ rtx tmp;
-+ enum machine_mode mode;
-+
-+ /* We want to avoid reusing operand 0 if we can because it limits
-+ our ability to optimize later. */
-+ tmp = ! can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
-+
-+ mode = GET_MODE (operands[0]);
-+ emit_insn (gen_rtx_SET (VOIDmode, tmp,
-+ gen_rtx_HIGH (mode, operands[1])));
-+ operands[1] = gen_rtx_LO_SUM (mode, tmp, operands[1]);
-+ if (can_create_pseudo_p() && ! REG_P (operands[0]))
-+ {
-+ tmp = gen_reg_rtx (mode);
-+ emit_insn (gen_rtx_SET (VOIDmode, tmp, operands[1]));
-+ operands[1] = tmp;
-+ }
-+ }
-+ }
-+}
-+
-+/* Emit code for addsi3. */
-+
-+void
-+ubicom32_expand_addsi3 (rtx *operands)
-+{
-+ rtx op, clob;
-+
-+ if (can_create_pseudo_p ())
-+ {
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (SImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (SImode, operands[2]);
-+ }
-+
-+ /* Emit the instruction. */
-+
-+ op = gen_rtx_SET (VOIDmode, operands[0],
-+ gen_rtx_PLUS (SImode, operands[1], operands[2]));
-+
-+ if (! can_create_pseudo_p ())
-+ {
-+ /* Reload doesn't know about the flags register, and doesn't know that
-+ it doesn't want to clobber it. We can only do this with PLUS. */
-+ emit_insn (op);
-+ }
-+ else
-+ {
-+ clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM));
-+ emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, op, clob)));
-+ }
-+}
-+
-+/* Emit code for mulsi3. Return 1 if we have generated all the code
-+ necessary to do the multiplication. */
-+
-+int
-+ubicom32_emit_mult_sequence (rtx *operands)
-+{
-+ if (! ubicom32_v4)
-+ {
-+ rtx a1, a1_1, a2;
-+ rtx b1, b1_1, b2;
-+ rtx mac_lo_rtx;
-+ rtx t1, t2, t3;
-+
-+ /* Give up if we cannot create new pseudos. */
-+ if (!can_create_pseudo_p())
-+ return 0;
-+
-+ /* Synthesize 32-bit multiplication using 16-bit operations:
-+
-+ a1 = highpart (a)
-+ a2 = lowpart (a)
-+
-+ b1 = highpart (b)
-+ b2 = lowpart (b)
-+
-+ c = (a1 * b1) << 32 + (a1 * b2) << 16 + (a2 * b1) << 16 + a2 * b2
-+ = 0 + (a1 * b2) << 16 + (a2 * b1) << 16 + a2 * b2
-+ ^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^ ^^^^^^^
-+ Signed Signed Unsigned */
-+
-+ if (!ubicom32_data_register_operand (operands[1], GET_MODE (operands[1])))
-+ {
-+ rtx op1;
-+
-+ op1 = gen_reg_rtx (SImode);
-+ emit_move_insn (op1, operands[1]);
-+ operands[1] = op1;
-+ }
-+
-+ if (!ubicom32_data_register_operand (operands[2], GET_MODE (operands[2])))
-+ {
-+ rtx op2;
-+
-+ op2 = gen_reg_rtx (SImode);
-+ emit_move_insn (op2, operands[2]);
-+ operands[2] = op2;
-+ }
-+
-+ /* a1 = highpart (a) */
-+ a1 = gen_reg_rtx (HImode);
-+ a1_1 = gen_reg_rtx (SImode);
-+ emit_insn (gen_ashrsi3 (a1_1, operands[1], GEN_INT (16)));
-+ emit_move_insn (a1, gen_lowpart (HImode, a1_1));
-+
-+ /* a2 = lowpart (a) */
-+ a2 = gen_reg_rtx (HImode);
-+ emit_move_insn (a2, gen_lowpart (HImode, operands[1]));
-+
-+ /* b1 = highpart (b) */
-+ b1 = gen_reg_rtx (HImode);
-+ b1_1 = gen_reg_rtx (SImode);
-+ emit_insn (gen_ashrsi3 (b1_1, operands[2], GEN_INT (16)));
-+ emit_move_insn (b1, gen_lowpart (HImode, b1_1));
-+
-+ /* b2 = lowpart (b) */
-+ b2 = gen_reg_rtx (HImode);
-+ emit_move_insn (b2, gen_lowpart (HImode, operands[2]));
-+
-+ /* t1 = (a1 * b2) << 16 */
-+ t1 = gen_reg_rtx (SImode);
-+ mac_lo_rtx = gen_rtx_REG (SImode, ACC0_LO_REGNUM);
-+ emit_insn (gen_mulhisi3 (mac_lo_rtx, a1, b2));
-+ emit_insn (gen_ashlsi3 (t1, mac_lo_rtx, GEN_INT (16)));
-+
-+ /* t2 = (a2 * b1) << 16 */
-+ t2 = gen_reg_rtx (SImode);
-+ emit_insn (gen_mulhisi3 (mac_lo_rtx, a2, b1));
-+ emit_insn (gen_ashlsi3 (t2, mac_lo_rtx, GEN_INT (16)));
-+
-+ /* mac_lo = a2 * b2 */
-+ emit_insn (gen_umulhisi3 (mac_lo_rtx, a2, b2));
-+
-+ /* t3 = t1 + t2 */
-+ t3 = gen_reg_rtx (SImode);
-+ emit_insn (gen_addsi3 (t3, t1, t2));
-+
-+ /* c = t3 + mac_lo_rtx */
-+ emit_insn (gen_addsi3 (operands[0], mac_lo_rtx, t3));
-+
-+ return 1;
-+ }
-+ else
-+ {
-+ rtx acc_rtx;
-+
-+ /* Give up if we cannot create new pseudos. */
-+ if (!can_create_pseudo_p())
-+ return 0;
-+
-+ if (!ubicom32_data_register_operand (operands[1], GET_MODE (operands[1])))
-+ {
-+ rtx op1;
-+
-+ op1 = gen_reg_rtx (SImode);
-+ emit_move_insn (op1, operands[1]);
-+ operands[1] = op1;
-+ }
-+
-+ if (!ubicom32_data_register_operand (operands[2], GET_MODE (operands[2])))
-+ {
-+ rtx op2;
-+
-+ op2 = gen_reg_rtx (SImode);
-+ emit_move_insn (op2, operands[2]);
-+ operands[2] = op2;
-+ }
-+
-+ acc_rtx = gen_reg_rtx (DImode);
-+ emit_insn (gen_umulsidi3 (acc_rtx, operands[1], operands[2]));
-+ emit_move_insn (operands[0], gen_lowpart (SImode, acc_rtx));
-+
-+ return 1;
-+ }
-+}
-+
-+/* Move the integer value VAL into OPERANDS[0]. */
-+
-+void
-+ubicom32_emit_move_const_int (rtx dest, rtx imm)
-+{
-+ rtx xoperands[2];
-+
-+ xoperands[0] = dest;
-+ xoperands[1] = imm;
-+
-+ /* Treat mem destinations separately. Values must be explicitly sign
-+ extended. */
-+ if (MEM_P (dest))
-+ {
-+ rtx low_hword_mem;
-+ rtx low_hword_addr;
-+
-+ /* Emit shorter sequence for signed 7-bit quantities. */
-+ if (satisfies_constraint_I (imm))
-+ {
-+ output_asm_insn ("move.4\t%0, %1", xoperands);
-+ return;
-+ }
-+
-+ /* Special case for pushing constants. */
-+ if (GET_CODE (XEXP (dest, 0)) == PRE_DEC
-+ && XEXP (XEXP (dest, 0), 0) == stack_pointer_rtx)
-+ {
-+ output_asm_insn ("movei\t-4(sp)++, #%%hi(%E1)", xoperands);
-+ output_asm_insn ("movei\t2(sp), #%%lo(%E1)", xoperands);
-+ return;
-+ }
-+
-+ /* See if we can add 2 to the original address. This is only
-+ possible if the original address is of the form REG or
-+ REG+const. */
-+ low_hword_addr = plus_constant (XEXP (dest, 0), 2);
-+ if (ubicom32_legitimate_address_p (HImode, low_hword_addr, 1))
-+ {
-+ low_hword_mem = gen_rtx_MEM (HImode, low_hword_addr);
-+ MEM_COPY_ATTRIBUTES (low_hword_mem, dest);
-+ output_asm_insn ("movei\t%0, #%%hi(%E1)", xoperands);
-+ xoperands[0] = low_hword_mem;
-+ output_asm_insn ("movei\t%0, #%%lo(%E1)", xoperands);
-+ return;
-+ }
-+
-+ /* The original address is too complex. We need to use a
-+ scratch memory by (sp) and move that to the original
-+ destination. */
-+ if (! reg_mentioned_p (stack_pointer_rtx, dest))
-+ {
-+ output_asm_insn ("movei\t-4(sp)++, #%%hi(%E1)", xoperands);
-+ output_asm_insn ("movei\t2(sp), #%%lo(%E1)", xoperands);
-+ output_asm_insn ("move.4\t%0, (sp)4++", xoperands);
-+ return;
-+ }
-+
-+ /* Our address mentions the stack pointer so we need to
-+ use our scratch data register here as well as scratch
-+ memory. */
-+ output_asm_insn ("movei\t-4(sp)++, #%%hi(%E1)", xoperands);
-+ output_asm_insn ("movei\t2(sp), #%%lo(%E1)", xoperands);
-+ output_asm_insn ("move.4\td15, (sp)4++", xoperands);
-+ output_asm_insn ("move.4\t%0, d15", xoperands);
-+ return;
-+ }
-+
-+ /* Move into registers are zero extended by default. */
-+ if (! REG_P (dest))
-+ abort ();
-+
-+ if (satisfies_constraint_N (imm))
-+ {
-+ output_asm_insn ("movei\t%0, %1", xoperands);
-+ return;
-+ }
-+
-+ if (INTVAL (xoperands[1]) >= 0xff80
-+ && INTVAL (xoperands[1]) < 0x10000)
-+ {
-+ xoperands[1] = GEN_INT (INTVAL (xoperands[1]) - 0x10000);
-+ output_asm_insn ("move.2\t%0, %1", xoperands);
-+ return;
-+ }
-+
-+ if ((REGNO_REG_CLASS (REGNO (xoperands[0])) == ADDRESS_REGS
-+ || REGNO_REG_CLASS (REGNO (xoperands[0])) == FDPIC_REG)
-+ && ((INTVAL (xoperands[1]) & 0x80000000) == 0))
-+ {
-+ output_asm_insn ("moveai\t%0, #%%hi(%E1)", xoperands);
-+ if ((INTVAL (xoperands[1]) & 0x7f) != 0)
-+ output_asm_insn ("lea.1\t%0, %%lo(%E1)(%0)", xoperands);
-+ return;
-+ }
-+
-+ if ((INTVAL (xoperands[1]) & 0xffff0000) == 0)
-+ {
-+ output_asm_insn ("movei\t%0, #%%lo(%E1)", xoperands);
-+ output_asm_insn ("move.2\t%0, %0", xoperands);
-+ return;
-+ }
-+
-+ /* This is very expensive. The constant is so large that we
-+ need to use the stack to do the load. */
-+ output_asm_insn ("movei\t-4(sp)++, #%%hi(%E1)", xoperands);
-+ output_asm_insn ("movei\t2(sp), #%%lo(%E1)", xoperands);
-+ output_asm_insn ("move.4\t%0, (sp)4++", xoperands);
-+}
-+
-+/* Stack layout. Prologue/Epilogue. */
-+
-+static int save_regs_size;
-+
-+static void
-+ubicom32_layout_frame (void)
-+{
-+ int regno;
-+
-+ memset ((char *) &save_regs[0], 0, sizeof (save_regs));
-+ nregs = 0;
-+ frame_size = get_frame_size ();
-+
-+ if (frame_pointer_needed || df_regs_ever_live_p (FRAME_POINTER_REGNUM))
-+ {
-+ save_regs[FRAME_POINTER_REGNUM] = 1;
-+ ++nregs;
-+ }
-+
-+ if (current_function_is_leaf && ! df_regs_ever_live_p (LINK_REGNO))
-+ ubicom32_can_use_calli_to_ret = 1;
-+ else
-+ {
-+ ubicom32_can_use_calli_to_ret = 0;
-+ save_regs[LINK_REGNO] = 1;
-+ ++nregs;
-+ }
-+
-+ /* Figure out which register(s) needs to be saved. */
-+ for (regno = 0; regno <= LAST_ADDRESS_REGNUM; regno++)
-+ if (df_regs_ever_live_p(regno)
-+ && ! call_used_regs[regno]
-+ && ! fixed_regs[regno]
-+ && ! save_regs[regno])
-+ {
-+ save_regs[regno] = 1;
-+ ++nregs;
-+ }
-+
-+ save_regs_size = 4 * nregs;
-+}
-+
-+static void
-+ubicom32_emit_add_movsi (int regno, int adj)
-+{
-+ rtx x;
-+ rtx reg = gen_rtx_REG (SImode, regno);
-+
-+ adj += 4;
-+ if (adj > 8 * 4)
-+ {
-+ x = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
-+ GEN_INT (-adj)));
-+ RTX_FRAME_RELATED_P (x) = 1;
-+ x = emit_move_insn (gen_rtx_MEM (SImode, stack_pointer_rtx), reg);
-+ }
-+ else
-+ {
-+ rtx addr = gen_rtx_PRE_MODIFY (Pmode, stack_pointer_rtx,
-+ gen_rtx_PLUS (Pmode, stack_pointer_rtx,
-+ GEN_INT (-adj)));
-+ x = emit_move_insn (gen_rtx_MEM (SImode, addr), reg);
-+ }
-+ RTX_FRAME_RELATED_P (x) = 1;
-+}
-+
-+void
-+ubicom32_expand_prologue (void)
-+{
-+ rtx x;
-+ int regno;
-+ int outgoing_args_size = crtl->outgoing_args_size;
-+ int adj;
-+
-+ if (ubicom32_naked_function_p ())
-+ return;
-+
-+ ubicom32_builtin_saveregs ();
-+
-+ ubicom32_layout_frame ();
-+ adj = (outgoing_args_size + get_frame_size () + save_regs_size
-+ + crtl->args.pretend_args_size);
-+
-+ if (!adj)
-+ ;
-+ else if (outgoing_args_size + save_regs_size < 508
-+ && get_frame_size () + save_regs_size > 508)
-+ {
-+ int i = 0;
-+ x = gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
-+ GEN_INT (-adj));
-+ x = emit_insn (x);
-+ RTX_FRAME_RELATED_P (x) = 1;
-+
-+ for (regno = LAST_ADDRESS_REGNUM; regno >= 0; --regno)
-+ if (save_regs[regno] && regno != LINK_REGNO)
-+ {
-+ x = gen_rtx_MEM (SImode,
-+ gen_rtx_PLUS (Pmode,
-+ stack_pointer_rtx,
-+ GEN_INT (i * 4 + outgoing_args_size)));
-+ x = emit_move_insn (x, gen_rtx_REG (SImode, regno));
-+ RTX_FRAME_RELATED_P (x) = 1;
-+ ++i;
-+ }
-+ if (save_regs[LINK_REGNO])
-+ {
-+ x = gen_rtx_MEM (SImode,
-+ gen_rtx_PLUS (Pmode,
-+ stack_pointer_rtx,
-+ GEN_INT (i * 4 + outgoing_args_size)));
-+ x = emit_move_insn (x, gen_rtx_REG (SImode, LINK_REGNO));
-+ RTX_FRAME_RELATED_P (x) = 1;
-+ }
-+ }
-+ else
-+ {
-+ int regno;
-+ int adj = get_frame_size () + crtl->args.pretend_args_size;
-+ int i = 0;
-+
-+ if (save_regs[LINK_REGNO])
-+ {
-+ ubicom32_emit_add_movsi (LINK_REGNO, adj);
-+ ++i;
-+ }
-+
-+ for (regno = 0; regno <= LAST_ADDRESS_REGNUM; ++regno)
-+ if (save_regs[regno] && regno != LINK_REGNO)
-+ {
-+ if (i)
-+ {
-+ rtx mem = gen_rtx_MEM (SImode,
-+ gen_rtx_PRE_DEC (Pmode,
-+ stack_pointer_rtx));
-+ x = emit_move_insn (mem, gen_rtx_REG (SImode, regno));
-+ RTX_FRAME_RELATED_P (x) = 1;
-+ }
-+ else
-+ ubicom32_emit_add_movsi (regno, adj);
-+ ++i;
-+ }
-+
-+ if (outgoing_args_size || (!i && adj))
-+ {
-+ x = gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
-+ GEN_INT (-outgoing_args_size - (i ? 0 : adj)));
-+ x = emit_insn (x);
-+ RTX_FRAME_RELATED_P (x) = 1;
-+ }
-+ }
-+
-+ if (frame_pointer_needed)
-+ {
-+ int fp_adj = save_regs_size + outgoing_args_size;
-+ x = gen_addsi3 (frame_pointer_rtx, stack_pointer_rtx,
-+ GEN_INT (fp_adj));
-+ x = emit_insn (x);
-+ RTX_FRAME_RELATED_P (x) = 1;
-+ }
-+}
-+
-+void
-+ubicom32_expand_epilogue (void)
-+{
-+ rtx x;
-+ int regno;
-+ int outgoing_args_size = crtl->outgoing_args_size;
-+ int adj;
-+ int i;
-+
-+ if (ubicom32_naked_function_p ())
-+ {
-+ emit_jump_insn (gen_return_internal (gen_rtx_REG (SImode,
-+ LINK_REGNO)));
-+ return;
-+ }
-+
-+ if (cfun->calls_alloca)
-+ {
-+ x = gen_addsi3 (stack_pointer_rtx, frame_pointer_rtx,
-+ GEN_INT (-save_regs_size));
-+ emit_insn (x);
-+ outgoing_args_size = 0;
-+ }
-+
-+ if (outgoing_args_size)
-+ {
-+ x = gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
-+ GEN_INT (outgoing_args_size));
-+ emit_insn (x);
-+ }
-+
-+ i = 0;
-+ for (regno = LAST_ADDRESS_REGNUM; regno >= 0; --regno)
-+ if (save_regs[regno] && regno != LINK_REGNO)
-+ {
-+ x = gen_rtx_MEM (SImode, gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
-+ emit_move_insn (gen_rtx_REG (SImode, regno), x);
-+ ++i;
-+ }
-+
-+ /* Do we have to adjust the stack after we've finished restoring regs? */
-+ adj = get_frame_size() + crtl->args.pretend_args_size;
-+ if (cfun->stdarg)
-+ adj += UBICOM32_FUNCTION_ARG_REGS * UNITS_PER_WORD;
-+
-+#if 0
-+ if (crtl->calls_eh_return && 0)
-+ {
-+ if (save_regs[LINK_REGNO])
-+ {
-+ x = gen_rtx_MEM (SImode, gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
-+ emit_move_insn (gen_rtx_REG (SImode, LINK_REGNO), x);
-+ }
-+
-+ if (adj)
-+ {
-+ x = gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
-+ GEN_INT (adj));
-+ x = emit_insn (x);
-+ }
-+
-+ /* Perform the additional bump for __throw. */
-+ emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
-+ EH_RETURN_STACKADJ_RTX));
-+ emit_jump_insn (gen_eh_return_internal ());
-+ return;
-+ }
-+#endif
-+
-+ if (save_regs[LINK_REGNO])
-+ {
-+ if (adj >= 4 && adj <= (6 * 4))
-+ {
-+ x = GEN_INT (adj + 4);
-+ emit_jump_insn (gen_return_from_post_modify_sp (x));
-+ return;
-+ }
-+
-+ if (adj == 0)
-+ {
-+ x = gen_rtx_MEM (SImode, gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
-+ emit_jump_insn (gen_return_internal (x));
-+ return;
-+ }
-+
-+ x = gen_rtx_MEM (SImode, gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
-+ emit_move_insn (gen_rtx_REG (SImode, LINK_REGNO), x);
-+ }
-+
-+ if (adj)
-+ {
-+ x = gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
-+ GEN_INT (adj));
-+ x = emit_insn (x);
-+ adj = 0;
-+ }
-+
-+ /* Given that we've just done all the hard work here we may as well use
-+ a calli to return. */
-+ ubicom32_can_use_calli_to_ret = 1;
-+ emit_jump_insn (gen_return_internal (gen_rtx_REG (SImode, LINK_REGNO)));
-+}
-+
-+void
-+ubicom32_expand_call_fdpic (rtx *operands)
-+{
-+ rtx c;
-+ rtx addr;
-+ rtx fdpic_reg = get_hard_reg_initial_val (SImode, FDPIC_REGNUM);
-+
-+ addr = XEXP (operands[0], 0);
-+
-+ c = gen_call_fdpic (addr, operands[1], fdpic_reg);
-+ emit_call_insn (c);
-+}
-+
-+void
-+ubicom32_expand_call_value_fdpic (rtx *operands)
-+{
-+ rtx c;
-+ rtx addr;
-+ rtx fdpic_reg = get_hard_reg_initial_val (SImode, FDPIC_REGNUM);
-+
-+ addr = XEXP (operands[1], 0);
-+
-+ c = gen_call_value_fdpic (operands[0], addr, operands[2], fdpic_reg);
-+ emit_call_insn (c);
-+}
-+
-+void
-+ubicom32_expand_eh_return (rtx *operands)
-+{
-+ if (REG_P (operands[0])
-+ || REGNO (operands[0]) != EH_RETURN_STACKADJ_REGNO)
-+ {
-+ rtx sp = EH_RETURN_STACKADJ_RTX;
-+ emit_move_insn (sp, operands[0]);
-+ operands[0] = sp;
-+ }
-+
-+ if (REG_P (operands[1])
-+ || REGNO (operands[1]) != EH_RETURN_HANDLER_REGNO)
-+ {
-+ rtx ra = EH_RETURN_HANDLER_RTX;
-+ emit_move_insn (ra, operands[1]);
-+ operands[1] = ra;
-+ }
-+}
-+
-+/* Compute the offsets between eliminable registers. */
-+
-+int
-+ubicom32_initial_elimination_offset (int from, int to)
-+{
-+ ubicom32_layout_frame ();
-+ if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
-+ return save_regs_size + crtl->outgoing_args_size;
-+
-+ if (from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
-+ return get_frame_size ()/* + save_regs_size */;
-+
-+ if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
-+ return get_frame_size ()
-+ + crtl->outgoing_args_size
-+ + save_regs_size;
-+
-+ return 0;
-+}
-+
-+/* Return 1 if it is appropriate to emit `ret' instructions in the
-+ body of a function. Do this only if the epilogue is simple, needing a
-+ couple of insns. Prior to reloading, we can't tell how many registers
-+ must be saved, so return 0 then. Return 0 if there is no frame
-+ marker to de-allocate.
-+
-+ If NON_SAVING_SETJMP is defined and true, then it is not possible
-+ for the epilogue to be simple, so return 0. This is a special case
-+ since NON_SAVING_SETJMP will not cause regs_ever_live to change
-+ until final, but jump_optimize may need to know sooner if a
-+ `return' is OK. */
-+
-+int
-+ubicom32_can_use_return_insn_p (void)
-+{
-+ if (! reload_completed || frame_pointer_needed)
-+ return 0;
-+
-+ return 1;
-+}
-+
-+/* Attributes and CC handling. */
-+
-+/* Handle an attribute requiring a FUNCTION_DECL; arguments as in
-+ struct attribute_spec.handler. */
-+static tree
-+ubicom32_handle_fndecl_attribute (tree *node, tree name,
-+ tree args ATTRIBUTE_UNUSED,
-+ int flags ATTRIBUTE_UNUSED,
-+ bool *no_add_attrs)
-+{
-+ if (TREE_CODE (*node) != FUNCTION_DECL)
-+ {
-+ warning ("'%s' attribute only applies to functions",
-+ IDENTIFIER_POINTER (name));
-+ *no_add_attrs = true;
-+ }
-+
-+ return NULL_TREE;
-+}
-+
-+/* A C expression that places additional restrictions on the register class to
-+ use when it is necessary to copy value X into a register in class CLASS.
-+ The value is a register class; perhaps CLASS, or perhaps another, smaller
-+ class. On many machines, the following definition is safe:
-+
-+ #define PREFERRED_RELOAD_CLASS(X,CLASS) CLASS
-+
-+ Sometimes returning a more restrictive class makes better code. For
-+ example, on the 68000, when X is an integer constant that is in range for a
-+ `moveq' instruction, the value of this macro is always `DATA_REGS' as long
-+ as CLASS includes the data registers. Requiring a data register guarantees
-+ that a `moveq' will be used.
-+
-+ If X is a `const_double', by returning `NO_REGS' you can force X into a
-+ memory constant. This is useful on certain machines where immediate
-+ floating values cannot be loaded into certain kinds of registers. */
-+
-+enum reg_class
-+ubicom32_preferred_reload_class (rtx x, enum reg_class class)
-+{
-+ /* If a symbolic constant, HIGH or a PLUS is reloaded,
-+ it is most likely being used as an address, so
-+ prefer ADDRESS_REGS. If 'class' is not a superset
-+ of ADDRESS_REGS, e.g. DATA_REGS, then reject this reload. */
-+ if (GET_CODE (x) == PLUS
-+ || GET_CODE (x) == HIGH
-+ || GET_CODE (x) == LABEL_REF
-+ || GET_CODE (x) == SYMBOL_REF
-+ || GET_CODE (x) == CONST)
-+ {
-+ if (reg_class_subset_p (ALL_ADDRESS_REGS, class))
-+ return ALL_ADDRESS_REGS;
-+
-+ return NO_REGS;
-+ }
-+
-+ return class;
-+}
-+
-+/* Function arguments and varargs. */
-+
-+int
-+ubicom32_reg_parm_stack_space (tree fndecl)
-+{
-+ return 0;
-+
-+ if (fndecl
-+ && TYPE_ARG_TYPES (TREE_TYPE (fndecl)) != 0
-+ && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (TREE_TYPE (fndecl))))
-+ != void_type_node))
-+ return UBICOM32_FUNCTION_ARG_REGS * UNITS_PER_WORD;
-+
-+ return 0;
-+}
-+
-+/* Flush the argument registers to the stack for a stdarg function;
-+ return the new argument pointer. */
-+
-+rtx
-+ubicom32_builtin_saveregs (void)
-+{
-+ int regno;
-+
-+ if (! cfun->stdarg)
-+ return 0;
-+
-+ for (regno = UBICOM32_FUNCTION_ARG_REGS - 1; regno >= 0; --regno)
-+ emit_move_insn (gen_rtx_MEM (SImode,
-+ gen_rtx_PRE_DEC (SImode,
-+ stack_pointer_rtx)),
-+ gen_rtx_REG (SImode, regno));
-+
-+ return stack_pointer_rtx;
-+}
-+
-+void
-+ubicom32_va_start (tree valist, rtx nextarg)
-+{
-+ std_expand_builtin_va_start (valist, nextarg);
-+}
-+
-+rtx
-+ubicom32_va_arg (tree valist, tree type)
-+{
-+ HOST_WIDE_INT size, rsize;
-+ tree addr, incr, tmp;
-+ rtx addr_rtx;
-+ int indirect = 0;
-+
-+ /* Round up sizeof(type) to a word. */
-+ size = int_size_in_bytes (type);
-+ rsize = (size + UNITS_PER_WORD - 1) & -UNITS_PER_WORD;
-+
-+ /* Large types are passed by reference. */
-+ if (size > 8)
-+ {
-+ indirect = 1;
-+ size = rsize = UNITS_PER_WORD;
-+ }
-+
-+ incr = valist;
-+ addr = incr = save_expr (incr);
-+
-+ /* FIXME Nat's version - is it correct? */
-+ tmp = fold_convert (ptr_type_node, size_int (rsize));
-+ tmp = build2 (PLUS_EXPR, ptr_type_node, incr, tmp);
-+ incr = fold (tmp);
-+
-+ /* FIXME Nat's version - is it correct? */
-+ incr = build2 (MODIFY_EXPR, ptr_type_node, valist, incr);
-+
-+ TREE_SIDE_EFFECTS (incr) = 1;
-+ expand_expr (incr, const0_rtx, VOIDmode, EXPAND_NORMAL);
-+
-+ addr_rtx = expand_expr (addr, NULL, Pmode, EXPAND_NORMAL);
-+
-+ if (size < UNITS_PER_WORD)
-+ emit_insn (gen_addsi3 (addr_rtx, addr_rtx,
-+ GEN_INT (UNITS_PER_WORD - size)));
-+
-+ if (indirect)
-+ {
-+ addr_rtx = force_reg (Pmode, addr_rtx);
-+ addr_rtx = gen_rtx_MEM (Pmode, addr_rtx);
-+ set_mem_alias_set (addr_rtx, get_varargs_alias_set ());
-+ }
-+
-+ return addr_rtx;
-+}
-+
-+void
-+init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype, rtx libname,
-+ int indirect ATTRIBUTE_UNUSED)
-+{
-+ cum->nbytes = 0;
-+
-+ if (!libname)
-+ {
-+ cum->stdarg = (TYPE_ARG_TYPES (fntype) != 0
-+ && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
-+ != void_type_node));
-+ }
-+}
-+
-+/* Return an RTX to represent where a value in mode MODE will be passed
-+ to a function. If the result is 0, the argument will be pushed. */
-+
-+rtx
-+function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
-+ int named ATTRIBUTE_UNUSED)
-+{
-+ rtx result = 0;
-+ int size, align;
-+ int nregs = UBICOM32_FUNCTION_ARG_REGS;
-+
-+ /* Figure out the size of the object to be passed. */
-+ if (mode == BLKmode)
-+ size = int_size_in_bytes (type);
-+ else
-+ size = GET_MODE_SIZE (mode);
-+
-+ /* Figure out the alignment of the object to be passed. */
-+ align = size;
-+
-+ cum->nbytes = (cum->nbytes + 3) & ~3;
-+
-+ /* Don't pass this arg via a register if all the argument registers
-+ are used up. */
-+ if (cum->nbytes >= nregs * UNITS_PER_WORD)
-+ return 0;
-+
-+ /* Don't pass this arg via a register if it would be split between
-+ registers and memory. */
-+ result = gen_rtx_REG (mode, cum->nbytes / UNITS_PER_WORD);
-+
-+ return result;
-+}
-+
-+rtx
-+function_incoming_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
-+ int named ATTRIBUTE_UNUSED)
-+{
-+ if (cfun->stdarg)
-+ return 0;
-+
-+ return function_arg (cum, mode, type, named);
-+}
-+
-+
-+/* Implement hook TARGET_ARG_PARTIAL_BYTES.
-+
-+ Returns the number of bytes at the beginning of an argument that
-+ must be put in registers. The value must be zero for arguments
-+ that are passed entirely in registers or that are entirely pushed
-+ on the stack. */
-+static int
-+ubicom32_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
-+ tree type, bool named ATTRIBUTE_UNUSED)
-+{
-+ int size, diff;
-+
-+ int nregs = UBICOM32_FUNCTION_ARG_REGS;
-+
-+ /* round up to full word */
-+ cum->nbytes = (cum->nbytes + 3) & ~3;
-+
-+ if (targetm.calls.pass_by_reference (cum, mode, type, named))
-+ return 0;
-+
-+ /* number of bytes left in registers */
-+ diff = nregs*UNITS_PER_WORD - cum->nbytes;
-+
-+ /* regs all used up */
-+ if (diff <= 0)
-+ return 0;
-+
-+ /* Figure out the size of the object to be passed. */
-+ if (mode == BLKmode)
-+ size = int_size_in_bytes (type);
-+ else
-+ size = GET_MODE_SIZE (mode);
-+
-+ /* enough space left in regs for size */
-+ if (size <= diff)
-+ return 0;
-+
-+ /* put diff bytes in regs and rest on stack */
-+ return diff;
-+
-+}
-+
-+static bool
-+ubicom32_pass_by_reference (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
-+ enum machine_mode mode, const_tree type,
-+ bool named ATTRIBUTE_UNUSED)
-+{
-+ int size;
-+
-+ if (type)
-+ size = int_size_in_bytes (type);
-+ else
-+ size = GET_MODE_SIZE (mode);
-+
-+ return size <= 0 || size > 8;
-+}
-+
-+static bool
-+ubicom32_callee_copies (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
-+ enum machine_mode mode, const_tree type,
-+ bool named ATTRIBUTE_UNUSED)
-+{
-+ int size;
-+
-+ if (type)
-+ size = int_size_in_bytes (type);
-+ else
-+ size = GET_MODE_SIZE (mode);
-+
-+ return size <= 0 || size > 8;
-+}
-+
-+static bool
-+ubicom32_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
-+{
-+ int size, mode;
-+
-+ if (!type)
-+ return true;
-+
-+ size = int_size_in_bytes(type);
-+ if (size > 8)
-+ return true;
-+
-+ mode = TYPE_MODE(type);
-+ if (mode == BLKmode)
-+ return true;
-+
-+ return false;
-+}
-+
-+/* Return true if a given register number REGNO is acceptable for machine
-+ mode MODE. */
-+bool
-+ubicom32_hard_regno_mode_ok (unsigned int regno, enum machine_mode mode)
-+{
-+ /* If we're not at least a v3 ISA then ACC0_HI is only 16 bits. */
-+ if (! ubicom32_v3)
-+ {
-+ if (regno == ACC0_HI_REGNUM)
-+ return (mode == QImode || mode == HImode);
-+ }
-+
-+ /* Only the flags reg can hold CCmode. */
-+ if (GET_MODE_CLASS (mode) == MODE_CC)
-+ return regno == CC_REGNUM;
-+
-+ /* We restrict the choice of DImode registers to only being address,
-+ data or accumulator regs. We also restrict them to only start on
-+ even register numbers so we never have to worry about partial
-+ overlaps between operands in instructions. */
-+ if (GET_MODE_SIZE (mode) > 4)
-+ {
-+ switch (REGNO_REG_CLASS (regno))
-+ {
-+ case ADDRESS_REGS:
-+ case DATA_REGS:
-+ case ACC_REGS:
-+ return (regno & 1) == 0;
-+
-+ default:
-+ return false;
-+ }
-+ }
-+
-+ return true;
-+}
-+
-+/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
-+ and check its validity for a certain class.
-+ We have two alternate definitions for each of them.
-+ The usual definition accepts all pseudo regs; the other rejects
-+ them unless they have been allocated suitable hard regs.
-+ The symbol REG_OK_STRICT causes the latter definition to be used.
-+
-+ Most source files want to accept pseudo regs in the hope that
-+ they will get allocated to the class that the insn wants them to be in.
-+ Source files for reload pass need to be strict.
-+ After reload, it makes no difference, since pseudo regs have
-+ been eliminated by then.
-+
-+ These assume that REGNO is a hard or pseudo reg number.
-+ They give nonzero only if REGNO is a hard reg of the suitable class
-+ or a pseudo reg currently allocated to a suitable hard reg.
-+ Since they use reg_renumber, they are safe only once reg_renumber
-+ has been allocated, which happens in local-alloc.c. */
-+
-+int
-+ubicom32_regno_ok_for_base_p (int regno, int strict)
-+{
-+ if ((regno >= FIRST_ADDRESS_REGNUM && regno <= STACK_POINTER_REGNUM)
-+ || (!strict
-+ && (regno >= FIRST_PSEUDO_REGISTER
-+ || regno == ARG_POINTER_REGNUM))
-+ || (strict && (reg_renumber
-+ && reg_renumber[regno] >= FIRST_ADDRESS_REGNUM
-+ && reg_renumber[regno] <= STACK_POINTER_REGNUM)))
-+ return 1;
-+
-+ return 0;
-+}
-+
-+int
-+ubicom32_regno_ok_for_index_p (int regno, int strict)
-+{
-+ if ((regno >= FIRST_DATA_REGNUM && regno <= LAST_DATA_REGNUM)
-+ || (!strict && regno >= FIRST_PSEUDO_REGISTER)
-+ || (strict && (reg_renumber
-+ && reg_renumber[regno] >= FIRST_DATA_REGNUM
-+ && reg_renumber[regno] <= LAST_DATA_REGNUM)))
-+ return 1;
-+
-+ return 0;
-+}
-+
-+/* Returns 1 if X is a valid index register. STRICT is 1 if only hard
-+ registers should be accepted. Accept either REG or SUBREG where a
-+ register is valid. */
-+
-+static bool
-+ubicom32_is_index_reg (rtx x, int strict)
-+{
-+ if ((REG_P (x) && ubicom32_regno_ok_for_index_p (REGNO (x), strict))
-+ || (GET_CODE (x) == SUBREG && REG_P (SUBREG_REG (x))
-+ && ubicom32_regno_ok_for_index_p (REGNO (SUBREG_REG (x)), strict)))
-+ return true;
-+
-+ return false;
-+}
-+
-+/* Return 1 if X is a valid index for a memory address. */
-+
-+static bool
-+ubicom32_is_index_expr (enum machine_mode mode, rtx x, int strict)
-+{
-+ /* Immediate index must be an unsigned 7-bit offset multiple of 1, 2
-+ or 4 depending on mode. */
-+ if (CONST_INT_P (x))
-+ {
-+ switch (mode)
-+ {
-+ case QImode:
-+ return satisfies_constraint_J (x);
-+
-+ case HImode:
-+ return satisfies_constraint_K (x);
-+
-+ case SImode:
-+ case SFmode:
-+ return satisfies_constraint_L (x);
-+
-+ case DImode:
-+ return satisfies_constraint_L (x)
-+ && satisfies_constraint_L (GEN_INT (INTVAL (x) + 4));
-+
-+ default:
-+ return false;
-+ }
-+ }
-+
-+ if (mode != SImode && mode != HImode && mode != QImode)
-+ return false;
-+
-+ /* Register index scaled by mode of operand: REG + REG * modesize.
-+ Valid scaled index registers are:
-+
-+ SImode (mult (dreg) 4))
-+ HImode (mult (dreg) 2))
-+ QImode (mult (dreg) 1)) */
-+ if (GET_CODE (x) == MULT
-+ && ubicom32_is_index_reg (XEXP (x, 0), strict)
-+ && CONST_INT_P (XEXP (x, 1))
-+ && INTVAL (XEXP (x, 1)) == (HOST_WIDE_INT)GET_MODE_SIZE (mode))
-+ return true;
-+
-+ /* REG + REG addressing is allowed for QImode. */
-+ if (ubicom32_is_index_reg (x, strict) && mode == QImode)
-+ return true;
-+
-+ return false;
-+}
-+
-+static bool
-+ubicom32_is_valid_offset (enum machine_mode mode, HOST_WIDE_INT offs)
-+{
-+ if (offs < 0)
-+ return false;
-+
-+ switch (mode)
-+ {
-+ case QImode:
-+ return offs <= 127;
-+
-+ case HImode:
-+ return offs <= 254;
-+
-+ case SImode:
-+ case SFmode:
-+ return offs <= 508;
-+
-+ case DImode:
-+ return offs <= 504;
-+
-+ default:
-+ return false;
-+ }
-+}
-+
-+static int
-+ubicom32_get_valid_offset_mask (enum machine_mode mode)
-+{
-+ switch (mode)
-+ {
-+ case QImode:
-+ return 127;
-+
-+ case HImode:
-+ return 255;
-+
-+ case SImode:
-+ case SFmode:
-+ return 511;
-+
-+ case DImode:
-+ return 255;
-+
-+ default:
-+ return 0;
-+ }
-+}
-+
-+/* Returns 1 if X is a valid base register. STRICT is 1 if only hard
-+ registers should be accepted. Accept either REG or SUBREG where a
-+ register is valid. */
-+
-+static bool
-+ubicom32_is_base_reg (rtx x, int strict)
-+{
-+ if ((REG_P (x) && ubicom32_regno_ok_for_base_p (REGNO (x), strict))
-+ || (GET_CODE (x) == SUBREG && REG_P (SUBREG_REG (x))
-+ && ubicom32_regno_ok_for_base_p (REGNO (SUBREG_REG (x)), strict)))
-+ return true;
-+
-+ return false;
-+}
-+
-+static bool
-+ubicom32_cannot_force_const_mem (rtx x ATTRIBUTE_UNUSED)
-+{
-+ return TARGET_FDPIC;
-+}
-+
-+/* Determine if X is a legitimate constant. */
-+
-+bool
-+ubicom32_legitimate_constant_p (rtx x)
-+{
-+ /* Among its other duties, LEGITIMATE_CONSTANT_P decides whether
-+ a constant can be entered into reg_equiv_constant[]. If we return true,
-+ reload can create new instances of the constant whenever it likes.
-+
-+ The idea is therefore to accept as many constants as possible (to give
-+ reload more freedom) while rejecting constants that can only be created
-+ at certain times. In particular, anything with a symbolic component will
-+ require use of the pseudo FDPIC register, which is only available before
-+ reload. */
-+ if (TARGET_FDPIC)
-+ {
-+ if (GET_CODE (x) == SYMBOL_REF
-+ || (GET_CODE (x) == CONST
-+ && GET_CODE (XEXP (x, 0)) == PLUS
-+ && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF)
-+ || CONSTANT_ADDRESS_P (x))
-+ return false;
-+
-+ return true;
-+ }
-+
-+ /* For non-PIC code anything goes! */
-+ return true;
-+}
-+
-+/* Address validation. */
-+
-+bool
-+ubicom32_legitimate_address_p (enum machine_mode mode, rtx x, int strict)
-+{
-+ if (TARGET_DEBUG_ADDRESS)
-+ {
-+ fprintf (stderr, "\n==> GO_IF_LEGITIMATE_ADDRESS%s\n",
-+ (strict) ? " (STRICT)" : "");
-+ debug_rtx (x);
-+ }
-+
-+ if (CONSTANT_ADDRESS_P (x))
-+ return false;
-+
-+ if (ubicom32_is_base_reg (x, strict))
-+ return true;
-+
-+ if ((GET_CODE (x) == POST_INC
-+ || GET_CODE (x) == PRE_INC
-+ || GET_CODE (x) == POST_DEC
-+ || GET_CODE (x) == PRE_DEC)
-+ && REG_P (XEXP (x, 0))
-+ && ubicom32_is_base_reg (XEXP (x, 0), strict)
-+ && mode != DImode)
-+ return true;
-+
-+ if ((GET_CODE (x) == PRE_MODIFY || GET_CODE (x) == POST_MODIFY)
-+ && ubicom32_is_base_reg (XEXP (x, 0), strict)
-+ && GET_CODE (XEXP (x, 1)) == PLUS
-+ && rtx_equal_p (XEXP (x, 0), XEXP (XEXP (x, 1), 0))
-+ && CONST_INT_P (XEXP (XEXP (x, 1), 1))
-+ && mode != DImode)
-+ {
-+ HOST_WIDE_INT disp = INTVAL (XEXP (XEXP (x, 1), 1));
-+ switch (mode)
-+ {
-+ case QImode:
-+ return disp >= -8 && disp <= 7;
-+
-+ case HImode:
-+ return disp >= -16 && disp <= 14 && ! (disp & 1);
-+
-+ case SImode:
-+ return disp >= -32 && disp <= 28 && ! (disp & 3);
-+
-+ default:
-+ return false;
-+ }
-+ }
-+
-+ /* Accept base + index * scale. */
-+ if (GET_CODE (x) == PLUS
-+ && ubicom32_is_base_reg (XEXP (x, 0), strict)
-+ && ubicom32_is_index_expr (mode, XEXP (x, 1), strict))
-+ return true;
-+
-+ /* Accept index * scale + base. */
-+ if (GET_CODE (x) == PLUS
-+ && ubicom32_is_base_reg (XEXP (x, 1), strict)
-+ && ubicom32_is_index_expr (mode, XEXP (x, 0), strict))
-+ return true;
-+
-+ if (! TARGET_FDPIC)
-+ {
-+ /* Accept (lo_sum (reg) (symbol_ref)) that can be used as a mem+7bits
-+ displacement operand:
-+
-+ moveai a1, #%hi(SYM)
-+ move.4 d3, %lo(SYM)(a1) */
-+ if (GET_CODE (x) == LO_SUM
-+ && ubicom32_is_base_reg (XEXP (x, 0), strict)
-+ && (GET_CODE (XEXP (x, 1)) == SYMBOL_REF
-+ || GET_CODE (XEXP (x, 1)) == LABEL_REF /* FIXME: wrong */)
-+ && mode != DImode)
-+ return true;
-+ }
-+
-+ if (TARGET_DEBUG_ADDRESS)
-+ fprintf (stderr, "\nNot a legitimate address.\n");
-+
-+ return false;
-+}
-+
-+rtx
-+ubicom32_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
-+ enum machine_mode mode)
-+{
-+ if (mode == BLKmode)
-+ return NULL_RTX;
-+
-+ if (GET_CODE (x) == PLUS
-+ && REG_P (XEXP (x, 0))
-+ && ! REGNO_PTR_FRAME_P (REGNO (XEXP (x, 0)))
-+ && CONST_INT_P (XEXP (x, 1))
-+ && ! ubicom32_is_valid_offset (mode, INTVAL (XEXP (x, 1))))
-+ {
-+ rtx base;
-+ rtx plus;
-+ rtx new_rtx;
-+ HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
-+ HOST_WIDE_INT low = val & ubicom32_get_valid_offset_mask (mode);
-+ HOST_WIDE_INT high = val ^ low;
-+
-+ if (val < 0)
-+ return NULL_RTX;
-+
-+ if (! low)
-+ return NULL_RTX;
-+
-+ /* Reload the high part into a base reg; leave the low part
-+ in the mem directly. */
-+ base = XEXP (x, 0);
-+ if (! ubicom32_is_base_reg (base, 0))
-+ base = copy_to_mode_reg (Pmode, base);
-+
-+ plus = expand_simple_binop (Pmode, PLUS,
-+ gen_int_mode (high, Pmode),
-+ base, NULL, 0, OPTAB_WIDEN);
-+ new_rtx = plus_constant (plus, low);
-+
-+ return new_rtx;
-+ }
-+
-+ return NULL_RTX;
-+}
-+
-+/* Try a machine-dependent way of reloading an illegitimate address AD
-+ operand. If we find one, push the reload and and return the new address.
-+
-+ MODE is the mode of the enclosing MEM. OPNUM is the operand number
-+ and TYPE is the reload type of the current reload. */
-+
-+rtx
-+ubicom32_legitimize_reload_address (rtx ad, enum machine_mode mode,
-+ int opnum, int type)
-+{
-+ /* Is this an address that we've already fixed up? If it is then
-+ recognize it and move on. */
-+ if (GET_CODE (ad) == PLUS
-+ && GET_CODE (XEXP (ad, 0)) == PLUS
-+ && REG_P (XEXP (XEXP (ad, 0), 0))
-+ && CONST_INT_P (XEXP (XEXP (ad, 0), 1))
-+ && CONST_INT_P (XEXP (ad, 1)))
-+ {
-+ push_reload (XEXP (ad, 0), NULL_RTX, &XEXP (ad, 0), NULL,
-+ BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
-+ opnum, (enum reload_type) type);
-+ return ad;
-+ }
-+
-+ /* Have we got an address where the offset is simply out of range? If
-+ yes then reload the range as a high part and smaller offset. */
-+ if (GET_CODE (ad) == PLUS
-+ && REG_P (XEXP (ad, 0))
-+ && REGNO (XEXP (ad, 0)) < FIRST_PSEUDO_REGISTER
-+ && REGNO_OK_FOR_BASE_P (REGNO (XEXP (ad, 0)))
-+ && CONST_INT_P (XEXP (ad, 1))
-+ && ! ubicom32_is_valid_offset (mode, INTVAL (XEXP (ad, 1))))
-+ {
-+ rtx temp;
-+ rtx new_rtx;
-+
-+ HOST_WIDE_INT val = INTVAL (XEXP (ad, 1));
-+ HOST_WIDE_INT low = val & ubicom32_get_valid_offset_mask (mode);
-+ HOST_WIDE_INT high = val ^ low;
-+
-+ /* Reload the high part into a base reg; leave the low part
-+ in the mem directly. */
-+ temp = gen_rtx_PLUS (Pmode, XEXP (ad, 0), GEN_INT (high));
-+ new_rtx = gen_rtx_PLUS (Pmode, temp, GEN_INT (low));
-+
-+ push_reload (XEXP (new_rtx, 0), NULL_RTX, &XEXP (new_rtx, 0), NULL,
-+ BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
-+ opnum, (enum reload_type) type);
-+ return new_rtx;
-+ }
-+
-+ /* If we're presented with an pre/post inc/dec then we must force this
-+ to be done in an address register. The register allocator should
-+ work this out for itself but at times ends up trying to use the wrong
-+ class. If we get the wrong class then reload will end up generating
-+ at least 3 instructions whereas this way we can hopefully keep it to
-+ just 2. */
-+ if ((GET_CODE (ad) == POST_INC
-+ || GET_CODE (ad) == PRE_INC
-+ || GET_CODE (ad) == POST_DEC
-+ || GET_CODE (ad) == PRE_DEC)
-+ && REG_P (XEXP (ad, 0))
-+ && REGNO (XEXP (ad, 0)) < FIRST_PSEUDO_REGISTER
-+ && ! REGNO_OK_FOR_BASE_P (REGNO (XEXP (ad, 0))))
-+ {
-+ push_reload (XEXP (ad, 0), XEXP (ad, 0), &XEXP (ad, 0), &XEXP (ad, 0),
-+ BASE_REG_CLASS, GET_MODE (XEXP (ad, 0)), GET_MODE (XEXP (ad, 0)), 0, 0,
-+ opnum, RELOAD_OTHER);
-+ return ad;
-+ }
-+
-+ return NULL_RTX;
-+}
-+
-+/* Compute a (partial) cost for rtx X. Return true if the complete
-+ cost has been computed, and false if subexpressions should be
-+ scanned. In either case, *TOTAL contains the cost result. */
-+
-+static bool
-+ubicom32_rtx_costs (rtx x, int code, int outer_code, int *total,
-+ bool speed ATTRIBUTE_UNUSED)
-+{
-+ enum machine_mode mode = GET_MODE (x);
-+
-+ switch (code)
-+ {
-+ case CONST_INT:
-+ /* Very short constants often fold into instructions so
-+ we pretend that they don't cost anything! This is
-+ really important as regards zero values as otherwise
-+ the compiler has a nasty habit of wanting to reuse
-+ zeroes that are in regs but that tends to pessimize
-+ the code. */
-+ if (satisfies_constraint_I (x))
-+ {
-+ *total = 0;
-+ return true;
-+ }
-+
-+ /* Bit clearing costs nothing */
-+ if (outer_code == AND
-+ && exact_log2 (~INTVAL (x)) != -1)
-+ {
-+ *total = 0;
-+ return true;
-+ }
-+
-+ /* Masking the lower set of bits costs nothing. */
-+ if (outer_code == AND
-+ && exact_log2 (INTVAL (x) + 1) != -1)
-+ {
-+ *total = 0;
-+ return true;
-+ }
-+
-+ /* Bit setting costs nothing. */
-+ if (outer_code == IOR
-+ && exact_log2 (INTVAL (x)) != -1)
-+ {
-+ *total = 0;
-+ return true;
-+ }
-+
-+ /* Larger constants that can be loaded via movei aren't too
-+ bad. If we're just doing a set they cost nothing extra. */
-+ if (satisfies_constraint_N (x))
-+ {
-+ if (mode == DImode)
-+ *total = COSTS_N_INSNS (2);
-+ else
-+ *total = COSTS_N_INSNS (1);
-+ return true;
-+ }
-+
-+ if (mode == DImode)
-+ *total = COSTS_N_INSNS (5);
-+ else
-+ *total = COSTS_N_INSNS (3);
-+ return true;
-+
-+ case CONST_DOUBLE:
-+ /* We don't optimize CONST_DOUBLEs well nor do we relax them well,
-+ so their cost is very high. */
-+ *total = COSTS_N_INSNS (6);
-+ return true;
-+
-+ case CONST:
-+ case SYMBOL_REF:
-+ case MEM:
-+ *total = 0;
-+ return true;
-+
-+ case IF_THEN_ELSE:
-+ *total = COSTS_N_INSNS (1);
-+ return true;
-+
-+ case LABEL_REF:
-+ case HIGH:
-+ case LO_SUM:
-+ case BSWAP:
-+ case PLUS:
-+ case MINUS:
-+ case AND:
-+ case IOR:
-+ case XOR:
-+ case ASHIFT:
-+ case ASHIFTRT:
-+ case LSHIFTRT:
-+ case NEG:
-+ case NOT:
-+ case SIGN_EXTEND:
-+ case ZERO_EXTEND:
-+ case ZERO_EXTRACT:
-+ if (outer_code == SET)
-+ {
-+ if (mode == DImode)
-+ *total = COSTS_N_INSNS (2);
-+ else
-+ *total = COSTS_N_INSNS (1);
-+ }
-+ return true;
-+
-+ case COMPARE:
-+ if (outer_code == SET)
-+ {
-+ if (GET_MODE (XEXP (x, 0)) == DImode
-+ || GET_MODE (XEXP (x, 1)) == DImode)
-+ *total = COSTS_N_INSNS (2);
-+ else
-+ *total = COSTS_N_INSNS (1);
-+ }
-+ return true;
-+
-+ case UMOD:
-+ case UDIV:
-+ case MOD:
-+ case DIV:
-+ if (outer_code == SET)
-+ {
-+ if (mode == DImode)
-+ *total = COSTS_N_INSNS (600);
-+ else
-+ *total = COSTS_N_INSNS (200);
-+ }
-+ return true;
-+
-+ case MULT:
-+ if (outer_code == SET)
-+ {
-+ if (! ubicom32_v4)
-+ {
-+ if (mode == DImode)
-+ *total = COSTS_N_INSNS (15);
-+ else
-+ *total = COSTS_N_INSNS (5);
-+ }
-+ else
-+ {
-+ if (mode == DImode)
-+ *total = COSTS_N_INSNS (6);
-+ else
-+ *total = COSTS_N_INSNS (2);
-+ }
-+ }
-+ return true;
-+
-+ case UNSPEC:
-+ if (XINT (x, 1) == UNSPEC_FDPIC_GOT
-+ || XINT (x, 1) == UNSPEC_FDPIC_GOT_FUNCDESC)
-+ *total = 0;
-+ return true;
-+
-+ default:
-+ return false;
-+ }
-+}
-+
-+/* Return 1 if ADDR can have different meanings depending on the machine
-+ mode of the memory reference it is used for or if the address is
-+ valid for some modes but not others.
-+
-+ Autoincrement and autodecrement addresses typically have
-+ mode-dependent effects because the amount of the increment or
-+ decrement is the size of the operand being addressed. Some machines
-+ have other mode-dependent addresses. Many RISC machines have no
-+ mode-dependent addresses.
-+
-+ You may assume that ADDR is a valid address for the machine. */
-+
-+int
-+ubicom32_mode_dependent_address_p (rtx addr)
-+{
-+ if (GET_CODE (addr) == POST_INC
-+ || GET_CODE (addr) == PRE_INC
-+ || GET_CODE (addr) == POST_DEC
-+ || GET_CODE (addr) == PRE_DEC
-+ || GET_CODE (addr) == POST_MODIFY
-+ || GET_CODE (addr) == PRE_MODIFY)
-+ return 1;
-+
-+ return 0;
-+}
-+
-+static void
-+ubicom32_function_prologue (FILE *file, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
-+{
-+ fprintf (file, "/* frame/pretend: %ld/%d save_regs: %d out_args: %d %s */\n",
-+ get_frame_size (), crtl->args.pretend_args_size,
-+ save_regs_size, crtl->outgoing_args_size,
-+ current_function_is_leaf ? "leaf" : "nonleaf");
-+}
-+
-+static void
-+ubicom32_function_epilogue (FILE *file ATTRIBUTE_UNUSED,
-+ HOST_WIDE_INT size ATTRIBUTE_UNUSED)
-+{
-+ ubicom32_reorg_completed = 0;
-+}
-+
-+static void
-+ubicom32_machine_dependent_reorg (void)
-+{
-+#if 0 /* Commenting out this optimization until it is fixed */
-+ if (optimize)
-+ {
-+ compute_bb_for_insn ();
-+
-+ /* Do a very simple CSE pass over just the hard registers. */
-+ reload_cse_regs (get_insns ());
-+
-+ /* Reload_cse_regs can eliminate potentially-trapping MEMs.
-+ Remove any EH edges associated with them. */
-+ if (flag_non_call_exceptions)
-+ purge_all_dead_edges ();
-+ }
-+#endif
-+ ubicom32_reorg_completed = 1;
-+}
-+
-+void
-+ubicom32_output_cond_jump (rtx insn, rtx cond, rtx target)
-+{
-+ rtx note;
-+ int mostly_false_jump;
-+ rtx xoperands[2];
-+ rtx cc_reg;
-+
-+ note = find_reg_note (insn, REG_BR_PROB, 0);
-+ mostly_false_jump = !note || (INTVAL (XEXP (note, 0))
-+ <= REG_BR_PROB_BASE / 2);
-+
-+ xoperands[0] = target;
-+ xoperands[1] = cond;
-+ cc_reg = XEXP (cond, 0);
-+
-+ if (GET_MODE (cc_reg) == CCWmode
-+ || GET_MODE (cc_reg) == CCWZmode
-+ || GET_MODE (cc_reg) == CCWZNmode)
-+ {
-+ if (mostly_false_jump)
-+ output_asm_insn ("jmp%b1.w.f\t%0", xoperands);
-+ else
-+ output_asm_insn ("jmp%b1.w.t\t%0", xoperands);
-+ return;
-+ }
-+
-+ if (GET_MODE (cc_reg) == CCSmode
-+ || GET_MODE (cc_reg) == CCSZmode
-+ || GET_MODE (cc_reg) == CCSZNmode)
-+ {
-+ if (mostly_false_jump)
-+ output_asm_insn ("jmp%b1.s.f\t%0", xoperands);
-+ else
-+ output_asm_insn ("jmp%b1.s.t\t%0", xoperands);
-+ return;
-+ }
-+
-+ abort ();
-+}
-+
-+/* Return non-zero if FUNC is a naked function. */
-+
-+static int
-+ubicom32_naked_function_p (void)
-+{
-+ return lookup_attribute ("naked", DECL_ATTRIBUTES (current_function_decl)) != NULL_TREE;
-+}
-+
-+/* Return an RTX indicating where the return address to the
-+ calling function can be found. */
-+rtx
-+ubicom32_return_addr_rtx (int count, rtx frame ATTRIBUTE_UNUSED)
-+{
-+ if (count != 0)
-+ return NULL_RTX;
-+
-+ return get_hard_reg_initial_val (Pmode, LINK_REGNO);
-+}
-+
-+/*
-+ * ubicom32_readonly_data_section: This routtine handles code
-+ * at the start of readonly data sections
-+ */
-+static void
-+ubicom32_readonly_data_section (const void *data ATTRIBUTE_UNUSED)
-+{
-+ static int num = 0;
-+ if (in_section == readonly_data_section){
-+ fprintf (asm_out_file, "%s", DATA_SECTION_ASM_OP);
-+ if (flag_data_sections){
-+ fprintf (asm_out_file, ".rodata%d", num);
-+ fprintf (asm_out_file, ",\"a\"");
-+ }
-+ fprintf (asm_out_file, "\n");
-+ }
-+ num++;
-+}
-+
-+/*
-+ * ubicom32_text_section: not in readonly section
-+ */
-+static void
-+ubicom32_text_section(const void *data ATTRIBUTE_UNUSED)
-+{
-+ fprintf (asm_out_file, "%s\n", TEXT_SECTION_ASM_OP);
-+}
-+
-+/*
-+ * ubicom32_data_section: not in readonly section
-+ */
-+static void
-+ubicom32_data_section(const void *data ATTRIBUTE_UNUSED)
-+{
-+ fprintf (asm_out_file, "%s\n", DATA_SECTION_ASM_OP);
-+}
-+
-+/*
-+ * ubicom32_asm_init_sections: This routine implements special
-+ * section handling
-+ */
-+static void
-+ubicom32_asm_init_sections(void)
-+{
-+ text_section = get_unnamed_section(SECTION_CODE, ubicom32_text_section, NULL);
-+
-+ data_section = get_unnamed_section(SECTION_WRITE, ubicom32_data_section, NULL);
-+
-+ readonly_data_section = get_unnamed_section(0, ubicom32_readonly_data_section, NULL);
-+}
-+
-+/*
-+ * ubicom32_profiler: This routine would call
-+ * mcount to support prof and gprof if mcount
-+ * was supported. Currently, do nothing.
-+ */
-+void
-+ubicom32_profiler(void)
-+{
-+}
-+
-+/* Initialise the builtin functions. Start by initialising
-+ descriptions of different types of functions (e.g., void fn(int),
-+ int fn(void)), and then use these to define the builtins. */
-+static void
-+ubicom32_init_builtins (void)
-+{
-+ tree endlink;
-+ tree short_unsigned_endlink;
-+ tree unsigned_endlink;
-+ tree short_unsigned_ftype_short_unsigned;
-+ tree unsigned_ftype_unsigned;
-+
-+ endlink = void_list_node;
-+
-+ short_unsigned_endlink
-+ = tree_cons (NULL_TREE, short_unsigned_type_node, endlink);
-+
-+ unsigned_endlink
-+ = tree_cons (NULL_TREE, unsigned_type_node, endlink);
-+
-+ short_unsigned_ftype_short_unsigned
-+ = build_function_type (short_unsigned_type_node, short_unsigned_endlink);
-+
-+ unsigned_ftype_unsigned
-+ = build_function_type (unsigned_type_node, unsigned_endlink);
-+
-+ /* Initialise the byte swap function. */
-+ add_builtin_function ("__builtin_ubicom32_swapb_2",
-+ short_unsigned_ftype_short_unsigned,
-+ UBICOM32_BUILTIN_UBICOM32_SWAPB_2,
-+ BUILT_IN_MD, NULL,
-+ NULL_TREE);
-+
-+ /* Initialise the byte swap function. */
-+ add_builtin_function ("__builtin_ubicom32_swapb_4",
-+ unsigned_ftype_unsigned,
-+ UBICOM32_BUILTIN_UBICOM32_SWAPB_4,
-+ BUILT_IN_MD, NULL,
-+ NULL_TREE);
-+}
-+
-+/* Given a builtin function taking 2 operands (i.e., target + source),
-+ emit the RTL for the underlying instruction. */
-+static rtx
-+ubicom32_expand_builtin_2op (enum insn_code icode, tree arglist, rtx target)
-+{
-+ tree arg0;
-+ rtx op0, pat;
-+ enum machine_mode tmode, mode0;
-+
-+ /* Grab the incoming argument and emit its RTL. */
-+ arg0 = TREE_VALUE (arglist);
-+ op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
-+
-+ /* Determine the modes of the instruction operands. */
-+ tmode = insn_data[icode].operand[0].mode;
-+ mode0 = insn_data[icode].operand[1].mode;
-+
-+ /* Ensure that the incoming argument RTL is in a register of the
-+ correct mode. */
-+ if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
-+ op0 = copy_to_mode_reg (mode0, op0);
-+
-+ /* If there isn't a suitable target, emit a target register. */
-+ if (target == 0
-+ || GET_MODE (target) != tmode
-+ || !(*insn_data[icode].operand[0].predicate) (target, tmode))
-+ target = gen_reg_rtx (tmode);
-+
-+ /* Emit and return the new instruction. */
-+ pat = GEN_FCN (icode) (target, op0);
-+ if (!pat)
-+ return 0;
-+ emit_insn (pat);
-+
-+ return target;
-+}
-+
-+/* Expand a call to a builtin function. */
-+static rtx
-+ubicom32_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
-+ enum machine_mode mode ATTRIBUTE_UNUSED,
-+ int ignore ATTRIBUTE_UNUSED)
-+{
-+ tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
-+ tree arglist = CALL_EXPR_ARGS(exp);
-+ int fcode = DECL_FUNCTION_CODE (fndecl);
-+
-+ switch (fcode)
-+ {
-+ case UBICOM32_BUILTIN_UBICOM32_SWAPB_2:
-+ return ubicom32_expand_builtin_2op (CODE_FOR_bswaphi, arglist, target);
-+
-+ case UBICOM32_BUILTIN_UBICOM32_SWAPB_4:
-+ return ubicom32_expand_builtin_2op (CODE_FOR_bswapsi, arglist, target);
-+
-+ default:
-+ gcc_unreachable();
-+ }
-+
-+ /* Should really do something sensible here. */
-+ return NULL_RTX;
-+}
-+
-+/* Fold any constant argument for a swapb.2 instruction. */
-+static tree
-+ubicom32_fold_builtin_ubicom32_swapb_2 (tree fndecl, tree arglist)
-+{
-+ tree arg0;
-+
-+ arg0 = TREE_VALUE (arglist);
-+
-+ /* Optimize constant value. */
-+ if (TREE_CODE (arg0) == INTEGER_CST)
-+ {
-+ HOST_WIDE_INT v;
-+ HOST_WIDE_INT res;
-+
-+ v = TREE_INT_CST_LOW (arg0);
-+ res = ((v >> 8) & 0xff)
-+ | ((v & 0xff) << 8);
-+
-+ return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), res);
-+ }
-+
-+ return NULL_TREE;
-+}
-+
-+/* Fold any constant argument for a swapb.4 instruction. */
-+static tree
-+ubicom32_fold_builtin_ubicom32_swapb_4 (tree fndecl, tree arglist)
-+{
-+ tree arg0;
-+
-+ arg0 = TREE_VALUE (arglist);
-+
-+ /* Optimize constant value. */
-+ if (TREE_CODE (arg0) == INTEGER_CST)
-+ {
-+ unsigned HOST_WIDE_INT v;
-+ unsigned HOST_WIDE_INT res;
-+
-+ v = TREE_INT_CST_LOW (arg0);
-+ res = ((v >> 24) & 0xff)
-+ | (((v >> 16) & 0xff) << 8)
-+ | (((v >> 8) & 0xff) << 16)
-+ | ((v & 0xff) << 24);
-+
-+ return build_int_cst_wide (TREE_TYPE (TREE_TYPE (fndecl)), res, 0);
-+ }
-+
-+ return NULL_TREE;
-+}
-+
-+/* Fold any constant arguments for builtin functions. */
-+static tree
-+ubicom32_fold_builtin (tree fndecl, tree arglist, bool ignore ATTRIBUTE_UNUSED)
-+{
-+ switch (DECL_FUNCTION_CODE (fndecl))
-+ {
-+ case UBICOM32_BUILTIN_UBICOM32_SWAPB_2:
-+ return ubicom32_fold_builtin_ubicom32_swapb_2 (fndecl, arglist);
-+
-+ case UBICOM32_BUILTIN_UBICOM32_SWAPB_4:
-+ return ubicom32_fold_builtin_ubicom32_swapb_4 (fndecl, arglist);
-+
-+ default:
-+ return NULL;
-+ }
-+}
-+
-+/* Implementation of TARGET_ASM_INTEGER. When using FD-PIC, we need to
-+ tell the assembler to generate pointers to function descriptors in
-+ some cases. */
-+static bool
-+ubicom32_assemble_integer (rtx value, unsigned int size, int aligned_p)
-+{
-+ if (TARGET_FDPIC && size == UNITS_PER_WORD)
-+ {
-+ if (GET_CODE (value) == SYMBOL_REF
-+ && SYMBOL_REF_FUNCTION_P (value))
-+ {
-+ fputs ("\t.picptr\t%funcdesc(", asm_out_file);
-+ output_addr_const (asm_out_file, value);
-+ fputs (")\n", asm_out_file);
-+ return true;
-+ }
-+
-+ if (!aligned_p)
-+ {
-+ /* We've set the unaligned SI op to NULL, so we always have to
-+ handle the unaligned case here. */
-+ assemble_integer_with_op ("\t.4byte\t", value);
-+ return true;
-+ }
-+ }
-+
-+ return default_assemble_integer (value, size, aligned_p);
-+}
-+
-+/* If the constant I can be constructed by shifting a source-1 immediate
-+ by a constant number of bits then return the bit count. If not
-+ return 0. */
-+
-+int
-+ubicom32_shiftable_const_int (int i)
-+{
-+ int shift = 0;
-+
-+ /* Note that any constant that can be represented as an immediate to
-+ a movei instruction is automatically ignored here in the interests
-+ of the clarity of the output asm code. */
-+ if (i >= -32768 && i <= 32767)
-+ return 0;
-+
-+ /* Find the number of trailing zeroes. We could use __builtin_ctz
-+ here but it's not obvious if this is supported on all build
-+ compilers so we err on the side of caution. */
-+ if ((i & 0xffff) == 0)
-+ {
-+ shift += 16;
-+ i >>= 16;
-+ }
-+
-+ if ((i & 0xff) == 0)
-+ {
-+ shift += 8;
-+ i >>= 8;
-+ }
-+
-+ if ((i & 0xf) == 0)
-+ {
-+ shift += 4;
-+ i >>= 4;
-+ }
-+
-+ if ((i & 0x3) == 0)
-+ {
-+ shift += 2;
-+ i >>= 2;
-+ }
-+
-+ if ((i & 0x1) == 0)
-+ {
-+ shift += 1;
-+ i >>= 1;
-+ }
-+
-+ if (i >= -128 && i <= 127)
-+ return shift;
-+
-+ return 0;
-+}
-+
---- /dev/null
-+++ b/gcc/config/ubicom32/ubicom32.h
-@@ -0,0 +1,1564 @@
-+/* Definitions of target machine for Ubicom32
-+
-+ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
-+ 2009 Free Software Foundation, Inc.
-+ Contributed by Ubicom, Inc.
-+
-+ This file is part of GCC.
-+
-+ GCC is free software; you can redistribute it and/or modify it
-+ under the terms of the GNU General Public License as published
-+ by the Free Software Foundation; either version 3, or (at your
-+ option) any later version.
-+
-+ GCC is distributed in the hope that it will be useful, but WITHOUT
-+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
-+ License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with GCC; see the file COPYING3. If not see
-+ <http://www.gnu.org/licenses/>. */
-+
-+\f
-+
-+#define OBJECT_FORMAT_ELF
-+
-+/* Run-time target specifications. */
-+
-+/* Target CPU builtins. */
-+#define TARGET_CPU_CPP_BUILTINS() \
-+ do \
-+ { \
-+ builtin_define_std ("__UBICOM32__"); \
-+ builtin_define_std ("__ubicom32__"); \
-+ \
-+ if (TARGET_FDPIC) \
-+ { \
-+ builtin_define ("__UBICOM32_FDPIC__"); \
-+ builtin_define ("__FDPIC__"); \
-+ } \
-+ } \
-+ while (0)
-+
-+#ifndef TARGET_DEFAULT
-+#define TARGET_DEFAULT 0
-+#endif
-+
-+extern int ubicom32_case_values_threshold;
-+
-+/* Nonzero if this chip supports the Ubicom32 v3 ISA. */
-+extern int ubicom32_v3;
-+
-+/* Nonzero if this chip supports the Ubicom32 v4 ISA. */
-+extern int ubicom32_v4;
-+
-+extern int ubicom32_stack_size;
-+
-+/* Flag for whether we can use calli instead of ret in returns. */
-+extern int ubicom32_can_use_calli_to_ret;
-+
-+/* This macro is a C statement to print on `stderr' a string describing the
-+ particular machine description choice. Every machine description should
-+ define `TARGET_VERSION'. */
-+#define TARGET_VERSION fprintf (stderr, " (UBICOM32)");
-+
-+/* We don't need a frame pointer to debug things. Doing this means
-+ that gcc can turn on -fomit-frame-pointer when '-O' is specified. */
-+#define CAN_DEBUG_WITHOUT_FP
-+
-+/* We need to handle processor-specific options. */
-+#define OVERRIDE_OPTIONS ubicom32_override_options ()
-+
-+#define OPTIMIZATION_OPTIONS(LEVEL, SIZE) \
-+ ubicom32_optimization_options (LEVEL, SIZE)
-+
-+/* For Ubicom32 the least significant bit has the lowest bit number
-+ so we define this to be 0. */
-+#define BITS_BIG_ENDIAN 0
-+
-+/* For Ubicom32 the most significant byte in a word has the lowest
-+ number. */
-+#define BYTES_BIG_ENDIAN 1
-+
-+/* For Ubicom32, in a multiword object, the most signifant word has the
-+ lowest number. */
-+#define WORDS_BIG_ENDIAN 1
-+
-+/* Ubicom32 has 8 bits per byte. */
-+#define BITS_PER_UNIT 8
-+
-+/* Ubicom32 has 32 bits per word. */
-+#define BITS_PER_WORD 32
-+
-+/* Width of a word, in units (bytes). */
-+#define UNITS_PER_WORD 4
-+
-+/* Width of a pointer, in bits. */
-+#define POINTER_SIZE 32
-+
-+/* Alias for pointers. Ubicom32 is a 32-bit architecture so we use
-+ SImode. */
-+#define Pmode SImode
-+
-+/* Normal alignment required for function parameters on the stack, in
-+ bits. */
-+#define PARM_BOUNDARY 32
-+
-+/* We need to maintain the stack on a 32-bit boundary. */
-+#define STACK_BOUNDARY 32
-+
-+/* Alignment required for a function entry point, in bits. */
-+#define FUNCTION_BOUNDARY 32
-+
-+/* Alias for the machine mode used for memory references to functions being
-+ called, in `call' RTL expressions. We use byte-oriented addresses
-+ here. */
-+#define FUNCTION_MODE QImode
-+
-+/* Biggest alignment that any data type can require on this machine,
-+ in bits. */
-+#define BIGGEST_ALIGNMENT 32
-+
-+/* this default to BIGGEST_ALIGNMENT unless defined */
-+/* ART: What's the correct value here? Default is (((unsigned int)1<<28)*8)*/
-+#undef MAX_OFILE_ALIGNMENT
-+#define MAX_OFILE_ALIGNMENT (128 * 8)
-+
-+/* Alignment in bits to be given to a structure bit field that follows an empty
-+ field such as `int : 0;'. */
-+#define EMPTY_FIELD_BOUNDARY 32
-+
-+/* All structures must be a multiple of 32 bits in size. */
-+#define STRUCTURE_SIZE_BOUNDARY 32
-+
-+/* A bit-field declared as `int' forces `int' alignment for the struct. */
-+#define PCC_BITFIELD_TYPE_MATTERS 1
-+
-+/* For Ubicom32 we absolutely require that data be aligned with nominal
-+ alignment. */
-+#define STRICT_ALIGNMENT 1
-+
-+/* Make strcpy of constants fast. */
-+#define CONSTANT_ALIGNMENT(EXP, ALIGN) \
-+ (TREE_CODE (EXP) == STRING_CST \
-+ && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
-+
-+/* Define this macro as an expression for the alignment of a structure
-+ (given by STRUCT as a tree node) if the alignment computed in the
-+ usual way is COMPUTED and the alignment explicitly specified was
-+ SPECIFIED. */
-+#define DATA_ALIGNMENT(TYPE, ALIGN) \
-+ ((((ALIGN) < BITS_PER_WORD) \
-+ && (TREE_CODE (TYPE) == ARRAY_TYPE \
-+ || TREE_CODE (TYPE) == UNION_TYPE \
-+ || TREE_CODE (TYPE) == RECORD_TYPE)) ? BITS_PER_WORD : (ALIGN))
-+
-+#define LOCAL_ALIGNMENT(TYPE,ALIGN) DATA_ALIGNMENT(TYPE,ALIGN)
-+
-+/* For Ubicom32 we default to unsigned chars. */
-+#define DEFAULT_SIGNED_CHAR 0
-+
-+/* Machine-specific data register numbers. */
-+#define FIRST_DATA_REGNUM 0
-+#define D10_REGNUM 10
-+#define D11_REGNUM 11
-+#define D12_REGNUM 12
-+#define D13_REGNUM 13
-+#define LAST_DATA_REGNUM 15
-+
-+/* Machine-specific address register numbers. */
-+#define FIRST_ADDRESS_REGNUM 16
-+#define LAST_ADDRESS_REGNUM 22
-+
-+/* Register numbers used for passing a function's static chain pointer. If
-+ register windows are used, the register number as seen by the called
-+ function is `STATIC_CHAIN_INCOMING_REGNUM', while the register number as
-+ seen by the calling function is `STATIC_CHAIN_REGNUM'. If these registers
-+ are the same, `STATIC_CHAIN_INCOMING_REGNUM' need not be defined.
-+
-+ The static chain register need not be a fixed register.
-+
-+ If the static chain is passed in memory, these macros should not be defined;
-+ instead, the next two macros should be defined. */
-+#define STATIC_CHAIN_REGNUM (FIRST_ADDRESS_REGNUM + 1)
-+
-+/* The register number of the frame pointer register, which is used to access
-+ automatic variables in the stack frame. We generally eliminate this anyway
-+ for Ubicom32 but we make it A6 by default. */
-+#define FRAME_POINTER_REGNUM (LAST_ADDRESS_REGNUM)
-+
-+/* The register number of the stack pointer register, which is also be a
-+ fixed register according to `FIXED_REGISTERS'. For Ubicom32 we don't
-+ have a hardware requirement about which register this is, but by convention
-+ we use A7. */
-+#define STACK_POINTER_REGNUM (LAST_ADDRESS_REGNUM + 1)
-+
-+/* Machine-specific accumulator register numbers. */
-+#define ACC0_HI_REGNUM 24
-+#define ACC0_LO_REGNUM 25
-+#define ACC1_HI_REGNUM 26
-+#define ACC1_LO_REGNUM 27
-+
-+/* source3 register number */
-+#define SOURCE3_REGNUM 28
-+
-+/* The register number of the arg pointer register, which is used to access the
-+ function's argument list. On some machines, this is the same as the frame
-+ pointer register. On some machines, the hardware determines which register
-+ this is. On other machines, you can choose any register you wish for this
-+ purpose. If this is not the same register as the frame pointer register,
-+ then you must mark it as a fixed register according to `FIXED_REGISTERS', or
-+ arrange to be able to eliminate it. */
-+#define ARG_POINTER_REGNUM 29
-+
-+/* Pseudo-reg for condition code. */
-+#define CC_REGNUM 30
-+
-+/* Interrupt set/clear registers. */
-+#define INT_SET0_REGNUM 31
-+#define INT_SET1_REGNUM 32
-+#define INT_CLR0_REGNUM 33
-+#define INT_CLR1_REGNUM 34
-+
-+/* Scratchpad registers. */
-+#define SCRATCHPAD0_REGNUM 35
-+#define SCRATCHPAD1_REGNUM 36
-+#define SCRATCHPAD2_REGNUM 37
-+#define SCRATCHPAD3_REGNUM 38
-+
-+/* FDPIC register. */
-+#define FDPIC_REGNUM 16
-+
-+/* Number of hardware registers known to the compiler. They receive numbers 0
-+ through `FIRST_PSEUDO_REGISTER-1'; thus, the first pseudo register's number
-+ really is assigned the number `FIRST_PSEUDO_REGISTER'. */
-+#define FIRST_PSEUDO_REGISTER 39
-+
-+/* An initializer that says which registers are used for fixed purposes all
-+ throughout the compiled code and are therefore not available for general
-+ allocation. These would include the stack pointer, the frame pointer
-+ (except on machines where that can be used as a general register when no
-+ frame pointer is needed), the program counter on machines where that is
-+ considered one of the addressable registers, and any other numbered register
-+ with a standard use.
-+
-+ This information is expressed as a sequence of numbers, separated by commas
-+ and surrounded by braces. The Nth number is 1 if register N is fixed, 0
-+ otherwise.
-+
-+ The table initialized from this macro, and the table initialized by the
-+ following one, may be overridden at run time either automatically, by the
-+ actions of the macro `CONDITIONAL_REGISTER_USAGE', or by the user with the
-+ command options `-ffixed-REG', `-fcall-used-REG' and `-fcall-saved-REG'. */
-+#define FIXED_REGISTERS \
-+ { \
-+ 0, 0, 0, 0, 0, 0, 0, 0, /* d0 - d7 */ \
-+ 0, 0, 0, 0, 0, 0, 0, 1, /* d8 - d15 */ \
-+ 0, 0, 0, 0, 0, 0, 0, 1, /* a0 - a7 */ \
-+ 0, 0, /* acc0 hi/lo */ \
-+ 0, 0, /* acc1 hi/lo */ \
-+ 0, /* source3 */ \
-+ 1, /* arg */ \
-+ 1, /* cc */ \
-+ 1, 1, /* int_set[01] */ \
-+ 1, 1, /* int_clr[01] */ \
-+ 1, 1, 1, 1 /* scratchpad[0123] */ \
-+ }
-+
-+/* Like `FIXED_REGISTERS' but has 1 for each register that is clobbered (in
-+ general) by function calls as well as for fixed registers. This macro
-+ therefore identifies the registers that are not available for general
-+ allocation of values that must live across function calls.
-+
-+ If a register has 0 in `CALL_USED_REGISTERS', the compiler automatically
-+ saves it on function entry and restores it on function exit, if the register
-+ is used within the function. */
-+#define CALL_USED_REGISTERS \
-+ { \
-+ 1, 1, 1, 1, 1, 1, 1, 1, /* d0 - d7 */ \
-+ 1, 1, 0, 0, 0, 0, 1, 1, /* d8 - d15 */ \
-+ 1, 0, 0, 1, 1, 1, 0, 1, /* a0 - a7 */ \
-+ 1, 1, /* acc0 hi/lo */ \
-+ 1, 1, /* acc1 hi/lo */ \
-+ 1, /* source3 */ \
-+ 1, /* arg */ \
-+ 1, /* cc */ \
-+ 1, 1, /* int_set[01] */ \
-+ 1, 1, /* int_clr[01] */ \
-+ 1, 1, 1, 1 /* scratchpad[0123] */ \
-+ }
-+
-+/* How to refer to registers in assembler output.
-+ This sequence is indexed by compiler's hard-register-number (see above). */
-+
-+/* A C initializer containing the assembler's names for the machine registers,
-+ each one as a C string constant. This is what translates register numbers
-+ in the compiler into assembler language. */
-+#define REGISTER_NAMES \
-+ { \
-+ "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", \
-+ "d8", "d9", "d10", "d11", "d12", "d13", "d14", "d15", \
-+ "a0", "a1", "a2", "a3", "a4", "a5", "a6", "sp", \
-+ "acc0_hi", "acc0_lo", \
-+ "acc1_hi", "acc1_lo", \
-+ "source3", \
-+ "arg", \
-+ "cc", \
-+ "int_set0", "int_set1", \
-+ "int_clr0", "int_clr1", \
-+ "scratchpad0", "scratchpad1", "scratchpad2", "scratchpad3" \
-+ }
-+
-+#define CONDITIONAL_REGISTER_USAGE \
-+ ubicom32_conditional_register_usage ();
-+
-+/* Order of allocation of registers. */
-+
-+/* If defined, an initializer for a vector of integers, containing the numbers
-+ of hard registers in the order in which GNU CC should prefer to use them
-+ (from most preferred to least).
-+
-+ For Ubicom32 we try using caller-clobbered data registers first, then
-+ callee-saved data registers, then caller-clobbered address registers,
-+ then callee-saved address registers and finally everything else.
-+
-+ The caller-clobbered registers are usually slightly cheaper to use because
-+ there's no need to save/restore. */
-+#define REG_ALLOC_ORDER \
-+ { \
-+ 0, 1, 2, 3, 4, /* d0 - d4 */ \
-+ 5, 6, 7, 8, 9, /* d5 - d9 */ \
-+ 14, /* d14 */ \
-+ 10, 11, 12, 13, /* d10 - d13 */ \
-+ 19, 20, 16, 21, /* a3, a4, a0, a5 */ \
-+ 17, 18, 22, /* a1, a2, a6 */ \
-+ 24, 25, /* acc0 hi/lo */ \
-+ 26, 27, /* acc0 hi/lo */ \
-+ 28 /* source3 */ \
-+ }
-+
-+/* C expression for the number of consecutive hard registers, starting at
-+ register number REGNO, required to hold a value of mode MODE. */
-+#define HARD_REGNO_NREGS(REGNO, MODE) \
-+ ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
-+
-+/* Most registers can hold QImode, HImode and SImode values but we have to
-+ be able to indicate any hard registers that cannot hold values with some
-+ modes. */
-+#define HARD_REGNO_MODE_OK(REGNO, MODE) \
-+ ubicom32_hard_regno_mode_ok(REGNO, MODE)
-+
-+/* We can rename most registers aside from the FDPIC register if we're using
-+ FDPIC. */
-+#define HARD_REGNO_RENAME_OK(from, to) (TARGET_FDPIC ? ((to) != FDPIC_REGNUM) : 1)
-+
-+/* A C expression that is nonzero if it is desirable to choose register
-+ allocation so as to avoid move instructions between a value of mode MODE1
-+ and a value of mode MODE2.
-+
-+ If `HARD_REGNO_MODE_OK (R, MODE1)' and `HARD_REGNO_MODE_OK (R, MODE2)' are
-+ ever different for any R, then `MODES_TIEABLE_P (MODE1, MODE2)' must be
-+ zero. */
-+#define MODES_TIEABLE_P(MODE1, MODE2) 1
-+
-+/* An enumeral type that must be defined with all the register class names as
-+ enumeral values. `NO_REGS' must be first. `ALL_REGS' must be the last
-+ register class, followed by one more enumeral value, `LIM_REG_CLASSES',
-+ which is not a register class but rather tells how many classes there are.
-+
-+ Each register class has a number, which is the value of casting the class
-+ name to type `int'. The number serves as an index in many of the tables
-+ described below. */
-+
-+enum reg_class
-+{
-+ NO_REGS,
-+ DATA_REGS,
-+ FDPIC_REG,
-+ ADDRESS_REGS,
-+ ALL_ADDRESS_REGS,
-+ ACC_LO_REGS,
-+ ACC_REGS,
-+ CC_REG,
-+ DATA_ACC_REGS,
-+ SOURCE3_REG,
-+ SPECIAL_REGS,
-+ GENERAL_REGS,
-+ ALL_REGS,
-+ LIM_REG_CLASSES
-+};
-+
-+/* The number of distinct register classes. */
-+#define N_REG_CLASSES (int) LIM_REG_CLASSES
-+
-+/* An initializer containing the names of the register classes as C string
-+ constants. These names are used in writing some of the debugging dumps. */
-+
-+#define REG_CLASS_NAMES \
-+{ \
-+ "NO_REGS", \
-+ "DATA_REGS", \
-+ "FDPIC_REG", \
-+ "ADDRESS_REGS", \
-+ "ALL_ADDRESS_REGS", \
-+ "ACC_LO_REGS", \
-+ "ACC_REGS", \
-+ "CC_REG", \
-+ "DATA_ACC_REGS", \
-+ "SOURCE3_REG", \
-+ "SPECIAL_REGS", \
-+ "GENERAL_REGS", \
-+ "ALL_REGS", \
-+ "LIM_REGS" \
-+}
-+
-+/* An initializer containing the contents of the register classes, as integers
-+ which are bit masks. The Nth integer specifies the contents of class N.
-+ The way the integer MASK is interpreted is that register R is in the class
-+ if `MASK & (1 << R)' is 1.
-+
-+ When the machine has more than 32 registers, an integer does not suffice.
-+ Then the integers are replaced by sub-initializers, braced groupings
-+ containing several integers. Each sub-initializer must be suitable as an
-+ initializer for the type `HARD_REG_SET' which is defined in
-+ `hard-reg-set.h'. */
-+#define REG_CLASS_CONTENTS \
-+{ \
-+ {0x00000000, 0x00000000}, /* No regs */ \
-+ {0x0000ffff, 0x00000000}, /* DATA_REGS */ \
-+ {0x00010000, 0x00000000}, /* FDPIC_REG */ \
-+ {0x20fe0000, 0x00000000}, /* ADDRESS_REGS */ \
-+ {0x20ff0000, 0x00000000}, /* ALL_ADDRESS_REGS */ \
-+ {0x0a000000, 0x00000000}, /* ACC_LO_REGS */ \
-+ {0x0f000000, 0x00000000}, /* ACC_REGS */ \
-+ {0x40000000, 0x00000000}, /* CC_REG */ \
-+ {0x0f00ffff, 0x00000000}, /* DATA_ACC_REGS */ \
-+ {0x10000000, 0x00000000}, /* SOURGE3_REG */ \
-+ {0x80000000, 0x0000007f}, /* SPECIAL_REGS */ \
-+ {0xbfffffff, 0x0000007f}, /* GENERAL_REGS */ \
-+ {0xbfffffff, 0x0000007f} /* ALL_REGS */ \
-+}
-+
-+extern enum reg_class const ubicom32_regclass_map[FIRST_PSEUDO_REGISTER];
-+
-+/* A C expression whose value is a register class containing hard register
-+ REGNO. In general there is more than one such class; choose a class which
-+ is "minimal", meaning that no smaller class also contains the register. */
-+#define REGNO_REG_CLASS(REGNO) (ubicom32_regclass_map[REGNO])
-+
-+#define IRA_COVER_CLASSES \
-+{ \
-+ GENERAL_REGS, \
-+ LIM_REG_CLASSES \
-+}
-+
-+/* Ubicom32 base registers must be address registers since addresses can
-+ only be reached via address registers. */
-+#define BASE_REG_CLASS ALL_ADDRESS_REGS
-+
-+/* Ubicom32 index registers must be data registers since we cannot add
-+ two address registers together to form an address. */
-+#define INDEX_REG_CLASS DATA_REGS
-+
-+/* A C expression which is nonzero if register number NUM is suitable for use
-+ as a base register in operand addresses. It may be either a suitable hard
-+ register or a pseudo register that has been allocated such a hard register. */
-+
-+#ifndef REG_OK_STRICT
-+#define REGNO_OK_FOR_BASE_P(regno) \
-+ ubicom32_regno_ok_for_base_p (regno, 0)
-+#else
-+#define REGNO_OK_FOR_BASE_P(regno) \
-+ ubicom32_regno_ok_for_base_p (regno, 1)
-+#endif
-+
-+/* A C expression which is nonzero if register number NUM is suitable for use
-+ as an index register in operand addresses. It may be either a suitable hard
-+ register or a pseudo register that has been allocated such a hard register.
-+
-+ The difference between an index register and a base register is that the
-+ index register may be scaled. If an address involves the sum of two
-+ registers, neither one of them scaled, then either one may be labeled the
-+ "base" and the other the "index"; but whichever labeling is used must fit
-+ the machine's constraints of which registers may serve in each capacity.
-+ The compiler will try both labelings, looking for one that is valid, and
-+ will reload one or both registers only if neither labeling works. */
-+#ifndef REG_OK_STRICT
-+#define REGNO_OK_FOR_INDEX_P(regno) \
-+ ubicom32_regno_ok_for_index_p (regno, 0)
-+#else
-+#define REGNO_OK_FOR_INDEX_P(regno) \
-+ ubicom32_regno_ok_for_index_p (regno, 1)
-+#endif
-+
-+/* Attempt to restrict the register class we need to copy value X intoto the
-+ would-be register class CLASS. Most things are fine for Ubicom32 but we
-+ have to restrict certain types of address loads. */
-+#define PREFERRED_RELOAD_CLASS(X, CLASS) \
-+ ubicom32_preferred_reload_class (X, CLASS)
-+
-+/* A C expression for the maximum number of consecutive registers of
-+ class CLASS needed to hold a value of mode MODE. For Ubicom32 this
-+ is pretty much identical to HARD_REGNO_NREGS. */
-+#define CLASS_MAX_NREGS(CLASS, MODE) \
-+ ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
-+
-+/* For Ubicom32 the stack grows downwards when we push a word onto the stack
-+ - i.e. it moves to a smaller address. */
-+#define STACK_GROWS_DOWNWARD 1
-+
-+/* Offset from the frame pointer to the first local variable slot to
-+ be allocated. */
-+#define STARTING_FRAME_OFFSET 0
-+
-+/* Offset from the argument pointer register to the first argument's
-+ address. */
-+#define FIRST_PARM_OFFSET(FNDECL) 0
-+
-+/* A C expression whose value is RTL representing the value of the return
-+ address for the frame COUNT steps up from the current frame, after the
-+ prologue. FRAMEADDR is the frame pointer of the COUNT frame, or the frame
-+ pointer of the COUNT - 1 frame if `RETURN_ADDR_IN_PREVIOUS_FRAME' is
-+ defined.
-+
-+ The value of the expression must always be the correct address when COUNT is
-+ zero, but may be `NULL_RTX' if there is not way to determine the return
-+ address of other frames. */
-+#define RETURN_ADDR_RTX(COUNT, FRAME) \
-+ ubicom32_return_addr_rtx (COUNT, FRAME)
-+
-+/* Register That Address the Stack Frame. */
-+
-+/* We don't actually require a frame pointer in most functions with the
-+ Ubicom32 architecture so we allow it to be eliminated. */
-+#define FRAME_POINTER_REQUIRED 0
-+
-+/* Macro that defines a table of register pairs used to eliminate unecessary
-+ registers that point into the stack frame.
-+
-+ For Ubicom32 we don't generally need an arg pointer of a frame pointer
-+ so we allow the arg pointer to be replaced by either the frame pointer or
-+ the stack pointer. We also allow the frame pointer to be replaced by
-+ the stack pointer. */
-+#define ELIMINABLE_REGS \
-+{ \
-+ {ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
-+ {ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM}, \
-+ {FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM} \
-+}
-+
-+/* Let the compiler know that we want to use the ELIMINABLE_REGS macro
-+ above. */
-+#define CAN_ELIMINATE(FROM, TO) 1
-+
-+/* This macro is similar to `INITIAL_FRAME_POINTER_OFFSET'. It specifies the
-+ initial difference between the specified pair of registers. This macro must
-+ be defined if `ELIMINABLE_REGS' is defined. */
-+#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
-+ (OFFSET) = ubicom32_initial_elimination_offset (FROM, TO)
-+
-+/* If defined, the maximum amount of space required for outgoing arguments will
-+ be computed and placed into the variable
-+ `current_function_outgoing_args_size'. No space will be pushed onto the
-+ stack for each call; instead, the function prologue should increase the
-+ stack frame size by this amount.
-+
-+ Defining both `PUSH_ROUNDING' and `ACCUMULATE_OUTGOING_ARGS' is not
-+ proper. */
-+#define ACCUMULATE_OUTGOING_ARGS 1
-+
-+/* Define this macro if functions should assume that stack space has been
-+ allocated for arguments even when their values are passed in registers.
-+
-+ The value of this macro is the size, in bytes, of the area reserved for
-+ arguments passed in registers for the function represented by FNDECL.
-+
-+ This space can be allocated by the caller, or be a part of the
-+ machine-dependent stack frame: `OUTGOING_REG_PARM_STACK_SPACE' says
-+ which. */
-+#define REG_PARM_STACK_SPACE(FNDECL) ubicom32_reg_parm_stack_space(FNDECL)
-+
-+/* A C expression that should indicate the number of bytes of its own arguments
-+ that a function pops on returning, or 0 if the function pops no arguments
-+ and the caller must therefore pop them all after the function returns.
-+
-+ FUNDECL is a C variable whose value is a tree node that describes the
-+ function in question. Normally it is a node of type `FUNCTION_DECL' that
-+ describes the declaration of the function. From this it is possible to
-+ obtain the DECL_MACHINE_ATTRIBUTES of the function.
-+
-+ FUNTYPE is a C variable whose value is a tree node that describes the
-+ function in question. Normally it is a node of type `FUNCTION_TYPE' that
-+ describes the data type of the function. From this it is possible to obtain
-+ the data types of the value and arguments (if known).
-+
-+ When a call to a library function is being considered, FUNTYPE will contain
-+ an identifier node for the library function. Thus, if you need to
-+ distinguish among various library functions, you can do so by their names.
-+ Note that "library function" in this context means a function used to
-+ perform arithmetic, whose name is known specially in the compiler and was
-+ not mentioned in the C code being compiled.
-+
-+ STACK-SIZE is the number of bytes of arguments passed on the stack. If a
-+ variable number of bytes is passed, it is zero, and argument popping will
-+ always be the responsibility of the calling function.
-+
-+ On the Vax, all functions always pop their arguments, so the definition of
-+ this macro is STACK-SIZE. On the 68000, using the standard calling
-+ convention, no functions pop their arguments, so the value of the macro is
-+ always 0 in this case. But an alternative calling convention is available
-+ in which functions that take a fixed number of arguments pop them but other
-+ functions (such as `printf') pop nothing (the caller pops all). When this
-+ convention is in use, FUNTYPE is examined to determine whether a function
-+ takes a fixed number of arguments. */
-+#define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, STACK_SIZE) 0
-+
-+/* A C expression that controls whether a function argument is passed in a
-+ register, and which register.
-+
-+ The arguments are CUM, of type CUMULATIVE_ARGS, which summarizes (in a way
-+ defined by INIT_CUMULATIVE_ARGS and FUNCTION_ARG_ADVANCE) all of the previous
-+ arguments so far passed in registers; MODE, the machine mode of the argument;
-+ TYPE, the data type of the argument as a tree node or 0 if that is not known
-+ (which happens for C support library functions); and NAMED, which is 1 for an
-+ ordinary argument and 0 for nameless arguments that correspond to `...' in the
-+ called function's prototype.
-+
-+ The value of the expression should either be a `reg' RTX for the hard
-+ register in which to pass the argument, or zero to pass the argument on the
-+ stack.
-+
-+ For machines like the Vax and 68000, where normally all arguments are
-+ pushed, zero suffices as a definition.
-+
-+ The usual way to make the ANSI library `stdarg.h' work on a machine where
-+ some arguments are usually passed in registers, is to cause nameless
-+ arguments to be passed on the stack instead. This is done by making
-+ `FUNCTION_ARG' return 0 whenever NAMED is 0.
-+
-+ You may use the macro `MUST_PASS_IN_STACK (MODE, TYPE)' in the definition of
-+ this macro to determine if this argument is of a type that must be passed in
-+ the stack. If `REG_PARM_STACK_SPACE' is not defined and `FUNCTION_ARG'
-+ returns non-zero for such an argument, the compiler will abort. If
-+ `REG_PARM_STACK_SPACE' is defined, the argument will be computed in the
-+ stack and then loaded into a register. */
-+#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
-+ function_arg (&CUM, MODE, TYPE, NAMED)
-+
-+#define FUNCTION_INCOMING_ARG(CUM, MODE, TYPE, NAMED) \
-+ function_incoming_arg (&CUM, MODE, TYPE, NAMED)
-+
-+/* A C expression for the number of words, at the beginning of an argument,
-+ must be put in registers. The value must be zero for arguments that are
-+ passed entirely in registers or that are entirely pushed on the stack.
-+
-+ On some machines, certain arguments must be passed partially in registers
-+ and partially in memory. On these machines, typically the first N words of
-+ arguments are passed in registers, and the rest on the stack. If a
-+ multi-word argument (a `double' or a structure) crosses that boundary, its
-+ first few words must be passed in registers and the rest must be pushed.
-+ This macro tells the compiler when this occurs, and how many of the words
-+ should go in registers.
-+
-+ `FUNCTION_ARG' for these arguments should return the first register to be
-+ used by the caller for this argument; likewise `FUNCTION_INCOMING_ARG', for
-+ the called function. */
-+
-+/* A C expression that indicates when an argument must be passed by reference.
-+ If nonzero for an argument, a copy of that argument is made in memory and a
-+ pointer to the argument is passed instead of the argument itself. The
-+ pointer is passed in whatever way is appropriate for passing a pointer to
-+ that type.
-+
-+ On machines where `REG_PARM_STACK_SPACE' is not defined, a suitable
-+ definition of this macro might be
-+ #define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \
-+ MUST_PASS_IN_STACK (MODE, TYPE) */
-+
-+/* If defined, a C expression that indicates when it is the called function's
-+ responsibility to make a copy of arguments passed by invisible reference.
-+ Normally, the caller makes a copy and passes the address of the copy to the
-+ routine being called. When FUNCTION_ARG_CALLEE_COPIES is defined and is
-+ nonzero, the caller does not make a copy. Instead, it passes a pointer to
-+ the "live" value. The called function must not modify this value. If it
-+ can be determined that the value won't be modified, it need not make a copy;
-+ otherwise a copy must be made. */
-+
-+/* 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
-+ `int' suffices and can hold the number of bytes of argument so far.
-+
-+ There is no need to record in `CUMULATIVE_ARGS' anything about the arguments
-+ that have been passed on the stack. The compiler has other variables to
-+ keep track of that. For target machines on which all arguments are passed
-+ on the stack, there is no need to store anything in `CUMULATIVE_ARGS';
-+ however, the data structure must exist and should not be empty, so use
-+ `int'. */
-+struct cum_arg
-+{
-+ int nbytes;
-+ int reg;
-+ int stdarg;
-+};
-+#define CUMULATIVE_ARGS struct cum_arg
-+
-+/* A C statement (sans semicolon) for initializing the variable CUM for the
-+ state at the beginning of the argument list. The variable has type
-+ `CUMULATIVE_ARGS'. The value of FNTYPE is the tree node for the data type
-+ of the function which will receive the args, or 0 if the args are to a
-+ compiler support library function. The value of INDIRECT is nonzero when
-+ processing an indirect call, for example a call through a function pointer.
-+ The value of INDIRECT is zero for a call to an explicitly named function, a
-+ library function call, or when `INIT_CUMULATIVE_ARGS' is used to find
-+ arguments for the function being compiled.
-+
-+ When processing a call to a compiler support library function, LIBNAME
-+ identifies which one. It is a `symbol_ref' rtx which contains the name of
-+ the function, as a string. LIBNAME is 0 when an ordinary C function call is
-+ being processed. Thus, each time this macro is called, either LIBNAME or
-+ FNTYPE is nonzero, but never both of them at once. */
-+
-+#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT, NAMED_ARGS) \
-+ init_cumulative_args (&(CUM), FNTYPE, LIBNAME, INDIRECT);
-+
-+/* A C statement (sans semicolon) to update the summarizer variable CUM to
-+ advance past an argument in the argument list. The values MODE, TYPE and
-+ NAMED describe that argument. Once this is done, the variable CUM is
-+ suitable for analyzing the *following* argument with `FUNCTION_ARG', etc.
-+
-+ This macro need not do anything if the argument in question was passed on
-+ the stack. The compiler knows how to track the amount of stack space used
-+ for arguments without any special help. */
-+#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
-+ ((CUM).nbytes += ((MODE) != BLKmode \
-+ ? (GET_MODE_SIZE (MODE) + 3) & ~3 \
-+ : (int_size_in_bytes (TYPE) + 3) & ~3))
-+
-+/* For the Ubicom32 we define the upper function argument register here. */
-+#define UBICOM32_FUNCTION_ARG_REGS 10
-+
-+/* A C expression that is nonzero if REGNO is the number of a hard register in
-+ which function arguments are sometimes passed. This does *not* include
-+ implicit arguments such as the static chain and the structure-value address.
-+ On many machines, no registers can be used for this purpose since all
-+ function arguments are pushed on the stack. */
-+#define FUNCTION_ARG_REGNO_P(N) ((N) < UBICOM32_FUNCTION_ARG_REGS)
-+
-+\f
-+/* How Scalar Function Values are Returned. */
-+
-+/* The number of the hard register that is used to return a scalar value from a
-+ function call. */
-+#define RETURN_VALUE_REGNUM 0
-+
-+/* A C expression to create an RTX representing the place where a function
-+ returns a value of data type VALTYPE. VALTYPE is a tree node representing a
-+ data type. Write `TYPE_MODE (VALTYPE)' to get the machine mode used to
-+ represent that type. On many machines, only the mode is relevant.
-+ (Actually, on most machines, scalar values are returned in the same place
-+ regardless of mode).
-+
-+ If `PROMOTE_FUNCTION_RETURN' is defined, you must apply the same promotion
-+ rules specified in `PROMOTE_MODE' if VALTYPE is a scalar type.
-+
-+ If the precise function being called is known, FUNC is a tree node
-+ (`FUNCTION_DECL') for it; otherwise, FUNC is a null pointer. This makes it
-+ possible to use a different value-returning convention for specific
-+ functions when all their calls are known.
-+
-+ `FUNCTION_VALUE' is not used for return vales with aggregate data types,
-+ because these are returned in another way. See `STRUCT_VALUE_REGNUM' and
-+ related macros, below. */
-+#define FUNCTION_VALUE(VALTYPE, FUNC) \
-+ gen_rtx_REG (TYPE_MODE (VALTYPE), FIRST_DATA_REGNUM)
-+
-+/* A C expression to create an RTX representing the place where a library
-+ function returns a value of mode MODE.
-+
-+ Note that "library function" in this context means a compiler support
-+ routine, used to perform arithmetic, whose name is known specially by the
-+ compiler and was not mentioned in the C code being compiled.
-+
-+ The definition of `LIBRARY_VALUE' need not be concerned aggregate data
-+ types, because none of the library functions returns such types. */
-+#define LIBCALL_VALUE(MODE) gen_rtx_REG (MODE, FIRST_DATA_REGNUM)
-+
-+/* A C expression that is nonzero if REGNO is the number of a hard register in
-+ which the values of called function may come back.
-+
-+ A register whose use for returning values is limited to serving as the
-+ second of a pair (for a value of type `double', say) need not be recognized
-+ by this macro. So for most machines, this definition suffices:
-+
-+ #define FUNCTION_VALUE_REGNO_P(N) ((N) == RETURN)
-+
-+ If the machine has register windows, so that the caller and the called
-+ function use different registers for the return value, this macro should
-+ recognize only the caller's register numbers. */
-+#define FUNCTION_VALUE_REGNO_P(N) ((N) == FIRST_DATA_REGNUM)
-+
-+\f
-+/* How Large Values are Returned. */
-+
-+/* A C expression which can inhibit the returning of certain function values in
-+ registers, based on the type of value. A nonzero value says to return the
-+ function value in memory, just as large structures are always returned.
-+ Here TYPE will be a C expression of type `tree', representing the data type
-+ of the value.
-+
-+ Note that values of mode `BLKmode' must be explicitly handled by this macro.
-+ Also, the option `-fpcc-struct-return' takes effect regardless of this
-+ macro. On most systems, it is possible to leave the macro undefined; this
-+ causes a default definition to be used, whose value is the constant 1 for
-+ `BLKmode' values, and 0 otherwise.
-+
-+ Do not use this macro to indicate that structures and unions should always
-+ be returned in memory. You should instead use `DEFAULT_PCC_STRUCT_RETURN'
-+ to indicate this. */
-+#define RETURN_IN_MEMORY(TYPE) \
-+ (int_size_in_bytes (TYPE) > 8 || TYPE_MODE (TYPE) == BLKmode)
-+
-+/* Define this macro to be 1 if all structure and union return values must be
-+ in memory. Since this results in slower code, this should be defined only
-+ if needed for compatibility with other compilers or with an ABI. If you
-+ define this macro to be 0, then the conventions used for structure and union
-+ return values are decided by the `RETURN_IN_MEMORY' macro.
-+
-+ If not defined, this defaults to the value 1. */
-+#define DEFAULT_PCC_STRUCT_RETURN 0
-+
-+/* If the structure value address is not passed in a register, define
-+ `STRUCT_VALUE' as an expression returning an RTX for the place
-+ where the address is passed. If it returns 0, the address is
-+ passed as an "invisible" first argument. */
-+#define STRUCT_VALUE 0
-+
-+/* Define this macro as a C expression that is nonzero if the return
-+ instruction or the function epilogue ignores the value of the stack pointer;
-+ in other words, if it is safe to delete an instruction to adjust the stack
-+ pointer before a return from the function.
-+
-+ Note that this macro's value is relevant only for functions for which frame
-+ pointers are maintained. It is never safe to delete a final stack
-+ adjustment in a function that has no frame pointer, and the compiler knows
-+ this regardless of `EXIT_IGNORE_STACK'. */
-+#define EXIT_IGNORE_STACK 1
-+
-+/* A C statement or compound statement to output to FILE some assembler code to
-+ call the profiling subroutine `mcount'. Before calling, the assembler code
-+ must load the address of a counter variable into a register where `mcount'
-+ expects to find the address. The name of this variable is `LP' followed by
-+ the number LABELNO, so you would generate the name using `LP%d' in a
-+ `fprintf'.
-+
-+ The details of how the address should be passed to `mcount' are determined
-+ by your operating system environment, not by GNU CC. To figure them out,
-+ compile a small program for profiling using the system's installed C
-+ compiler and look at the assembler code that results.
-+
-+ This declaration must be present, but it can be an abort if profiling is
-+ not implemented. */
-+
-+#define FUNCTION_PROFILER(file, labelno) ubicom32_profiler(file, labelno)
-+
-+/* A C statement to output, on the stream FILE, assembler code for a block of
-+ data that contains the constant parts of a trampoline. This code should not
-+ include a label--the label is taken care of automatically. */
-+#if 0
-+#define TRAMPOLINE_TEMPLATE(FILE) \
-+ do { \
-+ fprintf (FILE, "\tadd -4,sp\n"); \
-+ fprintf (FILE, "\t.long 0x0004fffa\n"); \
-+ fprintf (FILE, "\tmov (0,sp),a0\n"); \
-+ fprintf (FILE, "\tadd 4,sp\n"); \
-+ fprintf (FILE, "\tmov (13,a0),a1\n"); \
-+ fprintf (FILE, "\tmov (17,a0),a0\n"); \
-+ fprintf (FILE, "\tjmp (a0)\n"); \
-+ fprintf (FILE, "\t.long 0\n"); \
-+ fprintf (FILE, "\t.long 0\n"); \
-+ } while (0)
-+#endif
-+
-+/* A C expression for the size in bytes of the trampoline, as an integer. */
-+#define TRAMPOLINE_SIZE 0x1b
-+
-+/* Alignment required for trampolines, in bits.
-+
-+ If you don't define this macro, the value of `BIGGEST_ALIGNMENT' is used for
-+ aligning trampolines. */
-+#define TRAMPOLINE_ALIGNMENT 32
-+
-+/* A C statement to initialize the variable parts of a trampoline. ADDR is an
-+ RTX for the address of the trampoline; FNADDR is an RTX for the address of
-+ the nested function; STATIC_CHAIN is an RTX for the static chain value that
-+ should be passed to the function when it is called. */
-+#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
-+{ \
-+ emit_move_insn (gen_rtx_MEM (SImode, plus_constant ((TRAMP), 0x14)), \
-+ (CXT)); \
-+ emit_move_insn (gen_rtx_MEM (SImode, plus_constant ((TRAMP), 0x18)), \
-+ (FNADDR)); \
-+}
-+
-+/* Ubicom32 supports pre and post increment/decrement addressing. */
-+#define HAVE_POST_INCREMENT 1
-+#define HAVE_PRE_INCREMENT 1
-+#define HAVE_POST_DECREMENT 1
-+#define HAVE_PRE_DECREMENT 1
-+
-+/* Ubicom32 supports pre and post address side-effects with constants
-+ other than the size of the memory operand. */
-+#define HAVE_PRE_MODIFY_DISP 1
-+#define HAVE_POST_MODIFY_DISP 1
-+
-+/* A C expression that is 1 if the RTX X is a constant which is a valid
-+ address. On most machines, this can be defined as `CONSTANT_P (X)',
-+ but a few machines are more restrictive in which constant addresses
-+ are supported.
-+
-+ `CONSTANT_P' accepts integer-values expressions whose values are not
-+ explicitly known, such as `symbol_ref', `label_ref', and `high'
-+ expressions and `const' arithmetic expressions, in addition to
-+ `const_int' and `const_double' expressions. */
-+#define CONSTANT_ADDRESS_P(X) \
-+ (GET_CODE (X) == LABEL_REF \
-+ || (GET_CODE (X) == CONST \
-+ && GET_CODE (XEXP (X, 0)) == PLUS \
-+ && GET_CODE (XEXP (XEXP (X, 0), 0)) == LABEL_REF))
-+
-+/* Ubicom32 supports a maximum of 2 registers in a valid memory address.
-+ One is always an address register while a second, optional, one may be a
-+ data register. */
-+#define MAX_REGS_PER_ADDRESS 2
-+
-+/* A C compound statement with a conditional `goto LABEL;' executed if X (an
-+ RTX) is a legitimate memory address on the target machine for a memory
-+ operand of mode MODE.
-+
-+ It usually pays to define several simpler macros to serve as subroutines for
-+ this one. Otherwise it may be too complicated to understand.
-+
-+ This macro must exist in two variants: a strict variant and a non-strict
-+ one. The strict variant is used in the reload pass. It must be defined so
-+ that any pseudo-register that has not been allocated a hard register is
-+ considered a memory reference. In contexts where some kind of register is
-+ required, a pseudo-register with no hard register must be rejected.
-+
-+ The non-strict variant is used in other passes. It must be defined to
-+ accept all pseudo-registers in every context where some kind of register is
-+ required.
-+
-+ Compiler source files that want to use the strict variant of this macro
-+ define the macro `REG_OK_STRICT'. You should use an `#ifdef REG_OK_STRICT'
-+ conditional to define the strict variant in that case and the non-strict
-+ variant otherwise.
-+
-+ Subroutines to check for acceptable registers for various purposes (one for
-+ base registers, one for index registers, and so on) are typically among the
-+ subroutines used to define `GO_IF_LEGITIMATE_ADDRESS'. Then only these
-+ subroutine macros need have two variants; the higher levels of macros may be
-+ the same whether strict or not.
-+
-+ Normally, constant addresses which are the sum of a `symbol_ref' and an
-+ integer are stored inside a `const' RTX to mark them as constant.
-+ Therefore, there is no need to recognize such sums specifically as
-+ legitimate addresses. Normally you would simply recognize any `const' as
-+ legitimate.
-+
-+ Usually `PRINT_OPERAND_ADDRESS' is not prepared to handle constant sums that
-+ are not marked with `const'. It assumes that a naked `plus' indicates
-+ indexing. If so, then you *must* reject such naked constant sums as
-+ illegitimate addresses, so that none of them will be given to
-+ `PRINT_OPERAND_ADDRESS'.
-+
-+ On some machines, whether a symbolic address is legitimate depends on the
-+ section that the address refers to. On these machines, define the macro
-+ `ENCODE_SECTION_INFO' to store the information into the `symbol_ref', and
-+ then check for it here. When you see a `const', you will have to look
-+ inside it to find the `symbol_ref' in order to determine the section.
-+
-+ The best way to modify the name string is by adding text to the beginning,
-+ with suitable punctuation to prevent any ambiguity. Allocate the new name
-+ in `saveable_obstack'. You will have to modify `ASM_OUTPUT_LABELREF' to
-+ remove and decode the added text and output the name accordingly, and define
-+ `STRIP_NAME_ENCODING' to access the original name string.
-+
-+ You can check the information stored here into the `symbol_ref' in the
-+ definitions of the macros `GO_IF_LEGITIMATE_ADDRESS' and
-+ `PRINT_OPERAND_ADDRESS'. */
-+/* On the ubicom32, the value in the address register must be
-+ in the same memory space/segment as the effective address.
-+
-+ This is problematical for reload since it does not understand
-+ that base+index != index+base in a memory reference. */
-+
-+#ifdef REG_OK_STRICT
-+#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
-+ if (ubicom32_legitimate_address_p (MODE, X, 1)) goto ADDR;
-+#else
-+#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
-+ if (ubicom32_legitimate_address_p (MODE, X, 0)) goto ADDR;
-+#endif
-+
-+/* Try machine-dependent ways of modifying an illegitimate address
-+ to be legitimate. If we find one, return the new, valid address.
-+ This macro is used in only one place: `memory_address' in explow.c.
-+
-+ OLDX is the address as it was before break_out_memory_refs was called.
-+ In some cases it is useful to look at this to decide what needs to be done.
-+
-+ MODE and WIN are passed so that this macro can use
-+ GO_IF_LEGITIMATE_ADDRESS.
-+
-+ It is always safe for this macro to do nothing. It exists to recognize
-+ opportunities to optimize the output.
-+
-+ On RS/6000, first check for the sum of a register with a constant
-+ integer that is out of range. If so, generate code to add the
-+ constant with the low-order 16 bits masked to the register and force
-+ this result into another register (this can be done with `cau').
-+ Then generate an address of REG+(CONST&0xffff), allowing for the
-+ possibility of bit 16 being a one.
-+
-+ Then check for the sum of a register and something not constant, try to
-+ load the other things into a register and return the sum. */
-+
-+#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \
-+{ \
-+ rtx result = ubicom32_legitimize_address ((X), (OLDX), (MODE)); \
-+ if (result != NULL_RTX) \
-+ { \
-+ (X) = result; \
-+ goto WIN; \
-+ } \
-+}
-+
-+/* Try a machine-dependent way of reloading an illegitimate address
-+ operand. If we find one, push the reload and jump to WIN. This
-+ macro is used in only one place: `find_reloads_address' in reload.c. */
-+#define LEGITIMIZE_RELOAD_ADDRESS(AD, MODE, OPNUM, TYPE, IND, WIN) \
-+{ \
-+ rtx new_rtx = ubicom32_legitimize_reload_address ((AD), (MODE), (OPNUM), (int)(TYPE)); \
-+ if (new_rtx) \
-+ { \
-+ (AD) = new_rtx; \
-+ goto WIN; \
-+ } \
-+}
-+
-+/* A C statement or compound statement with a conditional `goto LABEL;'
-+ executed if memory address X (an RTX) can have different meanings depending
-+ on the machine mode of the memory reference it is used for or if the address
-+ is valid for some modes but not others.
-+
-+ Autoincrement and autodecrement addresses typically have mode-dependent
-+ effects because the amount of the increment or decrement is the size of the
-+ operand being addressed. Some machines have other mode-dependent addresses.
-+ Many RISC machines have no mode-dependent addresses.
-+
-+ You may assume that ADDR is a valid address for the machine. */
-+#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL) \
-+ if (ubicom32_mode_dependent_address_p (ADDR)) \
-+ goto LABEL;
-+
-+/* A C expression that is nonzero if X is a legitimate constant for an
-+ immediate operand on the target machine. You can assume that X
-+ satisfies `CONSTANT_P', so you need not check this. In fact, `1' is
-+ a suitable definition for this macro on machines where anything
-+ `CONSTANT_P' is valid. */
-+#define LEGITIMATE_CONSTANT_P(X) \
-+ ubicom32_legitimate_constant_p ((X))
-+
-+/* Moves between registers are pretty-much single instructions for
-+ Ubicom32. We make this the default "2" that gcc likes. */
-+#define REGISTER_MOVE_COST(MODE, FROM, TO) 2
-+
-+/* This is a little bit of magic from the S390 port that wins 2% on code
-+ size when building the Linux kernel! Unfortunately while it wins on
-+ that size the user-space apps built using FD-PIC don't improve and the
-+ performance is lower because we put more pressure on the caches. We may
-+ want this back on some future CPU that has higher cache performance. */
-+/* #define IRA_HARD_REGNO_ADD_COST_MULTIPLIER(regno) 0.5 */
-+
-+/* Moves between registers and memory are more expensive than between
-+ registers because we have caches and write buffers that slow things
-+ down! */
-+#define MEMORY_MOVE_COST(MODE, CLASS, IN) 2
-+
-+/* A fall-through branch is very low cost but anything that changes the PC
-+ incurs a major pipeline hazard. We don't make the full extent of this
-+ hazard visible because we hope that multiple threads will absorb much
-+ of the cost and so we don't want a jump being replaced with, say, 7
-+ instructions. */
-+#define BRANCH_COST(SPEED_P, PREDICTABLE_P) \
-+ ((PREDICTABLE_P) ? 1 : 3)
-+
-+/* Define this macro as a C expression which is nonzero if accessing less than
-+ a word of memory (i.e. a `char' or a `short') is no faster than accessing a
-+ word of memory, i.e., if such access require more than one instruction or if
-+ there is no difference in cost between byte and (aligned) word loads.
-+
-+ When this macro is not defined, the compiler will access a field by finding
-+ the smallest containing object; when it is defined, a fullword load will be
-+ used if alignment permits. Unless bytes accesses are faster than word
-+ accesses, using word accesses is preferable since it may eliminate
-+ subsequent memory access if subsequent accesses occur to other fields in the
-+ same word of the structure, but to different bytes. */
-+#define SLOW_BYTE_ACCESS 0
-+
-+/* The number of scalar move insns which should be generated instead of a
-+ string move insn or a library call. Increasing the value will always make
-+ code faster, but eventually incurs high cost in increased code size.
-+
-+ If you don't define this, a reasonable default is used. */
-+/* According to expr.c, a value of around 6 should minimize code size. */
-+#define MOVE_RATIO(SPEED) 6
-+
-+/* We're much better off calling a constant function address with the
-+ Ubicom32 architecture because we have an opcode for doing so. Don't
-+ let the compiler extract function addresses as common subexpressions
-+ into an address register. */
-+#define NO_FUNCTION_CSE
-+
-+#define SELECT_CC_MODE(OP, X, Y) ubicom32_select_cc_mode (OP, X, Y)
-+
-+#define REVERSIBLE_CC_MODE(MODE) 1
-+
-+/* Canonicalize a comparison from one we don't have to one we do have. */
-+#define CANONICALIZE_COMPARISON(CODE, OP0, OP1) \
-+ ubicom32_canonicalize_comparison (&(CODE), &(OP0), &(OP1))
-+
-+/* Dividing the output into sections. */
-+
-+/* A C expression whose value is a string containing the assembler operation
-+ that should precede instructions and read-only data. Normally `".text"' is
-+ right. */
-+#define TEXT_SECTION_ASM_OP "\t.section .text"
-+
-+/* A C expression whose value is a string containing the assembler operation to
-+ identify the following data as writable initialized data. Normally
-+ `".data"' is right. */
-+#define DATA_SECTION_ASM_OP "\t.section .data"
-+
-+
-+/* If defined, a C expression whose value is a string containing the
-+ assembler operation to identify the following data as
-+ uninitialized global data. If not defined, and neither
-+ `ASM_OUTPUT_BSS' nor `ASM_OUTPUT_ALIGNED_BSS' are defined,
-+ uninitialized global data will be output in the data section if
-+ `-fno-common' is passed, otherwise `ASM_OUTPUT_COMMON' will be
-+ used. */
-+#define BSS_SECTION_ASM_OP "\t.section .bss"
-+
-+/* This is how we tell the assembler that a symbol is weak. */
-+
-+#define ASM_WEAKEN_LABEL(FILE, NAME) \
-+ do \
-+ { \
-+ fputs ("\t.weak\t", (FILE)); \
-+ assemble_name ((FILE), (NAME)); \
-+ fputc ('\n', (FILE)); \
-+ } \
-+ while (0)
-+
-+/* The Overall Framework of an Assembler File. */
-+
-+#undef SET_ASM_OP
-+#define SET_ASM_OP "\t.set\t"
-+
-+/* A C string constant describing how to begin a comment in the target
-+ assembler language. The compiler assumes that the comment will end at the
-+ end of the line. */
-+#define ASM_COMMENT_START ";"
-+
-+/* A C string constant for text to be output before each `asm' statement or
-+ group of consecutive ones. Normally this is `"#APP"', which is a comment
-+ that has no effect on most assemblers but tells the GNU assembler that it
-+ must check the lines that follow for all valid assembler constructs. */
-+#define ASM_APP_ON "#APP\n"
-+
-+/* A C string constant for text to be output after each `asm' statement or
-+ group of consecutive ones. Normally this is `"#NO_APP"', which tells the
-+ GNU assembler to resume making the time-saving assumptions that are valid
-+ for ordinary compiler output. */
-+#define ASM_APP_OFF "#NO_APP\n"
-+
-+/* Like `ASM_OUTPUT_BSS' except takes the required alignment as a separate,
-+ explicit argument. If you define this macro, it is used in place of
-+ `ASM_OUTPUT_BSS', and gives you more flexibility in handling the required
-+ alignment of the variable. The alignment is specified as the number of
-+ bits.
-+
-+ Try to use function `asm_output_aligned_bss' defined in file `varasm.c' when
-+ defining this macro. */
-+#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
-+ asm_output_aligned_bss ((FILE), (DECL), (NAME), (SIZE), (ALIGN))
-+
-+/* A C expression to assign to OUTVAR (which is a variable of type `char *') a
-+ newly allocated string made from the string NAME and the number NUMBER, with
-+ some suitable punctuation added. Use `alloca' to get space for the string.
-+
-+ The string will be used as an argument to `ASM_OUTPUT_LABELREF' to produce
-+ an assembler label for an internal static variable whose name is NAME.
-+ Therefore, the string must be such as to result in valid assembler code.
-+ The argument NUMBER is different each time this macro is executed; it
-+ prevents conflicts between similarly-named internal static variables in
-+ different scopes.
-+
-+ Ideally this string should not be a valid C identifier, to prevent any
-+ conflict with the user's own symbols. Most assemblers allow periods or
-+ percent signs in assembler symbols; putting at least one of these between
-+ the name and the number will suffice. */
-+#define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \
-+ ((OUTPUT) = (char *) alloca (strlen ((NAME)) + 10), \
-+ sprintf ((OUTPUT), "%s___%d", (NAME), (LABELNO)))
-+
-+#define ASM_GENERATE_INTERNAL_LABEL(STRING, PREFIX, NUM) \
-+ sprintf (STRING, "*.%s%ld", PREFIX, (long)(NUM))
-+/* A C statement to store into the string STRING a label whose name
-+ is made from the string PREFIX and the number NUM.
-+
-+ This string, when output subsequently by `assemble_name', should
-+ produce the output that `(*targetm.asm_out.internal_label)' would produce
-+ with the same PREFIX and NUM.
-+
-+ If the string begins with `*', then `assemble_name' will output
-+ the rest of the string unchanged. It is often convenient for
-+ `ASM_GENERATE_INTERNAL_LABEL' to use `*' in this way. If the
-+ string doesn't start with `*', then `ASM_OUTPUT_LABELREF' gets to
-+ output the string, and may change it. (Of course,
-+ `ASM_OUTPUT_LABELREF' is also part of your machine description, so
-+ you should know what it does on your machine.) */
-+
-+/* This says how to output assembler code to declare an
-+ uninitialized external linkage data object. Under SVR4,
-+ the linker seems to want the alignment of data objects
-+ to depend on their types. We do exactly that here. */
-+
-+#define COMMON_ASM_OP "\t.comm\t"
-+
-+#undef ASM_OUTPUT_COMMON
-+#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \
-+ do \
-+ { \
-+ fprintf ((FILE), "%s", COMMON_ASM_OP); \
-+ assemble_name ((FILE), (NAME)); \
-+ fprintf ((FILE), ", %u\n", (SIZE)); \
-+ } \
-+ while (0)
-+
-+/* This says how to output assembler code to declare an
-+ uninitialized internal linkage data object. Under SVR4,
-+ the linker seems to want the alignment of data objects
-+ to depend on their types. We do exactly that here. */
-+#define LOCAL_ASM_OP "\t.lcomm\t"
-+
-+#undef ASM_OUTPUT_LOCAL
-+#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \
-+ do \
-+ { \
-+ fprintf ((FILE), "%s", LOCAL_ASM_OP); \
-+ assemble_name ((FILE), (NAME)); \
-+ fprintf ((FILE), ", %u\n", (SIZE)); \
-+ } \
-+ while (0)
-+
-+/* Globalizing directive for a label. */
-+#define GLOBAL_ASM_OP ".global\t"
-+
-+/* Output the operand of an instruction. */
-+#define PRINT_OPERAND(FILE, X, CODE) \
-+ ubicom32_print_operand(FILE, X, CODE)
-+
-+/* Output the address of an operand. */
-+#define PRINT_OPERAND_ADDRESS(FILE, ADDR) \
-+ ubicom32_print_operand_address (FILE, ADDR)
-+
-+/* A C expression to output to STREAM some assembler code which will push hard
-+ register number REGNO onto the stack. The code need not be optimal, since
-+ this macro is used only when profiling. */
-+#define ASM_OUTPUT_REG_PUSH(FILE, REGNO)
-+
-+/* A C expression to output to STREAM some assembler code which will pop hard
-+ register number REGNO off of the stack. The code need not be optimal, since
-+ this macro is used only when profiling. */
-+#define ASM_OUTPUT_REG_POP(FILE, REGNO)
-+
-+/* This macro should be provided on machines where the addresses in a dispatch
-+ table are relative to the table's own address.
-+
-+ The definition should be a C statement to output to the stdio stream STREAM
-+ an assembler pseudo-instruction to generate a difference between two labels.
-+ VALUE and REL are the numbers of two internal labels. The definitions of
-+ these labels are output using `ASM_OUTPUT_INTERNAL_LABEL', and they must be
-+ printed in the same way here. For example,
-+
-+ fprintf (STREAM, "\t.word L%d-L%d\n", VALUE, REL) */
-+#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
-+ fprintf (FILE, "\t%s .L%d-.L%d\n", ".long", VALUE, REL)
-+
-+/* This macro should be provided on machines where the addresses in a dispatch
-+ table are absolute.
-+
-+ The definition should be a C statement to output to the stdio stream STREAM
-+ an assembler pseudo-instruction to generate a reference to a label. VALUE
-+ is the number of an internal label whose definition is output using
-+ `ASM_OUTPUT_INTERNAL_LABEL'. For example,
-+
-+ fprintf (STREAM, "\t.word L%d\n", VALUE) */
-+#define ASM_OUTPUT_ADDR_VEC_ELT(STREAM, VALUE) \
-+ fprintf (STREAM, "\t.word .L%d\n", VALUE)
-+
-+/* Switch into a generic section. */
-+#define TARGET_ASM_NAMED_SECTION default_elf_asm_named_section
-+
-+/* Assembler Commands for Alignment. */
-+
-+#define ASM_OUTPUT_SKIP(STREAM, N) fprintf (STREAM, "\t.skip %d,0\n", N)
-+/* A C statement to output to the stdio stream STREAM an assembler
-+ instruction to advance the location counter by NBYTES bytes.
-+ Those bytes should be zero when loaded. NBYTES will be a C
-+ expression of type `int'. */
-+
-+/* A C statement to output to the stdio stream STREAM an assembler command to
-+ advance the location counter to a multiple of 2 to the POWER bytes. POWER
-+ will be a C expression of type `int'. */
-+#define ASM_OUTPUT_ALIGN(FILE, LOG) \
-+ if ((LOG) != 0) \
-+ fprintf (FILE, "\t.align %d\n", (LOG))
-+
-+/* A C expression that returns the DBX register number for the compiler
-+ register number REGNO. In simple cases, the value of this expression may be
-+ REGNO itself. But sometimes there are some registers that the compiler
-+ knows about and DBX does not, or vice versa. In such cases, some register
-+ may need to have one number in the compiler and another for DBX.
-+
-+ If two registers have consecutive numbers inside GNU CC, and they can be
-+ used as a pair to hold a multiword value, then they *must* have consecutive
-+ numbers after renumbering with `DBX_REGISTER_NUMBER'. Otherwise, debuggers
-+ will be unable to access such a pair, because they expect register pairs to
-+ be consecutive in their own numbering scheme.
-+
-+ If you find yourself defining `DBX_REGISTER_NUMBER' in way that does not
-+ preserve register pairs, then what you must do instead is redefine the
-+ actual register numbering scheme.
-+
-+ This declaration is required. */
-+#define DBX_REGISTER_NUMBER(REGNO) REGNO
-+
-+/* A C expression that returns the integer offset value for an automatic
-+ variable having address X (an RTL expression). The default computation
-+ assumes that X is based on the frame-pointer and gives the offset from the
-+ frame-pointer. This is required for targets that produce debugging output
-+ for DBX or COFF-style debugging output for SDB and allow the frame-pointer
-+ to be eliminated when the `-g' options is used. */
-+#define DEBUGGER_AUTO_OFFSET(X) \
-+ ((GET_CODE (X) == PLUS ? INTVAL (XEXP (X, 1)) : 0) \
-+ + (frame_pointer_needed \
-+ ? 0 : -initial_elimination_offset (FRAME_POINTER_REGNUM, \
-+ STACK_POINTER_REGNUM)))
-+
-+/* A C expression that returns the integer offset value for an argument having
-+ address X (an RTL expression). The nominal offset is OFFSET. */
-+#define DEBUGGER_ARG_OFFSET(OFFSET, X) \
-+ ((GET_CODE (X) == PLUS ? OFFSET : 0) \
-+ + (frame_pointer_needed \
-+ ? 0 : -initial_elimination_offset (ARG_POINTER_REGNUM, \
-+ STACK_POINTER_REGNUM)))
-+
-+/* A C expression that returns the type of debugging output GNU CC produces
-+ when the user specifies `-g' or `-ggdb'. Define this if you have arranged
-+ for GNU CC to support more than one format of debugging output. Currently,
-+ the allowable values are `DBX_DEBUG', `SDB_DEBUG', `DWARF_DEBUG',
-+ `DWARF2_DEBUG', and `XCOFF_DEBUG'.
-+
-+ The value of this macro only affects the default debugging output; the user
-+ can always get a specific type of output by using `-gstabs', `-gcoff',
-+ `-gdwarf-1', `-gdwarf-2', or `-gxcoff'.
-+
-+ Defined in svr4.h.
-+*/
-+#undef PREFERRED_DEBUGGING_TYPE
-+#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
-+
-+/* Define this macro if GNU CC should produce dwarf version 2 format debugging
-+ output in response to the `-g' option.
-+
-+ To support optional call frame debugging information, you must also define
-+ `INCOMING_RETURN_ADDR_RTX' and either set `RTX_FRAME_RELATED_P' on the
-+ prologue insns if you use RTL for the prologue, or call `dwarf2out_def_cfa'
-+ and `dwarf2out_reg_save' as appropriate from `FUNCTION_PROLOGUE' if you
-+ don't.
-+
-+ Defined in svr4.h. */
-+
-+#define DWARF2_DEBUGGING_INFO 1
-+/*#define DWARF2_UNWIND_INFO 1*/
-+#define DWARF2_UNWIND_INFO 0
-+#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (Pmode, LINK_REGNO)
-+#define INCOMING_FRAME_SP_OFFSET 0
-+#define DWARF_FRAME_RETURN_COLUMN DWARF_FRAME_REGNUM (LINK_REGNO)
-+#define EH_RETURN_FIRST 9
-+#define EH_RETURN_DATA_REGNO(N) ((N) < 2 ? (N) + EH_RETURN_FIRST : INVALID_REGNUM)
-+
-+/* The EH_RETURN_STACKADJ_RTX macro returns RTL which describes the
-+ location used to store the amount to ajdust the stack. This is
-+ usually a registers that is available from end of the function's body
-+ to the end of the epilogue. Thus, this cannot be a register used as a
-+ temporary by the epilogue.
-+
-+ This must be an integer register. */
-+#define EH_RETURN_STACKADJ_REGNO 11
-+#define EH_RETURN_STACKADJ_RTX \
-+ gen_rtx_REG (Pmode, EH_RETURN_STACKADJ_REGNO)
-+
-+/* The EH_RETURN_HANDLER_RTX macro returns RTL which describes the
-+ location used to store the address the processor should jump to
-+ catch exception. This is usually a registers that is available from
-+ end of the function's body to the end of the epilogue. Thus, this
-+ cannot be a register used as a temporary by the epilogue.
-+
-+ This must be an address register. */
-+#define EH_RETURN_HANDLER_REGNO 18
-+#define EH_RETURN_HANDLER_RTX \
-+ gen_rtx_REG (Pmode, EH_RETURN_HANDLER_REGNO)
-+
-+/* #define DWARF2_DEBUGGING_INFO */
-+
-+/* Define this macro if GNU CC should produce dwarf version 2-style
-+ line numbers. This usually requires extending the assembler to
-+ support them, and #defining DWARF2_LINE_MIN_INSN_LENGTH in the
-+ assembler configuration header files. */
-+/* #define DWARF2_ASM_LINE_DEBUG_INFO 1 */
-+
-+
-+/* An alias for a machine mode name. This is the machine mode that elements
-+ of a jump-table have. */
-+#define CASE_VECTOR_MODE Pmode
-+
-+/* Smallest number of different values for which it is best to use a
-+ jump-table instead of a tree of conditional branches. For most Ubicom32
-+ targets this is quite small, but for the v1 architecture implementations
-+ we had very little data memory and so heavily prefer the tree approach
-+ rather than the jump tables. */
-+#define CASE_VALUES_THRESHOLD ubicom32_case_values_threshold
-+
-+/* Register operations within the Ubicom32 architecture always operate on
-+ the whole register word and not just the sub-bits required for the opcode
-+ mode size. */
-+#define WORD_REGISTER_OPERATIONS
-+
-+/* The maximum number of bytes that a single instruction can move quickly from
-+ memory to memory. */
-+#define MOVE_MAX 4
-+
-+/* A C expression that is nonzero if on this machine the number of bits
-+ actually used for the count of a shift operation is equal to the number of
-+ bits needed to represent the size of the object being shifted. When this
-+ macro is non-zero, the compiler will assume that it is safe to omit a
-+ sign-extend, zero-extend, and certain bitwise `and' instructions that
-+ truncates the count of a shift operation. On machines that have
-+ instructions that act on bitfields at variable positions, which may include
-+ `bit test' instructions, a nonzero `SHIFT_COUNT_TRUNCATED' also enables
-+ deletion of truncations of the values that serve as arguments to bitfield
-+ instructions.
-+
-+ If both types of instructions truncate the count (for shifts) and position
-+ (for bitfield operations), or if no variable-position bitfield instructions
-+ exist, you should define this macro.
-+
-+ However, on some machines, such as the 80386 and the 680x0, truncation only
-+ applies to shift operations and not the (real or pretended) bitfield
-+ operations. Define `SHIFT_COUNT_TRUNCATED' to be zero on such machines.
-+ Instead, add patterns to the `md' file that include the implied truncation
-+ of the shift instructions.
-+
-+ You need not define this macro if it would always have the value of zero. */
-+#define SHIFT_COUNT_TRUNCATED 1
-+
-+/* A C expression which is nonzero if on this machine it is safe to "convert"
-+ an integer of INPREC bits to one of OUTPREC bits (where OUTPREC is smaller
-+ than INPREC) by merely operating on it as if it had only OUTPREC bits.
-+
-+ On many machines, this expression can be 1.
-+
-+ When `TRULY_NOOP_TRUNCATION' returns 1 for a pair of sizes for modes for
-+ which `MODES_TIEABLE_P' is 0, suboptimal code can result. If this is the
-+ case, making `TRULY_NOOP_TRUNCATION' return 0 in such cases may improve
-+ things. */
-+#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
-+
-+/* A C string constant that tells the GNU CC driver program options to pass
-+ to the assembler. It can also specify how to translate options you give
-+ to GNU CC into options for GNU CC to pass to the assembler. See the
-+ file `sun3.h' for an example of this.
-+
-+ Defined in svr4.h. */
-+#undef ASM_SPEC
-+#define ASM_SPEC \
-+ "%{march=*:-m%*} %{!march=*:-mubicom32v4} %{mfdpic:-mfdpic}"
-+
-+#define LINK_SPEC "\
-+%{h*} %{v:-V} \
-+%{b} \
-+%{mfdpic:-melf32ubicom32fdpic -z text} \
-+%{static:-dn -Bstatic} \
-+%{shared:-G -Bdynamic} \
-+%{symbolic:-Bsymbolic} \
-+%{G*} \
-+%{YP,*} \
-+%{Qy:} %{!Qn:-Qy}"
-+
-+#undef STARTFILE_SPEC
-+#undef ENDFILE_SPEC
-+
-+/* The svr4.h LIB_SPEC with -leval and --*group tacked on */
-+
-+#undef LIB_SPEC
-+#define LIB_SPEC "%{!shared:%{!symbolic:--start-group -lc -leval -lgcc --end-group}}"
-+
-+#undef HAVE_GAS_SHF_MERGE
-+#define HAVE_GAS_SHF_MERGE 0
-+
-+#define HANDLE_SYSV_PRAGMA 1
-+#undef HANDLE_PRAGMA_PACK
-+
-+typedef void (*ubicom32_func_ptr) (void);
-+
-+/* Define builtins for selected special-purpose instructions. */
-+enum ubicom32_builtins
-+{
-+ UBICOM32_BUILTIN_UBICOM32_SWAPB_2,
-+ UBICOM32_BUILTIN_UBICOM32_SWAPB_4
-+};
-+
-+extern rtx ubicom32_compare_op0;
-+extern rtx ubicom32_compare_op1;
-+
-+#define TYPE_ASM_OP "\t.type\t"
-+#define TYPE_OPERAND_FMT "@%s"
-+
-+#ifndef ASM_DECLARE_RESULT
-+#define ASM_DECLARE_RESULT(FILE, RESULT)
-+#endif
-+
-+/* These macros generate the special .type and .size directives which
-+ are used to set the corresponding fields of the linker symbol table
-+ entries in an ELF object file under SVR4. These macros also output
-+ the starting labels for the relevant functions/objects. */
-+
-+/* Write the extra assembler code needed to declare a function properly.
-+ Some svr4 assemblers need to also have something extra said about the
-+ function's return value. We allow for that here. */
-+
-+#ifndef ASM_DECLARE_FUNCTION_NAME
-+#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \
-+ do \
-+ { \
-+ ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "function"); \
-+ ASM_DECLARE_RESULT (FILE, DECL_RESULT (DECL)); \
-+ ASM_OUTPUT_LABEL (FILE, NAME); \
-+ } \
-+ while (0)
-+#endif
---- /dev/null
-+++ b/gcc/config/ubicom32/ubicom32.md
-@@ -0,0 +1,3753 @@
-+; GCC machine description for Ubicom32
-+;
-+; Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Free Software
-+; Foundation, Inc.
-+; Contributed by Ubicom, Inc.
-+;
-+; This file is part of GCC.
-+;
-+; GCC is free software; you can redistribute it and/or modify
-+; it under the terms of the GNU General Public License as published by
-+; the Free Software Foundation; either version 3, or (at your option)
-+; any later version.
-+;
-+; GCC is distributed in the hope that it will be useful,
-+; but WITHOUT ANY WARRANTY; without even the implied warranty of
-+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+; GNU General Public License for more details.
-+;
-+; You should have received a copy of the GNU General Public License
-+; along with GCC; see the file COPYING3. If not see
-+; <http://www.gnu.org/licenses/>.
-+
-+(define_constants
-+ [(AUX_DATA_REGNO 15)
-+ (LINK_REGNO 21)
-+ (SP_REGNO 23)
-+ (ACC0_HI_REGNO 24)
-+ (ACC1_HI_REGNO 26)
-+ (CC_REGNO 30)])
-+
-+(define_constants
-+ [(UNSPEC_FDPIC_GOT 0)
-+ (UNSPEC_FDPIC_GOT_FUNCDESC 1)])
-+
-+(define_constants
-+ [(UNSPEC_VOLATILE_LOAD_FDPIC_FUNCDESC 0)])
-+
-+;; Types of instructions (for scheduling purposes).
-+
-+(define_attr "type" "mul,addr,other"
-+ (const_string "other"))
-+
-+; Define instruction scheduling characteristics. We can only issue
-+; one instruction per clock so we don't need to define CPU units.
-+;
-+(define_automaton "ubicom32")
-+
-+(define_cpu_unit "i_pipeline" "ubicom32");
-+
-+; We have a 4 cycle hazard associated with address calculations which
-+; seems rather tricky to avoid so we go with a defensive assumption
-+; that almost anything can be used to generate addresses.
-+;
-+;(define_insn_reservation "ubicom32_other" 4
-+; (eq_attr "type" "other")
-+; "i_pipeline")
-+
-+; Some moves don't generate hazards.
-+;
-+;(define_insn_reservation "ubicom32_addr" 1
-+; (eq_attr "type" "addr")
-+; "i_pipeline")
-+
-+; We need 3 cycles between a multiply instruction and any use of the
-+; matching accumulator register(s).
-+;
-+(define_insn_reservation "ubicom32_mul" 4
-+ (eq_attr "type" "mul")
-+ "i_pipeline")
-+
-+(define_attr "length" ""
-+ (const_int 4))
-+
-+(include "predicates.md")
-+(include "constraints.md")
-+
-+; 8-bit move with no change to the flags reg.
-+;
-+(define_insn "movqi"
-+ [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
-+ (match_operand:QI 1 "ubicom32_move_operand" "g"))]
-+ ""
-+ "move.1\\t%0, %1")
-+
-+; Combiner-generated 8-bit move with the zero flag set accordingly.
-+;
-+(define_insn "movqi_ccszn"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:QI 0 "nonimmediate_operand" "rm")
-+ (const_int 0)))
-+ (set (match_operand:QI 1 "nonimmediate_operand" "=rm")
-+ (match_dup 0))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "ext.1\\t%1, %0")
-+
-+; Combine isn't very good at merging some types of operations so we
-+; have to make do with a peephole. It's not as effective but it's better
-+; than doing nothing.
-+;
-+(define_peephole2
-+ [(set (match_operand:QI 0 "nonimmediate_operand" "")
-+ (match_operand:QI 1 "nonimmediate_operand" ""))
-+ (set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (match_operator 3 "ubicom32_compare_operator"
-+ [(match_dup 0)
-+ (const_int 0)]))]
-+ "(GET_MODE (operands[2]) == CCSZNmode
-+ || GET_MODE (operands[2]) == CCSZmode)"
-+ [(parallel
-+ [(set (match_dup 2)
-+ (match_op_dup 3
-+ [(match_dup 1)
-+ (const_int 0)]))
-+ (set (match_dup 0)
-+ (match_dup 1))])]
-+ "")
-+
-+; Combine isn't very good at merging some types of operations so we
-+; have to make do with a peephole. It's not as effective but it's better
-+; than doing nothing.
-+;
-+(define_peephole2
-+ [(set (match_operand:QI 0 "nonimmediate_operand" "")
-+ (match_operand:QI 1 "nonimmediate_operand" ""))
-+ (set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (match_operator 3 "ubicom32_compare_operator"
-+ [(match_dup 1)
-+ (const_int 0)]))]
-+ "(GET_MODE (operands[2]) == CCSZNmode
-+ || GET_MODE (operands[2]) == CCSZmode)"
-+ [(parallel
-+ [(set (match_dup 2)
-+ (match_op_dup 3
-+ [(match_dup 1)
-+ (const_int 0)]))
-+ (set (match_dup 0)
-+ (match_dup 1))])]
-+ "")
-+
-+; 16-bit move with no change to the flags reg.
-+;
-+(define_insn "movhi"
-+ [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
-+ (match_operand:HI 1 "ubicom32_move_operand" "g"))]
-+ ""
-+ "*
-+ {
-+ if (CONST_INT_P (operands[1]))
-+ return \"movei\\t%0, %1\";
-+
-+ return \"move.2\\t%0, %1\";
-+ }")
-+
-+; Combiner-generated 16-bit move with the zero flag set accordingly.
-+;
-+(define_insn "movhi_ccszn"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:HI 0 "nonimmediate_operand" "rm")
-+ (const_int 0)))
-+ (set (match_operand:HI 1 "nonimmediate_operand" "=rm")
-+ (match_dup 0))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "ext.2\\t%1, %0")
-+
-+; Combine isn't very good at merging some types of operations so we
-+; have to make do with a peephole. It's not as effective but it's better
-+; than doing nothing.
-+;
-+(define_peephole2
-+ [(set (match_operand:HI 0 "nonimmediate_operand" "")
-+ (match_operand:HI 1 "nonimmediate_operand" ""))
-+ (set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (match_operator 3 "ubicom32_compare_operator"
-+ [(match_dup 0)
-+ (const_int 0)]))]
-+ "(GET_MODE (operands[2]) == CCSZNmode
-+ || GET_MODE (operands[2]) == CCSZmode)"
-+ [(parallel
-+ [(set (match_dup 2)
-+ (match_op_dup 3
-+ [(match_dup 1)
-+ (const_int 0)]))
-+ (set (match_dup 0)
-+ (match_dup 1))])]
-+ "")
-+
-+; Combine isn't very good at merging some types of operations so we
-+; have to make do with a peephole. It's not as effective but it's better
-+; than doing nothing.
-+;
-+(define_peephole2
-+ [(set (match_operand:HI 0 "nonimmediate_operand" "")
-+ (match_operand:HI 1 "nonimmediate_operand" ""))
-+ (set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (match_operator 3 "ubicom32_compare_operator"
-+ [(match_dup 1)
-+ (const_int 0)]))]
-+ "(GET_MODE (operands[2]) == CCSZNmode
-+ || GET_MODE (operands[2]) == CCSZmode)"
-+ [(parallel
-+ [(set (match_dup 2)
-+ (match_op_dup 3
-+ [(match_dup 1)
-+ (const_int 0)]))
-+ (set (match_dup 0)
-+ (match_dup 1))])]
-+ "")
-+
-+; 32-bit move with no change to the flags reg.
-+;
-+(define_expand "movsi"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
-+ (match_operand:SI 1 "general_operand" ""))]
-+ ""
-+ "{
-+ /* Convert any complexities in operand 1 into something that can just
-+ fall into the default expander code. */
-+ ubicom32_expand_movsi (operands);
-+ }")
-+
-+(define_insn "movsi_high"
-+ [(set (match_operand:SI 0 "ubicom32_address_register_operand" "=a")
-+ (high:SI (match_operand:SI 1 "ubicom32_symbolic_address_operand" "s")))]
-+ ""
-+ "moveai\\t%0, #%%hi(%E1)")
-+
-+(define_insn "movsi_lo_sum"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (lo_sum:SI (match_operand:SI 1 "ubicom32_address_register_operand" "a")
-+ (match_operand:SI 2 "immediate_operand" "s")))]
-+ ""
-+ "lea.1\\t%0, %%lo(%E2)(%1)")
-+
-+(define_insn "movsi_internal"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (match_operand:SI 1 "ubicom32_move_operand" "rmnY"))]
-+ ""
-+ "*
-+ {
-+ if (CONST_INT_P (operands[1]))
-+ {
-+ ubicom32_emit_move_const_int (operands[0], operands[1]);
-+ return \"\";
-+ }
-+
-+ if (GET_CODE (operands[1]) == CONST_DOUBLE)
-+ {
-+ HOST_WIDE_INT i = CONST_DOUBLE_LOW (operands[1]);
-+
-+ ubicom32_emit_move_const_int (operands[0], GEN_INT (i));
-+ return \"\";
-+ }
-+
-+ if (ubicom32_address_register_operand (operands[0], VOIDmode)
-+ && register_operand (operands[1], VOIDmode))
-+ {
-+ if (ubicom32_address_register_operand (operands[1], VOIDmode))
-+ return \"lea.1\\t%0, 0(%1)\";
-+
-+ /* Use movea here to utilize the hazard bypass in the >= v4 ISA. */
-+ if (ubicom32_v4)
-+ return \"movea\\t%0, %1\";
-+
-+ return \"move.4\\t%0, %1\";
-+ }
-+
-+ return \"move.4\\t%0, %1\";
-+ }")
-+
-+; If we're not dependent on the state of the condition codes we can construct
-+; constants of value 2^n by using a bset.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(exact_log2 (INTVAL (operands[1])) > 14
-+ && peep2_regno_dead_p (0, CC_REGNO))"
-+ [(parallel
-+ [(set (match_dup 0)
-+ (ior:SI (const_int 0)
-+ (match_dup 1)))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "")
-+
-+; If we're not dependent on the state of the condition codes we can construct
-+; constants of value ~(2^n) by using a bclr.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(exact_log2 (~INTVAL (operands[1])) > 14
-+ && peep2_regno_dead_p (0, CC_REGNO))"
-+ [(parallel
-+ [(set (match_dup 0)
-+ (and:SI (const_int -1)
-+ (match_dup 1)))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "")
-+
-+; For 32-bit constants that have bits 0 through 24 and bit 31 set the same
-+; we can use swapb.4!
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(ubicom32_v4
-+ && (INTVAL (operands[1]) & 0xffffffff) != 0xffffffff
-+ && (INTVAL (operands[1]) & 0xffffffff) != 0
-+ && ((INTVAL (operands[1]) & 0x80ffffff) == 0
-+ || (INTVAL (operands[1]) & 0x80ffffff) == 0x80ffffff))"
-+ [(set (match_dup 0)
-+ (bswap:SI (match_dup 2)))]
-+ "{
-+ operands[2] = GEN_INT (INTVAL (operands[1]) >> 24);
-+ }")
-+
-+; If this is a write of a constant to memory look to see if we can usefully
-+; transform this into 2 smaller writes.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "memory_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "! satisfies_constraint_I (operands[1])
-+ && ubicom32_legitimate_address_p (HImode, plus_constant (XEXP (operands[0], 0), 2), 1)"
-+ [(set (match_dup 4) (match_dup 2))
-+ (set (match_dup 5) (match_dup 3))]
-+ "{
-+ rtx low_hword_addr;
-+
-+ operands[2] = gen_highpart_mode (HImode, SImode, operands[1]);
-+ operands[3] = gen_lowpart (HImode, operands[1]);
-+
-+ operands[4] = gen_rtx_MEM (HImode, XEXP (operands[0], 0));
-+ MEM_COPY_ATTRIBUTES (operands[4], operands[0]);
-+
-+ low_hword_addr = plus_constant (XEXP (operands[0], 0), 2);
-+ operands[5] = gen_rtx_MEM (HImode, low_hword_addr);
-+ MEM_COPY_ATTRIBUTES (operands[5], operands[0]);
-+ }")
-+
-+; If we're writing memory and we've not found a better way to do this then
-+; try loading into a D register and then copying to memory. This will
-+; perform the fewest possible memory read/writes.
-+;
-+(define_peephole2
-+ [(match_scratch:SI 2 "d")
-+ (set (match_operand:SI 0 "memory_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "! satisfies_constraint_I (operands[1])"
-+ [(set (match_dup 2) (match_dup 1))
-+ (set (match_dup 0) (match_dup 2))]
-+ "")
-+
-+; If we're not dependent on the state of the condition codes we can construct
-+; constants of value (2^n - 1) by using an lsr.4.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(exact_log2 (INTVAL (operands[1]) + 1) > 14
-+ && peep2_regno_dead_p (0, CC_REGNO))"
-+ [(parallel
-+ [(set (match_dup 0)
-+ (lshiftrt:SI (const_int -1)
-+ (match_dup 2)))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "{
-+ operands[2] = GEN_INT (32 - exact_log2 (INTVAL (operands[1]) + 1));
-+ }")
-+
-+; If we're not dependent on the state of the condition codes we can construct
-+; constants of value (2^n - 1) by using an lsr.4.
-+;
-+(define_peephole2
-+ [(match_scratch:SI 2 "d")
-+ (set (match_operand:SI 0 "nonimmediate_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(exact_log2 (INTVAL (operands[1]) + 1) > 14
-+ && peep2_regno_dead_p (0, CC_REGNO))"
-+ [(parallel
-+ [(set (match_dup 2)
-+ (lshiftrt:SI (const_int -1)
-+ (match_dup 3)))
-+ (clobber (reg:CC CC_REGNO))])
-+ (set (match_dup 0)
-+ (match_dup 2))]
-+ "{
-+ operands[3] = GEN_INT (32 - exact_log2 (INTVAL (operands[1]) + 1));
-+ }")
-+
-+; If we're not dependent on the state of the condition codes we can construct
-+; some other constants by using an lsl.4 to shift 7 bits left by some
-+; constant.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(ubicom32_shiftable_const_int (INTVAL (operands[1]))
-+ && peep2_regno_dead_p (0, CC_REGNO))"
-+ [(parallel
-+ [(set (match_dup 0)
-+ (ashift:SI (match_dup 2)
-+ (match_dup 3)))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "{
-+ int shift = ubicom32_shiftable_const_int (INTVAL (operands[1]));
-+ operands[2] = GEN_INT (INTVAL (operands[1]) >> shift);
-+ operands[3] = GEN_INT (shift);
-+ }")
-+
-+; If we're not dependent on the state of the condition codes we can construct
-+; some other constants by using an lsl.4 to shift 7 bits left by some
-+; constant.
-+;
-+(define_peephole2
-+ [(match_scratch:SI 2 "d")
-+ (set (match_operand:SI 0 "nonimmediate_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(ubicom32_shiftable_const_int (INTVAL (operands[1]))
-+ && peep2_regno_dead_p (0, CC_REGNO))"
-+ [(parallel
-+ [(set (match_dup 2)
-+ (ashift:SI (match_dup 3)
-+ (match_dup 4)))
-+ (clobber (reg:CC CC_REGNO))])
-+ (set (match_dup 0)
-+ (match_dup 2))]
-+ "{
-+ int shift = ubicom32_shiftable_const_int (INTVAL (operands[1]));
-+ operands[3] = GEN_INT (INTVAL (operands[1]) >> shift);
-+ operands[4] = GEN_INT (shift);
-+ }")
-+
-+; For some 16-bit unsigned constants that have bit 15 set we can use
-+; swapb.2!
-+;
-+; Note that the movsi code emits the same sequence but by using a peephole2
-+; we split the pattern early enough to allow instruction scheduling to
-+; occur.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(ubicom32_v4
-+ && (INTVAL (operands[1]) & 0xffff80ff) == 0x80ff)"
-+ [(set (match_dup 0)
-+ (zero_extend:SI (bswap:HI (match_dup 2))))]
-+ "{
-+ HOST_WIDE_INT i = INTVAL (operands[1]) >> 8;
-+ if (i >= 0x80)
-+ i -= 0x100;
-+ operands[2] = GEN_INT (i);
-+ }")
-+
-+; In general for a 16-bit unsigned constant that has bit 15 set
-+; then we need a movei/move.2 pair unless we can represent it
-+; via just a move.2.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(INTVAL (operands[1]) & 0xffff8000) == 0x8000
-+ && (INTVAL (operands[1]) & 0xffff) < 0xff80"
-+ [(set (match_dup 2)
-+ (match_dup 1))
-+ (set (match_dup 0)
-+ (zero_extend:SI (match_dup 2)))]
-+ "{
-+ operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));
-+ }")
-+
-+; If we're not dependent on the state of the condition codes we can construct
-+; 32-bit constants that have bits 16 through 31 set to arbitrary values
-+; and have bits 0 through 15 set to something representable as a default
-+; source-1 immediate - we use movei/shmrg.2
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(((INTVAL (operands[1]) >= 0x8000
-+ && INTVAL (operands[1]) < 0xff80)
-+ || INTVAL (operands[1]) >= 0x10000
-+ || INTVAL (operands[1]) < -0x8000)
-+ && ((INTVAL (operands[1]) & 0xffff) >= 0xff80
-+ || (INTVAL (operands[1]) & 0xffff) < 0x80)
-+ && peep2_regno_dead_p (0, CC_REGNO))"
-+ [(set (match_dup 0)
-+ (match_dup 2))
-+ (parallel
-+ [(set (match_dup 0)
-+ (ior:SI
-+ (ashift:SI (match_dup 0)
-+ (const_int 16))
-+ (zero_extend:SI
-+ (match_dup 3))))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "{
-+ operands[2] = gen_highpart_mode (HImode, SImode, operands[1]);
-+ operands[3] = gen_lowpart (HImode, operands[1]);
-+ }")
-+
-+; Exactly the same as the peephole2 preceding except that this targets a
-+; general register instead of D register. Hopefully the later optimization
-+; passes will notice that the value ended up in a D register first here
-+; and eliminate away the other register!
-+;
-+(define_peephole2
-+ [(match_scratch:SI 2 "d")
-+ (set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(((INTVAL (operands[1]) >= 0x8000
-+ && INTVAL (operands[1]) < 0xff80)
-+ || INTVAL (operands[1]) >= 0x10000
-+ || INTVAL (operands[1]) < -0x8000)
-+ && ((INTVAL (operands[1]) & 0xffff) >= 0xff80
-+ || (INTVAL (operands[1]) & 0xffff) < 0x80)
-+ && peep2_regno_dead_p (0, CC_REGNO))"
-+ [(set (match_dup 2)
-+ (match_dup 3))
-+ (parallel
-+ [(set (match_dup 2)
-+ (ior:SI
-+ (ashift:SI (match_dup 2)
-+ (const_int 16))
-+ (zero_extend:SI
-+ (match_dup 4))))
-+ (clobber (reg:CC CC_REGNO))])
-+ (set (match_dup 0)
-+ (match_dup 2))]
-+ "{
-+ operands[3] = gen_highpart_mode (HImode, SImode, operands[1]);
-+ operands[4] = gen_lowpart (HImode, operands[1]);
-+ }")
-+
-+; If we have a load of a large integer constant which does not have bit 31
-+; set and we have a spare A reg then construct it with a moveai/lea.1 pair
-+; instead. This avoids constructing it in 3 instructions on the stack.
-+;
-+; Note that we have to be careful not to match anything that matches
-+; something we can do in a single instruction! There aren't many such
-+; constants but there are some.
-+;
-+(define_peephole2
-+ [(match_scratch:SI 2 "a")
-+ (set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(! (INTVAL (operands[1]) & 0x80000000)
-+ && ((INTVAL (operands[1]) >= 0x8000
-+ && INTVAL (operands[1]) < 0xff80)
-+ || INTVAL (operands[1]) >= 0x10000))"
-+ [(set (match_dup 2)
-+ (match_dup 3))
-+ (set (match_dup 0)
-+ (plus:SI (match_dup 2)
-+ (match_dup 4)))]
-+ "{
-+ HOST_WIDE_INT i = INTVAL (operands[1]);
-+ operands[3] = GEN_INT (i & 0xffffff80);
-+ operands[4] = GEN_INT (i & 0x7f);
-+ }")
-+
-+; If we're not dependent on the state of the condition codes we can construct
-+; a 32-bit constant with a movei/movei/shmrg.2 sequence if possible.
-+;
-+(define_peephole2
-+ [(match_scratch:HI 2 "d")
-+ (set (match_operand:SI 0 "ubicom32_data_register_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))
-+ (match_dup 2)]
-+ "(INTVAL (operands[1]) & 0x80000000
-+ && INTVAL (operands[1]) < -0x8000
-+ && peep2_regno_dead_p (0, CC_REGNO))"
-+ [(set (match_dup 0)
-+ (match_dup 3))
-+ (set (match_dup 2)
-+ (match_dup 4))
-+ (parallel
-+ [(set (match_dup 0)
-+ (ior:SI
-+ (ashift:SI (match_dup 0)
-+ (const_int 16))
-+ (zero_extend:SI
-+ (match_dup 2))))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "{
-+ operands[3] = gen_highpart_mode (HImode, SImode, operands[1]);
-+ operands[4] = gen_lowpart (HImode, operands[1]);
-+ }")
-+
-+; Exactly the same as the peephole2 preceding except that this targets a
-+; general register instead of D register. Hopefully the later optimization
-+; passes will notice that the value ended up in a D register first here
-+; and eliminate away the other register!
-+;
-+(define_peephole2
-+ [(match_scratch:SI 2 "d")
-+ (match_scratch:HI 3 "d")
-+ (set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))
-+ (match_dup 3)]
-+ "(INTVAL (operands[1]) & 0x80000000
-+ && INTVAL (operands[1]) < -0x8000
-+ && peep2_regno_dead_p (0, CC_REGNO))"
-+ [(set (match_dup 2)
-+ (match_dup 4))
-+ (set (match_dup 3)
-+ (match_dup 5))
-+ (parallel
-+ [(set (match_dup 2)
-+ (ior:SI
-+ (ashift:SI (match_dup 2)
-+ (const_int 16))
-+ (zero_extend:SI
-+ (match_dup 3))))
-+ (clobber (reg:CC CC_REGNO))])
-+ (set (match_dup 0)
-+ (match_dup 2))]
-+ "{
-+ operands[4] = gen_highpart_mode (HImode, SImode, operands[1]);
-+ operands[5] = gen_lowpart (HImode, operands[1]);
-+ }")
-+
-+(define_insn "movsi_fdpic_got_offset"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (match_operand:SI 1 "ubicom32_fdpic_got_offset_operand" "Y"))]
-+ ""
-+ "movei\\t%0, %1")
-+
-+; The explicit MEM inside the UNSPEC prevents the compiler from moving
-+; the load before a branch after a NULL test, or before a store that
-+; initializes a function descriptor.
-+
-+(define_insn_and_split "load_fdpic_funcdesc"
-+ [(set (match_operand:SI 0 "ubicom32_address_register_operand" "=a")
-+ (unspec_volatile:SI [(mem:SI (match_operand:SI 1 "address_operand" "p"))]
-+ UNSPEC_VOLATILE_LOAD_FDPIC_FUNCDESC))]
-+ ""
-+ "#"
-+ "reload_completed"
-+ [(set (match_dup 0)
-+ (mem:SI (match_dup 1)))])
-+
-+; Combiner-generated 32-bit move with the zero flag set accordingly.
-+;
-+(define_insn "movsi_ccwzn"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:SI 0 "nonimmediate_operand" "rm, d")
-+ (const_int 0)))
-+ (set (match_operand:SI 1 "nonimmediate_operand" "=d,rm")
-+ (match_dup 0))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "@
-+ lsl.4\\t%1, %0, #0
-+ add.4\\t%1, #0, %0")
-+
-+; Combiner-generated 32-bit move with all flags set accordingly.
-+;
-+(define_insn "movsi_ccw"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:SI 0 "ubicom32_data_register_operand" "d")
-+ (const_int 0)))
-+ (set (match_operand:SI 1 "nonimmediate_operand" "=rm")
-+ (match_dup 0))]
-+ "ubicom32_match_cc_mode(insn, CCWmode)"
-+ "add.4\\t%1, #0, %0")
-+
-+; Combine isn't very good at merging some types of operations so we
-+; have to make do with a peephole. It's not as effective but it's better
-+; than doing nothing.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "")
-+ (match_operand:SI 1 "nonimmediate_operand" ""))
-+ (parallel
-+ [(set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (match_operator 3 "ubicom32_compare_operator"
-+ [(match_dup 0)
-+ (const_int 0)]))
-+ (clobber (match_operand:SI 4 "ubicom32_data_register_operand" ""))])]
-+ "(GET_MODE (operands[2]) == CCWZNmode
-+ || GET_MODE (operands[2]) == CCWZmode)"
-+ [(parallel
-+ [(set (match_dup 2)
-+ (match_op_dup 3
-+ [(match_dup 1)
-+ (const_int 0)]))
-+ (set (match_dup 0)
-+ (match_dup 1))])]
-+ "")
-+
-+; Combine isn't very good at merging some types of operations so we
-+; have to make do with a peephole. It's not as effective but it's better
-+; than doing nothing.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
-+ (match_operand:SI 1 "ubicom32_data_register_operand" ""))
-+ (parallel
-+ [(set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (match_operator 3 "ubicom32_compare_operator"
-+ [(match_dup 1)
-+ (const_int 0)]))
-+ (clobber (match_operand:SI 4 "ubicom32_data_register_operand" ""))])]
-+ "(GET_MODE (operands[2]) == CCWZNmode
-+ || GET_MODE (operands[2]) == CCWZmode)"
-+ [(parallel
-+ [(set (match_dup 2)
-+ (match_op_dup 3
-+ [(match_dup 1)
-+ (const_int 0)]))
-+ (set (match_dup 0)
-+ (match_dup 1))])]
-+ "")
-+
-+; Combine isn't very good at merging some types of operations so we
-+; have to make do with a peephole. It's not as effective but it's better
-+; than doing nothing.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "nonimmediate_operand" ""))
-+ (parallel
-+ [(set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (match_operator 3 "ubicom32_compare_operator"
-+ [(match_dup 0)
-+ (const_int 0)]))
-+ (set (match_operand:SI 4 "ubicom32_data_register_operand" "")
-+ (match_dup 0))])]
-+ "(peep2_reg_dead_p (2, operands[0])
-+ && (GET_MODE (operands[2]) == CCWZNmode
-+ || GET_MODE (operands[2]) == CCWZmode))"
-+ [(parallel
-+ [(set (match_dup 2)
-+ (match_op_dup 3
-+ [(match_dup 1)
-+ (const_int 0)]))
-+ (set (match_dup 4)
-+ (match_dup 1))])]
-+ "")
-+
-+; Register renaming may make a general reg into a D reg in which case
-+; we may be able to simplify a compare.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "nonimmediate_operand" ""))
-+ (parallel
-+ [(set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (match_operator 3 "ubicom32_compare_operator"
-+ [(match_dup 0)
-+ (const_int 0)]))
-+ (clobber (match_operand:SI 4 "ubicom32_data_register_operand" ""))])]
-+ "(peep2_reg_dead_p (2, operands[0])
-+ && (GET_MODE (operands[2]) == CCWZNmode
-+ || GET_MODE (operands[2]) == CCWZmode))"
-+ [(parallel
-+ [(set (match_dup 2)
-+ (match_op_dup 3
-+ [(match_dup 1)
-+ (const_int 0)]))
-+ (clobber (match_dup 4))])]
-+ "")
-+
-+(define_insn_and_split "movdi"
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
-+ (match_operand:DI 1 "general_operand" "rmi,ri"))]
-+ ""
-+ "#"
-+ "reload_completed"
-+ [(set (match_dup 2) (match_dup 3))
-+ (set (match_dup 4) (match_dup 5))]
-+ "{
-+ rtx dest_low;
-+ rtx src_low;
-+
-+ dest_low = gen_lowpart (SImode, operands[0]);
-+ src_low = gen_lowpart (SImode, operands[1]);
-+
-+ if (REG_P (operands[0])
-+ && REG_P (operands[1])
-+ && REGNO (operands[0]) < REGNO (operands[1]))
-+ {
-+ operands[2] = gen_highpart (SImode, operands[0]);
-+ operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
-+ operands[4] = dest_low;
-+ operands[5] = src_low;
-+ }
-+ else if (reg_mentioned_p (dest_low, src_low))
-+ {
-+ operands[2] = gen_highpart (SImode, operands[0]);
-+ operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
-+ operands[4] = dest_low;
-+ operands[5] = src_low;
-+ }
-+ else
-+ {
-+ operands[2] = dest_low;
-+ operands[3] = src_low;
-+ operands[4] = gen_highpart (SImode, operands[0]);
-+ operands[5] = gen_highpart_mode (SImode, DImode, operands[1]);
-+ }
-+ }"
-+ [(set_attr "length" "8")])
-+
-+; Combiner-generated 64-bit move with all flags set accordingly.
-+;
-+(define_insn "movdi_ccwzn"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:DI 0 "nonimmediate_operand" "d, m, r")
-+ (const_int 0)))
-+ (set (match_operand:DI 1 "nonimmediate_operand" "=&rm,rm,!&rm")
-+ (match_dup 0))
-+ (clobber (match_scratch:SI 2 "=X, d, d"))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "*
-+ {
-+ operands[3] = gen_lowpart (SImode, operands[0]);
-+ operands[4] = gen_lowpart (SImode, operands[1]);
-+ operands[5] = gen_highpart (SImode, operands[0]);
-+ operands[6] = gen_highpart (SImode, operands[1]);
-+
-+ if (ubicom32_data_register_operand (operands[0], VOIDmode))
-+ return \"add.4\\t%4, #0, %3\;addc\\t%6, #0, %5\";
-+
-+ return \"movei\\t%2, #0\;add.4\\t%4, %3, %2\;addc\\t%6, %5, %2\";
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_insn "movdi_ccw"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:DI 0 "nonimmediate_operand" "d, m, r")
-+ (const_int 0)))
-+ (set (match_operand:DI 1 "nonimmediate_operand" "=&rm,rm,!&rm")
-+ (match_dup 0))
-+ (clobber (match_scratch:SI 2 "=X, d, d"))]
-+ "ubicom32_match_cc_mode(insn, CCWmode)"
-+ "*
-+ {
-+ operands[3] = gen_lowpart (SImode, operands[0]);
-+ operands[4] = gen_lowpart (SImode, operands[1]);
-+ operands[5] = gen_highpart (SImode, operands[0]);
-+ operands[6] = gen_highpart (SImode, operands[1]);
-+
-+ if (ubicom32_data_register_operand (operands[0], VOIDmode))
-+ return \"add.4\\t%4, #0, %3\;addc\\t%6, #0, %5\";
-+
-+ return \"movei\\t%2, #0\;add.4\\t%4, %3, %2\;addc\\t%6, %5, %2\";
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_insn "movsf"
-+ [(set (match_operand:SF 0 "nonimmediate_operand" "=!d,*rm")
-+ (match_operand:SF 1 "ubicom32_move_operand" "rmF,rmF"))]
-+ ""
-+ "*
-+ {
-+ if (GET_CODE (operands[1]) == CONST_DOUBLE)
-+ {
-+ HOST_WIDE_INT val;
-+ REAL_VALUE_TYPE rv;
-+
-+ REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
-+ REAL_VALUE_TO_TARGET_SINGLE (rv, val);
-+
-+ ubicom32_emit_move_const_int (operands[0], GEN_INT (val));
-+ return \"\";
-+ }
-+
-+ return \"move.4\\t%0, %1\";
-+ }")
-+
-+(define_insn "zero_extendqihi2"
-+ [(set (match_operand:HI 0 "register_operand" "=r")
-+ (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
-+ ""
-+ "move.1\\t%0, %1")
-+
-+(define_insn "zero_extendqisi2"
-+ [(set (match_operand:SI 0 "register_operand" "=r")
-+ (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
-+ ""
-+ "move.1\\t%0, %1")
-+
-+(define_insn "zero_extendqisi2_ccwz_1"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "rm"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (zero_extend:SI (match_dup 1)))]
-+ "ubicom32_match_cc_mode(insn, CCWZmode)"
-+ "shmrg.1\\t%0, %1, #0")
-+
-+(define_insn "zero_extendhisi2"
-+ [(set (match_operand:SI 0 "register_operand" "=r")
-+ (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
-+ ""
-+ "move.2\\t%0, %1")
-+
-+(define_insn "zero_extendhisi2_ccwz_1"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (zero_extend:SI (match_dup 1)))]
-+ "ubicom32_match_cc_mode(insn, CCWZmode)"
-+ "shmrg.2\\t%0, %1, #0")
-+
-+(define_insn_and_split "zero_extendqidi2"
-+ [(set (match_operand:DI 0 "register_operand" "=r")
-+ (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
-+ ""
-+ "#"
-+ "reload_completed"
-+ [(set (match_dup 2)
-+ (zero_extend:SI (match_dup 1)))
-+ (set (match_dup 3)
-+ (const_int 0))]
-+ "{
-+ operands[2] = gen_lowpart (SImode, operands[0]);
-+ operands[3] = gen_highpart (SImode, operands[0]);
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_insn_and_split "zero_extendhidi2"
-+ [(set (match_operand:DI 0 "register_operand" "=r")
-+ (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
-+ ""
-+ "#"
-+ "reload_completed"
-+ [(set (match_dup 2)
-+ (zero_extend:SI (match_dup 1)))
-+ (set (match_dup 3)
-+ (const_int 0))]
-+ "{
-+ operands[2] = gen_lowpart (SImode, operands[0]);
-+ operands[3] = gen_highpart (SImode, operands[0]);
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_insn_and_split "zero_extendsidi2"
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
-+ (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
-+ ""
-+ "#"
-+ "reload_completed"
-+ [(set (match_dup 2)
-+ (match_dup 1))
-+ (set (match_dup 3)
-+ (const_int 0))]
-+ "{
-+ operands[2] = gen_lowpart (SImode, operands[0]);
-+ operands[3] = gen_highpart (SImode, operands[0]);
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_insn "extendqihi2"
-+ [(set (match_operand:HI 0 "register_operand" "=r")
-+ (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "rm")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "ext.1\\t%0, %1")
-+
-+(define_insn "extendqisi2"
-+ [(set (match_operand:SI 0 "register_operand" "=r")
-+ (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "rm")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "ext.1\\t%0, %1")
-+
-+(define_insn "extendhisi2"
-+ [(set (match_operand:SI 0 "register_operand" "=r")
-+ (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "ext.2\\t%0, %1")
-+
-+(define_insn_and_split "extendsidi2"
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "=d")
-+ (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "#"
-+ "reload_completed"
-+ [(set (match_dup 2)
-+ (match_dup 1))
-+ (parallel
-+ [(set (match_dup 3)
-+ (ashiftrt:SI (match_dup 2)
-+ (const_int 31)))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "{
-+ operands[2] = gen_lowpart (SImode, operands[0]);
-+ operands[3] = gen_highpart (SImode, operands[0]);
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_insn "bswaphi"
-+ [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
-+ (bswap:HI (match_operand:HI 1 "ubicom32_arith_operand" "rmI")))]
-+ "(ubicom32_v4)"
-+ "swapb.2\\t%0, %1");
-+
-+(define_insn "bswaphisi"
-+ [(set (match_operand:SI 0 "register_operand" "=r")
-+ (zero_extend:SI
-+ (bswap:HI (match_operand:HI 1 "ubicom32_arith_operand" "rmI"))))]
-+ "(ubicom32_v4)"
-+ "swapb.2\\t%0, %1");
-+
-+(define_insn "bswapsi"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (bswap:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")))]
-+ "(ubicom32_v4)"
-+ "swapb.4\\t%0, %1");
-+
-+(define_insn "tstqi_ext1"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:QI 0 "nonimmediate_operand" "rm")
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "ext.1\\t#0, %0")
-+
-+(define_expand "cmpqi"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:QI 0 "ubicom32_arith_operand" "")
-+ (match_operand:QI 1 "ubicom32_data_register_operand" "")))]
-+ "(ubicom32_v4)"
-+ "{
-+ ubicom32_compare_op0 = operands[0];
-+ ubicom32_compare_op1 = operands[1];
-+ DONE;
-+ }")
-+
-+(define_insn "sub1_ccs"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:QI 0 "ubicom32_arith_operand" "rmI")
-+ (match_operand:QI 1 "ubicom32_data_register_operand" "d")))]
-+ "(ubicom32_v4)"
-+ "sub.1\\t#0, %0, %1")
-+
-+; If we're testing for equality we don't have to worry about reversing conditions.
-+;
-+(define_insn "sub1_ccsz_1"
-+ [(set (reg:CCSZ CC_REGNO)
-+ (compare:CCSZ (match_operand:QI 0 "nonimmediate_operand" "rm")
-+ (match_operand:QI 1 "ubicom32_data_register_operand" "d")))]
-+ "(ubicom32_v4)"
-+ "sub.1\\t#0, %0, %1")
-+
-+(define_insn "sub1_ccsz_2"
-+ [(set (reg:CCSZ CC_REGNO)
-+ (compare:CCSZ (match_operand:QI 0 "ubicom32_data_register_operand" "d")
-+ (match_operand:QI 1 "ubicom32_arith_operand" "rmI")))]
-+ "(ubicom32_v4)"
-+ "sub.1\\t#0, %1, %0")
-+
-+; When the combiner runs it doesn't have any insight into whether or not an argument
-+; to a compare is spilled to the stack and therefore can't swap the comparison in
-+; an attempt to use sub.1 more effectively. We peephole this case here.
-+;
-+(define_peephole2
-+ [(set (match_operand:QI 0 "register_operand" "")
-+ (match_operand:QI 1 "ubicom32_arith_operand" ""))
-+ (set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (compare (match_operand:QI 3 "ubicom32_data_register_operand" "")
-+ (match_dup 0)))
-+ (set (pc)
-+ (if_then_else (match_operator 4 "comparison_operator"
-+ [(match_dup 2)
-+ (const_int 0)])
-+ (label_ref (match_operand 5 "" ""))
-+ (pc)))]
-+ "(peep2_reg_dead_p (2, operands[0])
-+ && peep2_regno_dead_p (3, CC_REGNO))"
-+ [(set (match_dup 2)
-+ (compare (match_dup 1)
-+ (match_dup 3)))
-+ (set (pc)
-+ (if_then_else (match_op_dup 6
-+ [(match_dup 2)
-+ (const_int 0)])
-+ (label_ref (match_dup 5))
-+ (pc)))]
-+ "{
-+ rtx cc_reg;
-+
-+ cc_reg = gen_rtx_REG (GET_MODE (operands[2]), CC_REGNO);
-+ operands[6] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[4])),
-+ GET_MODE (operands[4]),
-+ cc_reg,
-+ const0_rtx);
-+ }")
-+
-+(define_insn "tsthi_ext2"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:HI 0 "nonimmediate_operand" "rm")
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "ext.2\\t#0, %0")
-+
-+(define_expand "cmphi"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:HI 0 "ubicom32_arith_operand" "")
-+ (match_operand:HI 1 "ubicom32_compare_operand" "")))]
-+ ""
-+ "{
-+ do
-+ {
-+ /* Is this a cmpi? */
-+ if (CONST_INT_P (operands[1]))
-+ break;
-+
-+ /* Must be a sub.2 - if necessary copy an operand into a reg. */
-+ if (! ubicom32_data_register_operand (operands[1], HImode))
-+ operands[1] = copy_to_mode_reg (HImode, operands[1]);
-+ }
-+ while (0);
-+
-+ ubicom32_compare_op0 = operands[0];
-+ ubicom32_compare_op1 = operands[1];
-+ DONE;
-+ }")
-+
-+(define_insn "cmpi"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:HI 0 "nonimmediate_operand" "rm")
-+ (match_operand 1 "const_int_operand" "N")))]
-+ ""
-+ "cmpi\\t%0, %1")
-+
-+(define_insn "sub2_ccs"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:HI 0 "ubicom32_arith_operand" "rmI")
-+ (match_operand:HI 1 "ubicom32_data_register_operand" "d")))]
-+ ""
-+ "sub.2\\t#0, %0, %1")
-+
-+; If we're testing for equality we don't have to worry about reversing conditions.
-+;
-+(define_insn "sub2_ccsz_1"
-+ [(set (reg:CCSZ CC_REGNO)
-+ (compare:CCSZ (match_operand:HI 0 "nonimmediate_operand" "rm")
-+ (match_operand:HI 1 "ubicom32_data_register_operand" "d")))]
-+ ""
-+ "sub.2\\t#0, %0, %1")
-+
-+(define_insn "sub2_ccsz_2"
-+ [(set (reg:CCSZ CC_REGNO)
-+ (compare:CCSZ (match_operand:HI 0 "ubicom32_data_register_operand" "d")
-+ (match_operand:HI 1 "ubicom32_arith_operand" "rmI")))]
-+ ""
-+ "sub.2\\t#0, %1, %0")
-+
-+; When the combiner runs it doesn't have any insight into whether or not an argument
-+; to a compare is spilled to the stack and therefore can't swap the comparison in
-+; an attempt to use sub.2 more effectively. We peephole this case here.
-+;
-+(define_peephole2
-+ [(set (match_operand:HI 0 "register_operand" "")
-+ (match_operand:HI 1 "ubicom32_arith_operand" ""))
-+ (set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (compare (match_operand:HI 3 "ubicom32_data_register_operand" "")
-+ (match_dup 0)))
-+ (set (pc)
-+ (if_then_else (match_operator 4 "comparison_operator"
-+ [(match_dup 2)
-+ (const_int 0)])
-+ (label_ref (match_operand 5 "" ""))
-+ (pc)))]
-+ "(peep2_reg_dead_p (2, operands[0])
-+ && peep2_regno_dead_p (3, CC_REGNO))"
-+ [(set (match_dup 2)
-+ (compare (match_dup 1)
-+ (match_dup 3)))
-+ (set (pc)
-+ (if_then_else (match_op_dup 6
-+ [(match_dup 2)
-+ (const_int 0)])
-+ (label_ref (match_dup 5))
-+ (pc)))]
-+ "{
-+ rtx cc_reg;
-+
-+ cc_reg = gen_rtx_REG (GET_MODE (operands[2]), CC_REGNO);
-+ operands[6] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[4])),
-+ GET_MODE (operands[4]),
-+ cc_reg,
-+ const0_rtx);
-+ }")
-+
-+(define_insn_and_split "tstsi_lsl4"
-+ [(set (match_operand 0 "ubicom32_cc_register_operand" "=r")
-+ (match_operator 1 "ubicom32_compare_operator"
-+ [(match_operand:SI 2 "nonimmediate_operand" "rm")
-+ (const_int 0)]))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "#"
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ [(parallel
-+ [(set (match_dup 0)
-+ (match_op_dup 1
-+ [(match_dup 2)
-+ (const_int 0)]))
-+ (clobber (match_dup 3))])]
-+ "{
-+ operands[3] = gen_reg_rtx (SImode);
-+ }")
-+
-+(define_insn "tstsi_lsl4_d"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:SI 0 "nonimmediate_operand" "rm")
-+ (const_int 0)))
-+ (clobber (match_operand:SI 1 "ubicom32_data_register_operand" "=d"))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "lsl.4\\t%1, %0, #0")
-+
-+; Comparison for equality with -1.
-+;
-+(define_insn "cmpsi_not4_ccwz"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:SI 0 "nonimmediate_operand" "rm")
-+ (const_int -1)))]
-+ "ubicom32_match_cc_mode(insn, CCWZmode)"
-+ "not.4\\t#0, %0")
-+
-+(define_expand "cmpsi"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:SI 0 "ubicom32_arith_operand" "")
-+ (match_operand:SI 1 "ubicom32_compare_operand" "")))]
-+ ""
-+ "{
-+ do
-+ {
-+ /* Is this a cmpi? We can't take a memory address as cmpi takes
-+ 16-bit operands. */
-+ if (register_operand (operands[0], SImode)
-+ && CONST_INT_P (operands[1])
-+ && satisfies_constraint_N (operands[1]))
-+ break;
-+
-+ /* Must be a sub.4 - if necessary copy an operand into a reg. */
-+ if (! ubicom32_data_register_operand (operands[1], SImode))
-+ operands[1] = copy_to_mode_reg (SImode, operands[1]);
-+ }
-+ while (0);
-+
-+ ubicom32_compare_op0 = operands[0];
-+ ubicom32_compare_op1 = operands[1];
-+ DONE;
-+ }")
-+
-+(define_insn "cmpsi_cmpi"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:SI 0 "register_operand" "r")
-+ (match_operand 1 "const_int_operand" "N")))]
-+ "(satisfies_constraint_N (operands[1]))"
-+ "cmpi\\t%0, %1")
-+
-+(define_insn "cmpsi_sub4"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:SI 0 "ubicom32_arith_operand" "rmI")
-+ (match_operand:SI 1 "ubicom32_data_register_operand" "d")))]
-+ ""
-+ "sub.4\\t#0, %0, %1")
-+
-+; If we're testing for equality we don't have to worry about reversing conditions.
-+;
-+(define_insn "cmpsi_sub4_ccwz_1"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:SI 0 "nonimmediate_operand" "rm")
-+ (match_operand:SI 1 "ubicom32_data_register_operand" "d")))]
-+ "ubicom32_match_cc_mode(insn, CCWZmode)"
-+ "sub.4\\t#0, %0, %1")
-+
-+(define_insn "cmpsi_sub4_ccwz_2"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:SI 0 "ubicom32_data_register_operand" "d")
-+ (match_operand:SI 1 "nonimmediate_operand" "rm")))]
-+ "ubicom32_match_cc_mode(insn, CCWZmode)"
-+ "sub.4\\t#0, %1, %0")
-+
-+; When the combiner runs it doesn't have any insight into whether or not an argument
-+; to a compare is spilled to the stack and therefore can't swap the comparison in
-+; an attempt to use sub.4 more effectively. We peephole this case here.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "ubicom32_arith_operand" ""))
-+ (set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (compare (match_operand:SI 3 "ubicom32_data_register_operand" "")
-+ (match_dup 0)))
-+ (set (pc)
-+ (if_then_else (match_operator 4 "comparison_operator"
-+ [(match_dup 2)
-+ (const_int 0)])
-+ (label_ref (match_operand 5 "" ""))
-+ (pc)))]
-+ "(peep2_reg_dead_p (2, operands[0])
-+ && peep2_regno_dead_p (3, CC_REGNO))"
-+ [(set (match_dup 2)
-+ (compare (match_dup 1)
-+ (match_dup 3)))
-+ (set (pc)
-+ (if_then_else (match_op_dup 6
-+ [(match_dup 2)
-+ (const_int 0)])
-+ (label_ref (match_dup 5))
-+ (pc)))]
-+ "{
-+ rtx cc_reg;
-+
-+ cc_reg = gen_rtx_REG (GET_MODE (operands[2]), CC_REGNO);
-+ operands[6] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[4])),
-+ GET_MODE (operands[4]),
-+ cc_reg,
-+ const0_rtx);
-+ }")
-+
-+(define_insn_and_split "tstdi_or4"
-+ [(set (reg:CCWZ CC_REGNO)
-+ (compare:CCWZ (match_operand:DI 0 "nonimmediate_operand" "rm")
-+ (const_int 0)))]
-+ ""
-+ "#"
-+ ""
-+ [(parallel
-+ [(set (reg:CCWZ CC_REGNO)
-+ (compare:CCWZ (match_dup 0)
-+ (const_int 0)))
-+ (clobber (match_dup 1))])]
-+ "{
-+ operands[1] = gen_reg_rtx (SImode);
-+ }")
-+
-+(define_insn "tstdi_or4_d"
-+ [(set (reg:CCWZ CC_REGNO)
-+ (compare:CCWZ (match_operand:DI 0 "nonimmediate_operand" "rm")
-+ (const_int 0)))
-+ (clobber (match_operand:SI 1 "ubicom32_data_register_operand" "=d"))]
-+ ""
-+ "*
-+ {
-+ operands[2] = gen_lowpart (SImode, operands[0]);
-+ operands[3] = gen_highpart_mode (SImode, DImode, operands[0]);
-+
-+ if (ubicom32_data_register_operand (operands[0], GET_MODE (operands[0])))
-+ return \"or.4\\t#0, %2, %3\";
-+
-+ return \"move.4\\t%1, %2\;or.4\\t%1, %3, %1\";
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_expand "cmpdi"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:DI 0 "ubicom32_arith_operand" "")
-+ (match_operand:DI 1 "ubicom32_data_register_operand" "")))]
-+ ""
-+ "{
-+ ubicom32_compare_op0 = operands[0];
-+ ubicom32_compare_op1 = operands[1];
-+ DONE;
-+ }")
-+
-+(define_insn "cmpdi_sub4subc"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:DI 0 "ubicom32_arith_operand" "rmI")
-+ (match_operand:DI 1 "ubicom32_data_register_operand" "d")))]
-+ ""
-+ "*
-+ {
-+ operands[2] = gen_lowpart (SImode, operands[0]);
-+ operands[3] = gen_lowpart (SImode, operands[1]);
-+ operands[4] = gen_highpart_mode (SImode, DImode, operands[0]);
-+ operands[5] = gen_highpart_mode (SImode, DImode, operands[1]);
-+
-+ return \"sub.4\\t#0, %2, %3\;subc\\t#0, %4, %5\";
-+ }"
-+ [(set_attr "length" "8")])
-+
-+; When the combiner runs it doesn't have any insight into whether or not an argument
-+; to a compare is spilled to the stack and therefore can't swap the comparison in
-+; an attempt to use sub.4/subc more effectively. We peephole this case here.
-+;
-+(define_peephole2
-+ [(set (match_operand:DI 0 "register_operand" "")
-+ (match_operand:DI 1 "ubicom32_arith_operand" ""))
-+ (set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (compare (match_operand:DI 3 "ubicom32_data_register_operand" "")
-+ (match_dup 0)))
-+ (set (pc)
-+ (if_then_else (match_operator 4 "comparison_operator"
-+ [(match_dup 2)
-+ (const_int 0)])
-+ (label_ref (match_operand 5 "" ""))
-+ (pc)))]
-+ "(peep2_reg_dead_p (2, operands[0])
-+ && peep2_regno_dead_p (3, CC_REGNO))"
-+ [(set (match_dup 2)
-+ (compare (match_dup 1)
-+ (match_dup 3)))
-+ (set (pc)
-+ (if_then_else (match_op_dup 6
-+ [(match_dup 2)
-+ (const_int 0)])
-+ (label_ref (match_dup 5))
-+ (pc)))]
-+ "{
-+ rtx cc_reg;
-+
-+ cc_reg = gen_rtx_REG (GET_MODE (operands[2]), CC_REGNO);
-+ operands[6] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[4])),
-+ GET_MODE (operands[4]),
-+ cc_reg,
-+ const0_rtx);
-+ }")
-+
-+(define_insn "btst"
-+ [(set (reg:CCWZ CC_REGNO)
-+ (compare:CCWZ
-+ (zero_extract:SI
-+ (match_operand:SI 0 "nonimmediate_operand" "rm")
-+ (const_int 1)
-+ (match_operand:SI 1 "ubicom32_arith_operand" "dM"))
-+ (const_int 0)))]
-+ ""
-+ "btst\\t%0, %1")
-+
-+(define_insn "bfextu_ccwz_null"
-+ [(set (reg:CCWZ CC_REGNO)
-+ (compare:CCWZ
-+ (zero_extract:SI
-+ (match_operand:SI 0 "nonimmediate_operand" "rm")
-+ (match_operand 1 "const_int_operand" "M")
-+ (const_int 0))
-+ (const_int 0)))
-+ (clobber (match_scratch:SI 2 "=d"))]
-+ ""
-+ "bfextu\\t%2, %0, %1")
-+
-+(define_expand "addqi3"
-+ [(parallel
-+ [(set (match_operand:QI 0 "memory_operand" "")
-+ (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
-+ (match_operand:QI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "(ubicom32_v4)"
-+ "{
-+ if (!memory_operand (operands[0], QImode))
-+ FAIL;
-+
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (QImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (QImode, operands[2]);
-+ }")
-+
-+(define_insn "addqi3_add1"
-+ [(set (match_operand:QI 0 "memory_operand" "=m, m")
-+ (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:QI 2 "ubicom32_arith_operand" "rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4)"
-+ "@
-+ add.1\\t%0, %2, %1
-+ add.1\\t%0, %1, %2")
-+
-+(define_insn "addqi3_add1_ccszn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (neg:QI (match_operand:QI 0 "nonimmediate_operand" "%d,rm"))
-+ (match_operand:QI 1 "ubicom32_arith_operand" "rmI, d")))]
-+ "(ubicom32_v4
-+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
-+ "@
-+ add.1\\t#0, %1, %0
-+ add.1\\t#0, %0, %1")
-+
-+(define_expand "addhi3"
-+ [(parallel
-+ [(set (match_operand:HI 0 "memory_operand" "")
-+ (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
-+ (match_operand:HI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ ""
-+ "{
-+ if (!memory_operand (operands[0], HImode))
-+ FAIL;
-+
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (HImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (HImode, operands[2]);
-+ }")
-+
-+(define_insn "addhi3_add2"
-+ [(set (match_operand:HI 0 "memory_operand" "=m, m")
-+ (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:HI 2 "ubicom32_arith_operand" "rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "@
-+ add.2\\t%0, %2, %1
-+ add.2\\t%0, %1, %2")
-+
-+(define_insn "addhi3_add2_ccszn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (neg:HI (match_operand:HI 0 "nonimmediate_operand" "%d,rm"))
-+ (match_operand:HI 1 "ubicom32_arith_operand" "rmI, d")))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "@
-+ add.2\\t#0, %1, %0
-+ add.2\\t#0, %0, %1")
-+
-+(define_expand "addsi3"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
-+ (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
-+ (match_operand:SI 2 "ubicom32_move_operand" "")))]
-+ ""
-+ "{
-+ ubicom32_expand_addsi3 (operands);
-+ DONE;
-+ }")
-+
-+; We start with an instruction pattern that can do all sorts of interesting
-+; things but we split out any uses of lea or pdec instructions because
-+; those instructions don't clobber the condition codes.
-+;
-+(define_insn_and_split "addsi3_1"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm,rm,rm,rm, rm,rm")
-+ (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%a, a, a, a, a, d,rm")
-+ (match_operand:SI 2 "ubicom32_move_operand" "L, K, J, P, d,rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "@
-+ #
-+ #
-+ #
-+ #
-+ #
-+ add.4\\t%0, %2, %1
-+ add.4\\t%0, %1, %2"
-+ "(reload_completed
-+ && ubicom32_address_register_operand (operands[1], GET_MODE (operands[1])))"
-+ [(set (match_dup 0)
-+ (plus:SI (match_dup 1)
-+ (match_dup 2)))]
-+ ""
-+)
-+
-+(define_insn "addsi3_1_ccwzn"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
-+ (plus:SI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "@
-+ add.4\\t%0, %2, %1
-+ add.4\\t%0, %1, %2")
-+
-+(define_insn "addsi3_1_ccwzn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (neg:SI (match_operand:SI 0 "nonimmediate_operand" "%d,rm"))
-+ (match_operand:SI 1 "ubicom32_arith_operand" "rmI, d")))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "@
-+ add.4\\t#0, %1, %0
-+ add.4\\t#0, %0, %1")
-+
-+(define_insn_and_split "addsi3_2"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm,rm,rm,rm,rm")
-+ (plus:SI (match_operand:SI 1 "ubicom32_address_register_operand" "%a, a, a, a, a, a")
-+ (match_operand:SI 2 "ubicom32_move_operand" "L, K, J, P, d, n")))]
-+ ""
-+ "@
-+ lea.4\\t%0, %E2(%1)
-+ lea.2\\t%0, %E2(%1)
-+ lea.1\\t%0, %E2(%1)
-+ pdec\\t%0, %n2(%1)
-+ lea.1\\t%0, (%1,%2)
-+ #"
-+ "(reload_completed
-+ && ! satisfies_constraint_L (operands[2])
-+ && ! satisfies_constraint_K (operands[2])
-+ && ! satisfies_constraint_J (operands[2])
-+ && ! satisfies_constraint_P (operands[2])
-+ && ! ubicom32_data_register_operand (operands[2], GET_MODE (operands[2])))"
-+ [(set (reg:SI AUX_DATA_REGNO)
-+ (match_dup 2))
-+ (set (match_dup 0)
-+ (plus:SI (match_dup 1)
-+ (reg:SI AUX_DATA_REGNO)))]
-+ ""
-+)
-+
-+(define_insn "lea_2"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (plus:SI (mult:SI (match_operand:SI 1 "ubicom32_data_register_operand" "d")
-+ (const_int 2))
-+ (match_operand:SI 2 "ubicom32_address_register_operand" "a")))]
-+ ""
-+ "lea.2\\t%0, (%2,%1)")
-+
-+(define_insn "lea_4"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (plus:SI (mult:SI (match_operand:SI 1 "ubicom32_data_register_operand" "d")
-+ (const_int 4))
-+ (match_operand:SI 2 "ubicom32_address_register_operand" "a")))]
-+ ""
-+ "lea.4\\t%0, (%2,%1)")
-+
-+(define_expand "adddi3"
-+ [(parallel
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "")
-+ (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
-+ (match_operand:DI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ ""
-+ "{
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (DImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (DImode, operands[2]);
-+ }")
-+
-+; We construct a 64-bit add from 32-bit operations. Note that we use the
-+; & constraint to prevent overlapping registers being allocated. We do
-+; allow identical registers though as that won't break anything.
-+;
-+(define_insn "adddi3_add4addc"
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,&r,rm, d, m, m")
-+ (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%d,rm, 0, 0, d,rm")
-+ (match_operand:DI 2 "ubicom32_arith_operand" "rmI, d, d,rmI,rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "*
-+ {
-+ operands[3] = gen_lowpart (SImode, operands[0]);
-+ operands[4] = gen_lowpart (SImode, operands[1]);
-+ operands[5] = gen_lowpart (SImode, operands[2]);
-+ operands[6] = gen_highpart (SImode, operands[0]);
-+ operands[7] = gen_highpart (SImode, operands[1]);
-+ operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
-+
-+ if (ubicom32_data_register_operand (operands[2], GET_MODE (operands[2])))
-+ return \"add.4\\t%3, %4, %5\;addc\\t%6, %7, %8\";
-+
-+ return \"add.4\\t%3, %5, %4\;addc\\t%6, %8, %7\";
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_insn "adddi3_ccwz"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%d,rm, 0, 0, d,rm")
-+ (match_operand:DI 2 "ubicom32_arith_operand" "rmI, d, d,rmI,rmI, d"))
-+ (const_int 0)))
-+ (set (match_operand:DI 0 "nonimmediate_operand" "=&r,&r,rm, d, m, m")
-+ (plus:DI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "*
-+ {
-+ operands[3] = gen_lowpart (SImode, operands[0]);
-+ operands[6] = gen_highpart (SImode, operands[0]);
-+
-+ if (ubicom32_data_register_operand (operands[1], GET_MODE (operands[1])))
-+ {
-+ operands[4] = gen_lowpart (SImode, operands[1]);
-+ operands[5] = gen_lowpart (SImode, operands[2]);
-+ operands[7] = gen_highpart (SImode, operands[1]);
-+ operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
-+ }
-+ else
-+ {
-+ operands[4] = gen_lowpart (SImode, operands[2]);
-+ operands[5] = gen_lowpart (SImode, operands[1]);
-+ operands[7] = gen_highpart (SImode, operands[2]);
-+ operands[8] = gen_highpart (SImode, operands[1]);
-+ }
-+
-+ return \"add.4\\t%3, %5, %4\;addc\\t%6, %8, %7\";
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_insn "adddi3_ccwz_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (neg:DI (match_operand:DI 0 "nonimmediate_operand" "%d,rm"))
-+ (match_operand:DI 1 "ubicom32_arith_operand" "rmI, d")))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "*
-+ {
-+ if (ubicom32_data_register_operand (operands[0], GET_MODE (operands[0])))
-+ {
-+ operands[2] = gen_lowpart (SImode, operands[0]);
-+ operands[3] = gen_lowpart (SImode, operands[1]);
-+ operands[4] = gen_highpart (SImode, operands[0]);
-+ operands[5] = gen_highpart_mode (SImode, DImode, operands[1]);
-+ }
-+ else
-+ {
-+ operands[2] = gen_lowpart (SImode, operands[1]);
-+ operands[3] = gen_lowpart (SImode, operands[0]);
-+ operands[4] = gen_highpart (SImode, operands[1]);
-+ operands[5] = gen_highpart (SImode, operands[0]);
-+ }
-+
-+ return \"add.4\\t#0, %3, %2\;addc\\t#0, %5, %4\";
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_expand "subqi3"
-+ [(parallel
-+ [(set (match_operand:QI 0 "memory_operand" "")
-+ (minus:QI (match_operand:QI 1 "ubicom32_arith_operand" "")
-+ (match_operand:QI 2 "ubicom32_data_register_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "(ubicom32_v4)"
-+ "{
-+ if (!memory_operand (operands[0], QImode))
-+ FAIL;
-+ }")
-+
-+(define_insn "subqi3_sub1"
-+ [(set (match_operand:QI 0 "memory_operand" "=m")
-+ (minus:QI (match_operand:QI 1 "ubicom32_arith_operand" "rmI")
-+ (match_operand:QI 2 "ubicom32_data_register_operand" "d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4)"
-+ "sub.1\\t%0, %1, %2")
-+
-+(define_expand "subhi3"
-+ [(parallel
-+ [(set (match_operand:HI 0 "memory_operand" "")
-+ (minus:HI (match_operand:HI 1 "ubicom32_arith_operand" "")
-+ (match_operand:HI 2 "ubicom32_data_register_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "(ubicom32_v4)"
-+ "{
-+ if (!memory_operand (operands[0], HImode))
-+ FAIL;
-+ }")
-+
-+(define_insn "subhi3_sub2"
-+ [(set (match_operand:HI 0 "memory_operand" "=m")
-+ (minus:HI (match_operand:HI 1 "ubicom32_arith_operand" "rmI")
-+ (match_operand:HI 2 "ubicom32_data_register_operand" "d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "sub.2\\t%0, %1, %2")
-+
-+(define_insn "subsi3"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (minus:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")
-+ (match_operand:SI 2 "ubicom32_data_register_operand" "d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "sub.4\\t%0, %1, %2")
-+
-+(define_insn "subsi3_ccwz"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (minus:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")
-+ (match_operand:SI 2 "ubicom32_data_register_operand" "d"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (minus:SI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "sub.4\\t%0, %1, %2")
-+
-+; We construct a 64-bit add from 32-bit operations. Note that we use the
-+; & constraint to prevent overlapping registers being allocated. We do
-+; allow identical registers though as that won't break anything.
-+;
-+(define_insn "subdi3"
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,r, d, m")
-+ (minus:DI (match_operand:DI 1 "ubicom32_arith_operand" "rmI,0,rmI,rmI")
-+ (match_operand:DI 2 "ubicom32_data_register_operand" "d,d, 0, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "*
-+ {
-+ operands[3] = gen_lowpart (SImode, operands[0]);
-+ operands[4] = gen_lowpart (SImode, operands[1]);
-+ operands[5] = gen_lowpart (SImode, operands[2]);
-+ operands[6] = gen_highpart (SImode, operands[0]);
-+ operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
-+ operands[8] = gen_highpart (SImode, operands[2]);
-+
-+ return \"sub.4\\t%3, %4, %5\;subc\\t%6, %7, %8\";
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_insn "subdi3_ccwz"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (minus:DI (match_operand:DI 1 "ubicom32_arith_operand" "rmI,rmI")
-+ (match_operand:DI 2 "ubicom32_data_register_operand" "d, d"))
-+ (const_int 0)))
-+ (set (match_operand:DI 0 "nonimmediate_operand" "=&r, m")
-+ (minus:DI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "*
-+ {
-+ operands[3] = gen_lowpart (SImode, operands[0]);
-+ operands[4] = gen_lowpart (SImode, operands[1]);
-+ operands[5] = gen_lowpart (SImode, operands[2]);
-+ operands[6] = gen_highpart (SImode, operands[0]);
-+ operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
-+ operands[8] = gen_highpart (SImode, operands[2]);
-+
-+ return \"sub.4\\t%3, %4, %5\;subc\\t%6, %7, %8\";
-+ }"
-+ [(set_attr "length" "8")])
-+
-+;(define_insn "negqi2"
-+; [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
-+; (neg:QI (match_operand:QI 1 "ubicom32_data_register_operand" "d")))
-+; (clobber (reg:CC CC_REGNO))]
-+; "(ubicom32_v4)"
-+; "sub.1\\t%0, #0, %1")
-+
-+;(define_insn "neghi2"
-+; [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
-+; (neg:HI (match_operand:HI 1 "ubicom32_data_register_operand" "d")))
-+; (clobber (reg:CC CC_REGNO))]
-+; ""
-+; "sub.2\\t%0, #0, %1")
-+
-+(define_insn "negsi2"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (neg:SI (match_operand:SI 1 "ubicom32_data_register_operand" "d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "sub.4\\t%0, #0, %1")
-+
-+(define_insn_and_split "negdi2"
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "=&rm")
-+ (neg:DI (match_operand:DI 1 "ubicom32_data_register_operand" "d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "#"
-+ "reload_completed"
-+ [(parallel [(set (match_dup 0)
-+ (minus:DI (const_int 0)
-+ (match_dup 1)))
-+ (clobber (reg:CC CC_REGNO))])]
-+ ""
-+ [(set_attr "length" "8")])
-+
-+(define_insn "umulhisi3"
-+ [(set (match_operand:SI 0 "ubicom32_acc_lo_register_operand" "=l, l")
-+ (mult:SI
-+ (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "%d,rm"))
-+ (zero_extend:SI (match_operand:HI 2 "nonimmediate_operand" "rm, d"))))
-+ (clobber (reg:HI ACC0_HI_REGNO))
-+ (clobber (reg:HI ACC1_HI_REGNO))]
-+ ""
-+ "@
-+ mulu\\t%A0, %2, %1
-+ mulu\\t%A0, %1, %2"
-+ [(set_attr "type" "mul,mul")])
-+
-+(define_insn "mulhisi3"
-+ [(set (match_operand:SI 0 "ubicom32_acc_lo_register_operand" "=l, l")
-+ (mult:SI
-+ (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "%d,rm"))
-+ (sign_extend:SI (match_operand:HI 2 "nonimmediate_operand" "rm, d"))))
-+ (clobber (reg:HI ACC0_HI_REGNO))
-+ (clobber (reg:HI ACC1_HI_REGNO))]
-+ ""
-+ "@
-+ muls\\t%A0, %2, %1
-+ muls\\t%A0, %1, %2"
-+ [(set_attr "type" "mul,mul")])
-+
-+(define_expand "mulsi3"
-+ [(set (match_operand:SI 0 "ubicom32_acc_hi_register_operand" "")
-+ (mult:SI (match_operand:SI 1 "ubicom32_arith_operand" "")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "")))]
-+ ""
-+ "{
-+ if (ubicom32_emit_mult_sequence (operands))
-+ DONE;
-+ }")
-+
-+(define_insn "umulsidi3"
-+ [(set (match_operand:DI 0 "ubicom32_acc_hi_register_operand" "=h, h")
-+ (mult:DI
-+ (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%d,rm"))
-+ (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm, d"))))]
-+ "(ubicom32_v4)"
-+ "@
-+ mulu.4\\t%A0, %2, %1
-+ mulu.4\\t%A0, %1, %2"
-+ [(set_attr "type" "mul,mul")])
-+
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "nonimmediate_operand" ""))
-+ (set (match_operand:DI 2 "ubicom32_acc_hi_register_operand" "")
-+ (mult:DI
-+ (zero_extend:DI (match_dup 0))
-+ (zero_extend:DI (match_operand:SI 3 "ubicom32_data_register_operand" ""))))]
-+ "(peep2_reg_dead_p (2, operands[0])
-+ || REGNO (operands[0]) == REGNO (operands[2])
-+ || REGNO (operands[0]) == REGNO (operands[2]) + 1)
-+ && ! rtx_equal_p (operands[0], operands[3])"
-+ [(set (match_dup 2)
-+ (mult:DI
-+ (zero_extend:DI (match_dup 1))
-+ (zero_extend:DI (match_dup 3))))]
-+ "")
-+
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "nonimmediate_operand" ""))
-+ (set (match_operand:DI 2 "ubicom32_acc_hi_register_operand" "")
-+ (mult:DI
-+ (zero_extend:DI (match_operand:SI 3 "ubicom32_data_register_operand" ""))
-+ (zero_extend:DI (match_dup 0))))]
-+ "(peep2_reg_dead_p (2, operands[0])
-+ || REGNO (operands[0]) == REGNO (operands[2])
-+ || REGNO (operands[0]) == REGNO (operands[2]) + 1)
-+ && ! rtx_equal_p (operands[0], operands[3])"
-+ [(set (match_dup 2)
-+ (mult:DI
-+ (zero_extend:DI (match_dup 1))
-+ (zero_extend:DI (match_dup 3))))]
-+ "")
-+
-+(define_insn "umulsidi3_const"
-+ [(set (match_operand:DI 0 "ubicom32_acc_hi_register_operand" "=h")
-+ (mult:DI
-+ (zero_extend:DI (match_operand:SI 1 "ubicom32_data_register_operand" "%d"))
-+ (match_operand 2 "const_int_operand" "I")))]
-+ "(ubicom32_v4 && satisfies_constraint_I (operands[2]))"
-+ "mulu.4\\t%A0, %2, %1"
-+ [(set_attr "type" "mul")])
-+
-+(define_insn "mulsidi3"
-+ [(set (match_operand:DI 0 "ubicom32_acc_hi_register_operand" "=h, h")
-+ (mult:DI
-+ (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%d,rm"))
-+ (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm, d"))))]
-+ "(ubicom32_v4)"
-+ "@
-+ muls.4\\t%A0, %2, %1
-+ muls.4\\t%A0, %1, %2"
-+ [(set_attr "type" "mul,mul")])
-+
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "nonimmediate_operand" ""))
-+ (set (match_operand:DI 2 "ubicom32_acc_hi_register_operand" "")
-+ (mult:DI
-+ (sign_extend:DI (match_dup 0))
-+ (sign_extend:DI (match_operand:SI 3 "ubicom32_data_register_operand" ""))))]
-+ "(peep2_reg_dead_p (2, operands[0])
-+ || REGNO (operands[0]) == REGNO (operands[2])
-+ || REGNO (operands[0]) == REGNO (operands[2]) + 1)
-+ && ! rtx_equal_p (operands[0], operands[3])"
-+ [(set (match_dup 2)
-+ (mult:DI
-+ (sign_extend:DI (match_dup 1))
-+ (sign_extend:DI (match_dup 3))))]
-+ "")
-+
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "nonimmediate_operand" ""))
-+ (set (match_operand:DI 2 "ubicom32_acc_hi_register_operand" "")
-+ (mult:DI
-+ (sign_extend:DI (match_operand:SI 3 "ubicom32_data_register_operand" ""))
-+ (sign_extend:DI (match_dup 0))))]
-+ "(peep2_reg_dead_p (2, operands[0])
-+ || REGNO (operands[0]) == REGNO (operands[2])
-+ || REGNO (operands[0]) == REGNO (operands[2]) + 1)
-+ && ! rtx_equal_p (operands[0], operands[3])"
-+ [(set (match_dup 2)
-+ (mult:DI
-+ (sign_extend:DI (match_dup 1))
-+ (sign_extend:DI (match_dup 3))))]
-+ "")
-+
-+(define_insn "mulsidi3_const"
-+ [(set (match_operand:DI 0 "ubicom32_acc_hi_register_operand" "=h")
-+ (mult:DI
-+ (sign_extend:DI (match_operand:SI 1 "ubicom32_data_register_operand" "%d"))
-+ (match_operand 2 "const_int_operand" "I")))]
-+ "(ubicom32_v4 && satisfies_constraint_I (operands[2]))"
-+ "muls.4\\t%A0, %2, %1"
-+ [(set_attr "type" "mul")])
-+
-+(define_expand "andqi3"
-+ [(parallel
-+ [(set (match_operand:QI 0 "memory_operand" "")
-+ (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
-+ (match_operand:QI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "(ubicom32_v4)"
-+ "{
-+ if (!memory_operand (operands[0], QImode))
-+ FAIL;
-+
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (QImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (QImode, operands[2]);
-+ }")
-+
-+(define_insn "andqi3_and1"
-+ [(set (match_operand:QI 0 "memory_operand" "=m, m")
-+ (and:QI (match_operand:QI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:QI 2 "ubicom32_arith_operand" "rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4)"
-+ "@
-+ and.1\\t%0, %2, %1
-+ and.1\\t%0, %1, %2")
-+
-+(define_insn "andqi3_and1_ccszn"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (and:QI (match_operand:QI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:QI 2 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))
-+ (set (match_operand:QI 0 "memory_operand" "=m, m")
-+ (and:QI (match_dup 1)
-+ (match_dup 2)))]
-+ "(ubicom32_v4
-+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
-+ "@
-+ and.1\\t%0, %2, %1
-+ and.1\\t%0, %1, %2")
-+
-+(define_insn "andqi3_and1_ccszn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (and:QI (match_operand:QI 0 "nonimmediate_operand" "%d,rm")
-+ (match_operand:QI 1 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))]
-+ "(ubicom32_v4
-+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
-+ "@
-+ and.1\\t#0, %1, %0
-+ and.1\\t#0, %0, %1")
-+
-+(define_insn "and1_ccszn_null_1"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:QI
-+ (and:SI (match_operand:SI 0 "ubicom32_data_register_operand" "%d")
-+ (match_operand:SI 1 "ubicom32_arith_operand" "rI"))
-+ 3)
-+ (const_int 0)))]
-+ "(ubicom32_v4
-+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
-+ "and.1\\t#0, %1, %0")
-+
-+(define_insn "and1_ccszn_null_2"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:QI
-+ (and:SI (match_operand:SI 0 "ubicom32_data_register_operand" "d")
-+ (subreg:SI
-+ (match_operand:QI 1 "memory_operand" "m")
-+ 0))
-+ 3)
-+ (const_int 0)))]
-+ "(ubicom32_v4
-+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
-+ "and.1\\t#0, %1, %0")
-+
-+(define_insn "and1_ccszn_null_3"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:QI
-+ (and:SI (subreg:SI
-+ (match_operand:QI 0 "memory_operand" "m")
-+ 0)
-+ (match_operand:SI 1 "ubicom32_data_register_operand" "d"))
-+ 3)
-+ (const_int 0)))]
-+ "(ubicom32_v4
-+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
-+ "and.1\\t#0, %0, %1")
-+
-+(define_expand "andhi3"
-+ [(parallel
-+ [(set (match_operand:HI 0 "memory_operand" "")
-+ (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
-+ (match_operand:HI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ ""
-+ "{
-+ if (!memory_operand (operands[0], HImode))
-+ FAIL;
-+
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (HImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (HImode, operands[2]);
-+ }")
-+
-+(define_insn "andhi3_and2"
-+ [(set (match_operand:HI 0 "memory_operand" "=m, m")
-+ (and:HI (match_operand:HI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:HI 2 "ubicom32_arith_operand" "rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "@
-+ and.2\\t%0, %2, %1
-+ and.2\\t%0, %1, %2")
-+
-+(define_insn "andhi3_and2_ccszn"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (and:HI (match_operand:HI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:HI 2 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))
-+ (set (match_operand:HI 0 "memory_operand" "=m, m")
-+ (and:HI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "@
-+ and.2\\t%0, %2, %1
-+ and.2\\t%0, %1, %2")
-+
-+(define_insn "andhi3_and2_ccszn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (and:HI (match_operand:HI 0 "nonimmediate_operand" "%d,rm")
-+ (match_operand:HI 1 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "@
-+ and.2\\t#0, %1, %0
-+ and.2\\t#0, %0, %1")
-+
-+(define_insn "and2_ccszn_null_1"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:HI
-+ (and:SI (match_operand:SI 0 "ubicom32_data_register_operand" "%d")
-+ (match_operand:SI 1 "ubicom32_arith_operand" "rI"))
-+ 2)
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "and.2\\t#0, %1, %0")
-+
-+(define_insn "and2_ccszn_null_2"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:HI
-+ (and:SI (match_operand:SI 0 "ubicom32_data_register_operand" "d")
-+ (subreg:SI
-+ (match_operand:HI 1 "memory_operand" "m")
-+ 0))
-+ 2)
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "and.2\\t#0, %1, %0")
-+
-+(define_insn "and2_ccszn_null_3"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:HI
-+ (and:SI (subreg:SI
-+ (match_operand:HI 0 "memory_operand" "m")
-+ 0)
-+ (match_operand:SI 1 "ubicom32_data_register_operand" "d"))
-+ 2)
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "and.2\\t#0, %0, %1")
-+
-+(define_expand "andsi3"
-+ [(parallel
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
-+ (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
-+ (match_operand:SI 2 "ubicom32_and_or_si3_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ ""
-+ "{
-+ do
-+ {
-+ /* Is this a bfextu? */
-+ if (ubicom32_data_register_operand (operands[0], SImode)
-+ && CONST_INT_P (operands[2])
-+ && exact_log2 (INTVAL (operands[2]) + 1) != -1)
-+ break;
-+
-+ /* Is this a bclr? */
-+ if (CONST_INT_P (operands[2])
-+ && exact_log2 (~INTVAL (operands[2])) != -1)
-+ break;
-+
-+ /* Must be an and.4 */
-+ if (!ubicom32_data_register_operand (operands[1], SImode))
-+ operands[1] = copy_to_mode_reg (SImode, operands[1]);
-+
-+ if (!ubicom32_arith_operand (operands[2], SImode))
-+ operands[2] = copy_to_mode_reg (SImode, operands[2]);
-+ }
-+ while (0);
-+ }")
-+
-+(define_insn "andsi3_bfextu"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (and:SI (match_operand:SI 1 "nonimmediate_operand" "%rm")
-+ (match_operand:SI 2 "const_int_operand" "O")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(satisfies_constraint_O (operands[2]))"
-+ "*
-+ {
-+ operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2]) + 1));
-+
-+ return \"bfextu\\t%0, %1, %3\";
-+ }")
-+
-+(define_insn "andsi3_bfextu_ccwz"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (and:SI (match_operand:SI 1 "nonimmediate_operand" "%rm")
-+ (match_operand:SI 2 "const_int_operand" "O"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (and:SI (match_dup 1)
-+ (match_dup 2)))]
-+ "(satisfies_constraint_O (operands[2])
-+ && ubicom32_match_cc_mode(insn, CCWZmode))"
-+ "*
-+ {
-+ operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2]) + 1));
-+
-+ return \"bfextu\\t%0, %1, %3\";
-+ }")
-+
-+(define_insn "andsi3_bfextu_ccwz_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (and:SI (match_operand:SI 0 "nonimmediate_operand" "%rm")
-+ (match_operand:SI 1 "const_int_operand" "O"))
-+ (const_int 0)))
-+ (clobber (match_scratch:SI 2 "=d"))]
-+ "(satisfies_constraint_O (operands[1])
-+ && ubicom32_match_cc_mode(insn, CCWZmode))"
-+ "*
-+ {
-+ operands[3] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1));
-+
-+ return \"bfextu\\t%2, %0, %3\";
-+ }")
-+
-+(define_insn "andsi3_bclr"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (and:SI (match_operand:SI 1 "ubicom32_arith_operand" "%rmI")
-+ (match_operand:SI 2 "const_int_operand" "n")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(exact_log2 (~INTVAL (operands[2])) != -1)"
-+ "bclr\\t%0, %1, #%D2")
-+
-+(define_insn "andsi3_and4"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
-+ (and:SI (match_operand:SI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "@
-+ and.4\\t%0, %2, %1
-+ and.4\\t%0, %1, %2")
-+
-+(define_insn "andsi3_and4_ccwzn"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (and:SI (match_operand:SI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
-+ (and:SI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "@
-+ and.4\\t%0, %2, %1
-+ and.4\\t%0, %1, %2")
-+
-+(define_insn "andsi3_and4_ccwzn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (and:SI (match_operand:SI 0 "nonimmediate_operand" "%d,rm")
-+ (match_operand:SI 1 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "@
-+ and.4\\t#0, %1, %0
-+ and.4\\t#0, %0, %1")
-+
-+(define_insn "andsi3_lsr4_ccwz_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (and:SI (match_operand:SI 0 "nonimmediate_operand" "%rm")
-+ (match_operand:SI 1 "const_int_operand" "n"))
-+ (const_int 0)))
-+ (clobber (match_scratch:SI 2 "=d"))]
-+ "(exact_log2 ((~(INTVAL (operands[1]))) + 1) != -1
-+ && ubicom32_match_cc_mode(insn, CCWZmode))"
-+ "*
-+ {
-+ operands[3] = GEN_INT (exact_log2 ((~(INTVAL (operands[1]))) + 1));
-+
-+ return \"lsr.4\\t%2, %0, %3\";
-+ }")
-+
-+; We really would like the combiner to recognize this scenario and deal with
-+; it but unfortunately it tries to canonicalize zero_extract ops on MEMs
-+; into QImode operations and we can't match them in any useful way.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))
-+ (set (reg:CCWZ CC_REGNO)
-+ (compare:CCWZ
-+ (and:SI (match_operand:SI 2 "nonimmediate_operand" "")
-+ (match_dup 0))
-+ (const_int 0)))]
-+ "(exact_log2 (INTVAL (operands[1])) != -1
-+ && peep2_reg_dead_p (2, operands[0]))"
-+ [(set (reg:CCWZ CC_REGNO)
-+ (compare:CCWZ
-+ (zero_extract:SI
-+ (match_dup 2)
-+ (const_int 1)
-+ (match_dup 3))
-+ (const_int 0)))]
-+ "{
-+ operands[3] = GEN_INT (exact_log2 (INTVAL (operands[1])));
-+ }")
-+
-+(define_expand "anddi3"
-+ [(parallel
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "")
-+ (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
-+ (match_operand:DI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ ""
-+ "{
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (DImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (DImode, operands[2]);
-+ }")
-+
-+(define_insn_and_split "anddi3_and4"
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,&r, d,rm, m, m")
-+ (and:DI (match_operand:DI 1 "nonimmediate_operand" "%d,rm, 0, 0, d,rm")
-+ (match_operand:DI 2 "ubicom32_arith_operand" "rmI, d,rmI, d,rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "#"
-+ "reload_completed"
-+ [(parallel [(set (match_dup 3)
-+ (and:SI (match_dup 4)
-+ (match_dup 5)))
-+ (clobber (reg:CC CC_REGNO))])
-+ (parallel [(set (match_dup 6)
-+ (and:SI (match_dup 7)
-+ (match_dup 8)))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "{
-+ operands[3] = gen_lowpart (SImode, operands[0]);
-+ operands[4] = gen_lowpart (SImode, operands[1]);
-+ operands[5] = gen_lowpart (SImode, operands[2]);
-+ operands[6] = gen_highpart (SImode, operands[0]);
-+ operands[7] = gen_highpart (SImode, operands[1]);
-+ operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_expand "iorqi3"
-+ [(parallel
-+ [(set (match_operand:QI 0 "memory_operand" "")
-+ (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
-+ (match_operand:QI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "(ubicom32_v4)"
-+ "{
-+ if (!memory_operand (operands[0], QImode))
-+ FAIL;
-+
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (QImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (QImode, operands[2]);
-+ }")
-+
-+(define_insn "iorqi3_or1"
-+ [(set (match_operand:QI 0 "memory_operand" "=m, m")
-+ (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:QI 2 "ubicom32_arith_operand" "rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4)"
-+ "@
-+ or.1\\t%0, %2, %1
-+ or.1\\t%0, %1, %2")
-+
-+(define_expand "iorhi3"
-+ [(parallel
-+ [(set (match_operand:HI 0 "memory_operand" "")
-+ (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
-+ (match_operand:HI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ ""
-+ "{
-+ if (!memory_operand (operands[0], HImode))
-+ FAIL;
-+
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (HImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (HImode, operands[2]);
-+ }")
-+
-+(define_insn "iorhi3_or2"
-+ [(set (match_operand:HI 0 "memory_operand" "=m, m")
-+ (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:HI 2 "ubicom32_arith_operand" "rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "@
-+ or.2\\t%0, %2, %1
-+ or.2\\t%0, %1, %2")
-+
-+(define_expand "iorsi3"
-+ [(parallel
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
-+ (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
-+ (match_operand:SI 2 "ubicom32_and_or_si3_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ ""
-+ "{
-+ do
-+ {
-+ /* Is this a bset? */
-+ if (CONST_INT_P (operands[2])
-+ && exact_log2 (INTVAL (operands[2])) != -1)
-+ break;
-+
-+ /* Must be an or.4 */
-+ if (!ubicom32_data_register_operand (operands[1], SImode))
-+ operands[1] = copy_to_mode_reg (SImode, operands[1]);
-+
-+ if (!ubicom32_arith_operand (operands[2], SImode))
-+ operands[2] = copy_to_mode_reg (SImode, operands[2]);
-+ }
-+ while (0);
-+ }")
-+
-+(define_insn "iorsi3_bset"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (ior:SI (match_operand:SI 1 "ubicom32_arith_operand" "%rmI")
-+ (match_operand 2 "const_int_operand" "n")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(exact_log2 (INTVAL (operands[2])) != -1)"
-+ "bset\\t%0, %1, #%d2")
-+
-+(define_insn "iorsi3_or4"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
-+ (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "@
-+ or.4\\t%0, %2, %1
-+ or.4\\t%0, %1, %2")
-+
-+(define_insn "iorsi3_ccwzn"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
-+ (ior:SI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "@
-+ or.4\\t%0, %2, %1
-+ or.4\\t%0, %1, %2")
-+
-+(define_insn "iorsi3_ccwzn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (ior:SI (match_operand:SI 0 "nonimmediate_operand" "%d,rm")
-+ (match_operand:SI 1 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "@
-+ or.4\\t#0, %1, %0
-+ or.4\\t#0, %0, %1")
-+
-+(define_expand "iordi3"
-+ [(parallel
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "")
-+ (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
-+ (match_operand:DI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ ""
-+ "{
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (DImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (DImode, operands[2]);
-+ }")
-+
-+(define_insn_and_split "iordi3_or4"
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,&r, d,rm, m, m")
-+ (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%d,rm, 0, 0, d,rm")
-+ (match_operand:DI 2 "ubicom32_arith_operand" "rmI, d,rmI, d,rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "#"
-+ "reload_completed"
-+ [(parallel [(set (match_dup 3)
-+ (ior:SI (match_dup 4)
-+ (match_dup 5)))
-+ (clobber (reg:CC CC_REGNO))])
-+ (parallel [(set (match_dup 6)
-+ (ior:SI (match_dup 7)
-+ (match_dup 8)))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "{
-+ operands[3] = gen_lowpart (SImode, operands[0]);
-+ operands[4] = gen_lowpart (SImode, operands[1]);
-+ operands[5] = gen_lowpart (SImode, operands[2]);
-+ operands[6] = gen_highpart (SImode, operands[0]);
-+ operands[7] = gen_highpart (SImode, operands[1]);
-+ operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_expand "xorqi3"
-+ [(parallel
-+ [(set (match_operand:QI 0 "memory_operand" "")
-+ (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
-+ (match_operand:QI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "(ubicom32_v4)"
-+ "{
-+ if (!memory_operand (operands[0], QImode))
-+ FAIL;
-+
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (QImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (QImode, operands[2]);
-+ }")
-+
-+(define_insn "xorqi3_xor1"
-+ [(set (match_operand:QI 0 "memory_operand" "=m, m")
-+ (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:QI 2 "ubicom32_arith_operand" "rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4)"
-+ "@
-+ xor.1\\t%0, %2, %1
-+ xor.1\\t%0, %1, %2")
-+
-+(define_insn "xorqi3_xor1_ccszn"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:QI 2 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))
-+ (set (match_operand:QI 0 "memory_operand" "=m, m")
-+ (xor:QI (match_dup 1)
-+ (match_dup 2)))]
-+ "(ubicom32_v4
-+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
-+ "@
-+ xor.1\\t%0, %2, %1
-+ xor.1\\t%0, %1, %2")
-+
-+(define_insn "xorqi3_xor1_ccszn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (xor:QI (match_operand:QI 0 "nonimmediate_operand" "%d,rm")
-+ (match_operand:QI 1 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))]
-+ "(ubicom32_v4
-+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
-+ "@
-+ xor.1\\t#0, %1, %0
-+ xor.1\\t#0, %0, %1")
-+
-+(define_insn "xor1_ccszn_null_1"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:QI
-+ (xor:SI (match_operand:SI 0 "ubicom32_data_register_operand" "%d")
-+ (match_operand:SI 1 "ubicom32_arith_operand" "rI"))
-+ 3)
-+ (const_int 0)))]
-+ "(ubicom32_v4
-+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
-+ "xor.1\\t#0, %1, %0")
-+
-+(define_insn "xor1_ccszn_null_2"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:QI
-+ (xor:SI (match_operand:SI 0 "ubicom32_data_register_operand" "d")
-+ (subreg:SI
-+ (match_operand:QI 1 "memory_operand" "m")
-+ 0))
-+ 3)
-+ (const_int 0)))]
-+ "(ubicom32_v4
-+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
-+ "xor.1\\t#0, %1, %0")
-+
-+(define_insn "xor1_ccwzn_null_3"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:QI
-+ (xor:SI (subreg:SI
-+ (match_operand:QI 0 "memory_operand" "m")
-+ 0)
-+ (match_operand:SI 1 "ubicom32_data_register_operand" "d"))
-+ 3)
-+ (const_int 0)))]
-+ "(ubicom32_v4
-+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
-+ "xor.1\\t#0, %0, %1")
-+
-+(define_expand "xorhi3"
-+ [(parallel
-+ [(set (match_operand:HI 0 "memory_operand" "")
-+ (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
-+ (match_operand:HI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ ""
-+ "{
-+ if (!memory_operand (operands[0], HImode))
-+ FAIL;
-+
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (HImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (HImode, operands[2]);
-+ }")
-+
-+(define_insn "xorhi3_xor2"
-+ [(set (match_operand:HI 0 "memory_operand" "=m, m")
-+ (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:HI 2 "ubicom32_arith_operand" "rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "@
-+ xor.2\\t%0, %2, %1
-+ xor.2\\t%0, %1, %2")
-+
-+(define_insn "xorhi3_xor2_ccszn"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:HI 2 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))
-+ (set (match_operand:HI 0 "memory_operand" "=m, m")
-+ (xor:HI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "@
-+ xor.2\\t%0, %2, %1
-+ xor.2\\t%0, %1, %2")
-+
-+(define_insn "xorhi3_xor2_ccszn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (xor:HI (match_operand:HI 0 "nonimmediate_operand" "%d,rm")
-+ (match_operand:HI 1 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "@
-+ xor.2\\t#0, %1, %0
-+ xor.2\\t#0, %0, %1")
-+
-+(define_insn "xor2_ccszn_null_1"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:HI
-+ (xor:SI (match_operand:SI 0 "ubicom32_data_register_operand" "%d")
-+ (match_operand:SI 1 "ubicom32_arith_operand" "rI"))
-+ 2)
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "xor.2\\t#0, %1, %0")
-+
-+(define_insn "xor2_ccszn_null_2"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:HI
-+ (xor:SI (match_operand:SI 0 "ubicom32_data_register_operand" "d")
-+ (subreg:SI
-+ (match_operand:HI 1 "memory_operand" "m")
-+ 0))
-+ 2)
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "xor.2\\t#0, %1, %0")
-+
-+(define_insn "xor2_ccszn_null_3"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:HI
-+ (xor:SI (subreg:SI
-+ (match_operand:HI 0 "memory_operand" "m")
-+ 0)
-+ (match_operand:SI 1 "ubicom32_data_register_operand" "d"))
-+ 2)
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "xor.2\\t#0, %0, %1")
-+
-+(define_insn "xorsi3"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
-+ (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "@
-+ xor.4\\t%0, %2, %1
-+ xor.4\\t%0, %1, %2")
-+
-+(define_insn "xorsi3_ccwzn"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
-+ (xor:SI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "@
-+ xor.4\\t%0, %2, %1
-+ xor.4\\t%0, %1, %2")
-+
-+(define_insn "xorsi3_ccwzn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (xor:SI (match_operand:SI 0 "nonimmediate_operand" "%d,rm")
-+ (match_operand:SI 1 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "@
-+ xor.4\\t#0, %1, %0
-+ xor.4\\t#0, %0, %1")
-+
-+(define_expand "xordi3"
-+ [(parallel
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "")
-+ (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
-+ (match_operand:DI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ ""
-+ "{
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (DImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (DImode, operands[2]);
-+ }")
-+
-+(define_insn_and_split "xordi3_xor4"
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,&r, d,rm, m, m")
-+ (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%d,rm, 0, 0, d,rm")
-+ (match_operand:DI 2 "ubicom32_arith_operand" "rmI, d,rmI, d,rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "#"
-+ "reload_completed"
-+ [(parallel [(set (match_dup 3)
-+ (xor:SI (match_dup 4)
-+ (match_dup 5)))
-+ (clobber (reg:CC CC_REGNO))])
-+ (parallel [(set (match_dup 6)
-+ (xor:SI (match_dup 7)
-+ (match_dup 8)))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "{
-+ operands[3] = gen_lowpart (SImode, operands[0]);
-+ operands[4] = gen_lowpart (SImode, operands[1]);
-+ operands[5] = gen_lowpart (SImode, operands[2]);
-+ operands[6] = gen_highpart (SImode, operands[0]);
-+ operands[7] = gen_highpart (SImode, operands[1]);
-+ operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_insn "not2_2"
-+ [(set (match_operand:HI 0 "memory_operand" "=m")
-+ (subreg:HI
-+ (not:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI"))
-+ 2))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "not.2\\t%0, %1")
-+
-+(define_insn "one_cmplsi2"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (not:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "not.4\\t%0, %1")
-+
-+(define_insn "one_cmplsi2_ccwzn"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (not:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (not:SI (match_dup 1)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "not.4\\t%0, %1")
-+
-+(define_insn "one_cmplsi2_ccwzn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (not:SI (match_operand:SI 0 "ubicom32_arith_operand" "rmI"))
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "not.4\\t#0, %0")
-+
-+(define_insn_and_split "one_cmpldi2"
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "=&rm")
-+ (not:DI (match_operand:DI 1 "nonimmediate_operand" "rmI0")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "#"
-+ ""
-+ [(parallel [(set (match_dup 2)
-+ (not:SI (match_dup 3)))
-+ (clobber (reg:CC CC_REGNO))])
-+ (parallel [(set (match_dup 4)
-+ (not:SI (match_dup 5)))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "{
-+ operands[2] = gen_lowpart (SImode, operands[0]);
-+ operands[3] = gen_lowpart (SImode, operands[1]);
-+ operands[4] = gen_highpart (SImode, operands[0]);
-+ operands[5] = gen_highpart (SImode, operands[1]);
-+ }"
-+ [(set_attr "length" "8")])
-+
-+; Conditional jump instructions
-+
-+(define_expand "beq"
-+ [(set (pc)
-+ (if_then_else (eq (match_dup 1)
-+ (const_int 0))
-+ (label_ref (match_operand 0 "" ""))
-+ (pc)))]
-+ ""
-+ "{
-+ operands[1] = ubicom32_gen_compare_reg (EQ, ubicom32_compare_op0,
-+ ubicom32_compare_op1);
-+ }")
-+
-+(define_expand "bne"
-+ [(set (pc)
-+ (if_then_else (ne (match_dup 1)
-+ (const_int 0))
-+ (label_ref (match_operand 0 "" ""))
-+ (pc)))]
-+ ""
-+ "{
-+ operands[1] = ubicom32_gen_compare_reg (NE, ubicom32_compare_op0,
-+ ubicom32_compare_op1);
-+ }")
-+
-+(define_expand "bgt"
-+ [(set (pc)
-+ (if_then_else (gt (match_dup 1)
-+ (const_int 0))
-+ (label_ref (match_operand 0 "" ""))
-+ (pc)))]
-+ ""
-+ "{
-+ operands[1] = ubicom32_gen_compare_reg (GT, ubicom32_compare_op0,
-+ ubicom32_compare_op1);
-+ }")
-+
-+(define_expand "ble"
-+ [(set (pc)
-+ (if_then_else (le (match_dup 1)
-+ (const_int 0))
-+ (label_ref (match_operand 0 "" ""))
-+ (pc)))]
-+ ""
-+ "{
-+ operands[1] = ubicom32_gen_compare_reg (LE, ubicom32_compare_op0,
-+ ubicom32_compare_op1);
-+ }")
-+
-+(define_expand "bge"
-+ [(set (pc)
-+ (if_then_else (ge (match_dup 1)
-+ (const_int 0))
-+ (label_ref (match_operand 0 "" ""))
-+ (pc)))]
-+ ""
-+ "{
-+ operands[1] = ubicom32_gen_compare_reg (GE, ubicom32_compare_op0,
-+ ubicom32_compare_op1);
-+ }")
-+
-+(define_expand "blt"
-+ [(set (pc)
-+ (if_then_else (lt (match_dup 1)
-+ (const_int 0))
-+ (label_ref (match_operand 0 "" ""))
-+ (pc)))]
-+ ""
-+ "{
-+ operands[1] = ubicom32_gen_compare_reg (LT, ubicom32_compare_op0,
-+ ubicom32_compare_op1);
-+ }")
-+
-+(define_expand "bgtu"
-+ [(set (pc)
-+ (if_then_else (gtu (match_dup 1)
-+ (const_int 0))
-+ (label_ref (match_operand 0 "" ""))
-+ (pc)))]
-+ ""
-+ "{
-+ operands[1] = ubicom32_gen_compare_reg (GTU, ubicom32_compare_op0,
-+ ubicom32_compare_op1);
-+ }")
-+
-+(define_expand "bleu"
-+ [(set (pc)
-+ (if_then_else (leu (match_dup 1)
-+ (const_int 0))
-+ (label_ref (match_operand 0 "" ""))
-+ (pc)))]
-+ ""
-+ "{
-+ operands[1] = ubicom32_gen_compare_reg (LEU, ubicom32_compare_op0,
-+ ubicom32_compare_op1);
-+ }")
-+
-+(define_expand "bgeu"
-+ [(set (pc)
-+ (if_then_else (geu (match_dup 1)
-+ (const_int 0))
-+ (label_ref (match_operand 0 "" ""))
-+ (pc)))]
-+ ""
-+ "{
-+ operands[1] = ubicom32_gen_compare_reg (GEU, ubicom32_compare_op0,
-+ ubicom32_compare_op1);
-+ }")
-+
-+(define_expand "bltu"
-+ [(set (pc)
-+ (if_then_else (ltu (match_dup 1)
-+ (const_int 0))
-+ (label_ref (match_operand 0 "" ""))
-+ (pc)))]
-+ ""
-+ "{
-+ operands[1] = ubicom32_gen_compare_reg (LTU, ubicom32_compare_op0,
-+ ubicom32_compare_op1);
-+ }")
-+
-+(define_insn "jcc"
-+ [(set (pc)
-+ (if_then_else (match_operator 1 "comparison_operator"
-+ [(match_operand 2 "ubicom32_cc_register_operand" "")
-+ (const_int 0)])
-+ (label_ref (match_operand 0 "" ""))
-+ (pc)))]
-+ ""
-+ "*
-+ {
-+ ubicom32_output_cond_jump (insn, operands[1], operands[0]);
-+ return \"\";
-+ }")
-+
-+; Reverse branch - reverse our comparison condition so that we can
-+; branch in the opposite sense.
-+;
-+(define_insn_and_split "jcc_reverse"
-+ [(set (pc)
-+ (if_then_else (match_operator 1 "comparison_operator"
-+ [(match_operand 2 "ubicom32_cc_register_operand" "")
-+ (const_int 0)])
-+ (pc)
-+ (label_ref (match_operand 0 "" ""))))]
-+ ""
-+ "#"
-+ "reload_completed"
-+ [(set (pc)
-+ (if_then_else (match_dup 3)
-+ (label_ref (match_dup 0))
-+ (pc)))]
-+ "{
-+ rtx cc_reg;
-+
-+ cc_reg = gen_rtx_REG (GET_MODE (operands[2]), CC_REGNO);
-+ operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[1])),
-+ GET_MODE (operands[1]),
-+ cc_reg,
-+ const0_rtx);
-+ }")
-+
-+(define_insn "jump"
-+ [(set (pc)
-+ (label_ref (match_operand 0 "" "")))]
-+ ""
-+ "jmpt\\t%l0")
-+
-+(define_expand "indirect_jump"
-+ [(parallel [(set (pc)
-+ (match_operand:SI 0 "register_operand" ""))
-+ (clobber (match_dup 0))])]
-+ ""
-+ "")
-+
-+(define_insn "indirect_jump_internal"
-+ [(set (pc)
-+ (match_operand:SI 0 "register_operand" "a"))
-+ (clobber (match_dup 0))]
-+ ""
-+ "calli\\t%0,0(%0)")
-+
-+; Program Space: The table contains instructions, typically jumps.
-+; CALL An,TABLE_SIZE(PC) ;An = Jump Table Base Address.
-+; <Jump Table is Here> ;An -> Here.
-+; LEA Ak, (An,Dn) ;Ak -> Table Entry
-+; JMP/CALL (Ak)
-+
-+(define_expand "tablejump"
-+ [(parallel [(set (pc)
-+ (match_operand:SI 0 "nonimmediate_operand" ""))
-+ (use (label_ref (match_operand 1 "" "")))])]
-+ ""
-+ "")
-+
-+(define_insn "tablejump_internal"
-+ [(set (pc)
-+ (match_operand:SI 0 "nonimmediate_operand" "rm"))
-+ (use (label_ref (match_operand 1 "" "")))]
-+ ""
-+ "ret\\t%0")
-+
-+; Call subroutine with no return value.
-+;
-+(define_expand "call"
-+ [(call (match_operand:QI 0 "general_operand" "")
-+ (match_operand:SI 1 "general_operand" ""))]
-+ ""
-+ "{
-+ if (TARGET_FDPIC)
-+ {
-+ ubicom32_expand_call_fdpic (operands);
-+ DONE;
-+ }
-+
-+ if (! ubicom32_call_address_operand (XEXP (operands[0], 0), VOIDmode))
-+ XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
-+ }")
-+
-+; We expand to a simple form that doesn't clobber the link register and
-+; then split to a form that does. This allows the RTL optimizers that
-+; run before the splitter to have the opportunity to eliminate the call
-+; without marking A5 as being clobbered and this in turn avoids saves
-+; and returns in a number of cases.
-+;
-+(define_insn_and_split "call_1"
-+ [(call (mem:QI (match_operand:SI 0 "ubicom32_call_address_operand" "a,S"))
-+ (match_operand:SI 1 "general_operand" "g,g"))]
-+ "! TARGET_FDPIC"
-+ "#"
-+ ""
-+ [(parallel
-+ [(call (mem:QI (match_dup 0))
-+ (match_dup 1))
-+ (clobber (reg:SI LINK_REGNO))])]
-+ "")
-+
-+(define_insn "call_slow"
-+ [(call (mem:QI (match_operand:SI 0 "ubicom32_call_address_operand" "a,S"))
-+ (match_operand:SI 1 "general_operand" "g,g"))
-+ (clobber (reg:SI LINK_REGNO))]
-+ "(! TARGET_FDPIC && ! TARGET_FASTCALL)"
-+ "@
-+ calli\\ta5, 0(%0)
-+ moveai\\ta5, #%%hi(%C0)\;calli\\ta5, %%lo(%C0)(a5)")
-+
-+(define_insn "call_fast"
-+ [(call (mem:QI (match_operand:SI 0 "ubicom32_call_address_operand" "a,S"))
-+ (match_operand:SI 1 "general_operand" "g,g"))
-+ (clobber (reg:SI LINK_REGNO))]
-+ "(! TARGET_FDPIC && TARGET_FASTCALL)"
-+ "@
-+ calli\\ta5, 0(%0)
-+ call\\ta5, %C0")
-+
-+; We expand to a simple form that doesn't clobber the link register and
-+; then split to a form that does. This allows the RTL optimizers that
-+; run before the splitter to have the opportunity to eliminate the call
-+; without marking A5 as being clobbered and this in turn avoids saves
-+; and returns in a number of cases.
-+;
-+(define_insn_and_split "call_fdpic"
-+ [(call (mem:QI (match_operand:SI 0 "ubicom32_call_address_operand" "a,S"))
-+ (match_operand:SI 1 "general_operand" "g,g"))
-+ (use (match_operand:SI 2 "ubicom32_fdpic_operand" "Z,Z"))]
-+ "TARGET_FDPIC"
-+ "#"
-+ ""
-+ [(parallel
-+ [(call (mem:QI (match_dup 0))
-+ (match_dup 1))
-+ (use (match_dup 2))
-+ (clobber (reg:SI LINK_REGNO))])]
-+ "")
-+
-+(define_insn "call_fdpic_clobber"
-+ [(call (mem:QI (match_operand:SI 0 "ubicom32_call_address_operand" "a,S"))
-+ (match_operand:SI 1 "general_operand" "g,g"))
-+ (use (match_operand:SI 2 "ubicom32_fdpic_operand" "Z,Z"))
-+ (clobber (reg:SI LINK_REGNO))]
-+ "TARGET_FDPIC"
-+ "@
-+ move.4\\ta5, 0(%0)\;move.4\\t%2, 4(%0)\;calli\\ta5, 0(a5)
-+ call\\ta5, %C0")
-+
-+; Call subroutine, returning value in operand 0
-+; (which must be a hard register).
-+;
-+(define_expand "call_value"
-+ [(set (match_operand 0 "" "")
-+ (call (match_operand:QI 1 "general_operand" "")
-+ (match_operand:SI 2 "general_operand" "")))]
-+ ""
-+ "{
-+ if (TARGET_FDPIC)
-+ {
-+ ubicom32_expand_call_value_fdpic (operands);
-+ DONE;
-+ }
-+
-+ if (! ubicom32_call_address_operand (XEXP (operands[1], 0), VOIDmode))
-+ XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
-+ }")
-+
-+; We expand to a simple form that doesn't clobber the link register and
-+; then split to a form that does. This allows the RTL optimizers that
-+; run before the splitter to have the opportunity to eliminate the call
-+; without marking A5 as being clobbered and this in turn avoids saves
-+; and returns in a number of cases.
-+;
-+(define_insn_and_split "call_value_1"
-+ [(set (match_operand 0 "register_operand" "=r,r")
-+ (call (mem:QI (match_operand:SI 1 "ubicom32_call_address_operand" "a,S"))
-+ (match_operand:SI 2 "general_operand" "g,g")))]
-+ "! TARGET_FDPIC"
-+ "#"
-+ ""
-+ [(parallel
-+ [(set (match_dup 0)
-+ (call (mem:QI (match_dup 1))
-+ (match_dup 2)))
-+ (clobber (reg:SI LINK_REGNO))])]
-+ "")
-+
-+(define_insn "call_value_slow"
-+ [(set (match_operand 0 "register_operand" "=r,r")
-+ (call (mem:QI (match_operand:SI 1 "ubicom32_call_address_operand" "a,S"))
-+ (match_operand:SI 2 "general_operand" "g,g")))
-+ (clobber (reg:SI LINK_REGNO))]
-+ "(! TARGET_FDPIC && ! TARGET_FASTCALL)"
-+ "@
-+ calli\\ta5, 0(%1)
-+ moveai\\ta5, #%%hi(%C1)\;calli\\ta5, %%lo(%C1)(a5)")
-+
-+(define_insn "call_value_fast"
-+ [(set (match_operand 0 "register_operand" "=r,r")
-+ (call (mem:QI (match_operand:SI 1 "ubicom32_call_address_operand" "a,S"))
-+ (match_operand:SI 2 "general_operand" "g,g")))
-+ (clobber (reg:SI LINK_REGNO))]
-+ "(! TARGET_FDPIC && TARGET_FASTCALL)"
-+ "@
-+ calli\\ta5, 0(%1)
-+ call\\ta5, %C1")
-+
-+; We expand to a simple form that doesn't clobber the link register and
-+; then split to a form that does. This allows the RTL optimizers that
-+; run before the splitter to have the opportunity to eliminate the call
-+; without marking A5 as being clobbered and this in turn avoids saves
-+; and returns in a number of cases.
-+;
-+(define_insn_and_split "call_value_fdpic"
-+ [(set (match_operand 0 "register_operand" "=r,r")
-+ (call (mem:QI (match_operand:SI 1 "ubicom32_call_address_operand" "a,S"))
-+ (match_operand:SI 2 "general_operand" "g,g")))
-+ (use (match_operand:SI 3 "ubicom32_fdpic_operand" "Z,Z"))]
-+ "TARGET_FDPIC"
-+ "#"
-+ ""
-+ [(parallel
-+ [(set (match_dup 0)
-+ (call (mem:QI (match_dup 1))
-+ (match_dup 2)))
-+ (use (match_dup 3))
-+ (clobber (reg:SI LINK_REGNO))])]
-+ "")
-+
-+(define_insn "call_value_fdpic_clobber"
-+ [(set (match_operand 0 "register_operand" "=r,r")
-+ (call (mem:QI (match_operand:SI 1 "ubicom32_call_address_operand" "a,S"))
-+ (match_operand:SI 2 "general_operand" "g,g")))
-+ (use (match_operand:SI 3 "ubicom32_fdpic_operand" "Z,Z"))
-+ (clobber (reg:SI LINK_REGNO))]
-+ "TARGET_FDPIC"
-+ "@
-+ move.4\\ta5, 0(%1)\;move.4\\t%3, 4(%1)\;calli\\ta5, 0(a5)
-+ call\\ta5, %C1")
-+
-+(define_expand "untyped_call"
-+ [(parallel [(call (match_operand 0 "" "")
-+ (const_int 0))
-+ (match_operand 1 "" "")
-+ (match_operand 2 "" "")])]
-+ ""
-+ "{
-+ int i;
-+
-+ emit_call_insn (gen_call (operands[0], const0_rtx));
-+
-+ for (i = 0; i < XVECLEN (operands[2], 0); i++)
-+ {
-+ rtx set = XVECEXP (operands[2], 0, i);
-+ emit_move_insn (SET_DEST (set), SET_SRC (set));
-+ }
-+ DONE;
-+ }")
-+
-+(define_insn "lsl1_1"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (ashift:SI (subreg:SI
-+ (match_operand:QI 1 "memory_operand" "m")
-+ 0)
-+ (match_operand:SI 2 "ubicom32_arith_operand" "dM")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4)"
-+ "lsl.1\\t%0, %1, %2")
-+
-+; The combiner gets rather creative about left shifts of sub-word memory
-+; operands because it's uncertain about whether the memory is sign or
-+; zero extended. It only wants zero-extended behaviour and so throws
-+; in an extra and operation.
-+;
-+(define_insn "lsl1_2"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (and:SI
-+ (ashift:SI (subreg:SI
-+ (match_operand:QI 1 "memory_operand" "m")
-+ 0)
-+ (match_operand:SI 2 "const_int_operand" "M"))
-+ (match_operand:SI 3 "const_int_operand" "n")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4
-+ && INTVAL (operands[3]) == (0xff << INTVAL (operands[2])))"
-+ "lsl.1\\t%0, %1, %2")
-+
-+(define_insn "lsl2_1"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (ashift:SI (subreg:SI
-+ (match_operand:HI 1 "memory_operand" "m")
-+ 0)
-+ (match_operand:SI 2 "ubicom32_arith_operand" "dM")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4)"
-+ "lsl.2\\t%0, %1, %2")
-+
-+; The combiner gets rather creative about left shifts of sub-word memory
-+; operands because it's uncertain about whether the memory is sign or
-+; zero extended. It only wants zero-extended behaviour and so throws
-+; in an extra and operation.
-+;
-+(define_insn "lsl2_2"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (and:SI
-+ (ashift:SI (subreg:SI
-+ (match_operand:HI 1 "memory_operand" "m")
-+ 0)
-+ (match_operand:SI 2 "const_int_operand" "M"))
-+ (match_operand:SI 3 "const_int_operand" "n")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4
-+ && INTVAL (operands[3]) == (0xffff << INTVAL (operands[2])))"
-+ "lsl.2\\t%0, %1, %2")
-+
-+(define_insn "ashlsi3"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (ashift:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "dM")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "lsl.4\\t%0, %1, %2")
-+
-+(define_insn "lshlsi3_ccwz"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (ashift:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "dM"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (ashift:SI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCWZmode)"
-+ "lsl.4\\t%0, %1, %2")
-+
-+(define_insn "lshlsi3_ccwz_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (ashift:SI (match_operand:SI 0 "ubicom32_arith_operand" "rmI")
-+ (match_operand:SI 1 "ubicom32_arith_operand" "dM"))
-+ (const_int 0)))
-+ (clobber (match_scratch:SI 2 "=d"))]
-+ "ubicom32_match_cc_mode(insn, CCWZmode)"
-+ "lsl.4\\t%2, %0, %1")
-+
-+; The combiner finds this canonical form for what is in essence a right
-+; shift.
-+;
-+(define_insn "asr1_2"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (sign_extract:SI (match_operand:QI 1 "memory_operand" "m")
-+ (match_operand:SI 2 "const_int_operand" "M")
-+ (match_operand:SI 3 "const_int_operand" "M")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4
-+ && (INTVAL (operands[2]) + INTVAL (operands[3]) == 8))"
-+ "asr.1\\t%0, %1, %3")
-+
-+; The combiner finds this canonical form for what is in essence a right
-+; shift.
-+;
-+(define_insn "asr2_2"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (sign_extract:SI (match_operand:HI 1 "memory_operand" "m")
-+ (match_operand:SI 2 "const_int_operand" "M")
-+ (match_operand:SI 3 "const_int_operand" "M")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4
-+ && (INTVAL (operands[2]) + INTVAL (operands[3]) == 16))"
-+ "asr.2\\t%0, %1, %3")
-+
-+(define_insn "ashrsi3"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (ashiftrt:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmJ")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "dM")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "asr.4\\t%0, %1, %2")
-+
-+(define_insn "ashrsi3_ccwzn"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (ashiftrt:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmJ")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "dM"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (ashiftrt:SI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "asr.4\\t%0, %1, %2")
-+
-+(define_insn "ashrsi3_ccwzn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (ashiftrt:SI (match_operand:SI 0 "ubicom32_arith_operand" "rmJ")
-+ (match_operand:SI 1 "ubicom32_arith_operand" "dM"))
-+ (const_int 0)))
-+ (clobber (match_scratch:SI 2 "=d"))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "asr.4\\t%2, %0, %1")
-+
-+(define_insn "lsr1_1"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (lshiftrt:SI (subreg:SI
-+ (match_operand:QI 1 "memory_operand" "m")
-+ 0)
-+ (match_operand:SI 2 "ubicom32_arith_operand" "dM")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4)"
-+ "lsr.1\\t%0, %1, %2")
-+
-+; The combiner finds this canonical form for what is in essence a right
-+; shift.
-+;
-+(define_insn "lsr1_2"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (zero_extract:SI (match_operand:QI 1 "memory_operand" "m")
-+ (match_operand:SI 2 "const_int_operand" "M")
-+ (match_operand:SI 3 "const_int_operand" "M")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4
-+ && (INTVAL (operands[2]) + INTVAL (operands[3]) == 8))"
-+ "lsr.1\\t%0, %1, %3")
-+
-+(define_insn "lsr2_1"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (lshiftrt:SI (subreg:SI
-+ (match_operand:HI 1 "memory_operand" "m")
-+ 0)
-+ (match_operand:SI 2 "ubicom32_arith_operand" "dM")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4)"
-+ "lsr.2\\t%0, %1, %2")
-+
-+; The combiner finds this canonical form for what is in essence a right
-+; shift.
-+;
-+(define_insn "lsr2_2"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (zero_extract:SI (match_operand:HI 1 "memory_operand" "m")
-+ (match_operand:SI 2 "const_int_operand" "M")
-+ (match_operand:SI 3 "const_int_operand" "M")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4
-+ && (INTVAL (operands[2]) + INTVAL (operands[3]) == 16))"
-+ "lsr.2\\t%0, %1, %3")
-+
-+(define_insn "lshrsi3"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (lshiftrt:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "dM")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "lsr.4\\t%0, %1, %2")
-+
-+(define_insn "lshrsi3_ccwz"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (lshiftrt:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "dM"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (lshiftrt:SI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCWZmode)"
-+ "lsr.4\\t%0, %1, %2")
-+
-+(define_insn "lshrsi3_ccwz_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (lshiftrt:SI (match_operand:SI 0 "ubicom32_arith_operand" "rmI")
-+ (match_operand:SI 1 "ubicom32_arith_operand" "dM"))
-+ (const_int 0)))
-+ (clobber (match_scratch:SI 2 "=d"))]
-+ "ubicom32_match_cc_mode(insn, CCWZmode)"
-+ "lsr.4\\t%2, %0, %1")
-+
-+(define_expand "prologue"
-+ [(const_int 0)]
-+ ""
-+ "{
-+ ubicom32_expand_prologue ();
-+ DONE;
-+ }")
-+
-+(define_expand "epilogue"
-+ [(return)]
-+ ""
-+ "{
-+ ubicom32_expand_epilogue ();
-+ DONE;
-+ }")
-+
-+(define_expand "return"
-+ [(return)]
-+ ""
-+ "{
-+ ubicom32_expand_epilogue ();
-+ DONE;
-+ }")
-+
-+(define_expand "_eh_return"
-+ [(use (match_operand:SI 0 "register_operand" "r"))
-+ (use (match_operand:SI 1 "register_operand" "r"))]
-+ ""
-+ "{
-+ ubicom32_expand_eh_return (operands);
-+ DONE;
-+ }")
-+
-+; XXX - it looks almost certain that we could make return_internal use a Dn
-+; register too. In that instance we'd have to use a ret instruction
-+; rather than a calli but it might save cycles.
-+;
-+(define_insn "return_internal"
-+ [(const_int 2)
-+ (return)
-+ (use (match_operand:SI 0 "ubicom32_mem_or_address_register_operand" "rm"))]
-+ ""
-+ "*
-+ {
-+ if (REG_P (operands[0]) && REGNO (operands[0]) == LINK_REGNO
-+ && ubicom32_can_use_calli_to_ret)
-+ return \"calli\\t%0, 0(%0)\";
-+
-+ return \"ret\\t%0\";
-+ }")
-+
-+(define_insn "return_from_post_modify_sp"
-+ [(parallel
-+ [(const_int 2)
-+ (return)
-+ (use (mem:SI (post_modify:SI
-+ (reg:SI SP_REGNO)
-+ (plus:SI (reg:SI SP_REGNO)
-+ (match_operand:SI 0 "const_int_operand" "n")))))])]
-+ "INTVAL (operands[0]) >= 4 && INTVAL (operands[0]) <= 7 * 4"
-+ "ret\\t(sp)%E0++")
-+
-+;(define_insn "eh_return_internal"
-+; [(const_int 4)
-+; (return)
-+; (use (reg:SI 34))]
-+; ""
-+; "ret\\ta2")
-+
-+; No operation, needed in case the user uses -g but not -O.
-+(define_expand "nop"
-+ [(const_int 0)]
-+ ""
-+ "")
-+
-+(define_insn "nop_internal"
-+ [(const_int 0)]
-+ ""
-+ "nop")
-+
-+; The combiner will generate this pattern given shift and add operations.
-+; The canonical form that the combiner wants to use appears to be multiplies
-+; instead of shifts even if the compiled sources use shifts.
-+;
-+(define_insn "shmrg1_add"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (plus:SI
-+ (mult:SI (match_operand:SI 1 "ubicom32_data_register_operand" "d")
-+ (const_int 256))
-+ (zero_extend:SI
-+ (match_operand:QI 2 "ubicom32_arith_operand" "rmI"))))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "shmrg.1\\t%0, %2, %1")
-+
-+; The combiner will generate this pattern given shift and or operations.
-+;
-+(define_insn "shmrg1_ior"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (ior:SI
-+ (ashift:SI (match_operand:SI 1 "ubicom32_data_register_operand" "d")
-+ (const_int 8))
-+ (zero_extend:SI
-+ (match_operand:QI 2 "ubicom32_arith_operand" "rmI"))))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "shmrg.1\\t%0, %2, %1")
-+
-+; The combiner will generate this pattern given shift and add operations.
-+; The canonical form that the combiner wants to use appears to be multiplies
-+; instead of shifts even if the compiled sources use shifts.
-+;
-+(define_insn "shmrg2_add"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (plus:SI
-+ (mult:SI (match_operand:SI 1 "ubicom32_data_register_operand" "d")
-+ (const_int 65536))
-+ (zero_extend:SI
-+ (match_operand:HI 2 "ubicom32_arith_operand" "rmI"))))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "shmrg.2\\t%0, %2, %1")
-+
-+; The combiner will generate this pattern given shift and or operations.
-+;
-+(define_insn "shmrg2_ior"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (ior:SI
-+ (ashift:SI (match_operand:SI 1 "ubicom32_data_register_operand" "d")
-+ (const_int 16))
-+ (zero_extend:SI
-+ (match_operand:HI 2 "ubicom32_arith_operand" "rmI"))))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "shmrg.2\\t%0, %2, %1")
-+
-+; Match the case where we load a word from the stack but then discard the
-+; upper 16 bits. We turn this into a zero-extended load of that useful
-+; 16 bits direct from the stack where possible.
-+;
-+
-+; XXX - do these peephole2 ops actually work after the CCmode conversion?
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (mem:SI (plus:SI (reg:SI SP_REGNO)
-+ (match_operand:SI 1 "const_int_operand" ""))))
-+ (set (match_operand:SI 2 "nonimmediate_operand" "")
-+ (zero_extend:SI (match_operand:HI 3 "register_operand" "")))]
-+ "(INTVAL (operands[1]) <= 252
-+ && REGNO (operands[3]) == REGNO (operands[0])
-+ && ((peep2_reg_dead_p (2, operands[0])
-+ && ! reg_mentioned_p (operands[0], operands[2]))
-+ || rtx_equal_p (operands[0], operands[2])))"
-+ [(set (match_dup 2)
-+ (zero_extend:SI (mem:HI (plus:SI (reg:SI SP_REGNO)
-+ (match_dup 4)))))]
-+ "{
-+ operands[4] = GEN_INT (INTVAL (operands[1]) + 2);
-+ }")
-+
-+; Match the case where we load a word from the stack but then discard the
-+; upper 16 bits. We turn this into a 16-bit load of that useful
-+; 16 bits direct from the stack where possible.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (mem:SI (plus:SI (reg:SI SP_REGNO)
-+ (match_operand:SI 1 "const_int_operand" ""))))
-+ (set (match_operand:HI 2 "nonimmediate_operand" "")
-+ (match_operand:HI 3 "register_operand" ""))]
-+ "(INTVAL (operands[1]) <= 252
-+ && REGNO (operands[3]) == REGNO (operands[0])
-+ && ((peep2_reg_dead_p (2, operands[0])
-+ && ! reg_mentioned_p (operands[0], operands[2]))
-+ || rtx_equal_p (operands[0], operands[2])))"
-+ [(set (match_dup 2)
-+ (mem:HI (plus:SI (reg:SI SP_REGNO)
-+ (match_dup 4))))]
-+ "{
-+ operands[4] = GEN_INT (INTVAL (operands[1]) + 2);
-+ }")
-+
-+; Match the case where we load a word from the stack but then discard the
-+; upper 24 bits. We turn this into a zero-extended load of that useful
-+; 8 bits direct from the stack where possible.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (mem:SI (plus:SI (reg:SI SP_REGNO)
-+ (match_operand:SI 1 "const_int_operand" ""))))
-+ (set (match_operand:SI 2 "nonimmediate_operand" "")
-+ (zero_extend:SI (match_operand:QI 3 "register_operand" "")))]
-+ "(INTVAL (operands[1]) <= 124
-+ && REGNO (operands[3]) == REGNO (operands[0])
-+ && ((peep2_reg_dead_p (2, operands[0])
-+ && ! reg_mentioned_p (operands[0], operands[2]))
-+ || rtx_equal_p (operands[0], operands[2])))"
-+ [(set (match_dup 2)
-+ (zero_extend:SI (mem:QI (plus:SI (reg:SI SP_REGNO)
-+ (match_dup 4)))))]
-+ "{
-+ operands[4] = GEN_INT (INTVAL (operands[1]) + 3);
-+ }")
-+
-+; Match the case where we load a word from the stack but then discard the
-+; upper 24 bits. We turn this into an 8-bit load of that useful
-+; 8 bits direct from the stack where possible.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (mem:SI (plus:SI (reg:SI SP_REGNO)
-+ (match_operand:SI 1 "const_int_operand" ""))))
-+ (set (match_operand:QI 2 "nonimmediate_operand" "")
-+ (match_operand:QI 3 "register_operand" ""))]
-+ "(INTVAL (operands[1]) <= 124
-+ && REGNO (operands[3]) == REGNO (operands[0])
-+ && ((peep2_reg_dead_p (2, operands[0])
-+ && ! reg_mentioned_p (operands[0], operands[2]))
-+ || rtx_equal_p (operands[0], operands[2])))"
-+ [(set (match_dup 2)
-+ (mem:QI (plus:SI (reg:SI SP_REGNO)
-+ (match_dup 4))))]
-+ "{
-+ operands[4] = GEN_INT (INTVAL (operands[1]) + 3);
-+ }")
-+
---- /dev/null
-+++ b/gcc/config/ubicom32/ubicom32.opt
-@@ -0,0 +1,27 @@
-+mdebug-address
-+Target RejectNegative Report Undocumented Mask(DEBUG_ADDRESS)
-+Debug addresses
-+
-+mdebug-context
-+Target RejectNegative Report Undocumented Mask(DEBUG_CONTEXT)
-+Debug contexts
-+
-+march=
-+Target Report Var(ubicom32_arch_name) Init("ubicom32v4") Joined
-+Specify the name of the target architecture
-+
-+mfdpic
-+Target Report Mask(FDPIC)
-+Enable Function Descriptor PIC mode
-+
-+minline-plt
-+Target Report Mask(INLINE_PLT)
-+Enable inlining of PLT in function calls
-+
-+mfastcall
-+Target Report Mask(FASTCALL)
-+Enable default fast (call) calling sequence for smaller applications
-+
-+mipos-abi
-+Target Report Mask(IPOS_ABI)
-+Enable the ipOS ABI in which D10-D13 are caller-clobbered
---- /dev/null
-+++ b/gcc/config/ubicom32/uclinux.h
-@@ -0,0 +1,67 @@
-+/* Definitions of target machine for Ubicom32-uclinux
-+
-+ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
-+ 2009 Free Software Foundation, Inc.
-+ Contributed by Ubicom, Inc.
-+
-+ This file is part of GCC.
-+
-+ GCC is free software; you can redistribute it and/or modify it
-+ under the terms of the GNU General Public License as published
-+ by the Free Software Foundation; either version 3, or (at your
-+ option) any later version.
-+
-+ GCC is distributed in the hope that it will be useful, but WITHOUT
-+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
-+ License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with GCC; see the file COPYING3. If not see
-+ <http://www.gnu.org/licenses/>. */
-+
-+/* Don't assume anything about the header files. */
-+#define NO_IMPLICIT_EXTERN_C
-+
-+#undef LIB_SPEC
-+#define LIB_SPEC \
-+ "%{pthread:-lpthread} " \
-+ "%{!shared:%{!symbolic: -lc}} "
-+
-+
-+#undef LINK_GCC_C_SEQUENCE_SPEC
-+#define LINK_GCC_C_SEQUENCE_SPEC \
-+ "%{!shared:--start-group} %G %L %{!shared:--end-group}%{shared:%G} "
-+
-+#undef STARTFILE_SPEC
-+#define STARTFILE_SPEC \
-+ "%{!shared: crt1%O%s}" \
-+ " crti%O%s crtbegin%O%s"
-+
-+#undef ENDFILE_SPEC
-+#define ENDFILE_SPEC "crtend%O%s crtn%O%s"
-+
-+/* This macro applies on top of OBJECT_FORMAT_ELF and indicates that
-+ we want to support both flat and ELF output. */
-+#define OBJECT_FORMAT_FLAT
-+
-+#undef DRIVER_SELF_SPECS
-+#define DRIVER_SELF_SPECS \
-+ "%{!mno-fastcall:-mfastcall}"
-+
-+/* taken from linux.h */
-+/* The GNU C++ standard library requires that these macros be defined. */
-+#undef CPLUSPLUS_CPP_SPEC
-+#define CPLUSPLUS_CPP_SPEC "-D_GNU_SOURCE %(cpp)"
-+
-+#define TARGET_OS_CPP_BUILTINS() \
-+ do { \
-+ builtin_define_std ("__UBICOM32__"); \
-+ builtin_define_std ("__ubicom32__"); \
-+ builtin_define ("__gnu_linux__"); \
-+ builtin_define_std ("linux"); \
-+ builtin_define_std ("unix"); \
-+ builtin_assert ("system=linux"); \
-+ builtin_assert ("system=unix"); \
-+ builtin_assert ("system=posix"); \
-+ } while (0)
---- /dev/null
-+++ b/gcc/config/ubicom32/xm-ubicom32.h
-@@ -0,0 +1,36 @@
-+/* Configuration for Ubicom's Ubicom32 architecture.
-+ Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Free Software
-+ Foundation, Inc.
-+ Contributed by Ubicom Inc.
-+
-+This file is part of GNU CC.
-+
-+GNU CC is free software; you can redistribute it and/or modify
-+it under the terms of the GNU General Public License as published by
-+the Free Software Foundation; either version 2, or (at your option)
-+any later version.
-+
-+GNU CC is distributed in the hope that it will be useful,
-+but WITHOUT ANY WARRANTY; without even the implied warranty of
-+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+GNU General Public License for more details.
-+
-+You should have received a copy of the GNU General Public License
-+along with GNU CC; see the file COPYING. If not, write to
-+the Free Software Foundation, 59 Temple Place - Suite 330,
-+Boston, MA 02111-1307, USA. */
-+
-+/* #defines that need visibility everywhere. */
-+#define FALSE 0
-+#define TRUE 1
-+
-+/* This describes the machine the compiler is hosted on. */
-+#define HOST_BITS_PER_CHAR 8
-+#define HOST_BITS_PER_SHORT 16
-+#define HOST_BITS_PER_INT 32
-+#define HOST_BITS_PER_LONG 32
-+#define HOST_BITS_PER_LONGLONG 64
-+
-+/* Arguments to use with `exit'. */
-+#define SUCCESS_EXIT_CODE 0
-+#define FATAL_EXIT_CODE 33
---- a/gcc/config.gcc
-+++ b/gcc/config.gcc
-@@ -2314,6 +2314,34 @@ spu-*-elf*)
- c_target_objs="${c_target_objs} spu-c.o"
- cxx_target_objs="${cxx_target_objs} spu-c.o"
- ;;
-+ubicom32-*-elf)
-+ xm_file=ubicom32/xm-ubicom32.h
-+ tm_file="${tm_file} ubicom32/elf.h" # still need dbxelf.h elfos.h
-+ tmake_file=ubicom32/t-ubicom32
-+ ;;
-+ubicom32-*-uclinux*)
-+ xm_file=ubicom32/xm-ubicom32.h
-+ tm_file="${tm_file} ubicom32/elf.h ubicom32/uclinux.h" # still need dbxelf.h elfos.h linux.h
-+ tm_defines="${tm_defines} UCLIBC_DEFAULT=1"
-+ extra_options="${extra_options} linux.opt"
-+ tmake_file=ubicom32/t-ubicom32-uclinux
-+ use_collect2=no
-+ ;;
-+ubicom32-*-linux-uclibc)
-+ xm_file=ubicom32/xm-ubicom32.h
-+ tm_file="${tm_file} ubicom32/elf.h linux.h ubicom32/linux.h" # still need dbxelf.h elfos.h
-+ tmake_file="t-slibgcc-elf-ver ubicom32/t-ubicom32-linux"
-+ extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
-+ use_collect2=no
-+ ;;
-+ubicom32-*-linux*)
-+ xm_file=ubicom32/xm-ubicom32.h
-+ tm_file="${tm_file} ubicom32/elf.h linux.h ubicom32/linux.h" # still need dbxelf.h elfos.h
-+ tmake_file="t-slibgcc-elf-ver ubicom32/t-ubicom32-linux"
-+ tm_defines="${tm_defines} UCLIBC_DEFAULT=1"
-+ extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
-+ use_collect2=no
-+ ;;
- v850e1-*-*)
- target_cpu_default="TARGET_CPU_v850e1"
- tm_file="dbxelf.h elfos.h svr4.h v850/v850.h"
---- a/libgcc/config.host
-+++ b/libgcc/config.host
-@@ -551,6 +551,15 @@ sparc64-*-netbsd*)
- ;;
- spu-*-elf*)
- ;;
-+ubicom32*-*-elf*)
-+ ;;
-+ubicom32*-*-uclinux*)
-+ ;;
-+ubicom32*-*-linux*)
-+ # No need to build crtbeginT.o on uClibc systems. Should probably
-+ # be moved to the OS specific section above.
-+ extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
-+ ;;
- v850e1-*-*)
- ;;
- v850e-*-*)
+++ /dev/null
---- a/gcc/config/arm/linux-elf.h
-+++ b/gcc/config/arm/linux-elf.h
-@@ -60,7 +60,7 @@
- %{shared:-lc} \
- %{!shared:%{profile:-lc_p}%{!profile:-lc}}"
-
--#define LIBGCC_SPEC "%{msoft-float:-lfloat} %{mfloat-abi=soft*:-lfloat} -lgcc"
-+#define LIBGCC_SPEC "-lgcc"
-
- #define GLIBC_DYNAMIC_LINKER "/lib/ld-linux.so.2"
-
---- a/gcc/config/arm/t-linux
-+++ b/gcc/config/arm/t-linux
-@@ -4,7 +4,10 @@
-
- LIB1ASMSRC = arm/lib1funcs.asm
- LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_lnx _clzsi2 _clzdi2 \
-- _arm_addsubdf3 _arm_addsubsf3
-+ _arm_addsubdf3 _arm_addsubsf3 \
-+ _negdf2 _addsubdf3 _muldivdf3 _cmpdf2 _unorddf2 _fixdfsi _fixunsdfsi \
-+ _truncdfsf2 _negsf2 _addsubsf3 _muldivsf3 _cmpsf2 _unordsf2 \
-+ _fixsfsi _fixunssfsi _floatdidf _floatundidf _floatdisf _floatundisf
-
- # MULTILIB_OPTIONS = mhard-float/msoft-float
- # MULTILIB_DIRNAMES = hard-float soft-float
+++ /dev/null
---- a/libgcc/Makefile.in
-+++ b/libgcc/Makefile.in
-@@ -729,11 +729,12 @@ $(libgcov-objects): %$(objext): $(gcc_sr
-
- # Static libraries.
- libgcc.a: $(libgcc-objects)
-+libgcc_pic.a: $(libgcc-s-objects)
- libgcov.a: $(libgcov-objects)
- libunwind.a: $(libunwind-objects)
- libgcc_eh.a: $(libgcc-eh-objects)
-
--libgcc.a libgcov.a libunwind.a libgcc_eh.a:
-+libgcc.a libgcov.a libunwind.a libgcc_eh.a libgcc_pic.a:
- -rm -f $@
-
- objects="$(objects)"; \
-@@ -755,7 +756,7 @@ libgcc_s$(SHLIB_EXT): libunwind$(SHLIB_E
- endif
-
- ifeq ($(enable_shared),yes)
--all: libgcc_eh.a libgcc_s$(SHLIB_EXT)
-+all: libgcc_eh.a libgcc_pic.a libgcc_s$(SHLIB_EXT)
- ifneq ($(LIBUNWIND),)
- all: libunwind$(SHLIB_EXT)
- endif
-@@ -928,6 +929,10 @@ install-shared:
- chmod 644 $(DESTDIR)$(inst_libdir)/libgcc_eh.a
- $(RANLIB) $(DESTDIR)$(inst_libdir)/libgcc_eh.a
-
-+ $(INSTALL_DATA) libgcc_pic.a $(mapfile) $(DESTDIR)$(inst_libdir)/
-+ chmod 644 $(DESTDIR)$(inst_libdir)/libgcc_pic.a
-+ $(RANLIB) $(DESTDIR)$(inst_libdir)/libgcc_pic.a
-+
- $(subst @multilib_dir@,$(MULTIDIR),$(subst \
- @shlib_base_name@,libgcc_s,$(subst \
- @shlib_slibdir_qual@,$(MULTIOSSUBDIR),$(SHLIB_INSTALL))))
+++ /dev/null
-
- This patch brings over a few features from MirBSD:
- * -fhonour-copts
- If this option is not given, it's warned (depending
- on environment variables). This is to catch errors
- of misbuilt packages which override CFLAGS themselves.
- * -Werror-maybe-reset
- Has the effect of -Wno-error if GCC_NO_WERROR is
- set and not '0', a no-operation otherwise. This is
- to be able to use -Werror in "make" but prevent
- GNU autoconf generated configure scripts from
- freaking out.
- * Make -fno-strict-aliasing and -fno-delete-null-pointer-checks
- the default for -O2/-Os, because they trigger gcc bugs
- and can delete code with security implications.
-
- This patch was authored by Thorsten Glaser <tg at mirbsd.de>
- with copyright assignment to the FSF in effect.
-
---- a/gcc/c-opts.c
-+++ b/gcc/c-opts.c
-@@ -105,6 +105,9 @@
- /* Number of deferred options scanned for -include. */
- static size_t include_cursor;
-
-+/* Check if a port honours COPTS. */
-+static int honour_copts = 0;
-+
- static void set_Wimplicit (int);
- static void handle_OPT_d (const char *);
- static void set_std_cxx98 (int);
-@@ -454,6 +457,14 @@
- enable_warning_as_error ("implicit-function-declaration", value, CL_C | CL_ObjC);
- break;
-
-+ case OPT_Werror_maybe_reset:
-+ {
-+ char *ev = getenv ("GCC_NO_WERROR");
-+ if ((ev != NULL) && (*ev != '0'))
-+ cpp_opts->warnings_are_errors = 0;
-+ }
-+ break;
-+
- case OPT_Wformat:
- set_Wformat (value);
- break;
-@@ -690,6 +701,12 @@
- flag_exceptions = value;
- break;
-
-+ case OPT_fhonour_copts:
-+ if (c_language == clk_c) {
-+ honour_copts++;
-+ }
-+ break;
-+
- case OPT_fimplement_inlines:
- flag_implement_inlines = value;
- break;
-@@ -1209,6 +1226,47 @@
- return false;
- }
-
-+ if (c_language == clk_c) {
-+ char *ev = getenv ("GCC_HONOUR_COPTS");
-+ int evv;
-+ if (ev == NULL)
-+ evv = -1;
-+ else if ((*ev == '0') || (*ev == '\0'))
-+ evv = 0;
-+ else if (*ev == '1')
-+ evv = 1;
-+ else if (*ev == '2')
-+ evv = 2;
-+ else if (*ev == 's')
-+ evv = -1;
-+ else {
-+ warning (0, "unknown GCC_HONOUR_COPTS value, assuming 1");
-+ evv = 1; /* maybe depend this on something like MIRBSD_NATIVE? */
-+ }
-+ if (evv == 1) {
-+ if (honour_copts == 0) {
-+ error ("someone does not honour COPTS at all in lenient mode");
-+ return false;
-+ } else if (honour_copts != 1) {
-+ warning (0, "someone does not honour COPTS correctly, passed %d times",
-+ honour_copts);
-+ }
-+ } else if (evv == 2) {
-+ if (honour_copts == 0) {
-+ error ("someone does not honour COPTS at all in strict mode");
-+ return false;
-+ } else if (honour_copts != 1) {
-+ error ("someone does not honour COPTS correctly, passed %d times",
-+ honour_copts);
-+ return false;
-+ }
-+ } else if (evv == 0) {
-+ if (honour_copts != 1)
-+ inform (0, "someone does not honour COPTS correctly, passed %d times",
-+ honour_copts);
-+ }
-+ }
-+
- return true;
- }
-
---- a/gcc/c.opt
-+++ b/gcc/c.opt
-@@ -215,6 +215,10 @@
- C ObjC RejectNegative Warning
- This switch is deprecated; use -Werror=implicit-function-declaration instead
-
-+Werror-maybe-reset
-+C ObjC C++ ObjC++
-+; Documented in common.opt
-+
- Wfloat-equal
- C ObjC C++ ObjC++ Var(warn_float_equal) Warning
- Warn if testing floating point numbers for equality
-@@ -609,6 +613,9 @@
- fhonor-std
- C++ ObjC++
-
-+fhonour-copts
-+C ObjC C++ ObjC++ RejectNegative
-+
- fhosted
- C ObjC
- Assume normal C execution environment
---- a/gcc/common.opt
-+++ b/gcc/common.opt
-@@ -102,6 +102,10 @@
- Common Joined
- Treat specified warning as error
-
-+Werror-maybe-reset
-+Common
-+If environment variable GCC_NO_WERROR is set, act as -Wno-error
-+
- Wextra
- Common Warning
- Print extra (possibly unwanted) warnings
-@@ -573,6 +577,9 @@
- Common Report Var(flag_guess_branch_prob) Optimization
- Enable guessing of branch probabilities
-
-+fhonour-copts
-+Common RejectNegative
-+
- ; Nonzero means ignore `#ident' directives. 0 means handle them.
- ; Generate position-independent code for executables if possible
- ; On SVR4 targets, it also controls whether or not to emit a
---- a/gcc/opts.c
-+++ b/gcc/opts.c
-@@ -896,9 +896,6 @@
- flag_schedule_insns_after_reload = opt2;
- #endif
- flag_regmove = opt2;
-- flag_strict_aliasing = opt2;
-- flag_strict_overflow = opt2;
-- flag_delete_null_pointer_checks = opt2;
- flag_reorder_blocks = opt2;
- flag_reorder_functions = opt2;
- flag_tree_vrp = opt2;
-@@ -922,6 +919,9 @@
-
- /* -O3 optimizations. */
- opt3 = (optimize >= 3);
-+ flag_strict_aliasing = opt3;
-+ flag_strict_overflow = opt3;
-+ flag_delete_null_pointer_checks = opt3;
- flag_predictive_commoning = opt3;
- flag_inline_functions = opt3;
- flag_unswitch_loops = opt3;
-@@ -1601,6 +1601,17 @@
- enable_warning_as_error (arg, value, lang_mask);
- break;
-
-+ case OPT_Werror_maybe_reset:
-+ {
-+ char *ev = getenv ("GCC_NO_WERROR");
-+ if ((ev != NULL) && (*ev != '0'))
-+ warnings_are_errors = 0;
-+ }
-+ break;
-+
-+ case OPT_fhonour_copts:
-+ break;
-+
- case OPT_Wextra:
- set_Wextra (value);
- break;
---- a/gcc/doc/cppopts.texi
-+++ b/gcc/doc/cppopts.texi
-@@ -164,6 +164,11 @@
- Make all warnings into hard errors. Source code which triggers warnings
- will be rejected.
-
-+ at item -Werror-maybe-reset
-+ at opindex Werror-maybe-reset
-+Act like @samp{-Wno-error} if the @env{GCC_NO_WERROR} environment
-+variable is set to anything other than 0 or empty.
-+
- @item -Wsystem-headers
- @opindex Wsystem-headers
- Issue warnings for code in system headers. These are normally unhelpful
---- a/gcc/doc/invoke.texi
-+++ b/gcc/doc/invoke.texi
-@@ -234,7 +234,7 @@
- -Wconversion -Wcoverage-mismatch -Wno-deprecated @gol
- -Wno-deprecated-declarations -Wdisabled-optimization @gol
- -Wno-div-by-zero -Wempty-body -Wenum-compare -Wno-endif-labels @gol
---Werror -Werror=* @gol
-+-Werror -Werror=* -Werror-maybe-reset @gol
- -Wfatal-errors -Wfloat-equal -Wformat -Wformat=2 @gol
- -Wno-format-contains-nul -Wno-format-extra-args -Wformat-nonliteral @gol
- -Wformat-security -Wformat-y2k @gol
-@@ -4161,6 +4161,22 @@
- @option{-Wall} and by @option{-pedantic}, which can be disabled with
- @option{-Wno-pointer-sign}.
-
-+ at item -Werror-maybe-reset
-+ at opindex Werror-maybe-reset
-+Act like @samp{-Wno-error} if the @env{GCC_NO_WERROR} environment
-+variable is set to anything other than 0 or empty.
-+
-+ at item -fhonour-copts
-+ at opindex fhonour-copts
-+If @env{GCC_HONOUR_COPTS} is set to 1, abort if this option is not
-+given at least once, and warn if it is given more than once.
-+If @env{GCC_HONOUR_COPTS} is set to 2, abort if this option is not
-+given exactly once.
-+If @env{GCC_HONOUR_COPTS} is set to 0 or unset, warn if this option
-+is not given exactly once.
-+The warning is quelled if @env{GCC_HONOUR_COPTS} is set to @samp{s}.
-+This flag and environment variable only affect the C language.
-+
- @item -Wstack-protector
- @opindex Wstack-protector
- @opindex Wno-stack-protector
-@@ -5699,7 +5715,7 @@
- second branch or a point immediately following it, depending on whether
- the condition is known to be true or false.
-
--Enabled at levels @option{-O2}, @option{-O3}, @option{-Os}.
-+Enabled at levels @option{-O3}.
-
- @item -fsplit-wide-types
- @opindex fsplit-wide-types
-@@ -5844,7 +5860,7 @@
- @option{-fno-delete-null-pointer-checks} to disable this optimization
- for programs which depend on that behavior.
-
--Enabled at levels @option{-O2}, @option{-O3}, @option{-Os}.
-+Enabled at levels @option{-O3}.
-
- @item -fexpensive-optimizations
- @opindex fexpensive-optimizations
---- a/gcc/java/jvspec.c
-+++ b/gcc/java/jvspec.c
-@@ -670,6 +670,7 @@
- class name. Append dummy `.c' that can be stripped by set_input so %b
- is correct. */
- set_input (concat (main_class_name, "main.c", NULL));
-+ putenv ("GCC_HONOUR_COPTS=s"); /* XXX hack! */
- err = do_spec (jvgenmain_spec);
- if (err == 0)
- {
+++ /dev/null
---- gcc-4.4.0/gcc/config/arm/arm-protos.h 2009-02-20 16:20:38.000000000 +0100
-+++ gcc-4.4.0.new/gcc/config/arm/arm-protos.h 2009-04-22 16:00:58.000000000 +0200
-@@ -43,10 +43,10 @@
- extern void arm_output_fn_unwind (FILE *, bool);
-
-
--#ifdef RTX_CODE
- extern bool arm_vector_mode_supported_p (enum machine_mode);
- extern int arm_hard_regno_mode_ok (unsigned int, enum machine_mode);
- extern int const_ok_for_arm (HOST_WIDE_INT);
-+#ifdef RTX_CODE
- extern int arm_split_constant (RTX_CODE, enum machine_mode, rtx,
- HOST_WIDE_INT, rtx, rtx, int);
- extern RTX_CODE arm_canonicalize_comparison (RTX_CODE, enum machine_mode,
+++ /dev/null
-Index: gcc-4.4.2/gcc/config.gcc
-===================================================================
---- gcc-4.4.2.orig/gcc/config.gcc 2009-10-21 16:19:39.000000000 +0200
-+++ gcc-4.4.2/gcc/config.gcc 2009-10-21 16:19:40.000000000 +0200
-@@ -1506,6 +1506,7 @@
- if test x$sjlj != x1; then
- tmake_file="$tmake_file m68k/t-slibgcc-elf-ver"
- fi
-+ tmake_file="m68k/t-floatlib m68k/t-m68kbare m68k/t-m68kelf"
- ;;
- m68k-*-rtems*)
- default_m68k_cpu=68020
+++ /dev/null
---- a/contrib/regression/objs-gcc.sh
-+++ b/contrib/regression/objs-gcc.sh
-@@ -106,6 +106,10 @@ if [ $H_REAL_TARGET = $H_REAL_HOST -a $H
- then
- make all-gdb all-dejagnu all-ld || exit 1
- make install-gdb install-dejagnu install-ld || exit 1
-+elif [ $H_REAL_TARGET = $H_REAL_HOST -a $H_REAL_TARGET = i686-pc-linux-uclibc ]
-+ then
-+ make all-gdb all-dejagnu all-ld || exit 1
-+ make install-gdb install-dejagnu install-ld || exit 1
- elif [ $H_REAL_TARGET = $H_REAL_HOST ] ; then
- make bootstrap || exit 1
- make install || exit 1
---- a/libjava/classpath/ltconfig
-+++ b/libjava/classpath/ltconfig
-@@ -603,7 +603,7 @@ host_os=`echo $host | sed 's/^\([^-]*\)-
-
- # Transform linux* to *-*-linux-gnu*, to support old configure scripts.
- case $host_os in
--linux-gnu*) ;;
-+linux-gnu*|linux-uclibc*) ;;
- linux*) host=`echo $host | sed 's/^\(.*-.*-linux\)\(.*\)$/\1-gnu\2/'`
- esac
-
-@@ -1251,7 +1251,7 @@ linux-gnuoldld* | linux-gnuaout* | linux
- ;;
-
- # This must be Linux ELF.
--linux-gnu*)
-+linux*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
+++ /dev/null
---- a/boehm-gc/include/gc.h
-+++ b/boehm-gc/include/gc.h
-@@ -503,7 +503,7 @@ GC_API GC_PTR GC_malloc_atomic_ignore_of
- #if defined(__linux__) || defined(__GLIBC__)
- # include <features.h>
- # if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1 || __GLIBC__ > 2) \
-- && !defined(__ia64__)
-+ && !defined(__ia64__) && !defined(__UCLIBC__)
- # ifndef GC_HAVE_BUILTIN_BACKTRACE
- # define GC_HAVE_BUILTIN_BACKTRACE
- # endif
+++ /dev/null
---- a/libstdc++-v3/include/c_global/cstdio
-+++ b/libstdc++-v3/include/c_global/cstdio
-@@ -139,7 +139,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
-
- _GLIBCXX_END_NAMESPACE
-
--#if _GLIBCXX_USE_C99
-+#if _GLIBCXX_USE_C99 || defined __UCLIBC__
-
- #undef snprintf
- #undef vfscanf
+++ /dev/null
---- a/libmudflap/mf-hooks2.c
-+++ b/libmudflap/mf-hooks2.c
-@@ -421,7 +421,7 @@ WRAPPER2(void, bzero, void *s, size_t n)
- {
- TRACE ("%s\n", __PRETTY_FUNCTION__);
- MF_VALIDATE_EXTENT(s, n, __MF_CHECK_WRITE, "bzero region");
-- bzero (s, n);
-+ memset (s, 0, n);
- }
-
-
-@@ -431,7 +431,7 @@ WRAPPER2(void, bcopy, const void *src, v
- TRACE ("%s\n", __PRETTY_FUNCTION__);
- MF_VALIDATE_EXTENT(src, n, __MF_CHECK_READ, "bcopy src");
- MF_VALIDATE_EXTENT(dest, n, __MF_CHECK_WRITE, "bcopy dest");
-- bcopy (src, dest, n);
-+ memmove (dest, src, n);
- }
-
-
-@@ -441,7 +441,7 @@ WRAPPER2(int, bcmp, const void *s1, cons
- TRACE ("%s\n", __PRETTY_FUNCTION__);
- MF_VALIDATE_EXTENT(s1, n, __MF_CHECK_READ, "bcmp 1st arg");
- MF_VALIDATE_EXTENT(s2, n, __MF_CHECK_READ, "bcmp 2nd arg");
-- return bcmp (s1, s2, n);
-+ return n == 0 ? 0 : memcmp (s1, s2, n);
- }
-
-
-@@ -450,7 +450,7 @@ WRAPPER2(char *, index, const char *s, i
- size_t n = strlen (s);
- TRACE ("%s\n", __PRETTY_FUNCTION__);
- MF_VALIDATE_EXTENT(s, CLAMPADD(n, 1), __MF_CHECK_READ, "index region");
-- return index (s, c);
-+ return strchr (s, c);
- }
-
-
-@@ -459,7 +459,7 @@ WRAPPER2(char *, rindex, const char *s,
- size_t n = strlen (s);
- TRACE ("%s\n", __PRETTY_FUNCTION__);
- MF_VALIDATE_EXTENT(s, CLAMPADD(n, 1), __MF_CHECK_READ, "rindex region");
-- return rindex (s, c);
-+ return strrchr (s, c);
- }
-
- /* XXX: stpcpy, memccpy */
+++ /dev/null
---- a/configure
-+++ b/configure
-@@ -2688,6 +2688,9 @@ case "${target}" in
- ip2k-*-*)
- noconfigdirs="$noconfigdirs target-libiberty target-libstdc++-v3 ${libgcj}"
- ;;
-+ ubicom32-*-*)
-+ noconfigdirs="$noconfigdirs target-libffi"
-+ ;;
- *-*-linux* | *-*-gnu* | *-*-k*bsd*-gnu | *-*-kopensolaris*-gnu)
- noconfigdirs="$noconfigdirs target-newlib target-libgloss"
- ;;
---- /dev/null
-+++ b/gcc/config/ubicom32/constraints.md
-@@ -0,0 +1,149 @@
-+; Constraint definitions for Ubicom32
-+
-+; Copyright (C) 2009 Free Software Foundation, Inc.
-+; Contributed by Ubicom, Inc.
-+
-+; This file is part of GCC.
-+
-+; GCC is free software; you can redistribute it and/or modify it
-+; under the terms of the GNU General Public License as published
-+; by the Free Software Foundation; either version 3, or (at your
-+; option) any later version.
-+
-+; GCC is distributed in the hope that it will be useful, but WITHOUT
-+; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-+; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
-+; License for more details.
-+
-+; You should have received a copy of the GNU General Public License
-+; along with GCC; see the file COPYING3. If not see
-+; <http://www.gnu.org/licenses/>.
-+
-+(define_register_constraint "a" "ALL_ADDRESS_REGS"
-+ "An An register.")
-+
-+(define_register_constraint "d" "DATA_REGS"
-+ "A Dn register.")
-+
-+(define_register_constraint "h" "ACC_REGS"
-+ "An accumulator register.")
-+
-+(define_register_constraint "l" "ACC_LO_REGS"
-+ "An accn_lo register.")
-+
-+(define_register_constraint "Z" "FDPIC_REG"
-+ "The FD-PIC GOT pointer: A0.")
-+
-+(define_constraint "I"
-+ "An 8-bit signed constant value."
-+ (and (match_code "const_int")
-+ (match_test "(ival >= -128) && (ival <= 127)")))
-+
-+(define_constraint "Q"
-+ "An 8-bit signed constant value represented as unsigned."
-+ (and (match_code "const_int")
-+ (match_test "(ival >= 0x00) && (ival <= 0xff)")))
-+
-+(define_constraint "R"
-+ "An 8-bit signed constant value represented as unsigned."
-+ (and (match_code "const_int")
-+ (match_test "((ival >= 0x0000) && (ival <= 0x007f)) || ((ival >= 0xff80) && (ival <= 0xffff))")))
-+
-+(define_constraint "J"
-+ "A 7-bit unsigned constant value."
-+ (and (match_code "const_int")
-+ (match_test "(ival >= 0) && (ival <= 127)")))
-+
-+(define_constraint "K"
-+ "A 7-bit unsigned constant value shifted << 1."
-+ (and (match_code "const_int")
-+ (match_test "(ival >= 0) && (ival <= 254) && ((ival & 1) == 0)")))
-+
-+(define_constraint "L"
-+ "A 7-bit unsigned constant value shifted << 2."
-+ (and (match_code "const_int")
-+ (match_test "(ival >= 0) && (ival <= 508) && ((ival & 3) == 0)")))
-+
-+(define_constraint "M"
-+ "A 5-bit unsigned constant value."
-+ (and (match_code "const_int")
-+ (match_test "(ival >= 0) && (ival <= 31)")))
-+
-+(define_constraint "N"
-+ "A signed 16 bit constant value."
-+ (and (match_code "const_int")
-+ (match_test "(ival >= -32768) && (ival <= 32767)")))
-+
-+(define_constraint "O"
-+ "An exact bitmask of contiguous 1 bits starting at bit 0."
-+ (and (match_code "const_int")
-+ (match_test "exact_log2 (ival + 1) != -1")))
-+
-+(define_constraint "P"
-+ "A 7-bit negative constant value shifted << 2."
-+ (and (match_code "const_int")
-+ (match_test "(ival >= -504) && (ival <= 0) && ((ival & 3) == 0)")))
-+
-+(define_constraint "S"
-+ "A symbolic reference."
-+ (match_code "symbol_ref"))
-+
-+(define_constraint "Y"
-+ "An FD-PIC symbolic reference."
-+ (and (match_test "TARGET_FDPIC")
-+ (match_test "GET_CODE (op) == UNSPEC")
-+ (ior (match_test "XINT (op, 1) == UNSPEC_FDPIC_GOT")
-+ (match_test "XINT (op, 1) == UNSPEC_FDPIC_GOT_FUNCDESC"))))
-+
-+(define_memory_constraint "T1"
-+ "A memory operand that can be used for .1 instruction."
-+ (and (match_test "memory_operand (op, GET_MODE(op))")
-+ (match_test "GET_MODE (op) == QImode")))
-+
-+(define_memory_constraint "T2"
-+ "A memory operand that can be used for .2 instruction."
-+ (and (match_test "memory_operand (op, GET_MODE(op))")
-+ (match_test "GET_MODE (op) == HImode")))
-+
-+(define_memory_constraint "T4"
-+ "A memory operand that can be used for .4 instruction."
-+ (and (match_test "memory_operand (op, GET_MODE(op))")
-+ (ior (match_test "GET_MODE (op) == SImode")
-+ (match_test "GET_MODE (op) == DImode")
-+ (match_test "GET_MODE (op) == SFmode"))))
-+
-+(define_memory_constraint "U1"
-+ "An offsettable memory operand that can be used for .1 instruction."
-+ (and (match_test "memory_operand (op, GET_MODE(op))")
-+ (match_test "GET_MODE (op) == QImode")
-+ (match_test "GET_CODE (XEXP (op, 0)) != POST_INC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_INC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != POST_DEC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_DEC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != POST_MODIFY")
-+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_MODIFY")))
-+
-+(define_memory_constraint "U2"
-+ "An offsettable memory operand that can be used for .2 instruction."
-+ (and (match_test "memory_operand (op, GET_MODE(op))")
-+ (match_test "GET_MODE (op) == HImode")
-+ (match_test "GET_CODE (XEXP (op, 0)) != POST_INC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_INC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != POST_DEC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_DEC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != POST_MODIFY")
-+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_MODIFY")))
-+
-+(define_memory_constraint "U4"
-+ "An offsettable memory operand that can be used for .4 instruction."
-+ (and (match_test "memory_operand (op, GET_MODE(op))")
-+ (ior (match_test "GET_MODE (op) == SImode")
-+ (match_test "GET_MODE (op) == DImode")
-+ (match_test "GET_MODE (op) == SFmode"))
-+ (match_test "GET_CODE (XEXP (op, 0)) != POST_INC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_INC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != POST_DEC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_DEC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != POST_MODIFY")
-+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_MODIFY")))
-+
---- /dev/null
-+++ b/gcc/config/ubicom32/crti.S
-@@ -0,0 +1,54 @@
-+/* Specialized code needed to support construction and destruction of
-+ file-scope objects in C++ and Java code, and to support exception handling.
-+ Copyright (C) 1999 Free Software Foundation, Inc.
-+ Contributed by Charles-Antoine Gauthier (charles.gauthier@iit.nrc.ca).
-+
-+This file is part of GCC.
-+
-+GCC is free software; you can redistribute it and/or modify
-+it under the terms of the GNU General Public License as published by
-+the Free Software Foundation; either version 2, or (at your option)
-+any later version.
-+
-+GCC is distributed in the hope that it will be useful,
-+but WITHOUT ANY WARRANTY; without even the implied warranty of
-+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+GNU General Public License for more details.
-+
-+You should have received a copy of the GNU General Public License
-+along with GCC; see the file COPYING. If not, write to
-+the Free Software Foundation, 59 Temple Place - Suite 330,
-+Boston, MA 02111-1307, USA. */
-+
-+/* As a special exception, if you link this library with files
-+ compiled with GCC to produce an executable, this does not cause
-+ the resulting executable to be covered by the GNU General Public License.
-+ This exception does not however invalidate any other reasons why
-+ the executable file might be covered by the GNU General Public License. */
-+
-+/*
-+ * This file just supplies function prologues for the .init and .fini
-+ * sections. It is linked in before crtbegin.o.
-+ */
-+ .file "crti.o"
-+ .ident "GNU C crti.o"
-+
-+ .section .init
-+ .align 2
-+ .globl _init
-+ .type _init, @function
-+_init:
-+ move.4 -4(sp)++, a5
-+#ifdef __UBICOM32_FDPIC__
-+ move.4 -4(sp)++, a0
-+#endif
-+
-+ .section .fini
-+ .align 2
-+ .globl _fini
-+ .type _fini, @function
-+_fini:
-+ move.4 -4(sp)++, a5
-+#ifdef __UBICOM32_FDPIC__
-+ move.4 -4(sp)++, a0
-+#endif
---- /dev/null
-+++ b/gcc/config/ubicom32/crtn.S
-@@ -0,0 +1,47 @@
-+/* Specialized code needed to support construction and destruction of
-+ file-scope objects in C++ and Java code, and to support exception handling.
-+ Copyright (C) 1999 Free Software Foundation, Inc.
-+ Contributed by Charles-Antoine Gauthier (charles.gauthier@iit.nrc.ca).
-+
-+This file is part of GCC.
-+
-+GCC is free software; you can redistribute it and/or modify
-+it under the terms of the GNU General Public License as published by
-+the Free Software Foundation; either version 2, or (at your option)
-+any later version.
-+
-+GCC is distributed in the hope that it will be useful,
-+but WITHOUT ANY WARRANTY; without even the implied warranty of
-+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+GNU General Public License for more details.
-+
-+You should have received a copy of the GNU General Public License
-+along with GCC; see the file COPYING. If not, write to
-+the Free Software Foundation, 59 Temple Place - Suite 330,
-+Boston, MA 02111-1307, USA. */
-+
-+/* As a special exception, if you link this library with files
-+ compiled with GCC to produce an executable, this does not cause
-+ the resulting executable to be covered by the GNU General Public License.
-+ This exception does not however invalidate any other reasons why
-+ the executable file might be covered by the GNU General Public License. */
-+
-+/*
-+ * This file supplies function epilogues for the .init and .fini sections.
-+ * It is linked in after all other files.
-+ */
-+
-+ .file "crtn.o"
-+ .ident "GNU C crtn.o"
-+
-+ .section .init
-+#ifdef __UBICOM32_FDPIC__
-+ move.4 a0, (sp)4++
-+#endif
-+ ret (sp)4++
-+
-+ .section .fini
-+#ifdef __UBICOM32_FDPIC__
-+ move.4 a0, (sp)4++
-+#endif
-+ ret (sp)4++
---- /dev/null
-+++ b/gcc/config/ubicom32/elf.h
-@@ -0,0 +1,29 @@
-+#undef STARTFILE_SPEC
-+#define STARTFILE_SPEC "\
-+%{msim:%{!shared:crt0%O%s}} \
-+crti%O%s crtbegin%O%s"
-+
-+#undef ENDFILE_SPEC
-+#define ENDFILE_SPEC "crtend%O%s crtn%O%s"
-+
-+#ifdef __UBICOM32_FDPIC__
-+#define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC) \
-+ asm (SECTION_OP); \
-+ asm ("move.4 a0, 0(sp);\n\t" \
-+ "call a5," USER_LABEL_PREFIX #FUNC ";"); \
-+ asm (TEXT_SECTION_ASM_OP);
-+#endif
-+
-+#undef SUBTARGET_DRIVER_SELF_SPECS
-+#define SUBTARGET_DRIVER_SELF_SPECS \
-+ "%{mfdpic:-msim} "
-+
-+#define NO_IMPLICIT_EXTERN_C
-+
-+/*
-+ * We need this to compile crtbegin/crtend. This should really be picked
-+ * up from elfos.h but at the moment including elfos.h causes other more
-+ * serous linker issues.
-+ */
-+#define INIT_SECTION_ASM_OP "\t.section\t.init"
-+#define FINI_SECTION_ASM_OP "\t.section\t.fini"
---- /dev/null
-+++ b/gcc/config/ubicom32/linux.h
-@@ -0,0 +1,80 @@
-+/* Definitions of target machine for Ubicom32-uclinux
-+
-+ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
-+ 2009 Free Software Foundation, Inc.
-+ Contributed by Ubicom, Inc.
-+
-+ This file is part of GCC.
-+
-+ GCC is free software; you can redistribute it and/or modify it
-+ under the terms of the GNU General Public License as published
-+ by the Free Software Foundation; either version 3, or (at your
-+ option) any later version.
-+
-+ GCC is distributed in the hope that it will be useful, but WITHOUT
-+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
-+ License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with GCC; see the file COPYING3. If not see
-+ <http://www.gnu.org/licenses/>. */
-+
-+/* Don't assume anything about the header files. */
-+#define NO_IMPLICIT_EXTERN_C
-+
-+#undef LIB_SPEC
-+#define LIB_SPEC \
-+ "%{pthread:-lpthread} " \
-+ "-lc"
-+
-+#undef LINK_GCC_C_SEQUENCE_SPEC
-+#define LINK_GCC_C_SEQUENCE_SPEC \
-+ "%{static:--start-group} %G %L %{static:--end-group} " \
-+ "%{!static: %G}"
-+
-+#undef STARTFILE_SPEC
-+#define STARTFILE_SPEC \
-+ "%{!shared: %{pg|p|profile:gcrt1%O%s;pie:Scrt1%O%s;:crt1%O%s}} " \
-+ "crtreloc%O%s crti%O%s %{shared|pie:crtbeginS%O%s;:crtbegin%O%s}"
-+
-+#undef ENDFILE_SPEC
-+#define ENDFILE_SPEC \
-+ "%{shared|pie:crtendS%O%s;:crtend%O%s} crtn%O%s"
-+
-+/* taken from linux.h */
-+/* The GNU C++ standard library requires that these macros be defined. */
-+#undef CPLUSPLUS_CPP_SPEC
-+#define CPLUSPLUS_CPP_SPEC "-D_GNU_SOURCE %(cpp)"
-+
-+#define TARGET_OS_CPP_BUILTINS() \
-+ do { \
-+ builtin_define_std ("__UBICOM32__"); \
-+ builtin_define_std ("__ubicom32__"); \
-+ builtin_define ("__gnu_linux__"); \
-+ builtin_define_std ("linux"); \
-+ builtin_define_std ("unix"); \
-+ builtin_assert ("system=linux"); \
-+ builtin_assert ("system=unix"); \
-+ builtin_assert ("system=posix"); \
-+ } while (0)
-+
-+#define OBJECT_FORMAT_ELF
-+
-+
-+#undef DRIVER_SELF_SPECS
-+#define DRIVER_SELF_SPECS \
-+ "%{!mno-fdpic:-mfdpic}"
-+
-+#undef LINK_SPEC
-+#define LINK_SPEC "%{mfdpic: -m elf32ubicom32fdpic -z text } %{shared} %{pie} \
-+ %{static:-dn -Bstatic} \
-+ %{shared:-G -Bdynamic} \
-+ %{!shared: %{!static: \
-+ %{rdynamic:-export-dynamic} \
-+ %{!dynamic-linker:-dynamic-linker /lib/ld-uClibc.so.0}} \
-+ %{static}} "
-+
-+/*
-+#define MD_UNWIND_SUPPORT "config/bfin/linux-unwind.h"
-+*/
---- /dev/null
-+++ b/gcc/config/ubicom32/predicates.md
-@@ -0,0 +1,327 @@
-+; Predicate definitions for Ubicom32.
-+
-+; Copyright (C) 2009 Free Software Foundation, Inc.
-+; Contributed by Ubicom, Inc.
-+
-+; This file is part of GCC.
-+
-+; GCC is free software; you can redistribute it and/or modify it
-+; under the terms of the GNU General Public License as published
-+; by the Free Software Foundation; either version 3, or (at your
-+; option) any later version.
-+
-+; GCC is distributed in the hope that it will be useful, but WITHOUT
-+; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-+; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
-+; License for more details.
-+
-+; You should have received a copy of the GNU General Public License
-+; along with GCC; see the file COPYING3. If not see
-+; <http://www.gnu.org/licenses/>.
-+
-+(define_predicate "ubicom32_move_operand"
-+ (match_code "const_int, const_double, const, mem, subreg, reg, lo_sum")
-+{
-+ if (CONST_INT_P (op))
-+ return true;
-+
-+ if (GET_CODE (op) == CONST_DOUBLE)
-+ return true;
-+
-+ if (GET_CODE (op) == CONST)
-+ return memory_address_p (mode, op);
-+
-+ if (GET_MODE (op) != mode)
-+ return false;
-+
-+ if (MEM_P (op))
-+ return memory_address_p (mode, XEXP (op, 0));
-+
-+ if (GET_CODE (op) == SUBREG) {
-+ op = SUBREG_REG (op);
-+
-+ if (REG_P (op))
-+ return true;
-+
-+ if (! MEM_P (op))
-+ return false;
-+
-+ /* Paradoxical SUBREG. */
-+ if (GET_MODE_SIZE (mode) > GET_MODE_SIZE (GET_MODE (op)))
-+ return false;
-+
-+ return memory_address_p (GET_MODE (op), XEXP (op, 0));
-+ }
-+
-+ return register_operand (op, mode);
-+})
-+
-+;; Returns true if OP is either a symbol reference or a sum of a
-+;; symbol reference and a constant.
-+
-+(define_predicate "ubicom32_symbolic_address_operand"
-+ (match_code "symbol_ref, label_ref, const")
-+{
-+ switch (GET_CODE (op))
-+ {
-+ case SYMBOL_REF:
-+ case LABEL_REF:
-+ return true;
-+
-+ case CONST:
-+ op = XEXP (op, 0);
-+ return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
-+ || GET_CODE (XEXP (op, 0)) == LABEL_REF)
-+ && CONST_INT_P (XEXP (op, 1)));
-+
-+ default:
-+ return false;
-+ }
-+})
-+
-+;; Return true if operand is the uClinux FD-PIC register.
-+
-+(define_predicate "ubicom32_fdpic_operand"
-+ (match_code "reg")
-+{
-+ if (! TARGET_FDPIC)
-+ return false;
-+
-+ if (!REG_P (op))
-+ return false;
-+
-+ if (GET_MODE (op) != mode && mode != VOIDmode)
-+ return false;
-+
-+ if (REGNO (op) != FDPIC_REGNUM && REGNO (op) < FIRST_PSEUDO_REGISTER)
-+ return false;
-+
-+ return true;
-+})
-+
-+(define_predicate "ubicom32_fdpic_got_offset_operand"
-+ (match_code "unspec")
-+{
-+ if (! TARGET_FDPIC)
-+ return false;
-+
-+ if (GET_CODE (op) != UNSPEC)
-+ return false;
-+
-+ if (XINT (op, 1) != UNSPEC_FDPIC_GOT
-+ && XINT (op, 1) != UNSPEC_FDPIC_GOT_FUNCDESC)
-+ return false;
-+
-+ return true;
-+})
-+
-+(define_predicate "ubicom32_arith_operand"
-+ (match_code "subreg, reg, const_int, lo_sum, mem")
-+{
-+ return (ubicom32_move_operand (op, mode)
-+ && ! ubicom32_symbolic_address_operand (op, mode)
-+ && (! CONST_INT_P (op)
-+ || satisfies_constraint_I (op)));
-+})
-+
-+(define_predicate "ubicom32_arith_operand_dot1"
-+ (match_code "subreg, reg, const_int, lo_sum, mem")
-+{
-+ return (ubicom32_move_operand (op, mode)
-+ && ! ubicom32_symbolic_address_operand (op, mode)
-+ && (! CONST_INT_P (op)
-+ || satisfies_constraint_Q (op)));
-+})
-+
-+(define_predicate "ubicom32_arith_operand_dot2"
-+ (match_code "subreg, reg, const_int, lo_sum, mem")
-+{
-+ return (ubicom32_move_operand (op, mode)
-+ && ! ubicom32_symbolic_address_operand (op, mode)
-+ && (! CONST_INT_P (op)
-+ || satisfies_constraint_R (op)));
-+})
-+
-+(define_predicate "ubicom32_compare_operand"
-+ (match_code "subreg, reg, const_int, lo_sum, mem")
-+{
-+ return (ubicom32_move_operand (op, mode)
-+ && ! ubicom32_symbolic_address_operand (op, mode)
-+ && (! CONST_INT_P (op)
-+ || satisfies_constraint_N (op)));
-+})
-+
-+(define_predicate "ubicom32_compare_operator"
-+ (match_code "compare"))
-+
-+(define_predicate "ubicom32_and_or_si3_operand"
-+ (match_code "subreg, reg, const_int, lo_sum, mem")
-+{
-+ return (ubicom32_arith_operand (op, mode)
-+ || (CONST_INT_P (op)
-+ && ((exact_log2 (INTVAL (op) + 1) != -1
-+ && exact_log2 (INTVAL (op) + 1) <= 31)
-+ || (exact_log2 (INTVAL (op)) != -1
-+ && exact_log2 (INTVAL (op)) <= 31)
-+ || (exact_log2 (~INTVAL (op)) != -1
-+ && exact_log2 (~INTVAL (op)) <= 31))));
-+})
-+
-+(define_predicate "ubicom32_and_or_hi3_operand"
-+ (match_code "subreg, reg, const_int, lo_sum, mem")
-+{
-+ return (ubicom32_arith_operand (op, mode)
-+ || (CONST_INT_P (op)
-+ && exact_log2 (INTVAL (op) + 1) != -1
-+ && exact_log2 (INTVAL (op) + 1) <= 15));
-+})
-+
-+(define_predicate "ubicom32_mem_or_address_register_operand"
-+ (match_code "subreg, reg, mem")
-+{
-+ unsigned int regno;
-+
-+ if (MEM_P (op)
-+ && memory_operand (op, mode))
-+ return true;
-+
-+ if (REG_P (op))
-+ regno = REGNO (op);
-+ else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
-+ {
-+ int offset;
-+ if (REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER)
-+ offset = SUBREG_BYTE (op) / (GET_MODE_SIZE (GET_MODE (op)));
-+ else
-+ offset = subreg_regno_offset (REGNO (SUBREG_REG (op)),
-+ GET_MODE (SUBREG_REG (op)),
-+ SUBREG_BYTE (op),
-+ GET_MODE (op));
-+ regno = REGNO (SUBREG_REG (op)) + offset;
-+ }
-+ else
-+ return false;
-+
-+ return (regno >= FIRST_PSEUDO_REGISTER
-+ || REGNO_REG_CLASS (regno) == FDPIC_REG
-+ || REGNO_REG_CLASS (regno) == ADDRESS_REGS);
-+})
-+
-+(define_predicate "ubicom32_data_register_operand"
-+ (match_code "subreg, reg")
-+{
-+ unsigned int regno;
-+
-+ if (REG_P (op))
-+ regno = REGNO (op);
-+ else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
-+ {
-+ int offset;
-+ if (REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER)
-+ offset = SUBREG_BYTE (op) / (GET_MODE_SIZE (GET_MODE (op)));
-+ else
-+ offset = subreg_regno_offset (REGNO (SUBREG_REG (op)),
-+ GET_MODE (SUBREG_REG (op)),
-+ SUBREG_BYTE (op),
-+ GET_MODE (op));
-+ regno = REGNO (SUBREG_REG (op)) + offset;
-+ }
-+ else
-+ return false;
-+
-+ return ((regno >= FIRST_PSEUDO_REGISTER
-+ && regno != REGNO (virtual_stack_vars_rtx))
-+ || REGNO_REG_CLASS (regno) == DATA_REGS);
-+})
-+
-+(define_predicate "ubicom32_address_register_operand"
-+ (match_code "subreg, reg")
-+{
-+ unsigned int regno;
-+
-+ if (REG_P (op))
-+ regno = REGNO (op);
-+ else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
-+ {
-+ int offset;
-+ if (REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER)
-+ offset = SUBREG_BYTE (op) / (GET_MODE_SIZE (GET_MODE (op)));
-+ else
-+ offset = subreg_regno_offset (REGNO (SUBREG_REG (op)),
-+ GET_MODE (SUBREG_REG (op)),
-+ SUBREG_BYTE (op),
-+ GET_MODE (op));
-+ regno = REGNO (SUBREG_REG (op)) + offset;
-+ }
-+ else
-+ return false;
-+
-+ return (regno >= FIRST_PSEUDO_REGISTER
-+ || REGNO_REG_CLASS (regno) == FDPIC_REG
-+ || REGNO_REG_CLASS (regno) == ADDRESS_REGS);
-+})
-+
-+(define_predicate "ubicom32_acc_lo_register_operand"
-+ (match_code "subreg, reg")
-+{
-+ unsigned int regno;
-+
-+ if (REG_P (op))
-+ regno = REGNO (op);
-+ else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
-+ {
-+ int offset;
-+ if (REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER)
-+ offset = SUBREG_BYTE (op) / (GET_MODE_SIZE (GET_MODE (op)));
-+ else
-+ offset = subreg_regno_offset (REGNO (SUBREG_REG (op)),
-+ GET_MODE (SUBREG_REG (op)),
-+ SUBREG_BYTE (op),
-+ GET_MODE (op));
-+ regno = REGNO (SUBREG_REG (op)) + offset;
-+ }
-+ else
-+ return false;
-+
-+ return ((regno >= FIRST_PSEUDO_REGISTER
-+ && regno != REGNO (virtual_stack_vars_rtx))
-+ || REGNO_REG_CLASS (regno) == ACC_LO_REGS);
-+})
-+
-+(define_predicate "ubicom32_acc_hi_register_operand"
-+ (match_code "subreg, reg")
-+{
-+ unsigned int regno;
-+
-+ if (REG_P (op))
-+ regno = REGNO (op);
-+ else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
-+ {
-+ int offset;
-+ if (REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER)
-+ offset = SUBREG_BYTE (op) / (GET_MODE_SIZE (GET_MODE (op)));
-+ else
-+ offset = subreg_regno_offset (REGNO (SUBREG_REG (op)),
-+ GET_MODE (SUBREG_REG (op)),
-+ SUBREG_BYTE (op),
-+ GET_MODE (op));
-+ regno = REGNO (SUBREG_REG (op)) + offset;
-+ }
-+ else
-+ return false;
-+
-+ return ((regno >= FIRST_PSEUDO_REGISTER
-+ && regno != REGNO (virtual_stack_vars_rtx))
-+ || REGNO_REG_CLASS (regno) == ACC_REGS);
-+})
-+
-+(define_predicate "ubicom32_call_address_operand"
-+ (match_code "symbol_ref, subreg, reg")
-+{
-+ return (GET_CODE (op) == SYMBOL_REF || REG_P (op));
-+})
-+
-+(define_special_predicate "ubicom32_cc_register_operand"
-+ (and (match_code "reg")
-+ (match_test "REGNO (op) == CC_REGNUM")))
-+
---- /dev/null
-+++ b/gcc/config/ubicom32/t-ubicom32
-@@ -0,0 +1,52 @@
-+# Name of assembly file containing libgcc1 functions.
-+# This entry must be present, but it can be empty if the target does
-+# not need any assembler functions to support its code generation.
-+CROSS_LIBGCC1 =
-+
-+# Alternatively if assembler functions *are* needed then define the
-+# entries below:
-+# CROSS_LIBGCC1 = libgcc1-asm.a
-+
-+LIB2FUNCS_EXTRA = \
-+ $(srcdir)/config/udivmodsi4.c \
-+ $(srcdir)/config/divmod.c \
-+ $(srcdir)/config/udivmod.c
-+
-+# If any special flags are necessary when building libgcc2 put them here.
-+#
-+# TARGET_LIBGCC2_CFLAGS =
-+
-+# 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
-+
-+fp-bit.c: $(srcdir)/config/fp-bit.c
-+ echo '#define FLOAT' > fp-bit.c
-+ cat $(srcdir)/config/fp-bit.c >> fp-bit.c
-+
-+dp-bit.c: $(srcdir)/config/fp-bit.c
-+ cat $(srcdir)/config/fp-bit.c > dp-bit.c
-+
-+# Commented out to speed up compiler development!
-+#
-+# MULTILIB_OPTIONS = march=ubicom32v1/march=ubicom32v2/march=ubicom32v3/march=ubicom32v4
-+# MULTILIB_DIRNAMES = ubicom32v1 ubicom32v2 ubicom32v3 ubicom32v4
-+
-+MULTILIB_OPTIONS = march=ubicom32v3/march=ubicom32v4
-+MULTILIB_OPTIONS += mfdpic
-+MULTILIB_OPTIONS += mno-ipos-abi/mipos-abi
-+MULTILIB_OPTIONS += fno-leading-underscore/fleading-underscore
-+
-+# Assemble startup files.
-+$(T)crti.o: $(srcdir)/config/ubicom32/crti.S $(GCC_PASSES)
-+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) \
-+ -c -o $(T)crti.o -x assembler-with-cpp $(srcdir)/config/ubicom32/crti.S
-+
-+$(T)crtn.o: $(srcdir)/config/ubicom32/crtn.S $(GCC_PASSES)
-+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) \
-+ -c -o $(T)crtn.o -x assembler-with-cpp $(srcdir)/config/ubicom32/crtn.S
-+
-+# these parts are required because uClibc ldso needs them to link.
-+# they are not in the specfile so they will not be included automatically.
-+EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o crtbeginS.o crtendS.o crti.o crtn.o
---- /dev/null
-+++ b/gcc/config/ubicom32/t-ubicom32-linux
-@@ -0,0 +1,35 @@
-+# Name of assembly file containing libgcc1 functions.
-+# This entry must be present, but it can be empty if the target does
-+# not need any assembler functions to support its code generation.
-+CROSS_LIBGCC1 =
-+
-+# Alternatively if assembler functions *are* needed then define the
-+# entries below:
-+# CROSS_LIBGCC1 = libgcc1-asm.a
-+
-+LIB2FUNCS_EXTRA = \
-+ $(srcdir)/config/udivmodsi4.c \
-+ $(srcdir)/config/divmod.c \
-+ $(srcdir)/config/udivmod.c
-+
-+# If any special flags are necessary when building libgcc2 put them here.
-+#
-+# TARGET_LIBGCC2_CFLAGS =
-+
-+# 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
-+
-+fp-bit.c: $(srcdir)/config/fp-bit.c
-+ echo '#define FLOAT' > fp-bit.c
-+ cat $(srcdir)/config/fp-bit.c >> fp-bit.c
-+
-+dp-bit.c: $(srcdir)/config/fp-bit.c
-+ cat $(srcdir)/config/fp-bit.c > dp-bit.c
-+
-+# We only support v3 and v4 ISAs for uClinux.
-+
-+MULTILIB_OPTIONS = march=ubicom32v3/march=ubicom32v4
-+
-+#EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o crtbeginS.o crtendS.o
---- /dev/null
-+++ b/gcc/config/ubicom32/t-ubicom32-uclinux
-@@ -0,0 +1,35 @@
-+# Name of assembly file containing libgcc1 functions.
-+# This entry must be present, but it can be empty if the target does
-+# not need any assembler functions to support its code generation.
-+CROSS_LIBGCC1 =
-+
-+# Alternatively if assembler functions *are* needed then define the
-+# entries below:
-+# CROSS_LIBGCC1 = libgcc1-asm.a
-+
-+LIB2FUNCS_EXTRA = \
-+ $(srcdir)/config/udivmodsi4.c \
-+ $(srcdir)/config/divmod.c \
-+ $(srcdir)/config/udivmod.c
-+
-+# If any special flags are necessary when building libgcc2 put them here.
-+#
-+# TARGET_LIBGCC2_CFLAGS =
-+
-+# 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
-+
-+fp-bit.c: $(srcdir)/config/fp-bit.c
-+ echo '#define FLOAT' > fp-bit.c
-+ cat $(srcdir)/config/fp-bit.c >> fp-bit.c
-+
-+dp-bit.c: $(srcdir)/config/fp-bit.c
-+ cat $(srcdir)/config/fp-bit.c > dp-bit.c
-+
-+# We only support v3 and v4 ISAs for uClinux.
-+
-+MULTILIB_OPTIONS = march=ubicom32v3/march=ubicom32v4
-+
-+EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o # crtbeginS.o crtendS.o
---- /dev/null
-+++ b/gcc/config/ubicom32/ubicom32-modes.def
-@@ -0,0 +1,30 @@
-+/* Definitions of target machine for GNU compiler, Ubicom32 architecture.
-+ Copyright (C) 2009 Free Software Foundation, Inc.
-+ Contributed by Ubicom, Inc.
-+
-+ This file is part of GCC.
-+
-+ GCC is free software; you can redistribute it and/or modify it
-+ under the terms of the GNU General Public License as published
-+ by the Free Software Foundation; either version 3, or (at your
-+ option) any later version.
-+
-+ GCC is distributed in the hope that it will be useful, but WITHOUT
-+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
-+ License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with GCC; see the file COPYING3. If not see
-+ <http://www.gnu.org/licenses/>. */
-+
-+/* Some insns set all condition code flags, some only set the Z and N flags, and
-+ some only set the Z flag. */
-+
-+CC_MODE (CCW);
-+CC_MODE (CCWZN);
-+CC_MODE (CCWZ);
-+CC_MODE (CCS);
-+CC_MODE (CCSZN);
-+CC_MODE (CCSZ);
-+
---- /dev/null
-+++ b/gcc/config/ubicom32/ubicom32-protos.h
-@@ -0,0 +1,84 @@
-+/* Function prototypes for Ubicom IP3000.
-+
-+ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
-+ 2009 Free Software Foundation, Inc.
-+ Contributed by Ubicom, Inc.
-+
-+ This file is part of GNU CC.
-+
-+ GNU CC is free software; you can redistribute it and/or modify it under
-+ the terms of the GNU General Public License as published by the Free
-+ Software Foundation; either version 2, or (at your option) any later
-+ version.
-+
-+ GNU CC is distributed in the hope that it will be useful, but WITHOUT
-+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-+ for more details.
-+
-+ You should have received a copy of the GNU General Public License along
-+ with GNU CC; see the file COPYING. If not, write to the Free Software
-+ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-+
-+#ifdef RTX_CODE
-+
-+#ifdef TREE_CODE
-+extern void ubicom32_va_start (tree, rtx);
-+#endif /* TREE_CODE */
-+
-+extern void ubicom32_print_operand (FILE *, rtx, int);
-+extern void ubicom32_print_operand_address (FILE *, rtx);
-+
-+extern void ubicom32_conditional_register_usage (void);
-+extern enum reg_class ubicom32_preferred_reload_class (rtx, enum reg_class);
-+extern int ubicom32_regno_ok_for_index_p (int, int);
-+extern void ubicom32_expand_movsi (rtx *);
-+extern void ubicom32_expand_addsi3 (rtx *);
-+extern int ubicom32_emit_mult_sequence (rtx *);
-+extern void ubicom32_emit_move_const_int (rtx, rtx);
-+extern bool ubicom32_legitimate_constant_p (rtx);
-+extern bool ubicom32_legitimate_address_p (enum machine_mode, rtx, int);
-+extern rtx ubicom32_legitimize_address (rtx, rtx, enum machine_mode);
-+extern rtx ubicom32_legitimize_reload_address (rtx, enum machine_mode, int, int);
-+extern void ubicom32_canonicalize_comparison (enum rtx_code *code, rtx *op0, rtx *op1);
-+extern int ubicom32_mode_dependent_address_p (rtx);
-+extern void ubicom32_output_cond_jump (rtx, rtx, rtx);
-+extern void ubicom32_expand_eh_return (rtx *);
-+extern void ubicom32_expand_call_fdpic (rtx *);
-+extern void ubicom32_expand_call_value_fdpic (rtx *);
-+extern enum machine_mode ubicom32_select_cc_mode (RTX_CODE, rtx, rtx);
-+extern rtx ubicom32_gen_compare_reg (RTX_CODE, rtx, rtx);
-+extern int ubicom32_shiftable_const_int (int);
-+#endif /* RTX_CODE */
-+
-+#ifdef TREE_CODE
-+extern void init_cumulative_args (CUMULATIVE_ARGS *cum,
-+ tree fntype,
-+ struct rtx_def *libname,
-+ int indirect);
-+extern struct rtx_def *function_arg (CUMULATIVE_ARGS *,
-+ enum machine_mode, tree, int);
-+extern struct rtx_def *function_incoming_arg (CUMULATIVE_ARGS *,
-+ enum machine_mode,
-+ tree, int);
-+extern int function_arg_partial_nregs (CUMULATIVE_ARGS *,
-+ enum machine_mode, tree, int);
-+extern struct rtx_def *ubicom32_va_arg (tree, tree);
-+extern int ubicom32_reg_parm_stack_space (tree);
-+#endif /* TREE_CODE */
-+
-+extern struct rtx_def * ubicom32_builtin_saveregs (void);
-+extern void asm_file_start (FILE *);
-+extern void ubicom32_expand_prologue (void);
-+extern void ubicom32_expand_epilogue (void);
-+extern int ubicom32_initial_elimination_offset (int, int);
-+extern int ubicom32_regno_ok_for_base_p (int, int);
-+extern bool ubicom32_hard_regno_mode_ok (unsigned int, enum machine_mode);
-+extern int ubicom32_can_use_return_insn_p (void);
-+extern rtx ubicom32_return_addr_rtx (int, rtx);
-+extern void ubicom32_optimization_options (int, int);
-+extern void ubicom32_override_options (void);
-+extern bool ubicom32_match_cc_mode (rtx, enum machine_mode);
-+
-+extern int ubicom32_reorg_completed;
-+
---- /dev/null
-+++ b/gcc/config/ubicom32/ubicom32.c
-@@ -0,0 +1,2881 @@
-+/* Subroutines for insn-output.c for Ubicom32
-+
-+ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
-+ 2009 Free Software Foundation, Inc.
-+ Contributed by Ubicom, Inc.
-+
-+ This file is part of GCC.
-+
-+ GCC is free software; you can redistribute it and/or modify it
-+ under the terms of the GNU General Public License as published
-+ by the Free Software Foundation; either version 3, or (at your
-+ option) any later version.
-+
-+ GCC is distributed in the hope that it will be useful, but WITHOUT
-+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
-+ License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with GCC; see the file COPYING3. If not see
-+ <http://www.gnu.org/licenses/>. */
-+
-+#include "config.h"
-+#include "system.h"
-+#include "coretypes.h"
-+#include "tm.h"
-+#include "rtl.h"
-+#include "tree.h"
-+#include "regs.h"
-+#include "hard-reg-set.h"
-+#include "real.h"
-+#include "insn-config.h"
-+#include "conditions.h"
-+#include "insn-flags.h"
-+#include "output.h"
-+#include "insn-attr.h"
-+#include "insn-codes.h"
-+#include "flags.h"
-+#include "recog.h"
-+#include "expr.h"
-+#include "function.h"
-+#include "obstack.h"
-+#include "toplev.h"
-+#include "tm_p.h"
-+#include "tm-constrs.h"
-+#include "basic-block.h"
-+#include "integrate.h"
-+#include "target.h"
-+#include "target-def.h"
-+#include "reload.h"
-+#include "df.h"
-+#include "langhooks.h"
-+#include "optabs.h"
-+
-+static tree ubicom32_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
-+static void ubicom32_layout_frame (void);
-+static void ubicom32_function_prologue (FILE *, HOST_WIDE_INT);
-+static void ubicom32_function_epilogue (FILE *, HOST_WIDE_INT);
-+static bool ubicom32_rtx_costs (rtx, int, int, int *, bool speed);
-+static bool ubicom32_fixed_condition_code_regs (unsigned int *,
-+ unsigned int *);
-+static enum machine_mode ubicom32_cc_modes_compatible (enum machine_mode,
-+ enum machine_mode);
-+static int ubicom32_naked_function_p (void);
-+static void ubicom32_machine_dependent_reorg (void);
-+static bool ubicom32_assemble_integer (rtx, unsigned int, int);
-+static void ubicom32_asm_init_sections (void);
-+static int ubicom32_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,tree,
-+ bool);
-+static bool ubicom32_pass_by_reference (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
-+ enum machine_mode mode, const_tree type,
-+ bool named ATTRIBUTE_UNUSED);
-+static bool ubicom32_callee_copies (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
-+ enum machine_mode mode, const_tree type,
-+ bool named ATTRIBUTE_UNUSED);
-+
-+static bool ubicom32_return_in_memory (const_tree type,
-+ const_tree fntype ATTRIBUTE_UNUSED);
-+static bool ubicom32_is_base_reg (rtx, int);
-+static void ubicom32_init_builtins (void);
-+static rtx ubicom32_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
-+static tree ubicom32_fold_builtin (tree, tree, bool);
-+static int ubicom32_get_valid_offset_mask (enum machine_mode);
-+static bool ubicom32_cannot_force_const_mem (rtx);
-+
-+/* Case values threshold */
-+int ubicom32_case_values_threshold = 6;
-+
-+/* Nonzero if this chip supports the Ubicom32 v3 ISA. */
-+int ubicom32_v3 = 1;
-+
-+/* Nonzero if this chip supports the Ubicom32 v4 ISA. */
-+int ubicom32_v4 = 1;
-+
-+/* Valid attributes:
-+ naked - don't generate function prologue/epilogue and `ret' command. */
-+const struct attribute_spec ubicom32_attribute_table[] =
-+{
-+ /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
-+ { "naked", 0, 0, true, false, false, ubicom32_handle_fndecl_attribute },
-+ { NULL, 0, 0, false, false, false, NULL }
-+};
-+
-+#undef TARGET_ASM_FUNCTION_PROLOGUE
-+#define TARGET_ASM_FUNCTION_PROLOGUE ubicom32_function_prologue
-+
-+#undef TARGET_ASM_FUNCTION_EPILOGUE
-+#define TARGET_ASM_FUNCTION_EPILOGUE ubicom32_function_epilogue
-+
-+#undef TARGET_ATTRIBUTE_TABLE
-+#define TARGET_ATTRIBUTE_TABLE ubicom32_attribute_table
-+
-+/* All addresses cost the same amount. */
-+#undef TARGET_ADDRESS_COST
-+#define TARGET_ADDRESS_COST hook_int_rtx_bool_0
-+
-+#undef TARGET_RTX_COSTS
-+#define TARGET_RTX_COSTS ubicom32_rtx_costs
-+
-+#undef TARGET_FIXED_CONDITION_CODE_REGS
-+#define TARGET_FIXED_CONDITION_CODE_REGS ubicom32_fixed_condition_code_regs
-+
-+#undef TARGET_CC_MODES_COMPATIBLE
-+#define TARGET_CC_MODES_COMPATIBLE ubicom32_cc_modes_compatible
-+
-+#undef TARGET_MACHINE_DEPENDENT_REORG
-+#define TARGET_MACHINE_DEPENDENT_REORG ubicom32_machine_dependent_reorg
-+
-+#undef TARGET_ASM_INTEGER
-+#define TARGET_ASM_INTEGER ubicom32_assemble_integer
-+
-+#undef TARGET_ASM_INIT_SECTIONS
-+#define TARGET_ASM_INIT_SECTIONS ubicom32_asm_init_sections
-+
-+#undef TARGET_ARG_PARTIAL_BYTES
-+#define TARGET_ARG_PARTIAL_BYTES ubicom32_arg_partial_bytes
-+
-+#undef TARGET_PASS_BY_REFERENCE
-+#define TARGET_PASS_BY_REFERENCE ubicom32_pass_by_reference
-+
-+#undef TARGET_CALLEE_COPIES
-+#define TARGET_CALLEE_COPIES ubicom32_callee_copies
-+
-+#undef TARGET_RETURN_IN_MEMORY
-+#define TARGET_RETURN_IN_MEMORY ubicom32_return_in_memory
-+
-+#undef TARGET_INIT_BUILTINS
-+#define TARGET_INIT_BUILTINS ubicom32_init_builtins
-+
-+#undef TARGET_EXPAND_BUILTIN
-+#define TARGET_EXPAND_BUILTIN ubicom32_expand_builtin
-+
-+#undef TARGET_FOLD_BUILTIN
-+#define TARGET_FOLD_BUILTIN ubicom32_fold_builtin
-+
-+#undef TARGET_CANNOT_FORCE_CONST_MEM
-+#define TARGET_CANNOT_FORCE_CONST_MEM ubicom32_cannot_force_const_mem
-+
-+struct gcc_target targetm = TARGET_INITIALIZER;
-+
-+static char save_regs[FIRST_PSEUDO_REGISTER];
-+static int nregs;
-+static int frame_size;
-+int ubicom32_stack_size = 0; /* size of allocated stack (including frame) */
-+int ubicom32_can_use_calli_to_ret;
-+
-+#define STACK_UNIT_BOUNDARY (STACK_BOUNDARY / BITS_PER_UNIT)
-+#define ROUND_CALL_BLOCK_SIZE(BYTES) \
-+ (((BYTES) + (STACK_UNIT_BOUNDARY - 1)) & ~(STACK_UNIT_BOUNDARY - 1))
-+
-+/* In case of a PRE_INC, POST_INC, PRE_DEC, POST_DEC memory reference, we
-+ must report the mode of the memory reference from PRINT_OPERAND to
-+ PRINT_OPERAND_ADDRESS. */
-+enum machine_mode output_memory_reference_mode;
-+
-+/* Flag for some split insns from the ubicom32.md. */
-+int ubicom32_reorg_completed;
-+
-+enum reg_class const ubicom32_regclass_map[FIRST_PSEUDO_REGISTER] =
-+{
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ FDPIC_REG,
-+ ADDRESS_REGS,
-+ ADDRESS_REGS,
-+ ADDRESS_REGS,
-+ ADDRESS_REGS,
-+ ADDRESS_REGS,
-+ ADDRESS_REGS,
-+ ADDRESS_REGS,
-+ ACC_REGS,
-+ ACC_LO_REGS,
-+ ACC_REGS,
-+ ACC_LO_REGS,
-+ SOURCE3_REG,
-+ ADDRESS_REGS,
-+ NO_REGS, /* CC_REG must be NO_REGS */
-+ SPECIAL_REGS,
-+ SPECIAL_REGS,
-+ SPECIAL_REGS,
-+ SPECIAL_REGS,
-+ SPECIAL_REGS,
-+ SPECIAL_REGS,
-+ SPECIAL_REGS,
-+ SPECIAL_REGS
-+};
-+
-+rtx ubicom32_compare_op0;
-+rtx ubicom32_compare_op1;
-+
-+/* Handle command line option overrides. */
-+
-+void
-+ubicom32_override_options (void)
-+{
-+ flag_pic = 0;
-+
-+ if (strcmp (ubicom32_arch_name, "ubicom32v1") == 0) {
-+ /* If we have a version 1 architecture then we want to avoid using jump
-+ tables. */
-+ ubicom32_case_values_threshold = 30000;
-+ ubicom32_v3 = 0;
-+ ubicom32_v4 = 0;
-+ } else if (strcmp (ubicom32_arch_name, "ubicom32v2") == 0) {
-+ ubicom32_v3 = 0;
-+ ubicom32_v4 = 0;
-+ } else if (strcmp (ubicom32_arch_name, "ubicom32v3") == 0) {
-+ ubicom32_v3 = 1;
-+ ubicom32_v4 = 0;
-+ } else if (strcmp (ubicom32_arch_name, "ubicom32v4") == 0) {
-+ ubicom32_v3 = 1;
-+ ubicom32_v4 = 1;
-+ }
-+
-+ /* There is no single unaligned SI op for PIC code. Sometimes we
-+ need to use ".4byte" and sometimes we need to use ".picptr".
-+ See ubicom32_assemble_integer for details. */
-+ if (TARGET_FDPIC)
-+ targetm.asm_out.unaligned_op.si = 0;
-+}
-+
-+void
-+ubicom32_conditional_register_usage (void)
-+{
-+ /* If we're using the old ipOS ABI we need to make D10 through D13
-+ caller-clobbered. */
-+ if (TARGET_IPOS_ABI)
-+ {
-+ call_used_regs[D10_REGNUM] = 1;
-+ call_used_regs[D11_REGNUM] = 1;
-+ call_used_regs[D12_REGNUM] = 1;
-+ call_used_regs[D13_REGNUM] = 1;
-+ }
-+}
-+
-+/* We have some number of optimizations that don't really work for the Ubicom32
-+ architecture so we deal with them here. */
-+
-+void
-+ubicom32_optimization_options (int level ATTRIBUTE_UNUSED,
-+ int size ATTRIBUTE_UNUSED)
-+{
-+ /* The tree IVOPTs pass seems to do really bad things for the Ubicom32
-+ architecture - it tends to turn things that would happily use pre/post
-+ increment/decrement into operations involving unecessary loop
-+ indicies. */
-+ flag_ivopts = 0;
-+
-+ /* We have problems where DSE at the RTL level misses partial stores
-+ to the stack. For now we disable it to avoid this. */
-+ flag_dse = 0;
-+}
-+
-+/* Print operand X using operand code CODE to assembly language output file
-+ FILE. */
-+
-+void
-+ubicom32_print_operand (FILE *file, rtx x, int code)
-+{
-+ switch (code)
-+ {
-+ case 'A':
-+ /* Identify the correct accumulator to use. */
-+ if (REGNO (x) == ACC0_HI_REGNUM || REGNO (x) == ACC0_LO_REGNUM)
-+ fprintf (file, "acc0");
-+ else if (REGNO (x) == ACC1_HI_REGNUM || REGNO (x) == ACC1_LO_REGNUM)
-+ fprintf (file, "acc1");
-+ else
-+ abort ();
-+ break;
-+
-+ case 'b':
-+ case 'B':
-+ {
-+ enum machine_mode mode;
-+
-+ mode = GET_MODE (XEXP (x, 0));
-+
-+ /* These are normal and reversed branches. */
-+ switch (code == 'b' ? GET_CODE (x) : reverse_condition (GET_CODE (x)))
-+ {
-+ case NE:
-+ fprintf (file, "ne");
-+ break;
-+
-+ case EQ:
-+ fprintf (file, "eq");
-+ break;
-+
-+ case GE:
-+ if (mode == CCSZNmode || mode == CCWZNmode)
-+ fprintf (file, "pl");
-+ else
-+ fprintf (file, "ge");
-+ break;
-+
-+ case GT:
-+ fprintf (file, "gt");
-+ break;
-+
-+ case LE:
-+ fprintf (file, "le");
-+ break;
-+
-+ case LT:
-+ if (mode == CCSZNmode || mode == CCWZNmode)
-+ fprintf (file, "mi");
-+ else
-+ fprintf (file, "lt");
-+ break;
-+
-+ case GEU:
-+ fprintf (file, "cs");
-+ break;
-+
-+ case GTU:
-+ fprintf (file, "hi");
-+ break;
-+
-+ case LEU:
-+ fprintf (file, "ls");
-+ break;
-+
-+ case LTU:
-+ fprintf (file, "cc");
-+ break;
-+
-+ default:
-+ abort ();
-+ }
-+ }
-+ break;
-+
-+ case 'C':
-+ /* This is used for the operand to a call instruction;
-+ if it's a REG, enclose it in parens, else output
-+ the operand normally. */
-+ if (REG_P (x))
-+ {
-+ fputc ('(', file);
-+ ubicom32_print_operand (file, x, 0);
-+ fputc (')', file);
-+ }
-+ else
-+ ubicom32_print_operand (file, x, 0);
-+ break;
-+
-+ case 'd':
-+ /* Bit operations we need bit numbers. */
-+ fprintf (file, "%d", exact_log2 (INTVAL (x)));
-+ break;
-+
-+ case 'D':
-+ /* Bit operations we need bit numbers. */
-+ fprintf (file, "%d", exact_log2 (~ INTVAL (x)));
-+ break;
-+
-+ case 'E':
-+ /* For lea, which we use to add address registers.
-+ We don't want the '#' on a constant. */
-+ if (CONST_INT_P (x))
-+ {
-+ fprintf (file, "%ld", INTVAL (x));
-+ break;
-+ }
-+ /* FALL THROUGH */
-+
-+ default:
-+ switch (GET_CODE (x))
-+ {
-+ case MEM:
-+ output_memory_reference_mode = GET_MODE (x);
-+ output_address (XEXP (x, 0));
-+ break;
-+
-+ case PLUS:
-+ output_address (x);
-+ break;
-+
-+ case REG:
-+ fprintf (file, "%s", reg_names[REGNO (x)]);
-+ break;
-+
-+ case SUBREG:
-+ fprintf (file, "%s", reg_names[subreg_regno (x)]);
-+ break;
-+
-+ /* This will only be single precision.... */
-+ case CONST_DOUBLE:
-+ {
-+ unsigned long val;
-+ REAL_VALUE_TYPE rv;
-+
-+ REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
-+ REAL_VALUE_TO_TARGET_SINGLE (rv, val);
-+ fprintf (file, "0x%lx", val);
-+ break;
-+ }
-+
-+ case CONST_INT:
-+ case SYMBOL_REF:
-+ case CONST:
-+ case LABEL_REF:
-+ case CODE_LABEL:
-+ case LO_SUM:
-+ ubicom32_print_operand_address (file, x);
-+ break;
-+
-+ case HIGH:
-+ fprintf (file, "#%%hi(");
-+ ubicom32_print_operand_address (file, XEXP (x, 0));
-+ fprintf (file, ")");
-+ break;
-+
-+ case UNSPEC:
-+ switch (XINT (x, 1))
-+ {
-+ case UNSPEC_FDPIC_GOT:
-+ fprintf (file, "#%%got_lo(");
-+ ubicom32_print_operand_address (file, XVECEXP (x, 0, 0));
-+ fprintf (file, ")");
-+ break;
-+
-+ case UNSPEC_FDPIC_GOT_FUNCDESC:
-+ fprintf (file, "#%%got_funcdesc_lo(");
-+ ubicom32_print_operand_address (file, XVECEXP (x, 0, 0));
-+ fprintf (file, ")");
-+ break;
-+
-+ default:
-+ abort ();
-+ }
-+ break;
-+
-+ default:
-+ abort ();
-+ }
-+ break;
-+ }
-+}
-+
-+/* Output assembly language output for the address ADDR to FILE. */
-+
-+void
-+ubicom32_print_operand_address (FILE *file, rtx addr)
-+{
-+ switch (GET_CODE (addr))
-+ {
-+ case POST_INC:
-+ ubicom32_print_operand_address (file, XEXP (addr, 0));
-+ fprintf (file, "%d++", GET_MODE_SIZE (output_memory_reference_mode));
-+ break;
-+
-+ case PRE_INC:
-+ fprintf (file, "%d", GET_MODE_SIZE (output_memory_reference_mode));
-+ ubicom32_print_operand_address (file, XEXP (addr, 0));
-+ fprintf (file, "++");
-+ break;
-+
-+ case POST_DEC:
-+ ubicom32_print_operand_address (file, XEXP (addr, 0));
-+ fprintf (file, "%d++", -GET_MODE_SIZE (output_memory_reference_mode));
-+ break;
-+
-+ case PRE_DEC:
-+ fprintf (file, "%d", -GET_MODE_SIZE (output_memory_reference_mode));
-+ ubicom32_print_operand_address (file, XEXP (addr, 0));
-+ fprintf (file, "++");
-+ break;
-+
-+ case POST_MODIFY:
-+ ubicom32_print_operand_address (file, XEXP (addr, 0));
-+ fprintf (file, "%ld++", INTVAL (XEXP (XEXP (addr,1), 1)));
-+ break;
-+
-+ case PRE_MODIFY:
-+ fprintf (file, "%ld", INTVAL (XEXP (XEXP (addr,1), 1)));
-+ ubicom32_print_operand_address (file, XEXP (addr, 0));
-+ fprintf (file, "++");
-+ break;
-+
-+ case REG:
-+ fputc ('(', file);
-+ fprintf (file, "%s", reg_names[REGNO (addr)]);
-+ fputc (')', file);
-+ break;
-+
-+ case PLUS:
-+ {
-+ rtx base = XEXP (addr, 0);
-+ rtx index = XEXP (addr, 1);
-+
-+ /* Switch around addresses of the form index * scaling + base. */
-+ if (! ubicom32_is_base_reg (base, 1))
-+ {
-+ rtx tmp = base;
-+ base = index;
-+ index = tmp;
-+ }
-+
-+ if (CONST_INT_P (index))
-+ {
-+ fprintf (file, "%ld", INTVAL (index));
-+ fputc ('(', file);
-+ fputs (reg_names[REGNO (base)], file);
-+ }
-+ else if (GET_CODE (index) == MULT
-+ || REG_P (index))
-+ {
-+ if (GET_CODE (index) == MULT)
-+ index = XEXP (index, 0);
-+ fputc ('(', file);
-+ fputs (reg_names[REGNO (base)], file);
-+ fputc (',', file);
-+ fputs (reg_names[REGNO (index)], file);
-+ }
-+ else
-+ abort ();
-+
-+ fputc (')', file);
-+ break;
-+ }
-+
-+ case LO_SUM:
-+ fprintf (file, "%%lo(");
-+ ubicom32_print_operand (file, XEXP (addr, 1), 'L');
-+ fprintf (file, ")(");
-+ ubicom32_print_operand (file, XEXP (addr, 0), 0);
-+ fprintf (file, ")");
-+ break;
-+
-+ case CONST_INT:
-+ fputc ('#', file);
-+ output_addr_const (file, addr);
-+ break;
-+
-+ default:
-+ output_addr_const (file, addr);
-+ break;
-+ }
-+}
-+
-+/* X and Y are two things to compare using CODE. Emit the compare insn and
-+ return the rtx for the cc reg in the proper mode. */
-+
-+rtx
-+ubicom32_gen_compare_reg (enum rtx_code code, rtx x, rtx y)
-+{
-+ enum machine_mode mode = SELECT_CC_MODE (code, x, y);
-+ rtx cc_reg;
-+
-+ cc_reg = gen_rtx_REG (mode, CC_REGNUM);
-+
-+ emit_insn (gen_rtx_SET (VOIDmode, cc_reg,
-+ gen_rtx_COMPARE (mode, x, y)));
-+
-+ return cc_reg;
-+}
-+
-+/* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
-+ return the mode to be used for the comparison. */
-+
-+enum machine_mode
-+ubicom32_select_cc_mode (enum rtx_code op, rtx x, rtx y)
-+{
-+ /* Is this a short compare? */
-+ if (GET_MODE (x) == QImode
-+ || GET_MODE (x) == HImode
-+ || GET_MODE (y) == QImode
-+ || GET_MODE (y) == HImode)
-+ {
-+ switch (op)
-+ {
-+ case EQ :
-+ case NE :
-+ return CCSZmode;
-+
-+ case GE:
-+ case LT:
-+ if (y == const0_rtx)
-+ return CCSZNmode;
-+
-+ default :
-+ return CCSmode;
-+ }
-+ }
-+
-+ /* We have a word compare. */
-+ switch (op)
-+ {
-+ case EQ :
-+ case NE :
-+ return CCWZmode;
-+
-+ case GE :
-+ case LT :
-+ if (y == const0_rtx)
-+ return CCWZNmode;
-+
-+ default :
-+ return CCWmode;
-+ }
-+}
-+
-+/* Return TRUE or FALSE depending on whether the first SET in INSN
-+ has source and destination with matching CC modes, and that the
-+ CC mode is at least as constrained as REQ_MODE. */
-+bool
-+ubicom32_match_cc_mode (rtx insn, enum machine_mode req_mode)
-+{
-+ rtx set;
-+ enum machine_mode set_mode;
-+
-+ set = PATTERN (insn);
-+ if (GET_CODE (set) == PARALLEL)
-+ set = XVECEXP (set, 0, 0);
-+ gcc_assert (GET_CODE (set) == SET);
-+ gcc_assert (GET_CODE (SET_SRC (set)) == COMPARE);
-+
-+ /* SET_MODE is the mode we have in the instruction. This must either
-+ be the same or less restrictive that the required mode REQ_MODE. */
-+ set_mode = GET_MODE (SET_DEST (set));
-+
-+ switch (req_mode)
-+ {
-+ case CCSZmode:
-+ if (set_mode != CCSZmode)
-+ return 0;
-+ break;
-+
-+ case CCSZNmode:
-+ if (set_mode != CCSZmode
-+ && set_mode != CCSZNmode)
-+ return 0;
-+ break;
-+
-+ case CCSmode:
-+ if (set_mode != CCSmode
-+ && set_mode != CCSZmode
-+ && set_mode != CCSZNmode)
-+ return 0;
-+ break;
-+
-+ case CCWZmode:
-+ if (set_mode != CCWZmode)
-+ return 0;
-+ break;
-+
-+ case CCWZNmode:
-+ if (set_mode != CCWZmode
-+ && set_mode != CCWZNmode)
-+ return 0;
-+ break;
-+
-+ case CCWmode:
-+ if (set_mode != CCWmode
-+ && set_mode != CCWZmode
-+ && set_mode != CCWZNmode)
-+ return 0;
-+ break;
-+
-+ default:
-+ gcc_unreachable ();
-+ }
-+
-+ return (GET_MODE (SET_SRC (set)) == set_mode);
-+}
-+
-+/* Replace the comparison OP0 CODE OP1 by a semantically equivalent one
-+ that we can implement more efficiently. */
-+
-+void
-+ubicom32_canonicalize_comparison (enum rtx_code *code, rtx *op0, rtx *op1)
-+{
-+ /* If we have a REG and a MEM then compare the MEM with the REG and not
-+ the other way round. */
-+ if (REG_P (*op0) && MEM_P (*op1))
-+ {
-+ rtx tem = *op0;
-+ *op0 = *op1;
-+ *op1 = tem;
-+ *code = swap_condition (*code);
-+ return;
-+ }
-+
-+ /* If we have a REG and a CONST_INT then we may want to reverse things
-+ if the constant can be represented as an "I" constraint. */
-+ if (REG_P (*op0) && CONST_INT_P (*op1) && satisfies_constraint_I (*op1))
-+ {
-+ rtx tem = *op0;
-+ *op0 = *op1;
-+ *op1 = tem;
-+ *code = swap_condition (*code);
-+ return;
-+ }
-+}
-+
-+/* Return the fixed registers used for condition codes. */
-+
-+static bool
-+ubicom32_fixed_condition_code_regs (unsigned int *p1, unsigned int *p2)
-+{
-+ *p1 = CC_REGNUM;
-+ *p2 = INVALID_REGNUM;
-+
-+ return true;
-+}
-+
-+/* If two condition code modes are compatible, return a condition code
-+ mode which is compatible with both. Otherwise, return
-+ VOIDmode. */
-+
-+static enum machine_mode
-+ubicom32_cc_modes_compatible (enum machine_mode m1, enum machine_mode m2)
-+{
-+ if (m1 == m2)
-+ return m1;
-+
-+ if (GET_MODE_CLASS (m1) != MODE_CC || GET_MODE_CLASS (m2) != MODE_CC)
-+ return VOIDmode;
-+
-+ switch (m1)
-+ {
-+ case CCWmode:
-+ if (m2 == CCWZNmode || m2 == CCWZmode)
-+ return m1;
-+
-+ return VOIDmode;
-+
-+ case CCWZNmode:
-+ if (m2 == CCWmode)
-+ return m2;
-+
-+ if (m2 == CCWZmode)
-+ return m1;
-+
-+ return VOIDmode;
-+
-+ case CCWZmode:
-+ if (m2 == CCWmode || m2 == CCWZNmode)
-+ return m2;
-+
-+ return VOIDmode;
-+
-+ case CCSmode:
-+ if (m2 == CCSZNmode || m2 == CCSZmode)
-+ return m1;
-+
-+ return VOIDmode;
-+
-+ case CCSZNmode:
-+ if (m2 == CCSmode)
-+ return m2;
-+
-+ if (m2 == CCSZmode)
-+ return m1;
-+
-+ return VOIDmode;
-+
-+ case CCSZmode:
-+ if (m2 == CCSmode || m2 == CCSZNmode)
-+ return m2;
-+
-+ return VOIDmode;
-+
-+ default:
-+ gcc_unreachable ();
-+ }
-+}
-+
-+static rtx
-+ubicom32_legitimize_fdpic_address_symbol (rtx orig, rtx reg, rtx fdpic_reg)
-+{
-+ int unspec;
-+ rtx got_offs;
-+ rtx got_offs_scaled;
-+ rtx plus_scaled;
-+ rtx tmp;
-+ rtx new_rtx;
-+
-+ gcc_assert (reg != 0);
-+
-+ if (GET_CODE (orig) == SYMBOL_REF
-+ && SYMBOL_REF_FUNCTION_P (orig))
-+ unspec = UNSPEC_FDPIC_GOT_FUNCDESC;
-+ else
-+ unspec = UNSPEC_FDPIC_GOT;
-+
-+ got_offs = gen_reg_rtx (SImode);
-+ tmp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, orig), unspec);
-+ emit_move_insn (got_offs, tmp);
-+
-+ got_offs_scaled = gen_rtx_MULT (SImode, got_offs, GEN_INT (4));
-+ plus_scaled = gen_rtx_PLUS (Pmode, fdpic_reg, got_offs_scaled);
-+ new_rtx = gen_const_mem (Pmode, plus_scaled);
-+ emit_move_insn (reg, new_rtx);
-+
-+ return reg;
-+}
-+
-+static rtx
-+ubicom32_legitimize_fdpic_address (rtx orig, rtx reg, rtx fdpic_reg)
-+{
-+ rtx addr = orig;
-+ rtx new_rtx = orig;
-+
-+ if (GET_CODE (addr) == CONST || GET_CODE (addr) == PLUS)
-+ {
-+ rtx base;
-+
-+ if (GET_CODE (addr) == CONST)
-+ {
-+ addr = XEXP (addr, 0);
-+ gcc_assert (GET_CODE (addr) == PLUS);
-+ }
-+
-+ base = ubicom32_legitimize_fdpic_address_symbol (XEXP (addr, 0), reg, fdpic_reg);
-+ return gen_rtx_PLUS (Pmode, base, XEXP (addr, 1));
-+ }
-+
-+ return new_rtx;
-+}
-+
-+/* Code generation. */
-+
-+void
-+ubicom32_expand_movsi (rtx *operands)
-+{
-+ if (GET_CODE (operands[1]) == SYMBOL_REF
-+ || (GET_CODE (operands[1]) == CONST
-+ && GET_CODE (XEXP (operands[1], 0)) == PLUS
-+ && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
-+ || CONSTANT_ADDRESS_P (operands[1]))
-+ {
-+ if (TARGET_FDPIC)
-+ {
-+ rtx tmp;
-+ rtx fdpic_reg;
-+
-+ gcc_assert (can_create_pseudo_p ());
-+ tmp = gen_reg_rtx (Pmode);
-+ fdpic_reg = get_hard_reg_initial_val (SImode, FDPIC_REGNUM);
-+ if (GET_CODE (operands[1]) == SYMBOL_REF
-+ || GET_CODE (operands[1]) == LABEL_REF)
-+ operands[1] = ubicom32_legitimize_fdpic_address_symbol (operands[1], tmp, fdpic_reg);
-+ else
-+ operands[1] = ubicom32_legitimize_fdpic_address (operands[1], tmp, fdpic_reg);
-+ }
-+ else
-+ {
-+ rtx tmp;
-+ enum machine_mode mode;
-+
-+ /* We want to avoid reusing operand 0 if we can because it limits
-+ our ability to optimize later. */
-+ tmp = ! can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
-+
-+ mode = GET_MODE (operands[0]);
-+ emit_insn (gen_rtx_SET (VOIDmode, tmp,
-+ gen_rtx_HIGH (mode, operands[1])));
-+ operands[1] = gen_rtx_LO_SUM (mode, tmp, operands[1]);
-+ if (can_create_pseudo_p() && ! REG_P (operands[0]))
-+ {
-+ tmp = gen_reg_rtx (mode);
-+ emit_insn (gen_rtx_SET (VOIDmode, tmp, operands[1]));
-+ operands[1] = tmp;
-+ }
-+ }
-+ }
-+}
-+
-+/* Emit code for addsi3. */
-+
-+void
-+ubicom32_expand_addsi3 (rtx *operands)
-+{
-+ rtx op, clob;
-+
-+ if (can_create_pseudo_p ())
-+ {
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (SImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (SImode, operands[2]);
-+ }
-+
-+ /* Emit the instruction. */
-+
-+ op = gen_rtx_SET (VOIDmode, operands[0],
-+ gen_rtx_PLUS (SImode, operands[1], operands[2]));
-+
-+ if (! can_create_pseudo_p ())
-+ {
-+ /* Reload doesn't know about the flags register, and doesn't know that
-+ it doesn't want to clobber it. We can only do this with PLUS. */
-+ emit_insn (op);
-+ }
-+ else
-+ {
-+ clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM));
-+ emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, op, clob)));
-+ }
-+}
-+
-+/* Emit code for mulsi3. Return 1 if we have generated all the code
-+ necessary to do the multiplication. */
-+
-+int
-+ubicom32_emit_mult_sequence (rtx *operands)
-+{
-+ if (! ubicom32_v4)
-+ {
-+ rtx a1, a1_1, a2;
-+ rtx b1, b1_1, b2;
-+ rtx mac_lo_rtx;
-+ rtx t1, t2, t3;
-+
-+ /* Give up if we cannot create new pseudos. */
-+ if (!can_create_pseudo_p())
-+ return 0;
-+
-+ /* Synthesize 32-bit multiplication using 16-bit operations:
-+
-+ a1 = highpart (a)
-+ a2 = lowpart (a)
-+
-+ b1 = highpart (b)
-+ b2 = lowpart (b)
-+
-+ c = (a1 * b1) << 32 + (a1 * b2) << 16 + (a2 * b1) << 16 + a2 * b2
-+ = 0 + (a1 * b2) << 16 + (a2 * b1) << 16 + a2 * b2
-+ ^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^ ^^^^^^^
-+ Signed Signed Unsigned */
-+
-+ if (!ubicom32_data_register_operand (operands[1], GET_MODE (operands[1])))
-+ {
-+ rtx op1;
-+
-+ op1 = gen_reg_rtx (SImode);
-+ emit_move_insn (op1, operands[1]);
-+ operands[1] = op1;
-+ }
-+
-+ if (!ubicom32_data_register_operand (operands[2], GET_MODE (operands[2])))
-+ {
-+ rtx op2;
-+
-+ op2 = gen_reg_rtx (SImode);
-+ emit_move_insn (op2, operands[2]);
-+ operands[2] = op2;
-+ }
-+
-+ /* a1 = highpart (a) */
-+ a1 = gen_reg_rtx (HImode);
-+ a1_1 = gen_reg_rtx (SImode);
-+ emit_insn (gen_ashrsi3 (a1_1, operands[1], GEN_INT (16)));
-+ emit_move_insn (a1, gen_lowpart (HImode, a1_1));
-+
-+ /* a2 = lowpart (a) */
-+ a2 = gen_reg_rtx (HImode);
-+ emit_move_insn (a2, gen_lowpart (HImode, operands[1]));
-+
-+ /* b1 = highpart (b) */
-+ b1 = gen_reg_rtx (HImode);
-+ b1_1 = gen_reg_rtx (SImode);
-+ emit_insn (gen_ashrsi3 (b1_1, operands[2], GEN_INT (16)));
-+ emit_move_insn (b1, gen_lowpart (HImode, b1_1));
-+
-+ /* b2 = lowpart (b) */
-+ b2 = gen_reg_rtx (HImode);
-+ emit_move_insn (b2, gen_lowpart (HImode, operands[2]));
-+
-+ /* t1 = (a1 * b2) << 16 */
-+ t1 = gen_reg_rtx (SImode);
-+ mac_lo_rtx = gen_rtx_REG (SImode, ACC0_LO_REGNUM);
-+ emit_insn (gen_mulhisi3 (mac_lo_rtx, a1, b2));
-+ emit_insn (gen_ashlsi3 (t1, mac_lo_rtx, GEN_INT (16)));
-+
-+ /* t2 = (a2 * b1) << 16 */
-+ t2 = gen_reg_rtx (SImode);
-+ emit_insn (gen_mulhisi3 (mac_lo_rtx, a2, b1));
-+ emit_insn (gen_ashlsi3 (t2, mac_lo_rtx, GEN_INT (16)));
-+
-+ /* mac_lo = a2 * b2 */
-+ emit_insn (gen_umulhisi3 (mac_lo_rtx, a2, b2));
-+
-+ /* t3 = t1 + t2 */
-+ t3 = gen_reg_rtx (SImode);
-+ emit_insn (gen_addsi3 (t3, t1, t2));
-+
-+ /* c = t3 + mac_lo_rtx */
-+ emit_insn (gen_addsi3 (operands[0], mac_lo_rtx, t3));
-+
-+ return 1;
-+ }
-+ else
-+ {
-+ rtx acc_rtx;
-+
-+ /* Give up if we cannot create new pseudos. */
-+ if (!can_create_pseudo_p())
-+ return 0;
-+
-+ if (!ubicom32_data_register_operand (operands[1], GET_MODE (operands[1])))
-+ {
-+ rtx op1;
-+
-+ op1 = gen_reg_rtx (SImode);
-+ emit_move_insn (op1, operands[1]);
-+ operands[1] = op1;
-+ }
-+
-+ if (!ubicom32_data_register_operand (operands[2], GET_MODE (operands[2])))
-+ {
-+ rtx op2;
-+
-+ op2 = gen_reg_rtx (SImode);
-+ emit_move_insn (op2, operands[2]);
-+ operands[2] = op2;
-+ }
-+
-+ acc_rtx = gen_reg_rtx (DImode);
-+ emit_insn (gen_umulsidi3 (acc_rtx, operands[1], operands[2]));
-+ emit_move_insn (operands[0], gen_lowpart (SImode, acc_rtx));
-+
-+ return 1;
-+ }
-+}
-+
-+/* Move the integer value VAL into OPERANDS[0]. */
-+
-+void
-+ubicom32_emit_move_const_int (rtx dest, rtx imm)
-+{
-+ rtx xoperands[2];
-+
-+ xoperands[0] = dest;
-+ xoperands[1] = imm;
-+
-+ /* Treat mem destinations separately. Values must be explicitly sign
-+ extended. */
-+ if (MEM_P (dest))
-+ {
-+ rtx low_hword_mem;
-+ rtx low_hword_addr;
-+
-+ /* Emit shorter sequence for signed 7-bit quantities. */
-+ if (satisfies_constraint_I (imm))
-+ {
-+ output_asm_insn ("move.4\t%0, %1", xoperands);
-+ return;
-+ }
-+
-+ /* Special case for pushing constants. */
-+ if (GET_CODE (XEXP (dest, 0)) == PRE_DEC
-+ && XEXP (XEXP (dest, 0), 0) == stack_pointer_rtx)
-+ {
-+ output_asm_insn ("movei\t-4(sp)++, #%%hi(%E1)", xoperands);
-+ output_asm_insn ("movei\t2(sp), #%%lo(%E1)", xoperands);
-+ return;
-+ }
-+
-+ /* See if we can add 2 to the original address. This is only
-+ possible if the original address is of the form REG or
-+ REG+const. */
-+ low_hword_addr = plus_constant (XEXP (dest, 0), 2);
-+ if (ubicom32_legitimate_address_p (HImode, low_hword_addr, 1))
-+ {
-+ low_hword_mem = gen_rtx_MEM (HImode, low_hword_addr);
-+ MEM_COPY_ATTRIBUTES (low_hword_mem, dest);
-+ output_asm_insn ("movei\t%0, #%%hi(%E1)", xoperands);
-+ xoperands[0] = low_hword_mem;
-+ output_asm_insn ("movei\t%0, #%%lo(%E1)", xoperands);
-+ return;
-+ }
-+
-+ /* The original address is too complex. We need to use a
-+ scratch memory by (sp) and move that to the original
-+ destination. */
-+ if (! reg_mentioned_p (stack_pointer_rtx, dest))
-+ {
-+ output_asm_insn ("movei\t-4(sp)++, #%%hi(%E1)", xoperands);
-+ output_asm_insn ("movei\t2(sp), #%%lo(%E1)", xoperands);
-+ output_asm_insn ("move.4\t%0, (sp)4++", xoperands);
-+ return;
-+ }
-+
-+ /* Our address mentions the stack pointer so we need to
-+ use our scratch data register here as well as scratch
-+ memory. */
-+ output_asm_insn ("movei\t-4(sp)++, #%%hi(%E1)", xoperands);
-+ output_asm_insn ("movei\t2(sp), #%%lo(%E1)", xoperands);
-+ output_asm_insn ("move.4\td15, (sp)4++", xoperands);
-+ output_asm_insn ("move.4\t%0, d15", xoperands);
-+ return;
-+ }
-+
-+ /* Move into registers are zero extended by default. */
-+ if (! REG_P (dest))
-+ abort ();
-+
-+ if (satisfies_constraint_N (imm))
-+ {
-+ output_asm_insn ("movei\t%0, %1", xoperands);
-+ return;
-+ }
-+
-+ if (INTVAL (xoperands[1]) >= 0xff80
-+ && INTVAL (xoperands[1]) < 0x10000)
-+ {
-+ xoperands[1] = GEN_INT (INTVAL (xoperands[1]) - 0x10000);
-+ output_asm_insn ("move.2\t%0, %1", xoperands);
-+ return;
-+ }
-+
-+ if ((REGNO_REG_CLASS (REGNO (xoperands[0])) == ADDRESS_REGS
-+ || REGNO_REG_CLASS (REGNO (xoperands[0])) == FDPIC_REG)
-+ && ((INTVAL (xoperands[1]) & 0x80000000) == 0))
-+ {
-+ output_asm_insn ("moveai\t%0, #%%hi(%E1)", xoperands);
-+ if ((INTVAL (xoperands[1]) & 0x7f) != 0)
-+ output_asm_insn ("lea.1\t%0, %%lo(%E1)(%0)", xoperands);
-+ return;
-+ }
-+
-+ if ((INTVAL (xoperands[1]) & 0xffff0000) == 0)
-+ {
-+ output_asm_insn ("movei\t%0, #%%lo(%E1)", xoperands);
-+ output_asm_insn ("move.2\t%0, %0", xoperands);
-+ return;
-+ }
-+
-+ /* This is very expensive. The constant is so large that we
-+ need to use the stack to do the load. */
-+ output_asm_insn ("movei\t-4(sp)++, #%%hi(%E1)", xoperands);
-+ output_asm_insn ("movei\t2(sp), #%%lo(%E1)", xoperands);
-+ output_asm_insn ("move.4\t%0, (sp)4++", xoperands);
-+}
-+
-+/* Stack layout. Prologue/Epilogue. */
-+
-+static int save_regs_size;
-+
-+static void
-+ubicom32_layout_frame (void)
-+{
-+ int regno;
-+
-+ memset ((char *) &save_regs[0], 0, sizeof (save_regs));
-+ nregs = 0;
-+ frame_size = get_frame_size ();
-+
-+ if (frame_pointer_needed || df_regs_ever_live_p (FRAME_POINTER_REGNUM))
-+ {
-+ save_regs[FRAME_POINTER_REGNUM] = 1;
-+ ++nregs;
-+ }
-+
-+ if (current_function_is_leaf && ! df_regs_ever_live_p (LINK_REGNO))
-+ ubicom32_can_use_calli_to_ret = 1;
-+ else
-+ {
-+ ubicom32_can_use_calli_to_ret = 0;
-+ save_regs[LINK_REGNO] = 1;
-+ ++nregs;
-+ }
-+
-+ /* Figure out which register(s) needs to be saved. */
-+ for (regno = 0; regno <= LAST_ADDRESS_REGNUM; regno++)
-+ if (df_regs_ever_live_p(regno)
-+ && ! call_used_regs[regno]
-+ && ! fixed_regs[regno]
-+ && ! save_regs[regno])
-+ {
-+ save_regs[regno] = 1;
-+ ++nregs;
-+ }
-+
-+ save_regs_size = 4 * nregs;
-+}
-+
-+static void
-+ubicom32_emit_add_movsi (int regno, int adj)
-+{
-+ rtx x;
-+ rtx reg = gen_rtx_REG (SImode, regno);
-+
-+ adj += 4;
-+ if (adj > 8 * 4)
-+ {
-+ x = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
-+ GEN_INT (-adj)));
-+ RTX_FRAME_RELATED_P (x) = 1;
-+ x = emit_move_insn (gen_rtx_MEM (SImode, stack_pointer_rtx), reg);
-+ }
-+ else
-+ {
-+ rtx addr = gen_rtx_PRE_MODIFY (Pmode, stack_pointer_rtx,
-+ gen_rtx_PLUS (Pmode, stack_pointer_rtx,
-+ GEN_INT (-adj)));
-+ x = emit_move_insn (gen_rtx_MEM (SImode, addr), reg);
-+ }
-+ RTX_FRAME_RELATED_P (x) = 1;
-+}
-+
-+void
-+ubicom32_expand_prologue (void)
-+{
-+ rtx x;
-+ int regno;
-+ int outgoing_args_size = crtl->outgoing_args_size;
-+ int adj;
-+
-+ if (ubicom32_naked_function_p ())
-+ return;
-+
-+ ubicom32_builtin_saveregs ();
-+
-+ ubicom32_layout_frame ();
-+ adj = (outgoing_args_size + get_frame_size () + save_regs_size
-+ + crtl->args.pretend_args_size);
-+
-+ if (!adj)
-+ ;
-+ else if (outgoing_args_size + save_regs_size < 508
-+ && get_frame_size () + save_regs_size > 508)
-+ {
-+ int i = 0;
-+ x = gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
-+ GEN_INT (-adj));
-+ x = emit_insn (x);
-+ RTX_FRAME_RELATED_P (x) = 1;
-+
-+ for (regno = LAST_ADDRESS_REGNUM; regno >= 0; --regno)
-+ if (save_regs[regno] && regno != LINK_REGNO)
-+ {
-+ x = gen_rtx_MEM (SImode,
-+ gen_rtx_PLUS (Pmode,
-+ stack_pointer_rtx,
-+ GEN_INT (i * 4 + outgoing_args_size)));
-+ x = emit_move_insn (x, gen_rtx_REG (SImode, regno));
-+ RTX_FRAME_RELATED_P (x) = 1;
-+ ++i;
-+ }
-+ if (save_regs[LINK_REGNO])
-+ {
-+ x = gen_rtx_MEM (SImode,
-+ gen_rtx_PLUS (Pmode,
-+ stack_pointer_rtx,
-+ GEN_INT (i * 4 + outgoing_args_size)));
-+ x = emit_move_insn (x, gen_rtx_REG (SImode, LINK_REGNO));
-+ RTX_FRAME_RELATED_P (x) = 1;
-+ }
-+ }
-+ else
-+ {
-+ int regno;
-+ int adj = get_frame_size () + crtl->args.pretend_args_size;
-+ int i = 0;
-+
-+ if (save_regs[LINK_REGNO])
-+ {
-+ ubicom32_emit_add_movsi (LINK_REGNO, adj);
-+ ++i;
-+ }
-+
-+ for (regno = 0; regno <= LAST_ADDRESS_REGNUM; ++regno)
-+ if (save_regs[regno] && regno != LINK_REGNO)
-+ {
-+ if (i)
-+ {
-+ rtx mem = gen_rtx_MEM (SImode,
-+ gen_rtx_PRE_DEC (Pmode,
-+ stack_pointer_rtx));
-+ x = emit_move_insn (mem, gen_rtx_REG (SImode, regno));
-+ RTX_FRAME_RELATED_P (x) = 1;
-+ }
-+ else
-+ ubicom32_emit_add_movsi (regno, adj);
-+ ++i;
-+ }
-+
-+ if (outgoing_args_size || (!i && adj))
-+ {
-+ x = gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
-+ GEN_INT (-outgoing_args_size - (i ? 0 : adj)));
-+ x = emit_insn (x);
-+ RTX_FRAME_RELATED_P (x) = 1;
-+ }
-+ }
-+
-+ if (frame_pointer_needed)
-+ {
-+ int fp_adj = save_regs_size + outgoing_args_size;
-+ x = gen_addsi3 (frame_pointer_rtx, stack_pointer_rtx,
-+ GEN_INT (fp_adj));
-+ x = emit_insn (x);
-+ RTX_FRAME_RELATED_P (x) = 1;
-+ }
-+}
-+
-+void
-+ubicom32_expand_epilogue (void)
-+{
-+ rtx x;
-+ int regno;
-+ int outgoing_args_size = crtl->outgoing_args_size;
-+ int adj;
-+ int i;
-+
-+ if (ubicom32_naked_function_p ())
-+ {
-+ emit_jump_insn (gen_return_internal (gen_rtx_REG (SImode,
-+ LINK_REGNO)));
-+ return;
-+ }
-+
-+ if (cfun->calls_alloca)
-+ {
-+ x = gen_addsi3 (stack_pointer_rtx, frame_pointer_rtx,
-+ GEN_INT (-save_regs_size));
-+ emit_insn (x);
-+ outgoing_args_size = 0;
-+ }
-+
-+ if (outgoing_args_size)
-+ {
-+ x = gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
-+ GEN_INT (outgoing_args_size));
-+ emit_insn (x);
-+ }
-+
-+ i = 0;
-+ for (regno = LAST_ADDRESS_REGNUM; regno >= 0; --regno)
-+ if (save_regs[regno] && regno != LINK_REGNO)
-+ {
-+ x = gen_rtx_MEM (SImode, gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
-+ emit_move_insn (gen_rtx_REG (SImode, regno), x);
-+ ++i;
-+ }
-+
-+ /* Do we have to adjust the stack after we've finished restoring regs? */
-+ adj = get_frame_size() + crtl->args.pretend_args_size;
-+ if (cfun->stdarg)
-+ adj += UBICOM32_FUNCTION_ARG_REGS * UNITS_PER_WORD;
-+
-+#if 0
-+ if (crtl->calls_eh_return && 0)
-+ {
-+ if (save_regs[LINK_REGNO])
-+ {
-+ x = gen_rtx_MEM (SImode, gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
-+ emit_move_insn (gen_rtx_REG (SImode, LINK_REGNO), x);
-+ }
-+
-+ if (adj)
-+ {
-+ x = gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
-+ GEN_INT (adj));
-+ x = emit_insn (x);
-+ }
-+
-+ /* Perform the additional bump for __throw. */
-+ emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
-+ EH_RETURN_STACKADJ_RTX));
-+ emit_jump_insn (gen_eh_return_internal ());
-+ return;
-+ }
-+#endif
-+
-+ if (save_regs[LINK_REGNO])
-+ {
-+ if (adj >= 4 && adj <= (6 * 4))
-+ {
-+ x = GEN_INT (adj + 4);
-+ emit_jump_insn (gen_return_from_post_modify_sp (x));
-+ return;
-+ }
-+
-+ if (adj == 0)
-+ {
-+ x = gen_rtx_MEM (SImode, gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
-+ emit_jump_insn (gen_return_internal (x));
-+ return;
-+ }
-+
-+ x = gen_rtx_MEM (SImode, gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
-+ emit_move_insn (gen_rtx_REG (SImode, LINK_REGNO), x);
-+ }
-+
-+ if (adj)
-+ {
-+ x = gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
-+ GEN_INT (adj));
-+ x = emit_insn (x);
-+ adj = 0;
-+ }
-+
-+ /* Given that we've just done all the hard work here we may as well use
-+ a calli to return. */
-+ ubicom32_can_use_calli_to_ret = 1;
-+ emit_jump_insn (gen_return_internal (gen_rtx_REG (SImode, LINK_REGNO)));
-+}
-+
-+void
-+ubicom32_expand_call_fdpic (rtx *operands)
-+{
-+ rtx c;
-+ rtx addr;
-+ rtx fdpic_reg = get_hard_reg_initial_val (SImode, FDPIC_REGNUM);
-+
-+ addr = XEXP (operands[0], 0);
-+
-+ c = gen_call_fdpic (addr, operands[1], fdpic_reg);
-+ emit_call_insn (c);
-+}
-+
-+void
-+ubicom32_expand_call_value_fdpic (rtx *operands)
-+{
-+ rtx c;
-+ rtx addr;
-+ rtx fdpic_reg = get_hard_reg_initial_val (SImode, FDPIC_REGNUM);
-+
-+ addr = XEXP (operands[1], 0);
-+
-+ c = gen_call_value_fdpic (operands[0], addr, operands[2], fdpic_reg);
-+ emit_call_insn (c);
-+}
-+
-+void
-+ubicom32_expand_eh_return (rtx *operands)
-+{
-+ if (REG_P (operands[0])
-+ || REGNO (operands[0]) != EH_RETURN_STACKADJ_REGNO)
-+ {
-+ rtx sp = EH_RETURN_STACKADJ_RTX;
-+ emit_move_insn (sp, operands[0]);
-+ operands[0] = sp;
-+ }
-+
-+ if (REG_P (operands[1])
-+ || REGNO (operands[1]) != EH_RETURN_HANDLER_REGNO)
-+ {
-+ rtx ra = EH_RETURN_HANDLER_RTX;
-+ emit_move_insn (ra, operands[1]);
-+ operands[1] = ra;
-+ }
-+}
-+
-+/* Compute the offsets between eliminable registers. */
-+
-+int
-+ubicom32_initial_elimination_offset (int from, int to)
-+{
-+ ubicom32_layout_frame ();
-+ if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
-+ return save_regs_size + crtl->outgoing_args_size;
-+
-+ if (from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
-+ return get_frame_size ()/* + save_regs_size */;
-+
-+ if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
-+ return get_frame_size ()
-+ + crtl->outgoing_args_size
-+ + save_regs_size;
-+
-+ return 0;
-+}
-+
-+/* Return 1 if it is appropriate to emit `ret' instructions in the
-+ body of a function. Do this only if the epilogue is simple, needing a
-+ couple of insns. Prior to reloading, we can't tell how many registers
-+ must be saved, so return 0 then. Return 0 if there is no frame
-+ marker to de-allocate.
-+
-+ If NON_SAVING_SETJMP is defined and true, then it is not possible
-+ for the epilogue to be simple, so return 0. This is a special case
-+ since NON_SAVING_SETJMP will not cause regs_ever_live to change
-+ until final, but jump_optimize may need to know sooner if a
-+ `return' is OK. */
-+
-+int
-+ubicom32_can_use_return_insn_p (void)
-+{
-+ if (! reload_completed || frame_pointer_needed)
-+ return 0;
-+
-+ return 1;
-+}
-+
-+/* Attributes and CC handling. */
-+
-+/* Handle an attribute requiring a FUNCTION_DECL; arguments as in
-+ struct attribute_spec.handler. */
-+static tree
-+ubicom32_handle_fndecl_attribute (tree *node, tree name,
-+ tree args ATTRIBUTE_UNUSED,
-+ int flags ATTRIBUTE_UNUSED,
-+ bool *no_add_attrs)
-+{
-+ if (TREE_CODE (*node) != FUNCTION_DECL)
-+ {
-+ warning ("'%s' attribute only applies to functions",
-+ IDENTIFIER_POINTER (name));
-+ *no_add_attrs = true;
-+ }
-+
-+ return NULL_TREE;
-+}
-+
-+/* A C expression that places additional restrictions on the register class to
-+ use when it is necessary to copy value X into a register in class CLASS.
-+ The value is a register class; perhaps CLASS, or perhaps another, smaller
-+ class. On many machines, the following definition is safe:
-+
-+ #define PREFERRED_RELOAD_CLASS(X,CLASS) CLASS
-+
-+ Sometimes returning a more restrictive class makes better code. For
-+ example, on the 68000, when X is an integer constant that is in range for a
-+ `moveq' instruction, the value of this macro is always `DATA_REGS' as long
-+ as CLASS includes the data registers. Requiring a data register guarantees
-+ that a `moveq' will be used.
-+
-+ If X is a `const_double', by returning `NO_REGS' you can force X into a
-+ memory constant. This is useful on certain machines where immediate
-+ floating values cannot be loaded into certain kinds of registers. */
-+
-+enum reg_class
-+ubicom32_preferred_reload_class (rtx x, enum reg_class class)
-+{
-+ /* If a symbolic constant, HIGH or a PLUS is reloaded,
-+ it is most likely being used as an address, so
-+ prefer ADDRESS_REGS. If 'class' is not a superset
-+ of ADDRESS_REGS, e.g. DATA_REGS, then reject this reload. */
-+ if (GET_CODE (x) == PLUS
-+ || GET_CODE (x) == HIGH
-+ || GET_CODE (x) == LABEL_REF
-+ || GET_CODE (x) == SYMBOL_REF
-+ || GET_CODE (x) == CONST)
-+ {
-+ if (reg_class_subset_p (ALL_ADDRESS_REGS, class))
-+ return ALL_ADDRESS_REGS;
-+
-+ return NO_REGS;
-+ }
-+
-+ return class;
-+}
-+
-+/* Function arguments and varargs. */
-+
-+int
-+ubicom32_reg_parm_stack_space (tree fndecl)
-+{
-+ return 0;
-+
-+ if (fndecl
-+ && TYPE_ARG_TYPES (TREE_TYPE (fndecl)) != 0
-+ && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (TREE_TYPE (fndecl))))
-+ != void_type_node))
-+ return UBICOM32_FUNCTION_ARG_REGS * UNITS_PER_WORD;
-+
-+ return 0;
-+}
-+
-+/* Flush the argument registers to the stack for a stdarg function;
-+ return the new argument pointer. */
-+
-+rtx
-+ubicom32_builtin_saveregs (void)
-+{
-+ int regno;
-+
-+ if (! cfun->stdarg)
-+ return 0;
-+
-+ for (regno = UBICOM32_FUNCTION_ARG_REGS - 1; regno >= 0; --regno)
-+ emit_move_insn (gen_rtx_MEM (SImode,
-+ gen_rtx_PRE_DEC (SImode,
-+ stack_pointer_rtx)),
-+ gen_rtx_REG (SImode, regno));
-+
-+ return stack_pointer_rtx;
-+}
-+
-+void
-+ubicom32_va_start (tree valist, rtx nextarg)
-+{
-+ std_expand_builtin_va_start (valist, nextarg);
-+}
-+
-+rtx
-+ubicom32_va_arg (tree valist, tree type)
-+{
-+ HOST_WIDE_INT size, rsize;
-+ tree addr, incr, tmp;
-+ rtx addr_rtx;
-+ int indirect = 0;
-+
-+ /* Round up sizeof(type) to a word. */
-+ size = int_size_in_bytes (type);
-+ rsize = (size + UNITS_PER_WORD - 1) & -UNITS_PER_WORD;
-+
-+ /* Large types are passed by reference. */
-+ if (size > 8)
-+ {
-+ indirect = 1;
-+ size = rsize = UNITS_PER_WORD;
-+ }
-+
-+ incr = valist;
-+ addr = incr = save_expr (incr);
-+
-+ /* FIXME Nat's version - is it correct? */
-+ tmp = fold_convert (ptr_type_node, size_int (rsize));
-+ tmp = build2 (PLUS_EXPR, ptr_type_node, incr, tmp);
-+ incr = fold (tmp);
-+
-+ /* FIXME Nat's version - is it correct? */
-+ incr = build2 (MODIFY_EXPR, ptr_type_node, valist, incr);
-+
-+ TREE_SIDE_EFFECTS (incr) = 1;
-+ expand_expr (incr, const0_rtx, VOIDmode, EXPAND_NORMAL);
-+
-+ addr_rtx = expand_expr (addr, NULL, Pmode, EXPAND_NORMAL);
-+
-+ if (size < UNITS_PER_WORD)
-+ emit_insn (gen_addsi3 (addr_rtx, addr_rtx,
-+ GEN_INT (UNITS_PER_WORD - size)));
-+
-+ if (indirect)
-+ {
-+ addr_rtx = force_reg (Pmode, addr_rtx);
-+ addr_rtx = gen_rtx_MEM (Pmode, addr_rtx);
-+ set_mem_alias_set (addr_rtx, get_varargs_alias_set ());
-+ }
-+
-+ return addr_rtx;
-+}
-+
-+void
-+init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype, rtx libname,
-+ int indirect ATTRIBUTE_UNUSED)
-+{
-+ cum->nbytes = 0;
-+
-+ if (!libname)
-+ {
-+ cum->stdarg = (TYPE_ARG_TYPES (fntype) != 0
-+ && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
-+ != void_type_node));
-+ }
-+}
-+
-+/* Return an RTX to represent where a value in mode MODE will be passed
-+ to a function. If the result is 0, the argument will be pushed. */
-+
-+rtx
-+function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
-+ int named ATTRIBUTE_UNUSED)
-+{
-+ rtx result = 0;
-+ int size, align;
-+ int nregs = UBICOM32_FUNCTION_ARG_REGS;
-+
-+ /* Figure out the size of the object to be passed. */
-+ if (mode == BLKmode)
-+ size = int_size_in_bytes (type);
-+ else
-+ size = GET_MODE_SIZE (mode);
-+
-+ /* Figure out the alignment of the object to be passed. */
-+ align = size;
-+
-+ cum->nbytes = (cum->nbytes + 3) & ~3;
-+
-+ /* Don't pass this arg via a register if all the argument registers
-+ are used up. */
-+ if (cum->nbytes >= nregs * UNITS_PER_WORD)
-+ return 0;
-+
-+ /* Don't pass this arg via a register if it would be split between
-+ registers and memory. */
-+ result = gen_rtx_REG (mode, cum->nbytes / UNITS_PER_WORD);
-+
-+ return result;
-+}
-+
-+rtx
-+function_incoming_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
-+ int named ATTRIBUTE_UNUSED)
-+{
-+ if (cfun->stdarg)
-+ return 0;
-+
-+ return function_arg (cum, mode, type, named);
-+}
-+
-+
-+/* Implement hook TARGET_ARG_PARTIAL_BYTES.
-+
-+ Returns the number of bytes at the beginning of an argument that
-+ must be put in registers. The value must be zero for arguments
-+ that are passed entirely in registers or that are entirely pushed
-+ on the stack. */
-+static int
-+ubicom32_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
-+ tree type, bool named ATTRIBUTE_UNUSED)
-+{
-+ int size, diff;
-+
-+ int nregs = UBICOM32_FUNCTION_ARG_REGS;
-+
-+ /* round up to full word */
-+ cum->nbytes = (cum->nbytes + 3) & ~3;
-+
-+ if (targetm.calls.pass_by_reference (cum, mode, type, named))
-+ return 0;
-+
-+ /* number of bytes left in registers */
-+ diff = nregs*UNITS_PER_WORD - cum->nbytes;
-+
-+ /* regs all used up */
-+ if (diff <= 0)
-+ return 0;
-+
-+ /* Figure out the size of the object to be passed. */
-+ if (mode == BLKmode)
-+ size = int_size_in_bytes (type);
-+ else
-+ size = GET_MODE_SIZE (mode);
-+
-+ /* enough space left in regs for size */
-+ if (size <= diff)
-+ return 0;
-+
-+ /* put diff bytes in regs and rest on stack */
-+ return diff;
-+
-+}
-+
-+static bool
-+ubicom32_pass_by_reference (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
-+ enum machine_mode mode, const_tree type,
-+ bool named ATTRIBUTE_UNUSED)
-+{
-+ int size;
-+
-+ if (type)
-+ size = int_size_in_bytes (type);
-+ else
-+ size = GET_MODE_SIZE (mode);
-+
-+ return size <= 0 || size > 8;
-+}
-+
-+static bool
-+ubicom32_callee_copies (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
-+ enum machine_mode mode, const_tree type,
-+ bool named ATTRIBUTE_UNUSED)
-+{
-+ int size;
-+
-+ if (type)
-+ size = int_size_in_bytes (type);
-+ else
-+ size = GET_MODE_SIZE (mode);
-+
-+ return size <= 0 || size > 8;
-+}
-+
-+static bool
-+ubicom32_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
-+{
-+ int size, mode;
-+
-+ if (!type)
-+ return true;
-+
-+ size = int_size_in_bytes(type);
-+ if (size > 8)
-+ return true;
-+
-+ mode = TYPE_MODE(type);
-+ if (mode == BLKmode)
-+ return true;
-+
-+ return false;
-+}
-+
-+/* Return true if a given register number REGNO is acceptable for machine
-+ mode MODE. */
-+bool
-+ubicom32_hard_regno_mode_ok (unsigned int regno, enum machine_mode mode)
-+{
-+ /* If we're not at least a v3 ISA then ACC0_HI is only 16 bits. */
-+ if (! ubicom32_v3)
-+ {
-+ if (regno == ACC0_HI_REGNUM)
-+ return (mode == QImode || mode == HImode);
-+ }
-+
-+ /* Only the flags reg can hold CCmode. */
-+ if (GET_MODE_CLASS (mode) == MODE_CC)
-+ return regno == CC_REGNUM;
-+
-+ /* We restrict the choice of DImode registers to only being address,
-+ data or accumulator regs. We also restrict them to only start on
-+ even register numbers so we never have to worry about partial
-+ overlaps between operands in instructions. */
-+ if (GET_MODE_SIZE (mode) > 4)
-+ {
-+ switch (REGNO_REG_CLASS (regno))
-+ {
-+ case ADDRESS_REGS:
-+ case DATA_REGS:
-+ case ACC_REGS:
-+ return (regno & 1) == 0;
-+
-+ default:
-+ return false;
-+ }
-+ }
-+
-+ return true;
-+}
-+
-+/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
-+ and check its validity for a certain class.
-+ We have two alternate definitions for each of them.
-+ The usual definition accepts all pseudo regs; the other rejects
-+ them unless they have been allocated suitable hard regs.
-+ The symbol REG_OK_STRICT causes the latter definition to be used.
-+
-+ Most source files want to accept pseudo regs in the hope that
-+ they will get allocated to the class that the insn wants them to be in.
-+ Source files for reload pass need to be strict.
-+ After reload, it makes no difference, since pseudo regs have
-+ been eliminated by then.
-+
-+ These assume that REGNO is a hard or pseudo reg number.
-+ They give nonzero only if REGNO is a hard reg of the suitable class
-+ or a pseudo reg currently allocated to a suitable hard reg.
-+ Since they use reg_renumber, they are safe only once reg_renumber
-+ has been allocated, which happens in local-alloc.c. */
-+
-+int
-+ubicom32_regno_ok_for_base_p (int regno, int strict)
-+{
-+ if ((regno >= FIRST_ADDRESS_REGNUM && regno <= STACK_POINTER_REGNUM)
-+ || (!strict
-+ && (regno >= FIRST_PSEUDO_REGISTER
-+ || regno == ARG_POINTER_REGNUM))
-+ || (strict && (reg_renumber
-+ && reg_renumber[regno] >= FIRST_ADDRESS_REGNUM
-+ && reg_renumber[regno] <= STACK_POINTER_REGNUM)))
-+ return 1;
-+
-+ return 0;
-+}
-+
-+int
-+ubicom32_regno_ok_for_index_p (int regno, int strict)
-+{
-+ if ((regno >= FIRST_DATA_REGNUM && regno <= LAST_DATA_REGNUM)
-+ || (!strict && regno >= FIRST_PSEUDO_REGISTER)
-+ || (strict && (reg_renumber
-+ && reg_renumber[regno] >= FIRST_DATA_REGNUM
-+ && reg_renumber[regno] <= LAST_DATA_REGNUM)))
-+ return 1;
-+
-+ return 0;
-+}
-+
-+/* Returns 1 if X is a valid index register. STRICT is 1 if only hard
-+ registers should be accepted. Accept either REG or SUBREG where a
-+ register is valid. */
-+
-+static bool
-+ubicom32_is_index_reg (rtx x, int strict)
-+{
-+ if ((REG_P (x) && ubicom32_regno_ok_for_index_p (REGNO (x), strict))
-+ || (GET_CODE (x) == SUBREG && REG_P (SUBREG_REG (x))
-+ && ubicom32_regno_ok_for_index_p (REGNO (SUBREG_REG (x)), strict)))
-+ return true;
-+
-+ return false;
-+}
-+
-+/* Return 1 if X is a valid index for a memory address. */
-+
-+static bool
-+ubicom32_is_index_expr (enum machine_mode mode, rtx x, int strict)
-+{
-+ /* Immediate index must be an unsigned 7-bit offset multiple of 1, 2
-+ or 4 depending on mode. */
-+ if (CONST_INT_P (x))
-+ {
-+ switch (mode)
-+ {
-+ case QImode:
-+ return satisfies_constraint_J (x);
-+
-+ case HImode:
-+ return satisfies_constraint_K (x);
-+
-+ case SImode:
-+ case SFmode:
-+ return satisfies_constraint_L (x);
-+
-+ case DImode:
-+ return satisfies_constraint_L (x)
-+ && satisfies_constraint_L (GEN_INT (INTVAL (x) + 4));
-+
-+ default:
-+ return false;
-+ }
-+ }
-+
-+ if (mode != SImode && mode != HImode && mode != QImode)
-+ return false;
-+
-+ /* Register index scaled by mode of operand: REG + REG * modesize.
-+ Valid scaled index registers are:
-+
-+ SImode (mult (dreg) 4))
-+ HImode (mult (dreg) 2))
-+ QImode (mult (dreg) 1)) */
-+ if (GET_CODE (x) == MULT
-+ && ubicom32_is_index_reg (XEXP (x, 0), strict)
-+ && CONST_INT_P (XEXP (x, 1))
-+ && INTVAL (XEXP (x, 1)) == (HOST_WIDE_INT)GET_MODE_SIZE (mode))
-+ return true;
-+
-+ /* REG + REG addressing is allowed for QImode. */
-+ if (ubicom32_is_index_reg (x, strict) && mode == QImode)
-+ return true;
-+
-+ return false;
-+}
-+
-+static bool
-+ubicom32_is_valid_offset (enum machine_mode mode, HOST_WIDE_INT offs)
-+{
-+ if (offs < 0)
-+ return false;
-+
-+ switch (mode)
-+ {
-+ case QImode:
-+ return offs <= 127;
-+
-+ case HImode:
-+ return offs <= 254;
-+
-+ case SImode:
-+ case SFmode:
-+ return offs <= 508;
-+
-+ case DImode:
-+ return offs <= 504;
-+
-+ default:
-+ return false;
-+ }
-+}
-+
-+static int
-+ubicom32_get_valid_offset_mask (enum machine_mode mode)
-+{
-+ switch (mode)
-+ {
-+ case QImode:
-+ return 127;
-+
-+ case HImode:
-+ return 255;
-+
-+ case SImode:
-+ case SFmode:
-+ return 511;
-+
-+ case DImode:
-+ return 255;
-+
-+ default:
-+ return 0;
-+ }
-+}
-+
-+/* Returns 1 if X is a valid base register. STRICT is 1 if only hard
-+ registers should be accepted. Accept either REG or SUBREG where a
-+ register is valid. */
-+
-+static bool
-+ubicom32_is_base_reg (rtx x, int strict)
-+{
-+ if ((REG_P (x) && ubicom32_regno_ok_for_base_p (REGNO (x), strict))
-+ || (GET_CODE (x) == SUBREG && REG_P (SUBREG_REG (x))
-+ && ubicom32_regno_ok_for_base_p (REGNO (SUBREG_REG (x)), strict)))
-+ return true;
-+
-+ return false;
-+}
-+
-+static bool
-+ubicom32_cannot_force_const_mem (rtx x ATTRIBUTE_UNUSED)
-+{
-+ return TARGET_FDPIC;
-+}
-+
-+/* Determine if X is a legitimate constant. */
-+
-+bool
-+ubicom32_legitimate_constant_p (rtx x)
-+{
-+ /* Among its other duties, LEGITIMATE_CONSTANT_P decides whether
-+ a constant can be entered into reg_equiv_constant[]. If we return true,
-+ reload can create new instances of the constant whenever it likes.
-+
-+ The idea is therefore to accept as many constants as possible (to give
-+ reload more freedom) while rejecting constants that can only be created
-+ at certain times. In particular, anything with a symbolic component will
-+ require use of the pseudo FDPIC register, which is only available before
-+ reload. */
-+ if (TARGET_FDPIC)
-+ {
-+ if (GET_CODE (x) == SYMBOL_REF
-+ || (GET_CODE (x) == CONST
-+ && GET_CODE (XEXP (x, 0)) == PLUS
-+ && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF)
-+ || CONSTANT_ADDRESS_P (x))
-+ return false;
-+
-+ return true;
-+ }
-+
-+ /* For non-PIC code anything goes! */
-+ return true;
-+}
-+
-+/* Address validation. */
-+
-+bool
-+ubicom32_legitimate_address_p (enum machine_mode mode, rtx x, int strict)
-+{
-+ if (TARGET_DEBUG_ADDRESS)
-+ {
-+ fprintf (stderr, "\n==> GO_IF_LEGITIMATE_ADDRESS%s\n",
-+ (strict) ? " (STRICT)" : "");
-+ debug_rtx (x);
-+ }
-+
-+ if (CONSTANT_ADDRESS_P (x))
-+ return false;
-+
-+ if (ubicom32_is_base_reg (x, strict))
-+ return true;
-+
-+ if ((GET_CODE (x) == POST_INC
-+ || GET_CODE (x) == PRE_INC
-+ || GET_CODE (x) == POST_DEC
-+ || GET_CODE (x) == PRE_DEC)
-+ && REG_P (XEXP (x, 0))
-+ && ubicom32_is_base_reg (XEXP (x, 0), strict)
-+ && mode != DImode)
-+ return true;
-+
-+ if ((GET_CODE (x) == PRE_MODIFY || GET_CODE (x) == POST_MODIFY)
-+ && ubicom32_is_base_reg (XEXP (x, 0), strict)
-+ && GET_CODE (XEXP (x, 1)) == PLUS
-+ && rtx_equal_p (XEXP (x, 0), XEXP (XEXP (x, 1), 0))
-+ && CONST_INT_P (XEXP (XEXP (x, 1), 1))
-+ && mode != DImode)
-+ {
-+ HOST_WIDE_INT disp = INTVAL (XEXP (XEXP (x, 1), 1));
-+ switch (mode)
-+ {
-+ case QImode:
-+ return disp >= -8 && disp <= 7;
-+
-+ case HImode:
-+ return disp >= -16 && disp <= 14 && ! (disp & 1);
-+
-+ case SImode:
-+ return disp >= -32 && disp <= 28 && ! (disp & 3);
-+
-+ default:
-+ return false;
-+ }
-+ }
-+
-+ /* Accept base + index * scale. */
-+ if (GET_CODE (x) == PLUS
-+ && ubicom32_is_base_reg (XEXP (x, 0), strict)
-+ && ubicom32_is_index_expr (mode, XEXP (x, 1), strict))
-+ return true;
-+
-+ /* Accept index * scale + base. */
-+ if (GET_CODE (x) == PLUS
-+ && ubicom32_is_base_reg (XEXP (x, 1), strict)
-+ && ubicom32_is_index_expr (mode, XEXP (x, 0), strict))
-+ return true;
-+
-+ if (! TARGET_FDPIC)
-+ {
-+ /* Accept (lo_sum (reg) (symbol_ref)) that can be used as a mem+7bits
-+ displacement operand:
-+
-+ moveai a1, #%hi(SYM)
-+ move.4 d3, %lo(SYM)(a1) */
-+ if (GET_CODE (x) == LO_SUM
-+ && ubicom32_is_base_reg (XEXP (x, 0), strict)
-+ && (GET_CODE (XEXP (x, 1)) == SYMBOL_REF
-+ || GET_CODE (XEXP (x, 1)) == LABEL_REF /* FIXME: wrong */)
-+ && mode != DImode)
-+ return true;
-+ }
-+
-+ if (TARGET_DEBUG_ADDRESS)
-+ fprintf (stderr, "\nNot a legitimate address.\n");
-+
-+ return false;
-+}
-+
-+rtx
-+ubicom32_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
-+ enum machine_mode mode)
-+{
-+ if (mode == BLKmode)
-+ return NULL_RTX;
-+
-+ if (GET_CODE (x) == PLUS
-+ && REG_P (XEXP (x, 0))
-+ && ! REGNO_PTR_FRAME_P (REGNO (XEXP (x, 0)))
-+ && CONST_INT_P (XEXP (x, 1))
-+ && ! ubicom32_is_valid_offset (mode, INTVAL (XEXP (x, 1))))
-+ {
-+ rtx base;
-+ rtx plus;
-+ rtx new_rtx;
-+ HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
-+ HOST_WIDE_INT low = val & ubicom32_get_valid_offset_mask (mode);
-+ HOST_WIDE_INT high = val ^ low;
-+
-+ if (val < 0)
-+ return NULL_RTX;
-+
-+ if (! low)
-+ return NULL_RTX;
-+
-+ /* Reload the high part into a base reg; leave the low part
-+ in the mem directly. */
-+ base = XEXP (x, 0);
-+ if (! ubicom32_is_base_reg (base, 0))
-+ base = copy_to_mode_reg (Pmode, base);
-+
-+ plus = expand_simple_binop (Pmode, PLUS,
-+ gen_int_mode (high, Pmode),
-+ base, NULL, 0, OPTAB_WIDEN);
-+ new_rtx = plus_constant (plus, low);
-+
-+ return new_rtx;
-+ }
-+
-+ return NULL_RTX;
-+}
-+
-+/* Try a machine-dependent way of reloading an illegitimate address AD
-+ operand. If we find one, push the reload and and return the new address.
-+
-+ MODE is the mode of the enclosing MEM. OPNUM is the operand number
-+ and TYPE is the reload type of the current reload. */
-+
-+rtx
-+ubicom32_legitimize_reload_address (rtx ad, enum machine_mode mode,
-+ int opnum, int type)
-+{
-+ /* Is this an address that we've already fixed up? If it is then
-+ recognize it and move on. */
-+ if (GET_CODE (ad) == PLUS
-+ && GET_CODE (XEXP (ad, 0)) == PLUS
-+ && REG_P (XEXP (XEXP (ad, 0), 0))
-+ && CONST_INT_P (XEXP (XEXP (ad, 0), 1))
-+ && CONST_INT_P (XEXP (ad, 1)))
-+ {
-+ push_reload (XEXP (ad, 0), NULL_RTX, &XEXP (ad, 0), NULL,
-+ BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
-+ opnum, (enum reload_type) type);
-+ return ad;
-+ }
-+
-+ /* Have we got an address where the offset is simply out of range? If
-+ yes then reload the range as a high part and smaller offset. */
-+ if (GET_CODE (ad) == PLUS
-+ && REG_P (XEXP (ad, 0))
-+ && REGNO (XEXP (ad, 0)) < FIRST_PSEUDO_REGISTER
-+ && REGNO_OK_FOR_BASE_P (REGNO (XEXP (ad, 0)))
-+ && CONST_INT_P (XEXP (ad, 1))
-+ && ! ubicom32_is_valid_offset (mode, INTVAL (XEXP (ad, 1))))
-+ {
-+ rtx temp;
-+ rtx new_rtx;
-+
-+ HOST_WIDE_INT val = INTVAL (XEXP (ad, 1));
-+ HOST_WIDE_INT low = val & ubicom32_get_valid_offset_mask (mode);
-+ HOST_WIDE_INT high = val ^ low;
-+
-+ /* Reload the high part into a base reg; leave the low part
-+ in the mem directly. */
-+ temp = gen_rtx_PLUS (Pmode, XEXP (ad, 0), GEN_INT (high));
-+ new_rtx = gen_rtx_PLUS (Pmode, temp, GEN_INT (low));
-+
-+ push_reload (XEXP (new_rtx, 0), NULL_RTX, &XEXP (new_rtx, 0), NULL,
-+ BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
-+ opnum, (enum reload_type) type);
-+ return new_rtx;
-+ }
-+
-+ /* If we're presented with an pre/post inc/dec then we must force this
-+ to be done in an address register. The register allocator should
-+ work this out for itself but at times ends up trying to use the wrong
-+ class. If we get the wrong class then reload will end up generating
-+ at least 3 instructions whereas this way we can hopefully keep it to
-+ just 2. */
-+ if ((GET_CODE (ad) == POST_INC
-+ || GET_CODE (ad) == PRE_INC
-+ || GET_CODE (ad) == POST_DEC
-+ || GET_CODE (ad) == PRE_DEC)
-+ && REG_P (XEXP (ad, 0))
-+ && REGNO (XEXP (ad, 0)) < FIRST_PSEUDO_REGISTER
-+ && ! REGNO_OK_FOR_BASE_P (REGNO (XEXP (ad, 0))))
-+ {
-+ push_reload (XEXP (ad, 0), XEXP (ad, 0), &XEXP (ad, 0), &XEXP (ad, 0),
-+ BASE_REG_CLASS, GET_MODE (XEXP (ad, 0)), GET_MODE (XEXP (ad, 0)), 0, 0,
-+ opnum, RELOAD_OTHER);
-+ return ad;
-+ }
-+
-+ return NULL_RTX;
-+}
-+
-+/* Compute a (partial) cost for rtx X. Return true if the complete
-+ cost has been computed, and false if subexpressions should be
-+ scanned. In either case, *TOTAL contains the cost result. */
-+
-+static bool
-+ubicom32_rtx_costs (rtx x, int code, int outer_code, int *total,
-+ bool speed ATTRIBUTE_UNUSED)
-+{
-+ enum machine_mode mode = GET_MODE (x);
-+
-+ switch (code)
-+ {
-+ case CONST_INT:
-+ /* Very short constants often fold into instructions so
-+ we pretend that they don't cost anything! This is
-+ really important as regards zero values as otherwise
-+ the compiler has a nasty habit of wanting to reuse
-+ zeroes that are in regs but that tends to pessimize
-+ the code. */
-+ if (satisfies_constraint_I (x))
-+ {
-+ *total = 0;
-+ return true;
-+ }
-+
-+ /* Bit clearing costs nothing */
-+ if (outer_code == AND
-+ && exact_log2 (~INTVAL (x)) != -1)
-+ {
-+ *total = 0;
-+ return true;
-+ }
-+
-+ /* Masking the lower set of bits costs nothing. */
-+ if (outer_code == AND
-+ && exact_log2 (INTVAL (x) + 1) != -1)
-+ {
-+ *total = 0;
-+ return true;
-+ }
-+
-+ /* Bit setting costs nothing. */
-+ if (outer_code == IOR
-+ && exact_log2 (INTVAL (x)) != -1)
-+ {
-+ *total = 0;
-+ return true;
-+ }
-+
-+ /* Larger constants that can be loaded via movei aren't too
-+ bad. If we're just doing a set they cost nothing extra. */
-+ if (satisfies_constraint_N (x))
-+ {
-+ if (mode == DImode)
-+ *total = COSTS_N_INSNS (2);
-+ else
-+ *total = COSTS_N_INSNS (1);
-+ return true;
-+ }
-+
-+ if (mode == DImode)
-+ *total = COSTS_N_INSNS (5);
-+ else
-+ *total = COSTS_N_INSNS (3);
-+ return true;
-+
-+ case CONST_DOUBLE:
-+ /* We don't optimize CONST_DOUBLEs well nor do we relax them well,
-+ so their cost is very high. */
-+ *total = COSTS_N_INSNS (6);
-+ return true;
-+
-+ case CONST:
-+ case SYMBOL_REF:
-+ case MEM:
-+ *total = 0;
-+ return true;
-+
-+ case IF_THEN_ELSE:
-+ *total = COSTS_N_INSNS (1);
-+ return true;
-+
-+ case LABEL_REF:
-+ case HIGH:
-+ case LO_SUM:
-+ case BSWAP:
-+ case PLUS:
-+ case MINUS:
-+ case AND:
-+ case IOR:
-+ case XOR:
-+ case ASHIFT:
-+ case ASHIFTRT:
-+ case LSHIFTRT:
-+ case NEG:
-+ case NOT:
-+ case SIGN_EXTEND:
-+ case ZERO_EXTEND:
-+ case ZERO_EXTRACT:
-+ if (outer_code == SET)
-+ {
-+ if (mode == DImode)
-+ *total = COSTS_N_INSNS (2);
-+ else
-+ *total = COSTS_N_INSNS (1);
-+ }
-+ return true;
-+
-+ case COMPARE:
-+ if (outer_code == SET)
-+ {
-+ if (GET_MODE (XEXP (x, 0)) == DImode
-+ || GET_MODE (XEXP (x, 1)) == DImode)
-+ *total = COSTS_N_INSNS (2);
-+ else
-+ *total = COSTS_N_INSNS (1);
-+ }
-+ return true;
-+
-+ case UMOD:
-+ case UDIV:
-+ case MOD:
-+ case DIV:
-+ if (outer_code == SET)
-+ {
-+ if (mode == DImode)
-+ *total = COSTS_N_INSNS (600);
-+ else
-+ *total = COSTS_N_INSNS (200);
-+ }
-+ return true;
-+
-+ case MULT:
-+ if (outer_code == SET)
-+ {
-+ if (! ubicom32_v4)
-+ {
-+ if (mode == DImode)
-+ *total = COSTS_N_INSNS (15);
-+ else
-+ *total = COSTS_N_INSNS (5);
-+ }
-+ else
-+ {
-+ if (mode == DImode)
-+ *total = COSTS_N_INSNS (6);
-+ else
-+ *total = COSTS_N_INSNS (2);
-+ }
-+ }
-+ return true;
-+
-+ case UNSPEC:
-+ if (XINT (x, 1) == UNSPEC_FDPIC_GOT
-+ || XINT (x, 1) == UNSPEC_FDPIC_GOT_FUNCDESC)
-+ *total = 0;
-+ return true;
-+
-+ default:
-+ return false;
-+ }
-+}
-+
-+/* Return 1 if ADDR can have different meanings depending on the machine
-+ mode of the memory reference it is used for or if the address is
-+ valid for some modes but not others.
-+
-+ Autoincrement and autodecrement addresses typically have
-+ mode-dependent effects because the amount of the increment or
-+ decrement is the size of the operand being addressed. Some machines
-+ have other mode-dependent addresses. Many RISC machines have no
-+ mode-dependent addresses.
-+
-+ You may assume that ADDR is a valid address for the machine. */
-+
-+int
-+ubicom32_mode_dependent_address_p (rtx addr)
-+{
-+ if (GET_CODE (addr) == POST_INC
-+ || GET_CODE (addr) == PRE_INC
-+ || GET_CODE (addr) == POST_DEC
-+ || GET_CODE (addr) == PRE_DEC
-+ || GET_CODE (addr) == POST_MODIFY
-+ || GET_CODE (addr) == PRE_MODIFY)
-+ return 1;
-+
-+ return 0;
-+}
-+
-+static void
-+ubicom32_function_prologue (FILE *file, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
-+{
-+ fprintf (file, "/* frame/pretend: %ld/%d save_regs: %d out_args: %d %s */\n",
-+ get_frame_size (), crtl->args.pretend_args_size,
-+ save_regs_size, crtl->outgoing_args_size,
-+ current_function_is_leaf ? "leaf" : "nonleaf");
-+}
-+
-+static void
-+ubicom32_function_epilogue (FILE *file ATTRIBUTE_UNUSED,
-+ HOST_WIDE_INT size ATTRIBUTE_UNUSED)
-+{
-+ ubicom32_reorg_completed = 0;
-+}
-+
-+static void
-+ubicom32_machine_dependent_reorg (void)
-+{
-+#if 0 /* Commenting out this optimization until it is fixed */
-+ if (optimize)
-+ {
-+ compute_bb_for_insn ();
-+
-+ /* Do a very simple CSE pass over just the hard registers. */
-+ reload_cse_regs (get_insns ());
-+
-+ /* Reload_cse_regs can eliminate potentially-trapping MEMs.
-+ Remove any EH edges associated with them. */
-+ if (flag_non_call_exceptions)
-+ purge_all_dead_edges ();
-+ }
-+#endif
-+ ubicom32_reorg_completed = 1;
-+}
-+
-+void
-+ubicom32_output_cond_jump (rtx insn, rtx cond, rtx target)
-+{
-+ rtx note;
-+ int mostly_false_jump;
-+ rtx xoperands[2];
-+ rtx cc_reg;
-+
-+ note = find_reg_note (insn, REG_BR_PROB, 0);
-+ mostly_false_jump = !note || (INTVAL (XEXP (note, 0))
-+ <= REG_BR_PROB_BASE / 2);
-+
-+ xoperands[0] = target;
-+ xoperands[1] = cond;
-+ cc_reg = XEXP (cond, 0);
-+
-+ if (GET_MODE (cc_reg) == CCWmode
-+ || GET_MODE (cc_reg) == CCWZmode
-+ || GET_MODE (cc_reg) == CCWZNmode)
-+ {
-+ if (mostly_false_jump)
-+ output_asm_insn ("jmp%b1.w.f\t%0", xoperands);
-+ else
-+ output_asm_insn ("jmp%b1.w.t\t%0", xoperands);
-+ return;
-+ }
-+
-+ if (GET_MODE (cc_reg) == CCSmode
-+ || GET_MODE (cc_reg) == CCSZmode
-+ || GET_MODE (cc_reg) == CCSZNmode)
-+ {
-+ if (mostly_false_jump)
-+ output_asm_insn ("jmp%b1.s.f\t%0", xoperands);
-+ else
-+ output_asm_insn ("jmp%b1.s.t\t%0", xoperands);
-+ return;
-+ }
-+
-+ abort ();
-+}
-+
-+/* Return non-zero if FUNC is a naked function. */
-+
-+static int
-+ubicom32_naked_function_p (void)
-+{
-+ return lookup_attribute ("naked", DECL_ATTRIBUTES (current_function_decl)) != NULL_TREE;
-+}
-+
-+/* Return an RTX indicating where the return address to the
-+ calling function can be found. */
-+rtx
-+ubicom32_return_addr_rtx (int count, rtx frame ATTRIBUTE_UNUSED)
-+{
-+ if (count != 0)
-+ return NULL_RTX;
-+
-+ return get_hard_reg_initial_val (Pmode, LINK_REGNO);
-+}
-+
-+/*
-+ * ubicom32_readonly_data_section: This routtine handles code
-+ * at the start of readonly data sections
-+ */
-+static void
-+ubicom32_readonly_data_section (const void *data ATTRIBUTE_UNUSED)
-+{
-+ static int num = 0;
-+ if (in_section == readonly_data_section){
-+ fprintf (asm_out_file, "%s", DATA_SECTION_ASM_OP);
-+ if (flag_data_sections){
-+ fprintf (asm_out_file, ".rodata%d", num);
-+ fprintf (asm_out_file, ",\"a\"");
-+ }
-+ fprintf (asm_out_file, "\n");
-+ }
-+ num++;
-+}
-+
-+/*
-+ * ubicom32_text_section: not in readonly section
-+ */
-+static void
-+ubicom32_text_section(const void *data ATTRIBUTE_UNUSED)
-+{
-+ fprintf (asm_out_file, "%s\n", TEXT_SECTION_ASM_OP);
-+}
-+
-+/*
-+ * ubicom32_data_section: not in readonly section
-+ */
-+static void
-+ubicom32_data_section(const void *data ATTRIBUTE_UNUSED)
-+{
-+ fprintf (asm_out_file, "%s\n", DATA_SECTION_ASM_OP);
-+}
-+
-+/*
-+ * ubicom32_asm_init_sections: This routine implements special
-+ * section handling
-+ */
-+static void
-+ubicom32_asm_init_sections(void)
-+{
-+ text_section = get_unnamed_section(SECTION_CODE, ubicom32_text_section, NULL);
-+
-+ data_section = get_unnamed_section(SECTION_WRITE, ubicom32_data_section, NULL);
-+
-+ readonly_data_section = get_unnamed_section(0, ubicom32_readonly_data_section, NULL);
-+}
-+
-+/*
-+ * ubicom32_profiler: This routine would call
-+ * mcount to support prof and gprof if mcount
-+ * was supported. Currently, do nothing.
-+ */
-+void
-+ubicom32_profiler(void)
-+{
-+}
-+
-+/* Initialise the builtin functions. Start by initialising
-+ descriptions of different types of functions (e.g., void fn(int),
-+ int fn(void)), and then use these to define the builtins. */
-+static void
-+ubicom32_init_builtins (void)
-+{
-+ tree endlink;
-+ tree short_unsigned_endlink;
-+ tree unsigned_endlink;
-+ tree short_unsigned_ftype_short_unsigned;
-+ tree unsigned_ftype_unsigned;
-+
-+ endlink = void_list_node;
-+
-+ short_unsigned_endlink
-+ = tree_cons (NULL_TREE, short_unsigned_type_node, endlink);
-+
-+ unsigned_endlink
-+ = tree_cons (NULL_TREE, unsigned_type_node, endlink);
-+
-+ short_unsigned_ftype_short_unsigned
-+ = build_function_type (short_unsigned_type_node, short_unsigned_endlink);
-+
-+ unsigned_ftype_unsigned
-+ = build_function_type (unsigned_type_node, unsigned_endlink);
-+
-+ /* Initialise the byte swap function. */
-+ add_builtin_function ("__builtin_ubicom32_swapb_2",
-+ short_unsigned_ftype_short_unsigned,
-+ UBICOM32_BUILTIN_UBICOM32_SWAPB_2,
-+ BUILT_IN_MD, NULL,
-+ NULL_TREE);
-+
-+ /* Initialise the byte swap function. */
-+ add_builtin_function ("__builtin_ubicom32_swapb_4",
-+ unsigned_ftype_unsigned,
-+ UBICOM32_BUILTIN_UBICOM32_SWAPB_4,
-+ BUILT_IN_MD, NULL,
-+ NULL_TREE);
-+}
-+
-+/* Given a builtin function taking 2 operands (i.e., target + source),
-+ emit the RTL for the underlying instruction. */
-+static rtx
-+ubicom32_expand_builtin_2op (enum insn_code icode, tree arglist, rtx target)
-+{
-+ tree arg0;
-+ rtx op0, pat;
-+ enum machine_mode tmode, mode0;
-+
-+ /* Grab the incoming argument and emit its RTL. */
-+ arg0 = TREE_VALUE (arglist);
-+ op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
-+
-+ /* Determine the modes of the instruction operands. */
-+ tmode = insn_data[icode].operand[0].mode;
-+ mode0 = insn_data[icode].operand[1].mode;
-+
-+ /* Ensure that the incoming argument RTL is in a register of the
-+ correct mode. */
-+ if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
-+ op0 = copy_to_mode_reg (mode0, op0);
-+
-+ /* If there isn't a suitable target, emit a target register. */
-+ if (target == 0
-+ || GET_MODE (target) != tmode
-+ || !(*insn_data[icode].operand[0].predicate) (target, tmode))
-+ target = gen_reg_rtx (tmode);
-+
-+ /* Emit and return the new instruction. */
-+ pat = GEN_FCN (icode) (target, op0);
-+ if (!pat)
-+ return 0;
-+ emit_insn (pat);
-+
-+ return target;
-+}
-+
-+/* Expand a call to a builtin function. */
-+static rtx
-+ubicom32_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
-+ enum machine_mode mode ATTRIBUTE_UNUSED,
-+ int ignore ATTRIBUTE_UNUSED)
-+{
-+ tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
-+ tree arglist = CALL_EXPR_ARGS(exp);
-+ int fcode = DECL_FUNCTION_CODE (fndecl);
-+
-+ switch (fcode)
-+ {
-+ case UBICOM32_BUILTIN_UBICOM32_SWAPB_2:
-+ return ubicom32_expand_builtin_2op (CODE_FOR_bswaphi, arglist, target);
-+
-+ case UBICOM32_BUILTIN_UBICOM32_SWAPB_4:
-+ return ubicom32_expand_builtin_2op (CODE_FOR_bswapsi, arglist, target);
-+
-+ default:
-+ gcc_unreachable();
-+ }
-+
-+ /* Should really do something sensible here. */
-+ return NULL_RTX;
-+}
-+
-+/* Fold any constant argument for a swapb.2 instruction. */
-+static tree
-+ubicom32_fold_builtin_ubicom32_swapb_2 (tree fndecl, tree arglist)
-+{
-+ tree arg0;
-+
-+ arg0 = TREE_VALUE (arglist);
-+
-+ /* Optimize constant value. */
-+ if (TREE_CODE (arg0) == INTEGER_CST)
-+ {
-+ HOST_WIDE_INT v;
-+ HOST_WIDE_INT res;
-+
-+ v = TREE_INT_CST_LOW (arg0);
-+ res = ((v >> 8) & 0xff)
-+ | ((v & 0xff) << 8);
-+
-+ return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), res);
-+ }
-+
-+ return NULL_TREE;
-+}
-+
-+/* Fold any constant argument for a swapb.4 instruction. */
-+static tree
-+ubicom32_fold_builtin_ubicom32_swapb_4 (tree fndecl, tree arglist)
-+{
-+ tree arg0;
-+
-+ arg0 = TREE_VALUE (arglist);
-+
-+ /* Optimize constant value. */
-+ if (TREE_CODE (arg0) == INTEGER_CST)
-+ {
-+ unsigned HOST_WIDE_INT v;
-+ unsigned HOST_WIDE_INT res;
-+
-+ v = TREE_INT_CST_LOW (arg0);
-+ res = ((v >> 24) & 0xff)
-+ | (((v >> 16) & 0xff) << 8)
-+ | (((v >> 8) & 0xff) << 16)
-+ | ((v & 0xff) << 24);
-+
-+ return build_int_cst_wide (TREE_TYPE (TREE_TYPE (fndecl)), res, 0);
-+ }
-+
-+ return NULL_TREE;
-+}
-+
-+/* Fold any constant arguments for builtin functions. */
-+static tree
-+ubicom32_fold_builtin (tree fndecl, tree arglist, bool ignore ATTRIBUTE_UNUSED)
-+{
-+ switch (DECL_FUNCTION_CODE (fndecl))
-+ {
-+ case UBICOM32_BUILTIN_UBICOM32_SWAPB_2:
-+ return ubicom32_fold_builtin_ubicom32_swapb_2 (fndecl, arglist);
-+
-+ case UBICOM32_BUILTIN_UBICOM32_SWAPB_4:
-+ return ubicom32_fold_builtin_ubicom32_swapb_4 (fndecl, arglist);
-+
-+ default:
-+ return NULL;
-+ }
-+}
-+
-+/* Implementation of TARGET_ASM_INTEGER. When using FD-PIC, we need to
-+ tell the assembler to generate pointers to function descriptors in
-+ some cases. */
-+static bool
-+ubicom32_assemble_integer (rtx value, unsigned int size, int aligned_p)
-+{
-+ if (TARGET_FDPIC && size == UNITS_PER_WORD)
-+ {
-+ if (GET_CODE (value) == SYMBOL_REF
-+ && SYMBOL_REF_FUNCTION_P (value))
-+ {
-+ fputs ("\t.picptr\t%funcdesc(", asm_out_file);
-+ output_addr_const (asm_out_file, value);
-+ fputs (")\n", asm_out_file);
-+ return true;
-+ }
-+
-+ if (!aligned_p)
-+ {
-+ /* We've set the unaligned SI op to NULL, so we always have to
-+ handle the unaligned case here. */
-+ assemble_integer_with_op ("\t.4byte\t", value);
-+ return true;
-+ }
-+ }
-+
-+ return default_assemble_integer (value, size, aligned_p);
-+}
-+
-+/* If the constant I can be constructed by shifting a source-1 immediate
-+ by a constant number of bits then return the bit count. If not
-+ return 0. */
-+
-+int
-+ubicom32_shiftable_const_int (int i)
-+{
-+ int shift = 0;
-+
-+ /* Note that any constant that can be represented as an immediate to
-+ a movei instruction is automatically ignored here in the interests
-+ of the clarity of the output asm code. */
-+ if (i >= -32768 && i <= 32767)
-+ return 0;
-+
-+ /* Find the number of trailing zeroes. We could use __builtin_ctz
-+ here but it's not obvious if this is supported on all build
-+ compilers so we err on the side of caution. */
-+ if ((i & 0xffff) == 0)
-+ {
-+ shift += 16;
-+ i >>= 16;
-+ }
-+
-+ if ((i & 0xff) == 0)
-+ {
-+ shift += 8;
-+ i >>= 8;
-+ }
-+
-+ if ((i & 0xf) == 0)
-+ {
-+ shift += 4;
-+ i >>= 4;
-+ }
-+
-+ if ((i & 0x3) == 0)
-+ {
-+ shift += 2;
-+ i >>= 2;
-+ }
-+
-+ if ((i & 0x1) == 0)
-+ {
-+ shift += 1;
-+ i >>= 1;
-+ }
-+
-+ if (i >= -128 && i <= 127)
-+ return shift;
-+
-+ return 0;
-+}
-+
---- /dev/null
-+++ b/gcc/config/ubicom32/ubicom32.h
-@@ -0,0 +1,1564 @@
-+/* Definitions of target machine for Ubicom32
-+
-+ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
-+ 2009 Free Software Foundation, Inc.
-+ Contributed by Ubicom, Inc.
-+
-+ This file is part of GCC.
-+
-+ GCC is free software; you can redistribute it and/or modify it
-+ under the terms of the GNU General Public License as published
-+ by the Free Software Foundation; either version 3, or (at your
-+ option) any later version.
-+
-+ GCC is distributed in the hope that it will be useful, but WITHOUT
-+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
-+ License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with GCC; see the file COPYING3. If not see
-+ <http://www.gnu.org/licenses/>. */
-+
-+\f
-+
-+#define OBJECT_FORMAT_ELF
-+
-+/* Run-time target specifications. */
-+
-+/* Target CPU builtins. */
-+#define TARGET_CPU_CPP_BUILTINS() \
-+ do \
-+ { \
-+ builtin_define_std ("__UBICOM32__"); \
-+ builtin_define_std ("__ubicom32__"); \
-+ \
-+ if (TARGET_FDPIC) \
-+ { \
-+ builtin_define ("__UBICOM32_FDPIC__"); \
-+ builtin_define ("__FDPIC__"); \
-+ } \
-+ } \
-+ while (0)
-+
-+#ifndef TARGET_DEFAULT
-+#define TARGET_DEFAULT 0
-+#endif
-+
-+extern int ubicom32_case_values_threshold;
-+
-+/* Nonzero if this chip supports the Ubicom32 v3 ISA. */
-+extern int ubicom32_v3;
-+
-+/* Nonzero if this chip supports the Ubicom32 v4 ISA. */
-+extern int ubicom32_v4;
-+
-+extern int ubicom32_stack_size;
-+
-+/* Flag for whether we can use calli instead of ret in returns. */
-+extern int ubicom32_can_use_calli_to_ret;
-+
-+/* This macro is a C statement to print on `stderr' a string describing the
-+ particular machine description choice. Every machine description should
-+ define `TARGET_VERSION'. */
-+#define TARGET_VERSION fprintf (stderr, " (UBICOM32)");
-+
-+/* We don't need a frame pointer to debug things. Doing this means
-+ that gcc can turn on -fomit-frame-pointer when '-O' is specified. */
-+#define CAN_DEBUG_WITHOUT_FP
-+
-+/* We need to handle processor-specific options. */
-+#define OVERRIDE_OPTIONS ubicom32_override_options ()
-+
-+#define OPTIMIZATION_OPTIONS(LEVEL, SIZE) \
-+ ubicom32_optimization_options (LEVEL, SIZE)
-+
-+/* For Ubicom32 the least significant bit has the lowest bit number
-+ so we define this to be 0. */
-+#define BITS_BIG_ENDIAN 0
-+
-+/* For Ubicom32 the most significant byte in a word has the lowest
-+ number. */
-+#define BYTES_BIG_ENDIAN 1
-+
-+/* For Ubicom32, in a multiword object, the most signifant word has the
-+ lowest number. */
-+#define WORDS_BIG_ENDIAN 1
-+
-+/* Ubicom32 has 8 bits per byte. */
-+#define BITS_PER_UNIT 8
-+
-+/* Ubicom32 has 32 bits per word. */
-+#define BITS_PER_WORD 32
-+
-+/* Width of a word, in units (bytes). */
-+#define UNITS_PER_WORD 4
-+
-+/* Width of a pointer, in bits. */
-+#define POINTER_SIZE 32
-+
-+/* Alias for pointers. Ubicom32 is a 32-bit architecture so we use
-+ SImode. */
-+#define Pmode SImode
-+
-+/* Normal alignment required for function parameters on the stack, in
-+ bits. */
-+#define PARM_BOUNDARY 32
-+
-+/* We need to maintain the stack on a 32-bit boundary. */
-+#define STACK_BOUNDARY 32
-+
-+/* Alignment required for a function entry point, in bits. */
-+#define FUNCTION_BOUNDARY 32
-+
-+/* Alias for the machine mode used for memory references to functions being
-+ called, in `call' RTL expressions. We use byte-oriented addresses
-+ here. */
-+#define FUNCTION_MODE QImode
-+
-+/* Biggest alignment that any data type can require on this machine,
-+ in bits. */
-+#define BIGGEST_ALIGNMENT 32
-+
-+/* this default to BIGGEST_ALIGNMENT unless defined */
-+/* ART: What's the correct value here? Default is (((unsigned int)1<<28)*8)*/
-+#undef MAX_OFILE_ALIGNMENT
-+#define MAX_OFILE_ALIGNMENT (128 * 8)
-+
-+/* Alignment in bits to be given to a structure bit field that follows an empty
-+ field such as `int : 0;'. */
-+#define EMPTY_FIELD_BOUNDARY 32
-+
-+/* All structures must be a multiple of 32 bits in size. */
-+#define STRUCTURE_SIZE_BOUNDARY 32
-+
-+/* A bit-field declared as `int' forces `int' alignment for the struct. */
-+#define PCC_BITFIELD_TYPE_MATTERS 1
-+
-+/* For Ubicom32 we absolutely require that data be aligned with nominal
-+ alignment. */
-+#define STRICT_ALIGNMENT 1
-+
-+/* Make strcpy of constants fast. */
-+#define CONSTANT_ALIGNMENT(EXP, ALIGN) \
-+ (TREE_CODE (EXP) == STRING_CST \
-+ && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
-+
-+/* Define this macro as an expression for the alignment of a structure
-+ (given by STRUCT as a tree node) if the alignment computed in the
-+ usual way is COMPUTED and the alignment explicitly specified was
-+ SPECIFIED. */
-+#define DATA_ALIGNMENT(TYPE, ALIGN) \
-+ ((((ALIGN) < BITS_PER_WORD) \
-+ && (TREE_CODE (TYPE) == ARRAY_TYPE \
-+ || TREE_CODE (TYPE) == UNION_TYPE \
-+ || TREE_CODE (TYPE) == RECORD_TYPE)) ? BITS_PER_WORD : (ALIGN))
-+
-+#define LOCAL_ALIGNMENT(TYPE,ALIGN) DATA_ALIGNMENT(TYPE,ALIGN)
-+
-+/* For Ubicom32 we default to unsigned chars. */
-+#define DEFAULT_SIGNED_CHAR 0
-+
-+/* Machine-specific data register numbers. */
-+#define FIRST_DATA_REGNUM 0
-+#define D10_REGNUM 10
-+#define D11_REGNUM 11
-+#define D12_REGNUM 12
-+#define D13_REGNUM 13
-+#define LAST_DATA_REGNUM 15
-+
-+/* Machine-specific address register numbers. */
-+#define FIRST_ADDRESS_REGNUM 16
-+#define LAST_ADDRESS_REGNUM 22
-+
-+/* Register numbers used for passing a function's static chain pointer. If
-+ register windows are used, the register number as seen by the called
-+ function is `STATIC_CHAIN_INCOMING_REGNUM', while the register number as
-+ seen by the calling function is `STATIC_CHAIN_REGNUM'. If these registers
-+ are the same, `STATIC_CHAIN_INCOMING_REGNUM' need not be defined.
-+
-+ The static chain register need not be a fixed register.
-+
-+ If the static chain is passed in memory, these macros should not be defined;
-+ instead, the next two macros should be defined. */
-+#define STATIC_CHAIN_REGNUM (FIRST_ADDRESS_REGNUM + 1)
-+
-+/* The register number of the frame pointer register, which is used to access
-+ automatic variables in the stack frame. We generally eliminate this anyway
-+ for Ubicom32 but we make it A6 by default. */
-+#define FRAME_POINTER_REGNUM (LAST_ADDRESS_REGNUM)
-+
-+/* The register number of the stack pointer register, which is also be a
-+ fixed register according to `FIXED_REGISTERS'. For Ubicom32 we don't
-+ have a hardware requirement about which register this is, but by convention
-+ we use A7. */
-+#define STACK_POINTER_REGNUM (LAST_ADDRESS_REGNUM + 1)
-+
-+/* Machine-specific accumulator register numbers. */
-+#define ACC0_HI_REGNUM 24
-+#define ACC0_LO_REGNUM 25
-+#define ACC1_HI_REGNUM 26
-+#define ACC1_LO_REGNUM 27
-+
-+/* source3 register number */
-+#define SOURCE3_REGNUM 28
-+
-+/* The register number of the arg pointer register, which is used to access the
-+ function's argument list. On some machines, this is the same as the frame
-+ pointer register. On some machines, the hardware determines which register
-+ this is. On other machines, you can choose any register you wish for this
-+ purpose. If this is not the same register as the frame pointer register,
-+ then you must mark it as a fixed register according to `FIXED_REGISTERS', or
-+ arrange to be able to eliminate it. */
-+#define ARG_POINTER_REGNUM 29
-+
-+/* Pseudo-reg for condition code. */
-+#define CC_REGNUM 30
-+
-+/* Interrupt set/clear registers. */
-+#define INT_SET0_REGNUM 31
-+#define INT_SET1_REGNUM 32
-+#define INT_CLR0_REGNUM 33
-+#define INT_CLR1_REGNUM 34
-+
-+/* Scratchpad registers. */
-+#define SCRATCHPAD0_REGNUM 35
-+#define SCRATCHPAD1_REGNUM 36
-+#define SCRATCHPAD2_REGNUM 37
-+#define SCRATCHPAD3_REGNUM 38
-+
-+/* FDPIC register. */
-+#define FDPIC_REGNUM 16
-+
-+/* Number of hardware registers known to the compiler. They receive numbers 0
-+ through `FIRST_PSEUDO_REGISTER-1'; thus, the first pseudo register's number
-+ really is assigned the number `FIRST_PSEUDO_REGISTER'. */
-+#define FIRST_PSEUDO_REGISTER 39
-+
-+/* An initializer that says which registers are used for fixed purposes all
-+ throughout the compiled code and are therefore not available for general
-+ allocation. These would include the stack pointer, the frame pointer
-+ (except on machines where that can be used as a general register when no
-+ frame pointer is needed), the program counter on machines where that is
-+ considered one of the addressable registers, and any other numbered register
-+ with a standard use.
-+
-+ This information is expressed as a sequence of numbers, separated by commas
-+ and surrounded by braces. The Nth number is 1 if register N is fixed, 0
-+ otherwise.
-+
-+ The table initialized from this macro, and the table initialized by the
-+ following one, may be overridden at run time either automatically, by the
-+ actions of the macro `CONDITIONAL_REGISTER_USAGE', or by the user with the
-+ command options `-ffixed-REG', `-fcall-used-REG' and `-fcall-saved-REG'. */
-+#define FIXED_REGISTERS \
-+ { \
-+ 0, 0, 0, 0, 0, 0, 0, 0, /* d0 - d7 */ \
-+ 0, 0, 0, 0, 0, 0, 0, 1, /* d8 - d15 */ \
-+ 0, 0, 0, 0, 0, 0, 0, 1, /* a0 - a7 */ \
-+ 0, 0, /* acc0 hi/lo */ \
-+ 0, 0, /* acc1 hi/lo */ \
-+ 0, /* source3 */ \
-+ 1, /* arg */ \
-+ 1, /* cc */ \
-+ 1, 1, /* int_set[01] */ \
-+ 1, 1, /* int_clr[01] */ \
-+ 1, 1, 1, 1 /* scratchpad[0123] */ \
-+ }
-+
-+/* Like `FIXED_REGISTERS' but has 1 for each register that is clobbered (in
-+ general) by function calls as well as for fixed registers. This macro
-+ therefore identifies the registers that are not available for general
-+ allocation of values that must live across function calls.
-+
-+ If a register has 0 in `CALL_USED_REGISTERS', the compiler automatically
-+ saves it on function entry and restores it on function exit, if the register
-+ is used within the function. */
-+#define CALL_USED_REGISTERS \
-+ { \
-+ 1, 1, 1, 1, 1, 1, 1, 1, /* d0 - d7 */ \
-+ 1, 1, 0, 0, 0, 0, 1, 1, /* d8 - d15 */ \
-+ 1, 0, 0, 1, 1, 1, 0, 1, /* a0 - a7 */ \
-+ 1, 1, /* acc0 hi/lo */ \
-+ 1, 1, /* acc1 hi/lo */ \
-+ 1, /* source3 */ \
-+ 1, /* arg */ \
-+ 1, /* cc */ \
-+ 1, 1, /* int_set[01] */ \
-+ 1, 1, /* int_clr[01] */ \
-+ 1, 1, 1, 1 /* scratchpad[0123] */ \
-+ }
-+
-+/* How to refer to registers in assembler output.
-+ This sequence is indexed by compiler's hard-register-number (see above). */
-+
-+/* A C initializer containing the assembler's names for the machine registers,
-+ each one as a C string constant. This is what translates register numbers
-+ in the compiler into assembler language. */
-+#define REGISTER_NAMES \
-+ { \
-+ "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", \
-+ "d8", "d9", "d10", "d11", "d12", "d13", "d14", "d15", \
-+ "a0", "a1", "a2", "a3", "a4", "a5", "a6", "sp", \
-+ "acc0_hi", "acc0_lo", \
-+ "acc1_hi", "acc1_lo", \
-+ "source3", \
-+ "arg", \
-+ "cc", \
-+ "int_set0", "int_set1", \
-+ "int_clr0", "int_clr1", \
-+ "scratchpad0", "scratchpad1", "scratchpad2", "scratchpad3" \
-+ }
-+
-+#define CONDITIONAL_REGISTER_USAGE \
-+ ubicom32_conditional_register_usage ();
-+
-+/* Order of allocation of registers. */
-+
-+/* If defined, an initializer for a vector of integers, containing the numbers
-+ of hard registers in the order in which GNU CC should prefer to use them
-+ (from most preferred to least).
-+
-+ For Ubicom32 we try using caller-clobbered data registers first, then
-+ callee-saved data registers, then caller-clobbered address registers,
-+ then callee-saved address registers and finally everything else.
-+
-+ The caller-clobbered registers are usually slightly cheaper to use because
-+ there's no need to save/restore. */
-+#define REG_ALLOC_ORDER \
-+ { \
-+ 0, 1, 2, 3, 4, /* d0 - d4 */ \
-+ 5, 6, 7, 8, 9, /* d5 - d9 */ \
-+ 14, /* d14 */ \
-+ 10, 11, 12, 13, /* d10 - d13 */ \
-+ 19, 20, 16, 21, /* a3, a4, a0, a5 */ \
-+ 17, 18, 22, /* a1, a2, a6 */ \
-+ 24, 25, /* acc0 hi/lo */ \
-+ 26, 27, /* acc0 hi/lo */ \
-+ 28 /* source3 */ \
-+ }
-+
-+/* C expression for the number of consecutive hard registers, starting at
-+ register number REGNO, required to hold a value of mode MODE. */
-+#define HARD_REGNO_NREGS(REGNO, MODE) \
-+ ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
-+
-+/* Most registers can hold QImode, HImode and SImode values but we have to
-+ be able to indicate any hard registers that cannot hold values with some
-+ modes. */
-+#define HARD_REGNO_MODE_OK(REGNO, MODE) \
-+ ubicom32_hard_regno_mode_ok(REGNO, MODE)
-+
-+/* We can rename most registers aside from the FDPIC register if we're using
-+ FDPIC. */
-+#define HARD_REGNO_RENAME_OK(from, to) (TARGET_FDPIC ? ((to) != FDPIC_REGNUM) : 1)
-+
-+/* A C expression that is nonzero if it is desirable to choose register
-+ allocation so as to avoid move instructions between a value of mode MODE1
-+ and a value of mode MODE2.
-+
-+ If `HARD_REGNO_MODE_OK (R, MODE1)' and `HARD_REGNO_MODE_OK (R, MODE2)' are
-+ ever different for any R, then `MODES_TIEABLE_P (MODE1, MODE2)' must be
-+ zero. */
-+#define MODES_TIEABLE_P(MODE1, MODE2) 1
-+
-+/* An enumeral type that must be defined with all the register class names as
-+ enumeral values. `NO_REGS' must be first. `ALL_REGS' must be the last
-+ register class, followed by one more enumeral value, `LIM_REG_CLASSES',
-+ which is not a register class but rather tells how many classes there are.
-+
-+ Each register class has a number, which is the value of casting the class
-+ name to type `int'. The number serves as an index in many of the tables
-+ described below. */
-+
-+enum reg_class
-+{
-+ NO_REGS,
-+ DATA_REGS,
-+ FDPIC_REG,
-+ ADDRESS_REGS,
-+ ALL_ADDRESS_REGS,
-+ ACC_LO_REGS,
-+ ACC_REGS,
-+ CC_REG,
-+ DATA_ACC_REGS,
-+ SOURCE3_REG,
-+ SPECIAL_REGS,
-+ GENERAL_REGS,
-+ ALL_REGS,
-+ LIM_REG_CLASSES
-+};
-+
-+/* The number of distinct register classes. */
-+#define N_REG_CLASSES (int) LIM_REG_CLASSES
-+
-+/* An initializer containing the names of the register classes as C string
-+ constants. These names are used in writing some of the debugging dumps. */
-+
-+#define REG_CLASS_NAMES \
-+{ \
-+ "NO_REGS", \
-+ "DATA_REGS", \
-+ "FDPIC_REG", \
-+ "ADDRESS_REGS", \
-+ "ALL_ADDRESS_REGS", \
-+ "ACC_LO_REGS", \
-+ "ACC_REGS", \
-+ "CC_REG", \
-+ "DATA_ACC_REGS", \
-+ "SOURCE3_REG", \
-+ "SPECIAL_REGS", \
-+ "GENERAL_REGS", \
-+ "ALL_REGS", \
-+ "LIM_REGS" \
-+}
-+
-+/* An initializer containing the contents of the register classes, as integers
-+ which are bit masks. The Nth integer specifies the contents of class N.
-+ The way the integer MASK is interpreted is that register R is in the class
-+ if `MASK & (1 << R)' is 1.
-+
-+ When the machine has more than 32 registers, an integer does not suffice.
-+ Then the integers are replaced by sub-initializers, braced groupings
-+ containing several integers. Each sub-initializer must be suitable as an
-+ initializer for the type `HARD_REG_SET' which is defined in
-+ `hard-reg-set.h'. */
-+#define REG_CLASS_CONTENTS \
-+{ \
-+ {0x00000000, 0x00000000}, /* No regs */ \
-+ {0x0000ffff, 0x00000000}, /* DATA_REGS */ \
-+ {0x00010000, 0x00000000}, /* FDPIC_REG */ \
-+ {0x20fe0000, 0x00000000}, /* ADDRESS_REGS */ \
-+ {0x20ff0000, 0x00000000}, /* ALL_ADDRESS_REGS */ \
-+ {0x0a000000, 0x00000000}, /* ACC_LO_REGS */ \
-+ {0x0f000000, 0x00000000}, /* ACC_REGS */ \
-+ {0x40000000, 0x00000000}, /* CC_REG */ \
-+ {0x0f00ffff, 0x00000000}, /* DATA_ACC_REGS */ \
-+ {0x10000000, 0x00000000}, /* SOURGE3_REG */ \
-+ {0x80000000, 0x0000007f}, /* SPECIAL_REGS */ \
-+ {0xbfffffff, 0x0000007f}, /* GENERAL_REGS */ \
-+ {0xbfffffff, 0x0000007f} /* ALL_REGS */ \
-+}
-+
-+extern enum reg_class const ubicom32_regclass_map[FIRST_PSEUDO_REGISTER];
-+
-+/* A C expression whose value is a register class containing hard register
-+ REGNO. In general there is more than one such class; choose a class which
-+ is "minimal", meaning that no smaller class also contains the register. */
-+#define REGNO_REG_CLASS(REGNO) (ubicom32_regclass_map[REGNO])
-+
-+#define IRA_COVER_CLASSES \
-+{ \
-+ GENERAL_REGS, \
-+ LIM_REG_CLASSES \
-+}
-+
-+/* Ubicom32 base registers must be address registers since addresses can
-+ only be reached via address registers. */
-+#define BASE_REG_CLASS ALL_ADDRESS_REGS
-+
-+/* Ubicom32 index registers must be data registers since we cannot add
-+ two address registers together to form an address. */
-+#define INDEX_REG_CLASS DATA_REGS
-+
-+/* A C expression which is nonzero if register number NUM is suitable for use
-+ as a base register in operand addresses. It may be either a suitable hard
-+ register or a pseudo register that has been allocated such a hard register. */
-+
-+#ifndef REG_OK_STRICT
-+#define REGNO_OK_FOR_BASE_P(regno) \
-+ ubicom32_regno_ok_for_base_p (regno, 0)
-+#else
-+#define REGNO_OK_FOR_BASE_P(regno) \
-+ ubicom32_regno_ok_for_base_p (regno, 1)
-+#endif
-+
-+/* A C expression which is nonzero if register number NUM is suitable for use
-+ as an index register in operand addresses. It may be either a suitable hard
-+ register or a pseudo register that has been allocated such a hard register.
-+
-+ The difference between an index register and a base register is that the
-+ index register may be scaled. If an address involves the sum of two
-+ registers, neither one of them scaled, then either one may be labeled the
-+ "base" and the other the "index"; but whichever labeling is used must fit
-+ the machine's constraints of which registers may serve in each capacity.
-+ The compiler will try both labelings, looking for one that is valid, and
-+ will reload one or both registers only if neither labeling works. */
-+#ifndef REG_OK_STRICT
-+#define REGNO_OK_FOR_INDEX_P(regno) \
-+ ubicom32_regno_ok_for_index_p (regno, 0)
-+#else
-+#define REGNO_OK_FOR_INDEX_P(regno) \
-+ ubicom32_regno_ok_for_index_p (regno, 1)
-+#endif
-+
-+/* Attempt to restrict the register class we need to copy value X intoto the
-+ would-be register class CLASS. Most things are fine for Ubicom32 but we
-+ have to restrict certain types of address loads. */
-+#define PREFERRED_RELOAD_CLASS(X, CLASS) \
-+ ubicom32_preferred_reload_class (X, CLASS)
-+
-+/* A C expression for the maximum number of consecutive registers of
-+ class CLASS needed to hold a value of mode MODE. For Ubicom32 this
-+ is pretty much identical to HARD_REGNO_NREGS. */
-+#define CLASS_MAX_NREGS(CLASS, MODE) \
-+ ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
-+
-+/* For Ubicom32 the stack grows downwards when we push a word onto the stack
-+ - i.e. it moves to a smaller address. */
-+#define STACK_GROWS_DOWNWARD 1
-+
-+/* Offset from the frame pointer to the first local variable slot to
-+ be allocated. */
-+#define STARTING_FRAME_OFFSET 0
-+
-+/* Offset from the argument pointer register to the first argument's
-+ address. */
-+#define FIRST_PARM_OFFSET(FNDECL) 0
-+
-+/* A C expression whose value is RTL representing the value of the return
-+ address for the frame COUNT steps up from the current frame, after the
-+ prologue. FRAMEADDR is the frame pointer of the COUNT frame, or the frame
-+ pointer of the COUNT - 1 frame if `RETURN_ADDR_IN_PREVIOUS_FRAME' is
-+ defined.
-+
-+ The value of the expression must always be the correct address when COUNT is
-+ zero, but may be `NULL_RTX' if there is not way to determine the return
-+ address of other frames. */
-+#define RETURN_ADDR_RTX(COUNT, FRAME) \
-+ ubicom32_return_addr_rtx (COUNT, FRAME)
-+
-+/* Register That Address the Stack Frame. */
-+
-+/* We don't actually require a frame pointer in most functions with the
-+ Ubicom32 architecture so we allow it to be eliminated. */
-+#define FRAME_POINTER_REQUIRED 0
-+
-+/* Macro that defines a table of register pairs used to eliminate unecessary
-+ registers that point into the stack frame.
-+
-+ For Ubicom32 we don't generally need an arg pointer of a frame pointer
-+ so we allow the arg pointer to be replaced by either the frame pointer or
-+ the stack pointer. We also allow the frame pointer to be replaced by
-+ the stack pointer. */
-+#define ELIMINABLE_REGS \
-+{ \
-+ {ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
-+ {ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM}, \
-+ {FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM} \
-+}
-+
-+/* Let the compiler know that we want to use the ELIMINABLE_REGS macro
-+ above. */
-+#define CAN_ELIMINATE(FROM, TO) 1
-+
-+/* This macro is similar to `INITIAL_FRAME_POINTER_OFFSET'. It specifies the
-+ initial difference between the specified pair of registers. This macro must
-+ be defined if `ELIMINABLE_REGS' is defined. */
-+#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
-+ (OFFSET) = ubicom32_initial_elimination_offset (FROM, TO)
-+
-+/* If defined, the maximum amount of space required for outgoing arguments will
-+ be computed and placed into the variable
-+ `current_function_outgoing_args_size'. No space will be pushed onto the
-+ stack for each call; instead, the function prologue should increase the
-+ stack frame size by this amount.
-+
-+ Defining both `PUSH_ROUNDING' and `ACCUMULATE_OUTGOING_ARGS' is not
-+ proper. */
-+#define ACCUMULATE_OUTGOING_ARGS 1
-+
-+/* Define this macro if functions should assume that stack space has been
-+ allocated for arguments even when their values are passed in registers.
-+
-+ The value of this macro is the size, in bytes, of the area reserved for
-+ arguments passed in registers for the function represented by FNDECL.
-+
-+ This space can be allocated by the caller, or be a part of the
-+ machine-dependent stack frame: `OUTGOING_REG_PARM_STACK_SPACE' says
-+ which. */
-+#define REG_PARM_STACK_SPACE(FNDECL) ubicom32_reg_parm_stack_space(FNDECL)
-+
-+/* A C expression that should indicate the number of bytes of its own arguments
-+ that a function pops on returning, or 0 if the function pops no arguments
-+ and the caller must therefore pop them all after the function returns.
-+
-+ FUNDECL is a C variable whose value is a tree node that describes the
-+ function in question. Normally it is a node of type `FUNCTION_DECL' that
-+ describes the declaration of the function. From this it is possible to
-+ obtain the DECL_MACHINE_ATTRIBUTES of the function.
-+
-+ FUNTYPE is a C variable whose value is a tree node that describes the
-+ function in question. Normally it is a node of type `FUNCTION_TYPE' that
-+ describes the data type of the function. From this it is possible to obtain
-+ the data types of the value and arguments (if known).
-+
-+ When a call to a library function is being considered, FUNTYPE will contain
-+ an identifier node for the library function. Thus, if you need to
-+ distinguish among various library functions, you can do so by their names.
-+ Note that "library function" in this context means a function used to
-+ perform arithmetic, whose name is known specially in the compiler and was
-+ not mentioned in the C code being compiled.
-+
-+ STACK-SIZE is the number of bytes of arguments passed on the stack. If a
-+ variable number of bytes is passed, it is zero, and argument popping will
-+ always be the responsibility of the calling function.
-+
-+ On the Vax, all functions always pop their arguments, so the definition of
-+ this macro is STACK-SIZE. On the 68000, using the standard calling
-+ convention, no functions pop their arguments, so the value of the macro is
-+ always 0 in this case. But an alternative calling convention is available
-+ in which functions that take a fixed number of arguments pop them but other
-+ functions (such as `printf') pop nothing (the caller pops all). When this
-+ convention is in use, FUNTYPE is examined to determine whether a function
-+ takes a fixed number of arguments. */
-+#define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, STACK_SIZE) 0
-+
-+/* A C expression that controls whether a function argument is passed in a
-+ register, and which register.
-+
-+ The arguments are CUM, of type CUMULATIVE_ARGS, which summarizes (in a way
-+ defined by INIT_CUMULATIVE_ARGS and FUNCTION_ARG_ADVANCE) all of the previous
-+ arguments so far passed in registers; MODE, the machine mode of the argument;
-+ TYPE, the data type of the argument as a tree node or 0 if that is not known
-+ (which happens for C support library functions); and NAMED, which is 1 for an
-+ ordinary argument and 0 for nameless arguments that correspond to `...' in the
-+ called function's prototype.
-+
-+ The value of the expression should either be a `reg' RTX for the hard
-+ register in which to pass the argument, or zero to pass the argument on the
-+ stack.
-+
-+ For machines like the Vax and 68000, where normally all arguments are
-+ pushed, zero suffices as a definition.
-+
-+ The usual way to make the ANSI library `stdarg.h' work on a machine where
-+ some arguments are usually passed in registers, is to cause nameless
-+ arguments to be passed on the stack instead. This is done by making
-+ `FUNCTION_ARG' return 0 whenever NAMED is 0.
-+
-+ You may use the macro `MUST_PASS_IN_STACK (MODE, TYPE)' in the definition of
-+ this macro to determine if this argument is of a type that must be passed in
-+ the stack. If `REG_PARM_STACK_SPACE' is not defined and `FUNCTION_ARG'
-+ returns non-zero for such an argument, the compiler will abort. If
-+ `REG_PARM_STACK_SPACE' is defined, the argument will be computed in the
-+ stack and then loaded into a register. */
-+#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
-+ function_arg (&CUM, MODE, TYPE, NAMED)
-+
-+#define FUNCTION_INCOMING_ARG(CUM, MODE, TYPE, NAMED) \
-+ function_incoming_arg (&CUM, MODE, TYPE, NAMED)
-+
-+/* A C expression for the number of words, at the beginning of an argument,
-+ must be put in registers. The value must be zero for arguments that are
-+ passed entirely in registers or that are entirely pushed on the stack.
-+
-+ On some machines, certain arguments must be passed partially in registers
-+ and partially in memory. On these machines, typically the first N words of
-+ arguments are passed in registers, and the rest on the stack. If a
-+ multi-word argument (a `double' or a structure) crosses that boundary, its
-+ first few words must be passed in registers and the rest must be pushed.
-+ This macro tells the compiler when this occurs, and how many of the words
-+ should go in registers.
-+
-+ `FUNCTION_ARG' for these arguments should return the first register to be
-+ used by the caller for this argument; likewise `FUNCTION_INCOMING_ARG', for
-+ the called function. */
-+
-+/* A C expression that indicates when an argument must be passed by reference.
-+ If nonzero for an argument, a copy of that argument is made in memory and a
-+ pointer to the argument is passed instead of the argument itself. The
-+ pointer is passed in whatever way is appropriate for passing a pointer to
-+ that type.
-+
-+ On machines where `REG_PARM_STACK_SPACE' is not defined, a suitable
-+ definition of this macro might be
-+ #define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \
-+ MUST_PASS_IN_STACK (MODE, TYPE) */
-+
-+/* If defined, a C expression that indicates when it is the called function's
-+ responsibility to make a copy of arguments passed by invisible reference.
-+ Normally, the caller makes a copy and passes the address of the copy to the
-+ routine being called. When FUNCTION_ARG_CALLEE_COPIES is defined and is
-+ nonzero, the caller does not make a copy. Instead, it passes a pointer to
-+ the "live" value. The called function must not modify this value. If it
-+ can be determined that the value won't be modified, it need not make a copy;
-+ otherwise a copy must be made. */
-+
-+/* 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
-+ `int' suffices and can hold the number of bytes of argument so far.
-+
-+ There is no need to record in `CUMULATIVE_ARGS' anything about the arguments
-+ that have been passed on the stack. The compiler has other variables to
-+ keep track of that. For target machines on which all arguments are passed
-+ on the stack, there is no need to store anything in `CUMULATIVE_ARGS';
-+ however, the data structure must exist and should not be empty, so use
-+ `int'. */
-+struct cum_arg
-+{
-+ int nbytes;
-+ int reg;
-+ int stdarg;
-+};
-+#define CUMULATIVE_ARGS struct cum_arg
-+
-+/* A C statement (sans semicolon) for initializing the variable CUM for the
-+ state at the beginning of the argument list. The variable has type
-+ `CUMULATIVE_ARGS'. The value of FNTYPE is the tree node for the data type
-+ of the function which will receive the args, or 0 if the args are to a
-+ compiler support library function. The value of INDIRECT is nonzero when
-+ processing an indirect call, for example a call through a function pointer.
-+ The value of INDIRECT is zero for a call to an explicitly named function, a
-+ library function call, or when `INIT_CUMULATIVE_ARGS' is used to find
-+ arguments for the function being compiled.
-+
-+ When processing a call to a compiler support library function, LIBNAME
-+ identifies which one. It is a `symbol_ref' rtx which contains the name of
-+ the function, as a string. LIBNAME is 0 when an ordinary C function call is
-+ being processed. Thus, each time this macro is called, either LIBNAME or
-+ FNTYPE is nonzero, but never both of them at once. */
-+
-+#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT, NAMED_ARGS) \
-+ init_cumulative_args (&(CUM), FNTYPE, LIBNAME, INDIRECT);
-+
-+/* A C statement (sans semicolon) to update the summarizer variable CUM to
-+ advance past an argument in the argument list. The values MODE, TYPE and
-+ NAMED describe that argument. Once this is done, the variable CUM is
-+ suitable for analyzing the *following* argument with `FUNCTION_ARG', etc.
-+
-+ This macro need not do anything if the argument in question was passed on
-+ the stack. The compiler knows how to track the amount of stack space used
-+ for arguments without any special help. */
-+#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
-+ ((CUM).nbytes += ((MODE) != BLKmode \
-+ ? (GET_MODE_SIZE (MODE) + 3) & ~3 \
-+ : (int_size_in_bytes (TYPE) + 3) & ~3))
-+
-+/* For the Ubicom32 we define the upper function argument register here. */
-+#define UBICOM32_FUNCTION_ARG_REGS 10
-+
-+/* A C expression that is nonzero if REGNO is the number of a hard register in
-+ which function arguments are sometimes passed. This does *not* include
-+ implicit arguments such as the static chain and the structure-value address.
-+ On many machines, no registers can be used for this purpose since all
-+ function arguments are pushed on the stack. */
-+#define FUNCTION_ARG_REGNO_P(N) ((N) < UBICOM32_FUNCTION_ARG_REGS)
-+
-+\f
-+/* How Scalar Function Values are Returned. */
-+
-+/* The number of the hard register that is used to return a scalar value from a
-+ function call. */
-+#define RETURN_VALUE_REGNUM 0
-+
-+/* A C expression to create an RTX representing the place where a function
-+ returns a value of data type VALTYPE. VALTYPE is a tree node representing a
-+ data type. Write `TYPE_MODE (VALTYPE)' to get the machine mode used to
-+ represent that type. On many machines, only the mode is relevant.
-+ (Actually, on most machines, scalar values are returned in the same place
-+ regardless of mode).
-+
-+ If `PROMOTE_FUNCTION_RETURN' is defined, you must apply the same promotion
-+ rules specified in `PROMOTE_MODE' if VALTYPE is a scalar type.
-+
-+ If the precise function being called is known, FUNC is a tree node
-+ (`FUNCTION_DECL') for it; otherwise, FUNC is a null pointer. This makes it
-+ possible to use a different value-returning convention for specific
-+ functions when all their calls are known.
-+
-+ `FUNCTION_VALUE' is not used for return vales with aggregate data types,
-+ because these are returned in another way. See `STRUCT_VALUE_REGNUM' and
-+ related macros, below. */
-+#define FUNCTION_VALUE(VALTYPE, FUNC) \
-+ gen_rtx_REG (TYPE_MODE (VALTYPE), FIRST_DATA_REGNUM)
-+
-+/* A C expression to create an RTX representing the place where a library
-+ function returns a value of mode MODE.
-+
-+ Note that "library function" in this context means a compiler support
-+ routine, used to perform arithmetic, whose name is known specially by the
-+ compiler and was not mentioned in the C code being compiled.
-+
-+ The definition of `LIBRARY_VALUE' need not be concerned aggregate data
-+ types, because none of the library functions returns such types. */
-+#define LIBCALL_VALUE(MODE) gen_rtx_REG (MODE, FIRST_DATA_REGNUM)
-+
-+/* A C expression that is nonzero if REGNO is the number of a hard register in
-+ which the values of called function may come back.
-+
-+ A register whose use for returning values is limited to serving as the
-+ second of a pair (for a value of type `double', say) need not be recognized
-+ by this macro. So for most machines, this definition suffices:
-+
-+ #define FUNCTION_VALUE_REGNO_P(N) ((N) == RETURN)
-+
-+ If the machine has register windows, so that the caller and the called
-+ function use different registers for the return value, this macro should
-+ recognize only the caller's register numbers. */
-+#define FUNCTION_VALUE_REGNO_P(N) ((N) == FIRST_DATA_REGNUM)
-+
-+\f
-+/* How Large Values are Returned. */
-+
-+/* A C expression which can inhibit the returning of certain function values in
-+ registers, based on the type of value. A nonzero value says to return the
-+ function value in memory, just as large structures are always returned.
-+ Here TYPE will be a C expression of type `tree', representing the data type
-+ of the value.
-+
-+ Note that values of mode `BLKmode' must be explicitly handled by this macro.
-+ Also, the option `-fpcc-struct-return' takes effect regardless of this
-+ macro. On most systems, it is possible to leave the macro undefined; this
-+ causes a default definition to be used, whose value is the constant 1 for
-+ `BLKmode' values, and 0 otherwise.
-+
-+ Do not use this macro to indicate that structures and unions should always
-+ be returned in memory. You should instead use `DEFAULT_PCC_STRUCT_RETURN'
-+ to indicate this. */
-+#define RETURN_IN_MEMORY(TYPE) \
-+ (int_size_in_bytes (TYPE) > 8 || TYPE_MODE (TYPE) == BLKmode)
-+
-+/* Define this macro to be 1 if all structure and union return values must be
-+ in memory. Since this results in slower code, this should be defined only
-+ if needed for compatibility with other compilers or with an ABI. If you
-+ define this macro to be 0, then the conventions used for structure and union
-+ return values are decided by the `RETURN_IN_MEMORY' macro.
-+
-+ If not defined, this defaults to the value 1. */
-+#define DEFAULT_PCC_STRUCT_RETURN 0
-+
-+/* If the structure value address is not passed in a register, define
-+ `STRUCT_VALUE' as an expression returning an RTX for the place
-+ where the address is passed. If it returns 0, the address is
-+ passed as an "invisible" first argument. */
-+#define STRUCT_VALUE 0
-+
-+/* Define this macro as a C expression that is nonzero if the return
-+ instruction or the function epilogue ignores the value of the stack pointer;
-+ in other words, if it is safe to delete an instruction to adjust the stack
-+ pointer before a return from the function.
-+
-+ Note that this macro's value is relevant only for functions for which frame
-+ pointers are maintained. It is never safe to delete a final stack
-+ adjustment in a function that has no frame pointer, and the compiler knows
-+ this regardless of `EXIT_IGNORE_STACK'. */
-+#define EXIT_IGNORE_STACK 1
-+
-+/* A C statement or compound statement to output to FILE some assembler code to
-+ call the profiling subroutine `mcount'. Before calling, the assembler code
-+ must load the address of a counter variable into a register where `mcount'
-+ expects to find the address. The name of this variable is `LP' followed by
-+ the number LABELNO, so you would generate the name using `LP%d' in a
-+ `fprintf'.
-+
-+ The details of how the address should be passed to `mcount' are determined
-+ by your operating system environment, not by GNU CC. To figure them out,
-+ compile a small program for profiling using the system's installed C
-+ compiler and look at the assembler code that results.
-+
-+ This declaration must be present, but it can be an abort if profiling is
-+ not implemented. */
-+
-+#define FUNCTION_PROFILER(file, labelno) ubicom32_profiler(file, labelno)
-+
-+/* A C statement to output, on the stream FILE, assembler code for a block of
-+ data that contains the constant parts of a trampoline. This code should not
-+ include a label--the label is taken care of automatically. */
-+#if 0
-+#define TRAMPOLINE_TEMPLATE(FILE) \
-+ do { \
-+ fprintf (FILE, "\tadd -4,sp\n"); \
-+ fprintf (FILE, "\t.long 0x0004fffa\n"); \
-+ fprintf (FILE, "\tmov (0,sp),a0\n"); \
-+ fprintf (FILE, "\tadd 4,sp\n"); \
-+ fprintf (FILE, "\tmov (13,a0),a1\n"); \
-+ fprintf (FILE, "\tmov (17,a0),a0\n"); \
-+ fprintf (FILE, "\tjmp (a0)\n"); \
-+ fprintf (FILE, "\t.long 0\n"); \
-+ fprintf (FILE, "\t.long 0\n"); \
-+ } while (0)
-+#endif
-+
-+/* A C expression for the size in bytes of the trampoline, as an integer. */
-+#define TRAMPOLINE_SIZE 0x1b
-+
-+/* Alignment required for trampolines, in bits.
-+
-+ If you don't define this macro, the value of `BIGGEST_ALIGNMENT' is used for
-+ aligning trampolines. */
-+#define TRAMPOLINE_ALIGNMENT 32
-+
-+/* A C statement to initialize the variable parts of a trampoline. ADDR is an
-+ RTX for the address of the trampoline; FNADDR is an RTX for the address of
-+ the nested function; STATIC_CHAIN is an RTX for the static chain value that
-+ should be passed to the function when it is called. */
-+#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
-+{ \
-+ emit_move_insn (gen_rtx_MEM (SImode, plus_constant ((TRAMP), 0x14)), \
-+ (CXT)); \
-+ emit_move_insn (gen_rtx_MEM (SImode, plus_constant ((TRAMP), 0x18)), \
-+ (FNADDR)); \
-+}
-+
-+/* Ubicom32 supports pre and post increment/decrement addressing. */
-+#define HAVE_POST_INCREMENT 1
-+#define HAVE_PRE_INCREMENT 1
-+#define HAVE_POST_DECREMENT 1
-+#define HAVE_PRE_DECREMENT 1
-+
-+/* Ubicom32 supports pre and post address side-effects with constants
-+ other than the size of the memory operand. */
-+#define HAVE_PRE_MODIFY_DISP 1
-+#define HAVE_POST_MODIFY_DISP 1
-+
-+/* A C expression that is 1 if the RTX X is a constant which is a valid
-+ address. On most machines, this can be defined as `CONSTANT_P (X)',
-+ but a few machines are more restrictive in which constant addresses
-+ are supported.
-+
-+ `CONSTANT_P' accepts integer-values expressions whose values are not
-+ explicitly known, such as `symbol_ref', `label_ref', and `high'
-+ expressions and `const' arithmetic expressions, in addition to
-+ `const_int' and `const_double' expressions. */
-+#define CONSTANT_ADDRESS_P(X) \
-+ (GET_CODE (X) == LABEL_REF \
-+ || (GET_CODE (X) == CONST \
-+ && GET_CODE (XEXP (X, 0)) == PLUS \
-+ && GET_CODE (XEXP (XEXP (X, 0), 0)) == LABEL_REF))
-+
-+/* Ubicom32 supports a maximum of 2 registers in a valid memory address.
-+ One is always an address register while a second, optional, one may be a
-+ data register. */
-+#define MAX_REGS_PER_ADDRESS 2
-+
-+/* A C compound statement with a conditional `goto LABEL;' executed if X (an
-+ RTX) is a legitimate memory address on the target machine for a memory
-+ operand of mode MODE.
-+
-+ It usually pays to define several simpler macros to serve as subroutines for
-+ this one. Otherwise it may be too complicated to understand.
-+
-+ This macro must exist in two variants: a strict variant and a non-strict
-+ one. The strict variant is used in the reload pass. It must be defined so
-+ that any pseudo-register that has not been allocated a hard register is
-+ considered a memory reference. In contexts where some kind of register is
-+ required, a pseudo-register with no hard register must be rejected.
-+
-+ The non-strict variant is used in other passes. It must be defined to
-+ accept all pseudo-registers in every context where some kind of register is
-+ required.
-+
-+ Compiler source files that want to use the strict variant of this macro
-+ define the macro `REG_OK_STRICT'. You should use an `#ifdef REG_OK_STRICT'
-+ conditional to define the strict variant in that case and the non-strict
-+ variant otherwise.
-+
-+ Subroutines to check for acceptable registers for various purposes (one for
-+ base registers, one for index registers, and so on) are typically among the
-+ subroutines used to define `GO_IF_LEGITIMATE_ADDRESS'. Then only these
-+ subroutine macros need have two variants; the higher levels of macros may be
-+ the same whether strict or not.
-+
-+ Normally, constant addresses which are the sum of a `symbol_ref' and an
-+ integer are stored inside a `const' RTX to mark them as constant.
-+ Therefore, there is no need to recognize such sums specifically as
-+ legitimate addresses. Normally you would simply recognize any `const' as
-+ legitimate.
-+
-+ Usually `PRINT_OPERAND_ADDRESS' is not prepared to handle constant sums that
-+ are not marked with `const'. It assumes that a naked `plus' indicates
-+ indexing. If so, then you *must* reject such naked constant sums as
-+ illegitimate addresses, so that none of them will be given to
-+ `PRINT_OPERAND_ADDRESS'.
-+
-+ On some machines, whether a symbolic address is legitimate depends on the
-+ section that the address refers to. On these machines, define the macro
-+ `ENCODE_SECTION_INFO' to store the information into the `symbol_ref', and
-+ then check for it here. When you see a `const', you will have to look
-+ inside it to find the `symbol_ref' in order to determine the section.
-+
-+ The best way to modify the name string is by adding text to the beginning,
-+ with suitable punctuation to prevent any ambiguity. Allocate the new name
-+ in `saveable_obstack'. You will have to modify `ASM_OUTPUT_LABELREF' to
-+ remove and decode the added text and output the name accordingly, and define
-+ `STRIP_NAME_ENCODING' to access the original name string.
-+
-+ You can check the information stored here into the `symbol_ref' in the
-+ definitions of the macros `GO_IF_LEGITIMATE_ADDRESS' and
-+ `PRINT_OPERAND_ADDRESS'. */
-+/* On the ubicom32, the value in the address register must be
-+ in the same memory space/segment as the effective address.
-+
-+ This is problematical for reload since it does not understand
-+ that base+index != index+base in a memory reference. */
-+
-+#ifdef REG_OK_STRICT
-+#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
-+ if (ubicom32_legitimate_address_p (MODE, X, 1)) goto ADDR;
-+#else
-+#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
-+ if (ubicom32_legitimate_address_p (MODE, X, 0)) goto ADDR;
-+#endif
-+
-+/* Try machine-dependent ways of modifying an illegitimate address
-+ to be legitimate. If we find one, return the new, valid address.
-+ This macro is used in only one place: `memory_address' in explow.c.
-+
-+ OLDX is the address as it was before break_out_memory_refs was called.
-+ In some cases it is useful to look at this to decide what needs to be done.
-+
-+ MODE and WIN are passed so that this macro can use
-+ GO_IF_LEGITIMATE_ADDRESS.
-+
-+ It is always safe for this macro to do nothing. It exists to recognize
-+ opportunities to optimize the output.
-+
-+ On RS/6000, first check for the sum of a register with a constant
-+ integer that is out of range. If so, generate code to add the
-+ constant with the low-order 16 bits masked to the register and force
-+ this result into another register (this can be done with `cau').
-+ Then generate an address of REG+(CONST&0xffff), allowing for the
-+ possibility of bit 16 being a one.
-+
-+ Then check for the sum of a register and something not constant, try to
-+ load the other things into a register and return the sum. */
-+
-+#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \
-+{ \
-+ rtx result = ubicom32_legitimize_address ((X), (OLDX), (MODE)); \
-+ if (result != NULL_RTX) \
-+ { \
-+ (X) = result; \
-+ goto WIN; \
-+ } \
-+}
-+
-+/* Try a machine-dependent way of reloading an illegitimate address
-+ operand. If we find one, push the reload and jump to WIN. This
-+ macro is used in only one place: `find_reloads_address' in reload.c. */
-+#define LEGITIMIZE_RELOAD_ADDRESS(AD, MODE, OPNUM, TYPE, IND, WIN) \
-+{ \
-+ rtx new_rtx = ubicom32_legitimize_reload_address ((AD), (MODE), (OPNUM), (int)(TYPE)); \
-+ if (new_rtx) \
-+ { \
-+ (AD) = new_rtx; \
-+ goto WIN; \
-+ } \
-+}
-+
-+/* A C statement or compound statement with a conditional `goto LABEL;'
-+ executed if memory address X (an RTX) can have different meanings depending
-+ on the machine mode of the memory reference it is used for or if the address
-+ is valid for some modes but not others.
-+
-+ Autoincrement and autodecrement addresses typically have mode-dependent
-+ effects because the amount of the increment or decrement is the size of the
-+ operand being addressed. Some machines have other mode-dependent addresses.
-+ Many RISC machines have no mode-dependent addresses.
-+
-+ You may assume that ADDR is a valid address for the machine. */
-+#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL) \
-+ if (ubicom32_mode_dependent_address_p (ADDR)) \
-+ goto LABEL;
-+
-+/* A C expression that is nonzero if X is a legitimate constant for an
-+ immediate operand on the target machine. You can assume that X
-+ satisfies `CONSTANT_P', so you need not check this. In fact, `1' is
-+ a suitable definition for this macro on machines where anything
-+ `CONSTANT_P' is valid. */
-+#define LEGITIMATE_CONSTANT_P(X) \
-+ ubicom32_legitimate_constant_p ((X))
-+
-+/* Moves between registers are pretty-much single instructions for
-+ Ubicom32. We make this the default "2" that gcc likes. */
-+#define REGISTER_MOVE_COST(MODE, FROM, TO) 2
-+
-+/* This is a little bit of magic from the S390 port that wins 2% on code
-+ size when building the Linux kernel! Unfortunately while it wins on
-+ that size the user-space apps built using FD-PIC don't improve and the
-+ performance is lower because we put more pressure on the caches. We may
-+ want this back on some future CPU that has higher cache performance. */
-+/* #define IRA_HARD_REGNO_ADD_COST_MULTIPLIER(regno) 0.5 */
-+
-+/* Moves between registers and memory are more expensive than between
-+ registers because we have caches and write buffers that slow things
-+ down! */
-+#define MEMORY_MOVE_COST(MODE, CLASS, IN) 2
-+
-+/* A fall-through branch is very low cost but anything that changes the PC
-+ incurs a major pipeline hazard. We don't make the full extent of this
-+ hazard visible because we hope that multiple threads will absorb much
-+ of the cost and so we don't want a jump being replaced with, say, 7
-+ instructions. */
-+#define BRANCH_COST(SPEED_P, PREDICTABLE_P) \
-+ ((PREDICTABLE_P) ? 1 : 3)
-+
-+/* Define this macro as a C expression which is nonzero if accessing less than
-+ a word of memory (i.e. a `char' or a `short') is no faster than accessing a
-+ word of memory, i.e., if such access require more than one instruction or if
-+ there is no difference in cost between byte and (aligned) word loads.
-+
-+ When this macro is not defined, the compiler will access a field by finding
-+ the smallest containing object; when it is defined, a fullword load will be
-+ used if alignment permits. Unless bytes accesses are faster than word
-+ accesses, using word accesses is preferable since it may eliminate
-+ subsequent memory access if subsequent accesses occur to other fields in the
-+ same word of the structure, but to different bytes. */
-+#define SLOW_BYTE_ACCESS 0
-+
-+/* The number of scalar move insns which should be generated instead of a
-+ string move insn or a library call. Increasing the value will always make
-+ code faster, but eventually incurs high cost in increased code size.
-+
-+ If you don't define this, a reasonable default is used. */
-+/* According to expr.c, a value of around 6 should minimize code size. */
-+#define MOVE_RATIO(SPEED) 6
-+
-+/* We're much better off calling a constant function address with the
-+ Ubicom32 architecture because we have an opcode for doing so. Don't
-+ let the compiler extract function addresses as common subexpressions
-+ into an address register. */
-+#define NO_FUNCTION_CSE
-+
-+#define SELECT_CC_MODE(OP, X, Y) ubicom32_select_cc_mode (OP, X, Y)
-+
-+#define REVERSIBLE_CC_MODE(MODE) 1
-+
-+/* Canonicalize a comparison from one we don't have to one we do have. */
-+#define CANONICALIZE_COMPARISON(CODE, OP0, OP1) \
-+ ubicom32_canonicalize_comparison (&(CODE), &(OP0), &(OP1))
-+
-+/* Dividing the output into sections. */
-+
-+/* A C expression whose value is a string containing the assembler operation
-+ that should precede instructions and read-only data. Normally `".text"' is
-+ right. */
-+#define TEXT_SECTION_ASM_OP "\t.section .text"
-+
-+/* A C expression whose value is a string containing the assembler operation to
-+ identify the following data as writable initialized data. Normally
-+ `".data"' is right. */
-+#define DATA_SECTION_ASM_OP "\t.section .data"
-+
-+
-+/* If defined, a C expression whose value is a string containing the
-+ assembler operation to identify the following data as
-+ uninitialized global data. If not defined, and neither
-+ `ASM_OUTPUT_BSS' nor `ASM_OUTPUT_ALIGNED_BSS' are defined,
-+ uninitialized global data will be output in the data section if
-+ `-fno-common' is passed, otherwise `ASM_OUTPUT_COMMON' will be
-+ used. */
-+#define BSS_SECTION_ASM_OP "\t.section .bss"
-+
-+/* This is how we tell the assembler that a symbol is weak. */
-+
-+#define ASM_WEAKEN_LABEL(FILE, NAME) \
-+ do \
-+ { \
-+ fputs ("\t.weak\t", (FILE)); \
-+ assemble_name ((FILE), (NAME)); \
-+ fputc ('\n', (FILE)); \
-+ } \
-+ while (0)
-+
-+/* The Overall Framework of an Assembler File. */
-+
-+#undef SET_ASM_OP
-+#define SET_ASM_OP "\t.set\t"
-+
-+/* A C string constant describing how to begin a comment in the target
-+ assembler language. The compiler assumes that the comment will end at the
-+ end of the line. */
-+#define ASM_COMMENT_START ";"
-+
-+/* A C string constant for text to be output before each `asm' statement or
-+ group of consecutive ones. Normally this is `"#APP"', which is a comment
-+ that has no effect on most assemblers but tells the GNU assembler that it
-+ must check the lines that follow for all valid assembler constructs. */
-+#define ASM_APP_ON "#APP\n"
-+
-+/* A C string constant for text to be output after each `asm' statement or
-+ group of consecutive ones. Normally this is `"#NO_APP"', which tells the
-+ GNU assembler to resume making the time-saving assumptions that are valid
-+ for ordinary compiler output. */
-+#define ASM_APP_OFF "#NO_APP\n"
-+
-+/* Like `ASM_OUTPUT_BSS' except takes the required alignment as a separate,
-+ explicit argument. If you define this macro, it is used in place of
-+ `ASM_OUTPUT_BSS', and gives you more flexibility in handling the required
-+ alignment of the variable. The alignment is specified as the number of
-+ bits.
-+
-+ Try to use function `asm_output_aligned_bss' defined in file `varasm.c' when
-+ defining this macro. */
-+#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
-+ asm_output_aligned_bss ((FILE), (DECL), (NAME), (SIZE), (ALIGN))
-+
-+/* A C expression to assign to OUTVAR (which is a variable of type `char *') a
-+ newly allocated string made from the string NAME and the number NUMBER, with
-+ some suitable punctuation added. Use `alloca' to get space for the string.
-+
-+ The string will be used as an argument to `ASM_OUTPUT_LABELREF' to produce
-+ an assembler label for an internal static variable whose name is NAME.
-+ Therefore, the string must be such as to result in valid assembler code.
-+ The argument NUMBER is different each time this macro is executed; it
-+ prevents conflicts between similarly-named internal static variables in
-+ different scopes.
-+
-+ Ideally this string should not be a valid C identifier, to prevent any
-+ conflict with the user's own symbols. Most assemblers allow periods or
-+ percent signs in assembler symbols; putting at least one of these between
-+ the name and the number will suffice. */
-+#define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \
-+ ((OUTPUT) = (char *) alloca (strlen ((NAME)) + 10), \
-+ sprintf ((OUTPUT), "%s___%d", (NAME), (LABELNO)))
-+
-+#define ASM_GENERATE_INTERNAL_LABEL(STRING, PREFIX, NUM) \
-+ sprintf (STRING, "*.%s%ld", PREFIX, (long)(NUM))
-+/* A C statement to store into the string STRING a label whose name
-+ is made from the string PREFIX and the number NUM.
-+
-+ This string, when output subsequently by `assemble_name', should
-+ produce the output that `(*targetm.asm_out.internal_label)' would produce
-+ with the same PREFIX and NUM.
-+
-+ If the string begins with `*', then `assemble_name' will output
-+ the rest of the string unchanged. It is often convenient for
-+ `ASM_GENERATE_INTERNAL_LABEL' to use `*' in this way. If the
-+ string doesn't start with `*', then `ASM_OUTPUT_LABELREF' gets to
-+ output the string, and may change it. (Of course,
-+ `ASM_OUTPUT_LABELREF' is also part of your machine description, so
-+ you should know what it does on your machine.) */
-+
-+/* This says how to output assembler code to declare an
-+ uninitialized external linkage data object. Under SVR4,
-+ the linker seems to want the alignment of data objects
-+ to depend on their types. We do exactly that here. */
-+
-+#define COMMON_ASM_OP "\t.comm\t"
-+
-+#undef ASM_OUTPUT_COMMON
-+#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \
-+ do \
-+ { \
-+ fprintf ((FILE), "%s", COMMON_ASM_OP); \
-+ assemble_name ((FILE), (NAME)); \
-+ fprintf ((FILE), ", %u\n", (SIZE)); \
-+ } \
-+ while (0)
-+
-+/* This says how to output assembler code to declare an
-+ uninitialized internal linkage data object. Under SVR4,
-+ the linker seems to want the alignment of data objects
-+ to depend on their types. We do exactly that here. */
-+#define LOCAL_ASM_OP "\t.lcomm\t"
-+
-+#undef ASM_OUTPUT_LOCAL
-+#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \
-+ do \
-+ { \
-+ fprintf ((FILE), "%s", LOCAL_ASM_OP); \
-+ assemble_name ((FILE), (NAME)); \
-+ fprintf ((FILE), ", %u\n", (SIZE)); \
-+ } \
-+ while (0)
-+
-+/* Globalizing directive for a label. */
-+#define GLOBAL_ASM_OP ".global\t"
-+
-+/* Output the operand of an instruction. */
-+#define PRINT_OPERAND(FILE, X, CODE) \
-+ ubicom32_print_operand(FILE, X, CODE)
-+
-+/* Output the address of an operand. */
-+#define PRINT_OPERAND_ADDRESS(FILE, ADDR) \
-+ ubicom32_print_operand_address (FILE, ADDR)
-+
-+/* A C expression to output to STREAM some assembler code which will push hard
-+ register number REGNO onto the stack. The code need not be optimal, since
-+ this macro is used only when profiling. */
-+#define ASM_OUTPUT_REG_PUSH(FILE, REGNO)
-+
-+/* A C expression to output to STREAM some assembler code which will pop hard
-+ register number REGNO off of the stack. The code need not be optimal, since
-+ this macro is used only when profiling. */
-+#define ASM_OUTPUT_REG_POP(FILE, REGNO)
-+
-+/* This macro should be provided on machines where the addresses in a dispatch
-+ table are relative to the table's own address.
-+
-+ The definition should be a C statement to output to the stdio stream STREAM
-+ an assembler pseudo-instruction to generate a difference between two labels.
-+ VALUE and REL are the numbers of two internal labels. The definitions of
-+ these labels are output using `ASM_OUTPUT_INTERNAL_LABEL', and they must be
-+ printed in the same way here. For example,
-+
-+ fprintf (STREAM, "\t.word L%d-L%d\n", VALUE, REL) */
-+#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
-+ fprintf (FILE, "\t%s .L%d-.L%d\n", ".long", VALUE, REL)
-+
-+/* This macro should be provided on machines where the addresses in a dispatch
-+ table are absolute.
-+
-+ The definition should be a C statement to output to the stdio stream STREAM
-+ an assembler pseudo-instruction to generate a reference to a label. VALUE
-+ is the number of an internal label whose definition is output using
-+ `ASM_OUTPUT_INTERNAL_LABEL'. For example,
-+
-+ fprintf (STREAM, "\t.word L%d\n", VALUE) */
-+#define ASM_OUTPUT_ADDR_VEC_ELT(STREAM, VALUE) \
-+ fprintf (STREAM, "\t.word .L%d\n", VALUE)
-+
-+/* Switch into a generic section. */
-+#define TARGET_ASM_NAMED_SECTION default_elf_asm_named_section
-+
-+/* Assembler Commands for Alignment. */
-+
-+#define ASM_OUTPUT_SKIP(STREAM, N) fprintf (STREAM, "\t.skip %d,0\n", N)
-+/* A C statement to output to the stdio stream STREAM an assembler
-+ instruction to advance the location counter by NBYTES bytes.
-+ Those bytes should be zero when loaded. NBYTES will be a C
-+ expression of type `int'. */
-+
-+/* A C statement to output to the stdio stream STREAM an assembler command to
-+ advance the location counter to a multiple of 2 to the POWER bytes. POWER
-+ will be a C expression of type `int'. */
-+#define ASM_OUTPUT_ALIGN(FILE, LOG) \
-+ if ((LOG) != 0) \
-+ fprintf (FILE, "\t.align %d\n", (LOG))
-+
-+/* A C expression that returns the DBX register number for the compiler
-+ register number REGNO. In simple cases, the value of this expression may be
-+ REGNO itself. But sometimes there are some registers that the compiler
-+ knows about and DBX does not, or vice versa. In such cases, some register
-+ may need to have one number in the compiler and another for DBX.
-+
-+ If two registers have consecutive numbers inside GNU CC, and they can be
-+ used as a pair to hold a multiword value, then they *must* have consecutive
-+ numbers after renumbering with `DBX_REGISTER_NUMBER'. Otherwise, debuggers
-+ will be unable to access such a pair, because they expect register pairs to
-+ be consecutive in their own numbering scheme.
-+
-+ If you find yourself defining `DBX_REGISTER_NUMBER' in way that does not
-+ preserve register pairs, then what you must do instead is redefine the
-+ actual register numbering scheme.
-+
-+ This declaration is required. */
-+#define DBX_REGISTER_NUMBER(REGNO) REGNO
-+
-+/* A C expression that returns the integer offset value for an automatic
-+ variable having address X (an RTL expression). The default computation
-+ assumes that X is based on the frame-pointer and gives the offset from the
-+ frame-pointer. This is required for targets that produce debugging output
-+ for DBX or COFF-style debugging output for SDB and allow the frame-pointer
-+ to be eliminated when the `-g' options is used. */
-+#define DEBUGGER_AUTO_OFFSET(X) \
-+ ((GET_CODE (X) == PLUS ? INTVAL (XEXP (X, 1)) : 0) \
-+ + (frame_pointer_needed \
-+ ? 0 : -initial_elimination_offset (FRAME_POINTER_REGNUM, \
-+ STACK_POINTER_REGNUM)))
-+
-+/* A C expression that returns the integer offset value for an argument having
-+ address X (an RTL expression). The nominal offset is OFFSET. */
-+#define DEBUGGER_ARG_OFFSET(OFFSET, X) \
-+ ((GET_CODE (X) == PLUS ? OFFSET : 0) \
-+ + (frame_pointer_needed \
-+ ? 0 : -initial_elimination_offset (ARG_POINTER_REGNUM, \
-+ STACK_POINTER_REGNUM)))
-+
-+/* A C expression that returns the type of debugging output GNU CC produces
-+ when the user specifies `-g' or `-ggdb'. Define this if you have arranged
-+ for GNU CC to support more than one format of debugging output. Currently,
-+ the allowable values are `DBX_DEBUG', `SDB_DEBUG', `DWARF_DEBUG',
-+ `DWARF2_DEBUG', and `XCOFF_DEBUG'.
-+
-+ The value of this macro only affects the default debugging output; the user
-+ can always get a specific type of output by using `-gstabs', `-gcoff',
-+ `-gdwarf-1', `-gdwarf-2', or `-gxcoff'.
-+
-+ Defined in svr4.h.
-+*/
-+#undef PREFERRED_DEBUGGING_TYPE
-+#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
-+
-+/* Define this macro if GNU CC should produce dwarf version 2 format debugging
-+ output in response to the `-g' option.
-+
-+ To support optional call frame debugging information, you must also define
-+ `INCOMING_RETURN_ADDR_RTX' and either set `RTX_FRAME_RELATED_P' on the
-+ prologue insns if you use RTL for the prologue, or call `dwarf2out_def_cfa'
-+ and `dwarf2out_reg_save' as appropriate from `FUNCTION_PROLOGUE' if you
-+ don't.
-+
-+ Defined in svr4.h. */
-+
-+#define DWARF2_DEBUGGING_INFO 1
-+/*#define DWARF2_UNWIND_INFO 1*/
-+#define DWARF2_UNWIND_INFO 0
-+#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (Pmode, LINK_REGNO)
-+#define INCOMING_FRAME_SP_OFFSET 0
-+#define DWARF_FRAME_RETURN_COLUMN DWARF_FRAME_REGNUM (LINK_REGNO)
-+#define EH_RETURN_FIRST 9
-+#define EH_RETURN_DATA_REGNO(N) ((N) < 2 ? (N) + EH_RETURN_FIRST : INVALID_REGNUM)
-+
-+/* The EH_RETURN_STACKADJ_RTX macro returns RTL which describes the
-+ location used to store the amount to ajdust the stack. This is
-+ usually a registers that is available from end of the function's body
-+ to the end of the epilogue. Thus, this cannot be a register used as a
-+ temporary by the epilogue.
-+
-+ This must be an integer register. */
-+#define EH_RETURN_STACKADJ_REGNO 11
-+#define EH_RETURN_STACKADJ_RTX \
-+ gen_rtx_REG (Pmode, EH_RETURN_STACKADJ_REGNO)
-+
-+/* The EH_RETURN_HANDLER_RTX macro returns RTL which describes the
-+ location used to store the address the processor should jump to
-+ catch exception. This is usually a registers that is available from
-+ end of the function's body to the end of the epilogue. Thus, this
-+ cannot be a register used as a temporary by the epilogue.
-+
-+ This must be an address register. */
-+#define EH_RETURN_HANDLER_REGNO 18
-+#define EH_RETURN_HANDLER_RTX \
-+ gen_rtx_REG (Pmode, EH_RETURN_HANDLER_REGNO)
-+
-+/* #define DWARF2_DEBUGGING_INFO */
-+
-+/* Define this macro if GNU CC should produce dwarf version 2-style
-+ line numbers. This usually requires extending the assembler to
-+ support them, and #defining DWARF2_LINE_MIN_INSN_LENGTH in the
-+ assembler configuration header files. */
-+/* #define DWARF2_ASM_LINE_DEBUG_INFO 1 */
-+
-+
-+/* An alias for a machine mode name. This is the machine mode that elements
-+ of a jump-table have. */
-+#define CASE_VECTOR_MODE Pmode
-+
-+/* Smallest number of different values for which it is best to use a
-+ jump-table instead of a tree of conditional branches. For most Ubicom32
-+ targets this is quite small, but for the v1 architecture implementations
-+ we had very little data memory and so heavily prefer the tree approach
-+ rather than the jump tables. */
-+#define CASE_VALUES_THRESHOLD ubicom32_case_values_threshold
-+
-+/* Register operations within the Ubicom32 architecture always operate on
-+ the whole register word and not just the sub-bits required for the opcode
-+ mode size. */
-+#define WORD_REGISTER_OPERATIONS
-+
-+/* The maximum number of bytes that a single instruction can move quickly from
-+ memory to memory. */
-+#define MOVE_MAX 4
-+
-+/* A C expression that is nonzero if on this machine the number of bits
-+ actually used for the count of a shift operation is equal to the number of
-+ bits needed to represent the size of the object being shifted. When this
-+ macro is non-zero, the compiler will assume that it is safe to omit a
-+ sign-extend, zero-extend, and certain bitwise `and' instructions that
-+ truncates the count of a shift operation. On machines that have
-+ instructions that act on bitfields at variable positions, which may include
-+ `bit test' instructions, a nonzero `SHIFT_COUNT_TRUNCATED' also enables
-+ deletion of truncations of the values that serve as arguments to bitfield
-+ instructions.
-+
-+ If both types of instructions truncate the count (for shifts) and position
-+ (for bitfield operations), or if no variable-position bitfield instructions
-+ exist, you should define this macro.
-+
-+ However, on some machines, such as the 80386 and the 680x0, truncation only
-+ applies to shift operations and not the (real or pretended) bitfield
-+ operations. Define `SHIFT_COUNT_TRUNCATED' to be zero on such machines.
-+ Instead, add patterns to the `md' file that include the implied truncation
-+ of the shift instructions.
-+
-+ You need not define this macro if it would always have the value of zero. */
-+#define SHIFT_COUNT_TRUNCATED 1
-+
-+/* A C expression which is nonzero if on this machine it is safe to "convert"
-+ an integer of INPREC bits to one of OUTPREC bits (where OUTPREC is smaller
-+ than INPREC) by merely operating on it as if it had only OUTPREC bits.
-+
-+ On many machines, this expression can be 1.
-+
-+ When `TRULY_NOOP_TRUNCATION' returns 1 for a pair of sizes for modes for
-+ which `MODES_TIEABLE_P' is 0, suboptimal code can result. If this is the
-+ case, making `TRULY_NOOP_TRUNCATION' return 0 in such cases may improve
-+ things. */
-+#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
-+
-+/* A C string constant that tells the GNU CC driver program options to pass
-+ to the assembler. It can also specify how to translate options you give
-+ to GNU CC into options for GNU CC to pass to the assembler. See the
-+ file `sun3.h' for an example of this.
-+
-+ Defined in svr4.h. */
-+#undef ASM_SPEC
-+#define ASM_SPEC \
-+ "%{march=*:-m%*} %{!march=*:-mubicom32v4} %{mfdpic:-mfdpic}"
-+
-+#define LINK_SPEC "\
-+%{h*} %{v:-V} \
-+%{b} \
-+%{mfdpic:-melf32ubicom32fdpic -z text} \
-+%{static:-dn -Bstatic} \
-+%{shared:-G -Bdynamic} \
-+%{symbolic:-Bsymbolic} \
-+%{G*} \
-+%{YP,*} \
-+%{Qy:} %{!Qn:-Qy}"
-+
-+#undef STARTFILE_SPEC
-+#undef ENDFILE_SPEC
-+
-+/* The svr4.h LIB_SPEC with -leval and --*group tacked on */
-+
-+#undef LIB_SPEC
-+#define LIB_SPEC "%{!shared:%{!symbolic:--start-group -lc -leval -lgcc --end-group}}"
-+
-+#undef HAVE_GAS_SHF_MERGE
-+#define HAVE_GAS_SHF_MERGE 0
-+
-+#define HANDLE_SYSV_PRAGMA 1
-+#undef HANDLE_PRAGMA_PACK
-+
-+typedef void (*ubicom32_func_ptr) (void);
-+
-+/* Define builtins for selected special-purpose instructions. */
-+enum ubicom32_builtins
-+{
-+ UBICOM32_BUILTIN_UBICOM32_SWAPB_2,
-+ UBICOM32_BUILTIN_UBICOM32_SWAPB_4
-+};
-+
-+extern rtx ubicom32_compare_op0;
-+extern rtx ubicom32_compare_op1;
-+
-+#define TYPE_ASM_OP "\t.type\t"
-+#define TYPE_OPERAND_FMT "@%s"
-+
-+#ifndef ASM_DECLARE_RESULT
-+#define ASM_DECLARE_RESULT(FILE, RESULT)
-+#endif
-+
-+/* These macros generate the special .type and .size directives which
-+ are used to set the corresponding fields of the linker symbol table
-+ entries in an ELF object file under SVR4. These macros also output
-+ the starting labels for the relevant functions/objects. */
-+
-+/* Write the extra assembler code needed to declare a function properly.
-+ Some svr4 assemblers need to also have something extra said about the
-+ function's return value. We allow for that here. */
-+
-+#ifndef ASM_DECLARE_FUNCTION_NAME
-+#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \
-+ do \
-+ { \
-+ ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "function"); \
-+ ASM_DECLARE_RESULT (FILE, DECL_RESULT (DECL)); \
-+ ASM_OUTPUT_LABEL (FILE, NAME); \
-+ } \
-+ while (0)
-+#endif
---- /dev/null
-+++ b/gcc/config/ubicom32/ubicom32.md
-@@ -0,0 +1,3753 @@
-+; GCC machine description for Ubicom32
-+;
-+; Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Free Software
-+; Foundation, Inc.
-+; Contributed by Ubicom, Inc.
-+;
-+; This file is part of GCC.
-+;
-+; GCC is free software; you can redistribute it and/or modify
-+; it under the terms of the GNU General Public License as published by
-+; the Free Software Foundation; either version 3, or (at your option)
-+; any later version.
-+;
-+; GCC is distributed in the hope that it will be useful,
-+; but WITHOUT ANY WARRANTY; without even the implied warranty of
-+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+; GNU General Public License for more details.
-+;
-+; You should have received a copy of the GNU General Public License
-+; along with GCC; see the file COPYING3. If not see
-+; <http://www.gnu.org/licenses/>.
-+
-+(define_constants
-+ [(AUX_DATA_REGNO 15)
-+ (LINK_REGNO 21)
-+ (SP_REGNO 23)
-+ (ACC0_HI_REGNO 24)
-+ (ACC1_HI_REGNO 26)
-+ (CC_REGNO 30)])
-+
-+(define_constants
-+ [(UNSPEC_FDPIC_GOT 0)
-+ (UNSPEC_FDPIC_GOT_FUNCDESC 1)])
-+
-+(define_constants
-+ [(UNSPEC_VOLATILE_LOAD_FDPIC_FUNCDESC 0)])
-+
-+;; Types of instructions (for scheduling purposes).
-+
-+(define_attr "type" "mul,addr,other"
-+ (const_string "other"))
-+
-+; Define instruction scheduling characteristics. We can only issue
-+; one instruction per clock so we don't need to define CPU units.
-+;
-+(define_automaton "ubicom32")
-+
-+(define_cpu_unit "i_pipeline" "ubicom32");
-+
-+; We have a 4 cycle hazard associated with address calculations which
-+; seems rather tricky to avoid so we go with a defensive assumption
-+; that almost anything can be used to generate addresses.
-+;
-+;(define_insn_reservation "ubicom32_other" 4
-+; (eq_attr "type" "other")
-+; "i_pipeline")
-+
-+; Some moves don't generate hazards.
-+;
-+;(define_insn_reservation "ubicom32_addr" 1
-+; (eq_attr "type" "addr")
-+; "i_pipeline")
-+
-+; We need 3 cycles between a multiply instruction and any use of the
-+; matching accumulator register(s).
-+;
-+(define_insn_reservation "ubicom32_mul" 4
-+ (eq_attr "type" "mul")
-+ "i_pipeline")
-+
-+(define_attr "length" ""
-+ (const_int 4))
-+
-+(include "predicates.md")
-+(include "constraints.md")
-+
-+; 8-bit move with no change to the flags reg.
-+;
-+(define_insn "movqi"
-+ [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
-+ (match_operand:QI 1 "ubicom32_move_operand" "g"))]
-+ ""
-+ "move.1\\t%0, %1")
-+
-+; Combiner-generated 8-bit move with the zero flag set accordingly.
-+;
-+(define_insn "movqi_ccszn"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:QI 0 "nonimmediate_operand" "rm")
-+ (const_int 0)))
-+ (set (match_operand:QI 1 "nonimmediate_operand" "=rm")
-+ (match_dup 0))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "ext.1\\t%1, %0")
-+
-+; Combine isn't very good at merging some types of operations so we
-+; have to make do with a peephole. It's not as effective but it's better
-+; than doing nothing.
-+;
-+(define_peephole2
-+ [(set (match_operand:QI 0 "nonimmediate_operand" "")
-+ (match_operand:QI 1 "nonimmediate_operand" ""))
-+ (set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (match_operator 3 "ubicom32_compare_operator"
-+ [(match_dup 0)
-+ (const_int 0)]))]
-+ "(GET_MODE (operands[2]) == CCSZNmode
-+ || GET_MODE (operands[2]) == CCSZmode)"
-+ [(parallel
-+ [(set (match_dup 2)
-+ (match_op_dup 3
-+ [(match_dup 1)
-+ (const_int 0)]))
-+ (set (match_dup 0)
-+ (match_dup 1))])]
-+ "")
-+
-+; Combine isn't very good at merging some types of operations so we
-+; have to make do with a peephole. It's not as effective but it's better
-+; than doing nothing.
-+;
-+(define_peephole2
-+ [(set (match_operand:QI 0 "nonimmediate_operand" "")
-+ (match_operand:QI 1 "nonimmediate_operand" ""))
-+ (set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (match_operator 3 "ubicom32_compare_operator"
-+ [(match_dup 1)
-+ (const_int 0)]))]
-+ "(GET_MODE (operands[2]) == CCSZNmode
-+ || GET_MODE (operands[2]) == CCSZmode)"
-+ [(parallel
-+ [(set (match_dup 2)
-+ (match_op_dup 3
-+ [(match_dup 1)
-+ (const_int 0)]))
-+ (set (match_dup 0)
-+ (match_dup 1))])]
-+ "")
-+
-+; 16-bit move with no change to the flags reg.
-+;
-+(define_insn "movhi"
-+ [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
-+ (match_operand:HI 1 "ubicom32_move_operand" "g"))]
-+ ""
-+ "*
-+ {
-+ if (CONST_INT_P (operands[1]))
-+ return \"movei\\t%0, %1\";
-+
-+ return \"move.2\\t%0, %1\";
-+ }")
-+
-+; Combiner-generated 16-bit move with the zero flag set accordingly.
-+;
-+(define_insn "movhi_ccszn"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:HI 0 "nonimmediate_operand" "rm")
-+ (const_int 0)))
-+ (set (match_operand:HI 1 "nonimmediate_operand" "=rm")
-+ (match_dup 0))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "ext.2\\t%1, %0")
-+
-+; Combine isn't very good at merging some types of operations so we
-+; have to make do with a peephole. It's not as effective but it's better
-+; than doing nothing.
-+;
-+(define_peephole2
-+ [(set (match_operand:HI 0 "nonimmediate_operand" "")
-+ (match_operand:HI 1 "nonimmediate_operand" ""))
-+ (set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (match_operator 3 "ubicom32_compare_operator"
-+ [(match_dup 0)
-+ (const_int 0)]))]
-+ "(GET_MODE (operands[2]) == CCSZNmode
-+ || GET_MODE (operands[2]) == CCSZmode)"
-+ [(parallel
-+ [(set (match_dup 2)
-+ (match_op_dup 3
-+ [(match_dup 1)
-+ (const_int 0)]))
-+ (set (match_dup 0)
-+ (match_dup 1))])]
-+ "")
-+
-+; Combine isn't very good at merging some types of operations so we
-+; have to make do with a peephole. It's not as effective but it's better
-+; than doing nothing.
-+;
-+(define_peephole2
-+ [(set (match_operand:HI 0 "nonimmediate_operand" "")
-+ (match_operand:HI 1 "nonimmediate_operand" ""))
-+ (set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (match_operator 3 "ubicom32_compare_operator"
-+ [(match_dup 1)
-+ (const_int 0)]))]
-+ "(GET_MODE (operands[2]) == CCSZNmode
-+ || GET_MODE (operands[2]) == CCSZmode)"
-+ [(parallel
-+ [(set (match_dup 2)
-+ (match_op_dup 3
-+ [(match_dup 1)
-+ (const_int 0)]))
-+ (set (match_dup 0)
-+ (match_dup 1))])]
-+ "")
-+
-+; 32-bit move with no change to the flags reg.
-+;
-+(define_expand "movsi"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
-+ (match_operand:SI 1 "general_operand" ""))]
-+ ""
-+ "{
-+ /* Convert any complexities in operand 1 into something that can just
-+ fall into the default expander code. */
-+ ubicom32_expand_movsi (operands);
-+ }")
-+
-+(define_insn "movsi_high"
-+ [(set (match_operand:SI 0 "ubicom32_address_register_operand" "=a")
-+ (high:SI (match_operand:SI 1 "ubicom32_symbolic_address_operand" "s")))]
-+ ""
-+ "moveai\\t%0, #%%hi(%E1)")
-+
-+(define_insn "movsi_lo_sum"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (lo_sum:SI (match_operand:SI 1 "ubicom32_address_register_operand" "a")
-+ (match_operand:SI 2 "immediate_operand" "s")))]
-+ ""
-+ "lea.1\\t%0, %%lo(%E2)(%1)")
-+
-+(define_insn "movsi_internal"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (match_operand:SI 1 "ubicom32_move_operand" "rmnY"))]
-+ ""
-+ "*
-+ {
-+ if (CONST_INT_P (operands[1]))
-+ {
-+ ubicom32_emit_move_const_int (operands[0], operands[1]);
-+ return \"\";
-+ }
-+
-+ if (GET_CODE (operands[1]) == CONST_DOUBLE)
-+ {
-+ HOST_WIDE_INT i = CONST_DOUBLE_LOW (operands[1]);
-+
-+ ubicom32_emit_move_const_int (operands[0], GEN_INT (i));
-+ return \"\";
-+ }
-+
-+ if (ubicom32_address_register_operand (operands[0], VOIDmode)
-+ && register_operand (operands[1], VOIDmode))
-+ {
-+ if (ubicom32_address_register_operand (operands[1], VOIDmode))
-+ return \"lea.1\\t%0, 0(%1)\";
-+
-+ /* Use movea here to utilize the hazard bypass in the >= v4 ISA. */
-+ if (ubicom32_v4)
-+ return \"movea\\t%0, %1\";
-+
-+ return \"move.4\\t%0, %1\";
-+ }
-+
-+ return \"move.4\\t%0, %1\";
-+ }")
-+
-+; If we're not dependent on the state of the condition codes we can construct
-+; constants of value 2^n by using a bset.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(exact_log2 (INTVAL (operands[1])) > 14
-+ && peep2_regno_dead_p (0, CC_REGNO))"
-+ [(parallel
-+ [(set (match_dup 0)
-+ (ior:SI (const_int 0)
-+ (match_dup 1)))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "")
-+
-+; If we're not dependent on the state of the condition codes we can construct
-+; constants of value ~(2^n) by using a bclr.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(exact_log2 (~INTVAL (operands[1])) > 14
-+ && peep2_regno_dead_p (0, CC_REGNO))"
-+ [(parallel
-+ [(set (match_dup 0)
-+ (and:SI (const_int -1)
-+ (match_dup 1)))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "")
-+
-+; For 32-bit constants that have bits 0 through 24 and bit 31 set the same
-+; we can use swapb.4!
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(ubicom32_v4
-+ && (INTVAL (operands[1]) & 0xffffffff) != 0xffffffff
-+ && (INTVAL (operands[1]) & 0xffffffff) != 0
-+ && ((INTVAL (operands[1]) & 0x80ffffff) == 0
-+ || (INTVAL (operands[1]) & 0x80ffffff) == 0x80ffffff))"
-+ [(set (match_dup 0)
-+ (bswap:SI (match_dup 2)))]
-+ "{
-+ operands[2] = GEN_INT (INTVAL (operands[1]) >> 24);
-+ }")
-+
-+; If this is a write of a constant to memory look to see if we can usefully
-+; transform this into 2 smaller writes.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "memory_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "! satisfies_constraint_I (operands[1])
-+ && ubicom32_legitimate_address_p (HImode, plus_constant (XEXP (operands[0], 0), 2), 1)"
-+ [(set (match_dup 4) (match_dup 2))
-+ (set (match_dup 5) (match_dup 3))]
-+ "{
-+ rtx low_hword_addr;
-+
-+ operands[2] = gen_highpart_mode (HImode, SImode, operands[1]);
-+ operands[3] = gen_lowpart (HImode, operands[1]);
-+
-+ operands[4] = gen_rtx_MEM (HImode, XEXP (operands[0], 0));
-+ MEM_COPY_ATTRIBUTES (operands[4], operands[0]);
-+
-+ low_hword_addr = plus_constant (XEXP (operands[0], 0), 2);
-+ operands[5] = gen_rtx_MEM (HImode, low_hword_addr);
-+ MEM_COPY_ATTRIBUTES (operands[5], operands[0]);
-+ }")
-+
-+; If we're writing memory and we've not found a better way to do this then
-+; try loading into a D register and then copying to memory. This will
-+; perform the fewest possible memory read/writes.
-+;
-+(define_peephole2
-+ [(match_scratch:SI 2 "d")
-+ (set (match_operand:SI 0 "memory_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "! satisfies_constraint_I (operands[1])"
-+ [(set (match_dup 2) (match_dup 1))
-+ (set (match_dup 0) (match_dup 2))]
-+ "")
-+
-+; If we're not dependent on the state of the condition codes we can construct
-+; constants of value (2^n - 1) by using an lsr.4.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(exact_log2 (INTVAL (operands[1]) + 1) > 14
-+ && peep2_regno_dead_p (0, CC_REGNO))"
-+ [(parallel
-+ [(set (match_dup 0)
-+ (lshiftrt:SI (const_int -1)
-+ (match_dup 2)))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "{
-+ operands[2] = GEN_INT (32 - exact_log2 (INTVAL (operands[1]) + 1));
-+ }")
-+
-+; If we're not dependent on the state of the condition codes we can construct
-+; constants of value (2^n - 1) by using an lsr.4.
-+;
-+(define_peephole2
-+ [(match_scratch:SI 2 "d")
-+ (set (match_operand:SI 0 "nonimmediate_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(exact_log2 (INTVAL (operands[1]) + 1) > 14
-+ && peep2_regno_dead_p (0, CC_REGNO))"
-+ [(parallel
-+ [(set (match_dup 2)
-+ (lshiftrt:SI (const_int -1)
-+ (match_dup 3)))
-+ (clobber (reg:CC CC_REGNO))])
-+ (set (match_dup 0)
-+ (match_dup 2))]
-+ "{
-+ operands[3] = GEN_INT (32 - exact_log2 (INTVAL (operands[1]) + 1));
-+ }")
-+
-+; If we're not dependent on the state of the condition codes we can construct
-+; some other constants by using an lsl.4 to shift 7 bits left by some
-+; constant.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(ubicom32_shiftable_const_int (INTVAL (operands[1]))
-+ && peep2_regno_dead_p (0, CC_REGNO))"
-+ [(parallel
-+ [(set (match_dup 0)
-+ (ashift:SI (match_dup 2)
-+ (match_dup 3)))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "{
-+ int shift = ubicom32_shiftable_const_int (INTVAL (operands[1]));
-+ operands[2] = GEN_INT (INTVAL (operands[1]) >> shift);
-+ operands[3] = GEN_INT (shift);
-+ }")
-+
-+; If we're not dependent on the state of the condition codes we can construct
-+; some other constants by using an lsl.4 to shift 7 bits left by some
-+; constant.
-+;
-+(define_peephole2
-+ [(match_scratch:SI 2 "d")
-+ (set (match_operand:SI 0 "nonimmediate_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(ubicom32_shiftable_const_int (INTVAL (operands[1]))
-+ && peep2_regno_dead_p (0, CC_REGNO))"
-+ [(parallel
-+ [(set (match_dup 2)
-+ (ashift:SI (match_dup 3)
-+ (match_dup 4)))
-+ (clobber (reg:CC CC_REGNO))])
-+ (set (match_dup 0)
-+ (match_dup 2))]
-+ "{
-+ int shift = ubicom32_shiftable_const_int (INTVAL (operands[1]));
-+ operands[3] = GEN_INT (INTVAL (operands[1]) >> shift);
-+ operands[4] = GEN_INT (shift);
-+ }")
-+
-+; For some 16-bit unsigned constants that have bit 15 set we can use
-+; swapb.2!
-+;
-+; Note that the movsi code emits the same sequence but by using a peephole2
-+; we split the pattern early enough to allow instruction scheduling to
-+; occur.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(ubicom32_v4
-+ && (INTVAL (operands[1]) & 0xffff80ff) == 0x80ff)"
-+ [(set (match_dup 0)
-+ (zero_extend:SI (bswap:HI (match_dup 2))))]
-+ "{
-+ HOST_WIDE_INT i = INTVAL (operands[1]) >> 8;
-+ if (i >= 0x80)
-+ i -= 0x100;
-+ operands[2] = GEN_INT (i);
-+ }")
-+
-+; In general for a 16-bit unsigned constant that has bit 15 set
-+; then we need a movei/move.2 pair unless we can represent it
-+; via just a move.2.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(INTVAL (operands[1]) & 0xffff8000) == 0x8000
-+ && (INTVAL (operands[1]) & 0xffff) < 0xff80"
-+ [(set (match_dup 2)
-+ (match_dup 1))
-+ (set (match_dup 0)
-+ (zero_extend:SI (match_dup 2)))]
-+ "{
-+ operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));
-+ }")
-+
-+; If we're not dependent on the state of the condition codes we can construct
-+; 32-bit constants that have bits 16 through 31 set to arbitrary values
-+; and have bits 0 through 15 set to something representable as a default
-+; source-1 immediate - we use movei/shmrg.2
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(((INTVAL (operands[1]) >= 0x8000
-+ && INTVAL (operands[1]) < 0xff80)
-+ || INTVAL (operands[1]) >= 0x10000
-+ || INTVAL (operands[1]) < -0x8000)
-+ && ((INTVAL (operands[1]) & 0xffff) >= 0xff80
-+ || (INTVAL (operands[1]) & 0xffff) < 0x80)
-+ && peep2_regno_dead_p (0, CC_REGNO))"
-+ [(set (match_dup 0)
-+ (match_dup 2))
-+ (parallel
-+ [(set (match_dup 0)
-+ (ior:SI
-+ (ashift:SI (match_dup 0)
-+ (const_int 16))
-+ (zero_extend:SI
-+ (match_dup 3))))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "{
-+ operands[2] = gen_highpart_mode (HImode, SImode, operands[1]);
-+ operands[3] = gen_lowpart (HImode, operands[1]);
-+ }")
-+
-+; Exactly the same as the peephole2 preceding except that this targets a
-+; general register instead of D register. Hopefully the later optimization
-+; passes will notice that the value ended up in a D register first here
-+; and eliminate away the other register!
-+;
-+(define_peephole2
-+ [(match_scratch:SI 2 "d")
-+ (set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(((INTVAL (operands[1]) >= 0x8000
-+ && INTVAL (operands[1]) < 0xff80)
-+ || INTVAL (operands[1]) >= 0x10000
-+ || INTVAL (operands[1]) < -0x8000)
-+ && ((INTVAL (operands[1]) & 0xffff) >= 0xff80
-+ || (INTVAL (operands[1]) & 0xffff) < 0x80)
-+ && peep2_regno_dead_p (0, CC_REGNO))"
-+ [(set (match_dup 2)
-+ (match_dup 3))
-+ (parallel
-+ [(set (match_dup 2)
-+ (ior:SI
-+ (ashift:SI (match_dup 2)
-+ (const_int 16))
-+ (zero_extend:SI
-+ (match_dup 4))))
-+ (clobber (reg:CC CC_REGNO))])
-+ (set (match_dup 0)
-+ (match_dup 2))]
-+ "{
-+ operands[3] = gen_highpart_mode (HImode, SImode, operands[1]);
-+ operands[4] = gen_lowpart (HImode, operands[1]);
-+ }")
-+
-+; If we have a load of a large integer constant which does not have bit 31
-+; set and we have a spare A reg then construct it with a moveai/lea.1 pair
-+; instead. This avoids constructing it in 3 instructions on the stack.
-+;
-+; Note that we have to be careful not to match anything that matches
-+; something we can do in a single instruction! There aren't many such
-+; constants but there are some.
-+;
-+(define_peephole2
-+ [(match_scratch:SI 2 "a")
-+ (set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(! (INTVAL (operands[1]) & 0x80000000)
-+ && ((INTVAL (operands[1]) >= 0x8000
-+ && INTVAL (operands[1]) < 0xff80)
-+ || INTVAL (operands[1]) >= 0x10000))"
-+ [(set (match_dup 2)
-+ (match_dup 3))
-+ (set (match_dup 0)
-+ (plus:SI (match_dup 2)
-+ (match_dup 4)))]
-+ "{
-+ HOST_WIDE_INT i = INTVAL (operands[1]);
-+ operands[3] = GEN_INT (i & 0xffffff80);
-+ operands[4] = GEN_INT (i & 0x7f);
-+ }")
-+
-+; If we're not dependent on the state of the condition codes we can construct
-+; a 32-bit constant with a movei/movei/shmrg.2 sequence if possible.
-+;
-+(define_peephole2
-+ [(match_scratch:HI 2 "d")
-+ (set (match_operand:SI 0 "ubicom32_data_register_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))
-+ (match_dup 2)]
-+ "(INTVAL (operands[1]) & 0x80000000
-+ && INTVAL (operands[1]) < -0x8000
-+ && peep2_regno_dead_p (0, CC_REGNO))"
-+ [(set (match_dup 0)
-+ (match_dup 3))
-+ (set (match_dup 2)
-+ (match_dup 4))
-+ (parallel
-+ [(set (match_dup 0)
-+ (ior:SI
-+ (ashift:SI (match_dup 0)
-+ (const_int 16))
-+ (zero_extend:SI
-+ (match_dup 2))))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "{
-+ operands[3] = gen_highpart_mode (HImode, SImode, operands[1]);
-+ operands[4] = gen_lowpart (HImode, operands[1]);
-+ }")
-+
-+; Exactly the same as the peephole2 preceding except that this targets a
-+; general register instead of D register. Hopefully the later optimization
-+; passes will notice that the value ended up in a D register first here
-+; and eliminate away the other register!
-+;
-+(define_peephole2
-+ [(match_scratch:SI 2 "d")
-+ (match_scratch:HI 3 "d")
-+ (set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))
-+ (match_dup 3)]
-+ "(INTVAL (operands[1]) & 0x80000000
-+ && INTVAL (operands[1]) < -0x8000
-+ && peep2_regno_dead_p (0, CC_REGNO))"
-+ [(set (match_dup 2)
-+ (match_dup 4))
-+ (set (match_dup 3)
-+ (match_dup 5))
-+ (parallel
-+ [(set (match_dup 2)
-+ (ior:SI
-+ (ashift:SI (match_dup 2)
-+ (const_int 16))
-+ (zero_extend:SI
-+ (match_dup 3))))
-+ (clobber (reg:CC CC_REGNO))])
-+ (set (match_dup 0)
-+ (match_dup 2))]
-+ "{
-+ operands[4] = gen_highpart_mode (HImode, SImode, operands[1]);
-+ operands[5] = gen_lowpart (HImode, operands[1]);
-+ }")
-+
-+(define_insn "movsi_fdpic_got_offset"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (match_operand:SI 1 "ubicom32_fdpic_got_offset_operand" "Y"))]
-+ ""
-+ "movei\\t%0, %1")
-+
-+; The explicit MEM inside the UNSPEC prevents the compiler from moving
-+; the load before a branch after a NULL test, or before a store that
-+; initializes a function descriptor.
-+
-+(define_insn_and_split "load_fdpic_funcdesc"
-+ [(set (match_operand:SI 0 "ubicom32_address_register_operand" "=a")
-+ (unspec_volatile:SI [(mem:SI (match_operand:SI 1 "address_operand" "p"))]
-+ UNSPEC_VOLATILE_LOAD_FDPIC_FUNCDESC))]
-+ ""
-+ "#"
-+ "reload_completed"
-+ [(set (match_dup 0)
-+ (mem:SI (match_dup 1)))])
-+
-+; Combiner-generated 32-bit move with the zero flag set accordingly.
-+;
-+(define_insn "movsi_ccwzn"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:SI 0 "nonimmediate_operand" "rm, d")
-+ (const_int 0)))
-+ (set (match_operand:SI 1 "nonimmediate_operand" "=d,rm")
-+ (match_dup 0))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "@
-+ lsl.4\\t%1, %0, #0
-+ add.4\\t%1, #0, %0")
-+
-+; Combiner-generated 32-bit move with all flags set accordingly.
-+;
-+(define_insn "movsi_ccw"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:SI 0 "ubicom32_data_register_operand" "d")
-+ (const_int 0)))
-+ (set (match_operand:SI 1 "nonimmediate_operand" "=rm")
-+ (match_dup 0))]
-+ "ubicom32_match_cc_mode(insn, CCWmode)"
-+ "add.4\\t%1, #0, %0")
-+
-+; Combine isn't very good at merging some types of operations so we
-+; have to make do with a peephole. It's not as effective but it's better
-+; than doing nothing.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "")
-+ (match_operand:SI 1 "nonimmediate_operand" ""))
-+ (parallel
-+ [(set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (match_operator 3 "ubicom32_compare_operator"
-+ [(match_dup 0)
-+ (const_int 0)]))
-+ (clobber (match_operand:SI 4 "ubicom32_data_register_operand" ""))])]
-+ "(GET_MODE (operands[2]) == CCWZNmode
-+ || GET_MODE (operands[2]) == CCWZmode)"
-+ [(parallel
-+ [(set (match_dup 2)
-+ (match_op_dup 3
-+ [(match_dup 1)
-+ (const_int 0)]))
-+ (set (match_dup 0)
-+ (match_dup 1))])]
-+ "")
-+
-+; Combine isn't very good at merging some types of operations so we
-+; have to make do with a peephole. It's not as effective but it's better
-+; than doing nothing.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
-+ (match_operand:SI 1 "ubicom32_data_register_operand" ""))
-+ (parallel
-+ [(set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (match_operator 3 "ubicom32_compare_operator"
-+ [(match_dup 1)
-+ (const_int 0)]))
-+ (clobber (match_operand:SI 4 "ubicom32_data_register_operand" ""))])]
-+ "(GET_MODE (operands[2]) == CCWZNmode
-+ || GET_MODE (operands[2]) == CCWZmode)"
-+ [(parallel
-+ [(set (match_dup 2)
-+ (match_op_dup 3
-+ [(match_dup 1)
-+ (const_int 0)]))
-+ (set (match_dup 0)
-+ (match_dup 1))])]
-+ "")
-+
-+; Combine isn't very good at merging some types of operations so we
-+; have to make do with a peephole. It's not as effective but it's better
-+; than doing nothing.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "nonimmediate_operand" ""))
-+ (parallel
-+ [(set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (match_operator 3 "ubicom32_compare_operator"
-+ [(match_dup 0)
-+ (const_int 0)]))
-+ (set (match_operand:SI 4 "ubicom32_data_register_operand" "")
-+ (match_dup 0))])]
-+ "(peep2_reg_dead_p (2, operands[0])
-+ && (GET_MODE (operands[2]) == CCWZNmode
-+ || GET_MODE (operands[2]) == CCWZmode))"
-+ [(parallel
-+ [(set (match_dup 2)
-+ (match_op_dup 3
-+ [(match_dup 1)
-+ (const_int 0)]))
-+ (set (match_dup 4)
-+ (match_dup 1))])]
-+ "")
-+
-+; Register renaming may make a general reg into a D reg in which case
-+; we may be able to simplify a compare.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "nonimmediate_operand" ""))
-+ (parallel
-+ [(set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (match_operator 3 "ubicom32_compare_operator"
-+ [(match_dup 0)
-+ (const_int 0)]))
-+ (clobber (match_operand:SI 4 "ubicom32_data_register_operand" ""))])]
-+ "(peep2_reg_dead_p (2, operands[0])
-+ && (GET_MODE (operands[2]) == CCWZNmode
-+ || GET_MODE (operands[2]) == CCWZmode))"
-+ [(parallel
-+ [(set (match_dup 2)
-+ (match_op_dup 3
-+ [(match_dup 1)
-+ (const_int 0)]))
-+ (clobber (match_dup 4))])]
-+ "")
-+
-+(define_insn_and_split "movdi"
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
-+ (match_operand:DI 1 "general_operand" "rmi,ri"))]
-+ ""
-+ "#"
-+ "reload_completed"
-+ [(set (match_dup 2) (match_dup 3))
-+ (set (match_dup 4) (match_dup 5))]
-+ "{
-+ rtx dest_low;
-+ rtx src_low;
-+
-+ dest_low = gen_lowpart (SImode, operands[0]);
-+ src_low = gen_lowpart (SImode, operands[1]);
-+
-+ if (REG_P (operands[0])
-+ && REG_P (operands[1])
-+ && REGNO (operands[0]) < REGNO (operands[1]))
-+ {
-+ operands[2] = gen_highpart (SImode, operands[0]);
-+ operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
-+ operands[4] = dest_low;
-+ operands[5] = src_low;
-+ }
-+ else if (reg_mentioned_p (dest_low, src_low))
-+ {
-+ operands[2] = gen_highpart (SImode, operands[0]);
-+ operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
-+ operands[4] = dest_low;
-+ operands[5] = src_low;
-+ }
-+ else
-+ {
-+ operands[2] = dest_low;
-+ operands[3] = src_low;
-+ operands[4] = gen_highpart (SImode, operands[0]);
-+ operands[5] = gen_highpart_mode (SImode, DImode, operands[1]);
-+ }
-+ }"
-+ [(set_attr "length" "8")])
-+
-+; Combiner-generated 64-bit move with all flags set accordingly.
-+;
-+(define_insn "movdi_ccwzn"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:DI 0 "nonimmediate_operand" "d, m, r")
-+ (const_int 0)))
-+ (set (match_operand:DI 1 "nonimmediate_operand" "=&rm,rm,!&rm")
-+ (match_dup 0))
-+ (clobber (match_scratch:SI 2 "=X, d, d"))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "*
-+ {
-+ operands[3] = gen_lowpart (SImode, operands[0]);
-+ operands[4] = gen_lowpart (SImode, operands[1]);
-+ operands[5] = gen_highpart (SImode, operands[0]);
-+ operands[6] = gen_highpart (SImode, operands[1]);
-+
-+ if (ubicom32_data_register_operand (operands[0], VOIDmode))
-+ return \"add.4\\t%4, #0, %3\;addc\\t%6, #0, %5\";
-+
-+ return \"movei\\t%2, #0\;add.4\\t%4, %3, %2\;addc\\t%6, %5, %2\";
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_insn "movdi_ccw"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:DI 0 "nonimmediate_operand" "d, m, r")
-+ (const_int 0)))
-+ (set (match_operand:DI 1 "nonimmediate_operand" "=&rm,rm,!&rm")
-+ (match_dup 0))
-+ (clobber (match_scratch:SI 2 "=X, d, d"))]
-+ "ubicom32_match_cc_mode(insn, CCWmode)"
-+ "*
-+ {
-+ operands[3] = gen_lowpart (SImode, operands[0]);
-+ operands[4] = gen_lowpart (SImode, operands[1]);
-+ operands[5] = gen_highpart (SImode, operands[0]);
-+ operands[6] = gen_highpart (SImode, operands[1]);
-+
-+ if (ubicom32_data_register_operand (operands[0], VOIDmode))
-+ return \"add.4\\t%4, #0, %3\;addc\\t%6, #0, %5\";
-+
-+ return \"movei\\t%2, #0\;add.4\\t%4, %3, %2\;addc\\t%6, %5, %2\";
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_insn "movsf"
-+ [(set (match_operand:SF 0 "nonimmediate_operand" "=!d,*rm")
-+ (match_operand:SF 1 "ubicom32_move_operand" "rmF,rmF"))]
-+ ""
-+ "*
-+ {
-+ if (GET_CODE (operands[1]) == CONST_DOUBLE)
-+ {
-+ HOST_WIDE_INT val;
-+ REAL_VALUE_TYPE rv;
-+
-+ REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
-+ REAL_VALUE_TO_TARGET_SINGLE (rv, val);
-+
-+ ubicom32_emit_move_const_int (operands[0], GEN_INT (val));
-+ return \"\";
-+ }
-+
-+ return \"move.4\\t%0, %1\";
-+ }")
-+
-+(define_insn "zero_extendqihi2"
-+ [(set (match_operand:HI 0 "register_operand" "=r")
-+ (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
-+ ""
-+ "move.1\\t%0, %1")
-+
-+(define_insn "zero_extendqisi2"
-+ [(set (match_operand:SI 0 "register_operand" "=r")
-+ (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
-+ ""
-+ "move.1\\t%0, %1")
-+
-+(define_insn "zero_extendqisi2_ccwz_1"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "rm"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (zero_extend:SI (match_dup 1)))]
-+ "ubicom32_match_cc_mode(insn, CCWZmode)"
-+ "shmrg.1\\t%0, %1, #0")
-+
-+(define_insn "zero_extendhisi2"
-+ [(set (match_operand:SI 0 "register_operand" "=r")
-+ (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
-+ ""
-+ "move.2\\t%0, %1")
-+
-+(define_insn "zero_extendhisi2_ccwz_1"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (zero_extend:SI (match_dup 1)))]
-+ "ubicom32_match_cc_mode(insn, CCWZmode)"
-+ "shmrg.2\\t%0, %1, #0")
-+
-+(define_insn_and_split "zero_extendqidi2"
-+ [(set (match_operand:DI 0 "register_operand" "=r")
-+ (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
-+ ""
-+ "#"
-+ "reload_completed"
-+ [(set (match_dup 2)
-+ (zero_extend:SI (match_dup 1)))
-+ (set (match_dup 3)
-+ (const_int 0))]
-+ "{
-+ operands[2] = gen_lowpart (SImode, operands[0]);
-+ operands[3] = gen_highpart (SImode, operands[0]);
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_insn_and_split "zero_extendhidi2"
-+ [(set (match_operand:DI 0 "register_operand" "=r")
-+ (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
-+ ""
-+ "#"
-+ "reload_completed"
-+ [(set (match_dup 2)
-+ (zero_extend:SI (match_dup 1)))
-+ (set (match_dup 3)
-+ (const_int 0))]
-+ "{
-+ operands[2] = gen_lowpart (SImode, operands[0]);
-+ operands[3] = gen_highpart (SImode, operands[0]);
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_insn_and_split "zero_extendsidi2"
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
-+ (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
-+ ""
-+ "#"
-+ "reload_completed"
-+ [(set (match_dup 2)
-+ (match_dup 1))
-+ (set (match_dup 3)
-+ (const_int 0))]
-+ "{
-+ operands[2] = gen_lowpart (SImode, operands[0]);
-+ operands[3] = gen_highpart (SImode, operands[0]);
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_insn "extendqihi2"
-+ [(set (match_operand:HI 0 "register_operand" "=r")
-+ (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "rm")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "ext.1\\t%0, %1")
-+
-+(define_insn "extendqisi2"
-+ [(set (match_operand:SI 0 "register_operand" "=r")
-+ (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "rm")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "ext.1\\t%0, %1")
-+
-+(define_insn "extendhisi2"
-+ [(set (match_operand:SI 0 "register_operand" "=r")
-+ (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "ext.2\\t%0, %1")
-+
-+(define_insn_and_split "extendsidi2"
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "=d")
-+ (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "#"
-+ "reload_completed"
-+ [(set (match_dup 2)
-+ (match_dup 1))
-+ (parallel
-+ [(set (match_dup 3)
-+ (ashiftrt:SI (match_dup 2)
-+ (const_int 31)))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "{
-+ operands[2] = gen_lowpart (SImode, operands[0]);
-+ operands[3] = gen_highpart (SImode, operands[0]);
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_insn "bswaphi"
-+ [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
-+ (bswap:HI (match_operand:HI 1 "ubicom32_arith_operand" "rmI")))]
-+ "(ubicom32_v4)"
-+ "swapb.2\\t%0, %1");
-+
-+(define_insn "bswaphisi"
-+ [(set (match_operand:SI 0 "register_operand" "=r")
-+ (zero_extend:SI
-+ (bswap:HI (match_operand:HI 1 "ubicom32_arith_operand" "rmI"))))]
-+ "(ubicom32_v4)"
-+ "swapb.2\\t%0, %1");
-+
-+(define_insn "bswapsi"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (bswap:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")))]
-+ "(ubicom32_v4)"
-+ "swapb.4\\t%0, %1");
-+
-+(define_insn "tstqi_ext1"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:QI 0 "nonimmediate_operand" "rm")
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "ext.1\\t#0, %0")
-+
-+(define_expand "cmpqi"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:QI 0 "ubicom32_arith_operand" "")
-+ (match_operand:QI 1 "ubicom32_data_register_operand" "")))]
-+ "(ubicom32_v4)"
-+ "{
-+ ubicom32_compare_op0 = operands[0];
-+ ubicom32_compare_op1 = operands[1];
-+ DONE;
-+ }")
-+
-+(define_insn "sub1_ccs"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:QI 0 "ubicom32_arith_operand" "rmI")
-+ (match_operand:QI 1 "ubicom32_data_register_operand" "d")))]
-+ "(ubicom32_v4)"
-+ "sub.1\\t#0, %0, %1")
-+
-+; If we're testing for equality we don't have to worry about reversing conditions.
-+;
-+(define_insn "sub1_ccsz_1"
-+ [(set (reg:CCSZ CC_REGNO)
-+ (compare:CCSZ (match_operand:QI 0 "nonimmediate_operand" "rm")
-+ (match_operand:QI 1 "ubicom32_data_register_operand" "d")))]
-+ "(ubicom32_v4)"
-+ "sub.1\\t#0, %0, %1")
-+
-+(define_insn "sub1_ccsz_2"
-+ [(set (reg:CCSZ CC_REGNO)
-+ (compare:CCSZ (match_operand:QI 0 "ubicom32_data_register_operand" "d")
-+ (match_operand:QI 1 "ubicom32_arith_operand" "rmI")))]
-+ "(ubicom32_v4)"
-+ "sub.1\\t#0, %1, %0")
-+
-+; When the combiner runs it doesn't have any insight into whether or not an argument
-+; to a compare is spilled to the stack and therefore can't swap the comparison in
-+; an attempt to use sub.1 more effectively. We peephole this case here.
-+;
-+(define_peephole2
-+ [(set (match_operand:QI 0 "register_operand" "")
-+ (match_operand:QI 1 "ubicom32_arith_operand" ""))
-+ (set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (compare (match_operand:QI 3 "ubicom32_data_register_operand" "")
-+ (match_dup 0)))
-+ (set (pc)
-+ (if_then_else (match_operator 4 "comparison_operator"
-+ [(match_dup 2)
-+ (const_int 0)])
-+ (label_ref (match_operand 5 "" ""))
-+ (pc)))]
-+ "(peep2_reg_dead_p (2, operands[0])
-+ && peep2_regno_dead_p (3, CC_REGNO))"
-+ [(set (match_dup 2)
-+ (compare (match_dup 1)
-+ (match_dup 3)))
-+ (set (pc)
-+ (if_then_else (match_op_dup 6
-+ [(match_dup 2)
-+ (const_int 0)])
-+ (label_ref (match_dup 5))
-+ (pc)))]
-+ "{
-+ rtx cc_reg;
-+
-+ cc_reg = gen_rtx_REG (GET_MODE (operands[2]), CC_REGNO);
-+ operands[6] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[4])),
-+ GET_MODE (operands[4]),
-+ cc_reg,
-+ const0_rtx);
-+ }")
-+
-+(define_insn "tsthi_ext2"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:HI 0 "nonimmediate_operand" "rm")
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "ext.2\\t#0, %0")
-+
-+(define_expand "cmphi"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:HI 0 "ubicom32_arith_operand" "")
-+ (match_operand:HI 1 "ubicom32_compare_operand" "")))]
-+ ""
-+ "{
-+ do
-+ {
-+ /* Is this a cmpi? */
-+ if (CONST_INT_P (operands[1]))
-+ break;
-+
-+ /* Must be a sub.2 - if necessary copy an operand into a reg. */
-+ if (! ubicom32_data_register_operand (operands[1], HImode))
-+ operands[1] = copy_to_mode_reg (HImode, operands[1]);
-+ }
-+ while (0);
-+
-+ ubicom32_compare_op0 = operands[0];
-+ ubicom32_compare_op1 = operands[1];
-+ DONE;
-+ }")
-+
-+(define_insn "cmpi"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:HI 0 "nonimmediate_operand" "rm")
-+ (match_operand 1 "const_int_operand" "N")))]
-+ ""
-+ "cmpi\\t%0, %1")
-+
-+(define_insn "sub2_ccs"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:HI 0 "ubicom32_arith_operand" "rmI")
-+ (match_operand:HI 1 "ubicom32_data_register_operand" "d")))]
-+ ""
-+ "sub.2\\t#0, %0, %1")
-+
-+; If we're testing for equality we don't have to worry about reversing conditions.
-+;
-+(define_insn "sub2_ccsz_1"
-+ [(set (reg:CCSZ CC_REGNO)
-+ (compare:CCSZ (match_operand:HI 0 "nonimmediate_operand" "rm")
-+ (match_operand:HI 1 "ubicom32_data_register_operand" "d")))]
-+ ""
-+ "sub.2\\t#0, %0, %1")
-+
-+(define_insn "sub2_ccsz_2"
-+ [(set (reg:CCSZ CC_REGNO)
-+ (compare:CCSZ (match_operand:HI 0 "ubicom32_data_register_operand" "d")
-+ (match_operand:HI 1 "ubicom32_arith_operand" "rmI")))]
-+ ""
-+ "sub.2\\t#0, %1, %0")
-+
-+; When the combiner runs it doesn't have any insight into whether or not an argument
-+; to a compare is spilled to the stack and therefore can't swap the comparison in
-+; an attempt to use sub.2 more effectively. We peephole this case here.
-+;
-+(define_peephole2
-+ [(set (match_operand:HI 0 "register_operand" "")
-+ (match_operand:HI 1 "ubicom32_arith_operand" ""))
-+ (set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (compare (match_operand:HI 3 "ubicom32_data_register_operand" "")
-+ (match_dup 0)))
-+ (set (pc)
-+ (if_then_else (match_operator 4 "comparison_operator"
-+ [(match_dup 2)
-+ (const_int 0)])
-+ (label_ref (match_operand 5 "" ""))
-+ (pc)))]
-+ "(peep2_reg_dead_p (2, operands[0])
-+ && peep2_regno_dead_p (3, CC_REGNO))"
-+ [(set (match_dup 2)
-+ (compare (match_dup 1)
-+ (match_dup 3)))
-+ (set (pc)
-+ (if_then_else (match_op_dup 6
-+ [(match_dup 2)
-+ (const_int 0)])
-+ (label_ref (match_dup 5))
-+ (pc)))]
-+ "{
-+ rtx cc_reg;
-+
-+ cc_reg = gen_rtx_REG (GET_MODE (operands[2]), CC_REGNO);
-+ operands[6] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[4])),
-+ GET_MODE (operands[4]),
-+ cc_reg,
-+ const0_rtx);
-+ }")
-+
-+(define_insn_and_split "tstsi_lsl4"
-+ [(set (match_operand 0 "ubicom32_cc_register_operand" "=r")
-+ (match_operator 1 "ubicom32_compare_operator"
-+ [(match_operand:SI 2 "nonimmediate_operand" "rm")
-+ (const_int 0)]))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "#"
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ [(parallel
-+ [(set (match_dup 0)
-+ (match_op_dup 1
-+ [(match_dup 2)
-+ (const_int 0)]))
-+ (clobber (match_dup 3))])]
-+ "{
-+ operands[3] = gen_reg_rtx (SImode);
-+ }")
-+
-+(define_insn "tstsi_lsl4_d"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:SI 0 "nonimmediate_operand" "rm")
-+ (const_int 0)))
-+ (clobber (match_operand:SI 1 "ubicom32_data_register_operand" "=d"))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "lsl.4\\t%1, %0, #0")
-+
-+; Comparison for equality with -1.
-+;
-+(define_insn "cmpsi_not4_ccwz"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:SI 0 "nonimmediate_operand" "rm")
-+ (const_int -1)))]
-+ "ubicom32_match_cc_mode(insn, CCWZmode)"
-+ "not.4\\t#0, %0")
-+
-+(define_expand "cmpsi"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:SI 0 "ubicom32_arith_operand" "")
-+ (match_operand:SI 1 "ubicom32_compare_operand" "")))]
-+ ""
-+ "{
-+ do
-+ {
-+ /* Is this a cmpi? We can't take a memory address as cmpi takes
-+ 16-bit operands. */
-+ if (register_operand (operands[0], SImode)
-+ && CONST_INT_P (operands[1])
-+ && satisfies_constraint_N (operands[1]))
-+ break;
-+
-+ /* Must be a sub.4 - if necessary copy an operand into a reg. */
-+ if (! ubicom32_data_register_operand (operands[1], SImode))
-+ operands[1] = copy_to_mode_reg (SImode, operands[1]);
-+ }
-+ while (0);
-+
-+ ubicom32_compare_op0 = operands[0];
-+ ubicom32_compare_op1 = operands[1];
-+ DONE;
-+ }")
-+
-+(define_insn "cmpsi_cmpi"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:SI 0 "register_operand" "r")
-+ (match_operand 1 "const_int_operand" "N")))]
-+ "(satisfies_constraint_N (operands[1]))"
-+ "cmpi\\t%0, %1")
-+
-+(define_insn "cmpsi_sub4"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:SI 0 "ubicom32_arith_operand" "rmI")
-+ (match_operand:SI 1 "ubicom32_data_register_operand" "d")))]
-+ ""
-+ "sub.4\\t#0, %0, %1")
-+
-+; If we're testing for equality we don't have to worry about reversing conditions.
-+;
-+(define_insn "cmpsi_sub4_ccwz_1"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:SI 0 "nonimmediate_operand" "rm")
-+ (match_operand:SI 1 "ubicom32_data_register_operand" "d")))]
-+ "ubicom32_match_cc_mode(insn, CCWZmode)"
-+ "sub.4\\t#0, %0, %1")
-+
-+(define_insn "cmpsi_sub4_ccwz_2"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:SI 0 "ubicom32_data_register_operand" "d")
-+ (match_operand:SI 1 "nonimmediate_operand" "rm")))]
-+ "ubicom32_match_cc_mode(insn, CCWZmode)"
-+ "sub.4\\t#0, %1, %0")
-+
-+; When the combiner runs it doesn't have any insight into whether or not an argument
-+; to a compare is spilled to the stack and therefore can't swap the comparison in
-+; an attempt to use sub.4 more effectively. We peephole this case here.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "ubicom32_arith_operand" ""))
-+ (set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (compare (match_operand:SI 3 "ubicom32_data_register_operand" "")
-+ (match_dup 0)))
-+ (set (pc)
-+ (if_then_else (match_operator 4 "comparison_operator"
-+ [(match_dup 2)
-+ (const_int 0)])
-+ (label_ref (match_operand 5 "" ""))
-+ (pc)))]
-+ "(peep2_reg_dead_p (2, operands[0])
-+ && peep2_regno_dead_p (3, CC_REGNO))"
-+ [(set (match_dup 2)
-+ (compare (match_dup 1)
-+ (match_dup 3)))
-+ (set (pc)
-+ (if_then_else (match_op_dup 6
-+ [(match_dup 2)
-+ (const_int 0)])
-+ (label_ref (match_dup 5))
-+ (pc)))]
-+ "{
-+ rtx cc_reg;
-+
-+ cc_reg = gen_rtx_REG (GET_MODE (operands[2]), CC_REGNO);
-+ operands[6] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[4])),
-+ GET_MODE (operands[4]),
-+ cc_reg,
-+ const0_rtx);
-+ }")
-+
-+(define_insn_and_split "tstdi_or4"
-+ [(set (reg:CCWZ CC_REGNO)
-+ (compare:CCWZ (match_operand:DI 0 "nonimmediate_operand" "rm")
-+ (const_int 0)))]
-+ ""
-+ "#"
-+ ""
-+ [(parallel
-+ [(set (reg:CCWZ CC_REGNO)
-+ (compare:CCWZ (match_dup 0)
-+ (const_int 0)))
-+ (clobber (match_dup 1))])]
-+ "{
-+ operands[1] = gen_reg_rtx (SImode);
-+ }")
-+
-+(define_insn "tstdi_or4_d"
-+ [(set (reg:CCWZ CC_REGNO)
-+ (compare:CCWZ (match_operand:DI 0 "nonimmediate_operand" "rm")
-+ (const_int 0)))
-+ (clobber (match_operand:SI 1 "ubicom32_data_register_operand" "=d"))]
-+ ""
-+ "*
-+ {
-+ operands[2] = gen_lowpart (SImode, operands[0]);
-+ operands[3] = gen_highpart_mode (SImode, DImode, operands[0]);
-+
-+ if (ubicom32_data_register_operand (operands[0], GET_MODE (operands[0])))
-+ return \"or.4\\t#0, %2, %3\";
-+
-+ return \"move.4\\t%1, %2\;or.4\\t%1, %3, %1\";
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_expand "cmpdi"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:DI 0 "ubicom32_arith_operand" "")
-+ (match_operand:DI 1 "ubicom32_data_register_operand" "")))]
-+ ""
-+ "{
-+ ubicom32_compare_op0 = operands[0];
-+ ubicom32_compare_op1 = operands[1];
-+ DONE;
-+ }")
-+
-+(define_insn "cmpdi_sub4subc"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:DI 0 "ubicom32_arith_operand" "rmI")
-+ (match_operand:DI 1 "ubicom32_data_register_operand" "d")))]
-+ ""
-+ "*
-+ {
-+ operands[2] = gen_lowpart (SImode, operands[0]);
-+ operands[3] = gen_lowpart (SImode, operands[1]);
-+ operands[4] = gen_highpart_mode (SImode, DImode, operands[0]);
-+ operands[5] = gen_highpart_mode (SImode, DImode, operands[1]);
-+
-+ return \"sub.4\\t#0, %2, %3\;subc\\t#0, %4, %5\";
-+ }"
-+ [(set_attr "length" "8")])
-+
-+; When the combiner runs it doesn't have any insight into whether or not an argument
-+; to a compare is spilled to the stack and therefore can't swap the comparison in
-+; an attempt to use sub.4/subc more effectively. We peephole this case here.
-+;
-+(define_peephole2
-+ [(set (match_operand:DI 0 "register_operand" "")
-+ (match_operand:DI 1 "ubicom32_arith_operand" ""))
-+ (set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (compare (match_operand:DI 3 "ubicom32_data_register_operand" "")
-+ (match_dup 0)))
-+ (set (pc)
-+ (if_then_else (match_operator 4 "comparison_operator"
-+ [(match_dup 2)
-+ (const_int 0)])
-+ (label_ref (match_operand 5 "" ""))
-+ (pc)))]
-+ "(peep2_reg_dead_p (2, operands[0])
-+ && peep2_regno_dead_p (3, CC_REGNO))"
-+ [(set (match_dup 2)
-+ (compare (match_dup 1)
-+ (match_dup 3)))
-+ (set (pc)
-+ (if_then_else (match_op_dup 6
-+ [(match_dup 2)
-+ (const_int 0)])
-+ (label_ref (match_dup 5))
-+ (pc)))]
-+ "{
-+ rtx cc_reg;
-+
-+ cc_reg = gen_rtx_REG (GET_MODE (operands[2]), CC_REGNO);
-+ operands[6] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[4])),
-+ GET_MODE (operands[4]),
-+ cc_reg,
-+ const0_rtx);
-+ }")
-+
-+(define_insn "btst"
-+ [(set (reg:CCWZ CC_REGNO)
-+ (compare:CCWZ
-+ (zero_extract:SI
-+ (match_operand:SI 0 "nonimmediate_operand" "rm")
-+ (const_int 1)
-+ (match_operand:SI 1 "ubicom32_arith_operand" "dM"))
-+ (const_int 0)))]
-+ ""
-+ "btst\\t%0, %1")
-+
-+(define_insn "bfextu_ccwz_null"
-+ [(set (reg:CCWZ CC_REGNO)
-+ (compare:CCWZ
-+ (zero_extract:SI
-+ (match_operand:SI 0 "nonimmediate_operand" "rm")
-+ (match_operand 1 "const_int_operand" "M")
-+ (const_int 0))
-+ (const_int 0)))
-+ (clobber (match_scratch:SI 2 "=d"))]
-+ ""
-+ "bfextu\\t%2, %0, %1")
-+
-+(define_expand "addqi3"
-+ [(parallel
-+ [(set (match_operand:QI 0 "memory_operand" "")
-+ (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
-+ (match_operand:QI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "(ubicom32_v4)"
-+ "{
-+ if (!memory_operand (operands[0], QImode))
-+ FAIL;
-+
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (QImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (QImode, operands[2]);
-+ }")
-+
-+(define_insn "addqi3_add1"
-+ [(set (match_operand:QI 0 "memory_operand" "=m, m")
-+ (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:QI 2 "ubicom32_arith_operand" "rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4)"
-+ "@
-+ add.1\\t%0, %2, %1
-+ add.1\\t%0, %1, %2")
-+
-+(define_insn "addqi3_add1_ccszn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (neg:QI (match_operand:QI 0 "nonimmediate_operand" "%d,rm"))
-+ (match_operand:QI 1 "ubicom32_arith_operand" "rmI, d")))]
-+ "(ubicom32_v4
-+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
-+ "@
-+ add.1\\t#0, %1, %0
-+ add.1\\t#0, %0, %1")
-+
-+(define_expand "addhi3"
-+ [(parallel
-+ [(set (match_operand:HI 0 "memory_operand" "")
-+ (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
-+ (match_operand:HI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ ""
-+ "{
-+ if (!memory_operand (operands[0], HImode))
-+ FAIL;
-+
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (HImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (HImode, operands[2]);
-+ }")
-+
-+(define_insn "addhi3_add2"
-+ [(set (match_operand:HI 0 "memory_operand" "=m, m")
-+ (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:HI 2 "ubicom32_arith_operand" "rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "@
-+ add.2\\t%0, %2, %1
-+ add.2\\t%0, %1, %2")
-+
-+(define_insn "addhi3_add2_ccszn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (neg:HI (match_operand:HI 0 "nonimmediate_operand" "%d,rm"))
-+ (match_operand:HI 1 "ubicom32_arith_operand" "rmI, d")))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "@
-+ add.2\\t#0, %1, %0
-+ add.2\\t#0, %0, %1")
-+
-+(define_expand "addsi3"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
-+ (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
-+ (match_operand:SI 2 "ubicom32_move_operand" "")))]
-+ ""
-+ "{
-+ ubicom32_expand_addsi3 (operands);
-+ DONE;
-+ }")
-+
-+; We start with an instruction pattern that can do all sorts of interesting
-+; things but we split out any uses of lea or pdec instructions because
-+; those instructions don't clobber the condition codes.
-+;
-+(define_insn_and_split "addsi3_1"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm,rm,rm,rm, rm,rm")
-+ (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%a, a, a, a, a, d,rm")
-+ (match_operand:SI 2 "ubicom32_move_operand" "L, K, J, P, d,rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "@
-+ #
-+ #
-+ #
-+ #
-+ #
-+ add.4\\t%0, %2, %1
-+ add.4\\t%0, %1, %2"
-+ "(reload_completed
-+ && ubicom32_address_register_operand (operands[1], GET_MODE (operands[1])))"
-+ [(set (match_dup 0)
-+ (plus:SI (match_dup 1)
-+ (match_dup 2)))]
-+ ""
-+)
-+
-+(define_insn "addsi3_1_ccwzn"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
-+ (plus:SI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "@
-+ add.4\\t%0, %2, %1
-+ add.4\\t%0, %1, %2")
-+
-+(define_insn "addsi3_1_ccwzn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (neg:SI (match_operand:SI 0 "nonimmediate_operand" "%d,rm"))
-+ (match_operand:SI 1 "ubicom32_arith_operand" "rmI, d")))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "@
-+ add.4\\t#0, %1, %0
-+ add.4\\t#0, %0, %1")
-+
-+(define_insn_and_split "addsi3_2"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm,rm,rm,rm,rm")
-+ (plus:SI (match_operand:SI 1 "ubicom32_address_register_operand" "%a, a, a, a, a, a")
-+ (match_operand:SI 2 "ubicom32_move_operand" "L, K, J, P, d, n")))]
-+ ""
-+ "@
-+ lea.4\\t%0, %E2(%1)
-+ lea.2\\t%0, %E2(%1)
-+ lea.1\\t%0, %E2(%1)
-+ pdec\\t%0, %n2(%1)
-+ lea.1\\t%0, (%1,%2)
-+ #"
-+ "(reload_completed
-+ && ! satisfies_constraint_L (operands[2])
-+ && ! satisfies_constraint_K (operands[2])
-+ && ! satisfies_constraint_J (operands[2])
-+ && ! satisfies_constraint_P (operands[2])
-+ && ! ubicom32_data_register_operand (operands[2], GET_MODE (operands[2])))"
-+ [(set (reg:SI AUX_DATA_REGNO)
-+ (match_dup 2))
-+ (set (match_dup 0)
-+ (plus:SI (match_dup 1)
-+ (reg:SI AUX_DATA_REGNO)))]
-+ ""
-+)
-+
-+(define_insn "lea_2"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (plus:SI (mult:SI (match_operand:SI 1 "ubicom32_data_register_operand" "d")
-+ (const_int 2))
-+ (match_operand:SI 2 "ubicom32_address_register_operand" "a")))]
-+ ""
-+ "lea.2\\t%0, (%2,%1)")
-+
-+(define_insn "lea_4"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (plus:SI (mult:SI (match_operand:SI 1 "ubicom32_data_register_operand" "d")
-+ (const_int 4))
-+ (match_operand:SI 2 "ubicom32_address_register_operand" "a")))]
-+ ""
-+ "lea.4\\t%0, (%2,%1)")
-+
-+(define_expand "adddi3"
-+ [(parallel
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "")
-+ (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
-+ (match_operand:DI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ ""
-+ "{
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (DImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (DImode, operands[2]);
-+ }")
-+
-+; We construct a 64-bit add from 32-bit operations. Note that we use the
-+; & constraint to prevent overlapping registers being allocated. We do
-+; allow identical registers though as that won't break anything.
-+;
-+(define_insn "adddi3_add4addc"
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,&r,rm, d, m, m")
-+ (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%d,rm, 0, 0, d,rm")
-+ (match_operand:DI 2 "ubicom32_arith_operand" "rmI, d, d,rmI,rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "*
-+ {
-+ operands[3] = gen_lowpart (SImode, operands[0]);
-+ operands[4] = gen_lowpart (SImode, operands[1]);
-+ operands[5] = gen_lowpart (SImode, operands[2]);
-+ operands[6] = gen_highpart (SImode, operands[0]);
-+ operands[7] = gen_highpart (SImode, operands[1]);
-+ operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
-+
-+ if (ubicom32_data_register_operand (operands[2], GET_MODE (operands[2])))
-+ return \"add.4\\t%3, %4, %5\;addc\\t%6, %7, %8\";
-+
-+ return \"add.4\\t%3, %5, %4\;addc\\t%6, %8, %7\";
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_insn "adddi3_ccwz"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%d,rm, 0, 0, d,rm")
-+ (match_operand:DI 2 "ubicom32_arith_operand" "rmI, d, d,rmI,rmI, d"))
-+ (const_int 0)))
-+ (set (match_operand:DI 0 "nonimmediate_operand" "=&r,&r,rm, d, m, m")
-+ (plus:DI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "*
-+ {
-+ operands[3] = gen_lowpart (SImode, operands[0]);
-+ operands[6] = gen_highpart (SImode, operands[0]);
-+
-+ if (ubicom32_data_register_operand (operands[1], GET_MODE (operands[1])))
-+ {
-+ operands[4] = gen_lowpart (SImode, operands[1]);
-+ operands[5] = gen_lowpart (SImode, operands[2]);
-+ operands[7] = gen_highpart (SImode, operands[1]);
-+ operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
-+ }
-+ else
-+ {
-+ operands[4] = gen_lowpart (SImode, operands[2]);
-+ operands[5] = gen_lowpart (SImode, operands[1]);
-+ operands[7] = gen_highpart (SImode, operands[2]);
-+ operands[8] = gen_highpart (SImode, operands[1]);
-+ }
-+
-+ return \"add.4\\t%3, %5, %4\;addc\\t%6, %8, %7\";
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_insn "adddi3_ccwz_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (neg:DI (match_operand:DI 0 "nonimmediate_operand" "%d,rm"))
-+ (match_operand:DI 1 "ubicom32_arith_operand" "rmI, d")))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "*
-+ {
-+ if (ubicom32_data_register_operand (operands[0], GET_MODE (operands[0])))
-+ {
-+ operands[2] = gen_lowpart (SImode, operands[0]);
-+ operands[3] = gen_lowpart (SImode, operands[1]);
-+ operands[4] = gen_highpart (SImode, operands[0]);
-+ operands[5] = gen_highpart_mode (SImode, DImode, operands[1]);
-+ }
-+ else
-+ {
-+ operands[2] = gen_lowpart (SImode, operands[1]);
-+ operands[3] = gen_lowpart (SImode, operands[0]);
-+ operands[4] = gen_highpart (SImode, operands[1]);
-+ operands[5] = gen_highpart (SImode, operands[0]);
-+ }
-+
-+ return \"add.4\\t#0, %3, %2\;addc\\t#0, %5, %4\";
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_expand "subqi3"
-+ [(parallel
-+ [(set (match_operand:QI 0 "memory_operand" "")
-+ (minus:QI (match_operand:QI 1 "ubicom32_arith_operand" "")
-+ (match_operand:QI 2 "ubicom32_data_register_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "(ubicom32_v4)"
-+ "{
-+ if (!memory_operand (operands[0], QImode))
-+ FAIL;
-+ }")
-+
-+(define_insn "subqi3_sub1"
-+ [(set (match_operand:QI 0 "memory_operand" "=m")
-+ (minus:QI (match_operand:QI 1 "ubicom32_arith_operand" "rmI")
-+ (match_operand:QI 2 "ubicom32_data_register_operand" "d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4)"
-+ "sub.1\\t%0, %1, %2")
-+
-+(define_expand "subhi3"
-+ [(parallel
-+ [(set (match_operand:HI 0 "memory_operand" "")
-+ (minus:HI (match_operand:HI 1 "ubicom32_arith_operand" "")
-+ (match_operand:HI 2 "ubicom32_data_register_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "(ubicom32_v4)"
-+ "{
-+ if (!memory_operand (operands[0], HImode))
-+ FAIL;
-+ }")
-+
-+(define_insn "subhi3_sub2"
-+ [(set (match_operand:HI 0 "memory_operand" "=m")
-+ (minus:HI (match_operand:HI 1 "ubicom32_arith_operand" "rmI")
-+ (match_operand:HI 2 "ubicom32_data_register_operand" "d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "sub.2\\t%0, %1, %2")
-+
-+(define_insn "subsi3"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (minus:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")
-+ (match_operand:SI 2 "ubicom32_data_register_operand" "d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "sub.4\\t%0, %1, %2")
-+
-+(define_insn "subsi3_ccwz"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (minus:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")
-+ (match_operand:SI 2 "ubicom32_data_register_operand" "d"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (minus:SI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "sub.4\\t%0, %1, %2")
-+
-+; We construct a 64-bit add from 32-bit operations. Note that we use the
-+; & constraint to prevent overlapping registers being allocated. We do
-+; allow identical registers though as that won't break anything.
-+;
-+(define_insn "subdi3"
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,r, d, m")
-+ (minus:DI (match_operand:DI 1 "ubicom32_arith_operand" "rmI,0,rmI,rmI")
-+ (match_operand:DI 2 "ubicom32_data_register_operand" "d,d, 0, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "*
-+ {
-+ operands[3] = gen_lowpart (SImode, operands[0]);
-+ operands[4] = gen_lowpart (SImode, operands[1]);
-+ operands[5] = gen_lowpart (SImode, operands[2]);
-+ operands[6] = gen_highpart (SImode, operands[0]);
-+ operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
-+ operands[8] = gen_highpart (SImode, operands[2]);
-+
-+ return \"sub.4\\t%3, %4, %5\;subc\\t%6, %7, %8\";
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_insn "subdi3_ccwz"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (minus:DI (match_operand:DI 1 "ubicom32_arith_operand" "rmI,rmI")
-+ (match_operand:DI 2 "ubicom32_data_register_operand" "d, d"))
-+ (const_int 0)))
-+ (set (match_operand:DI 0 "nonimmediate_operand" "=&r, m")
-+ (minus:DI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "*
-+ {
-+ operands[3] = gen_lowpart (SImode, operands[0]);
-+ operands[4] = gen_lowpart (SImode, operands[1]);
-+ operands[5] = gen_lowpart (SImode, operands[2]);
-+ operands[6] = gen_highpart (SImode, operands[0]);
-+ operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
-+ operands[8] = gen_highpart (SImode, operands[2]);
-+
-+ return \"sub.4\\t%3, %4, %5\;subc\\t%6, %7, %8\";
-+ }"
-+ [(set_attr "length" "8")])
-+
-+;(define_insn "negqi2"
-+; [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
-+; (neg:QI (match_operand:QI 1 "ubicom32_data_register_operand" "d")))
-+; (clobber (reg:CC CC_REGNO))]
-+; "(ubicom32_v4)"
-+; "sub.1\\t%0, #0, %1")
-+
-+;(define_insn "neghi2"
-+; [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
-+; (neg:HI (match_operand:HI 1 "ubicom32_data_register_operand" "d")))
-+; (clobber (reg:CC CC_REGNO))]
-+; ""
-+; "sub.2\\t%0, #0, %1")
-+
-+(define_insn "negsi2"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (neg:SI (match_operand:SI 1 "ubicom32_data_register_operand" "d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "sub.4\\t%0, #0, %1")
-+
-+(define_insn_and_split "negdi2"
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "=&rm")
-+ (neg:DI (match_operand:DI 1 "ubicom32_data_register_operand" "d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "#"
-+ "reload_completed"
-+ [(parallel [(set (match_dup 0)
-+ (minus:DI (const_int 0)
-+ (match_dup 1)))
-+ (clobber (reg:CC CC_REGNO))])]
-+ ""
-+ [(set_attr "length" "8")])
-+
-+(define_insn "umulhisi3"
-+ [(set (match_operand:SI 0 "ubicom32_acc_lo_register_operand" "=l, l")
-+ (mult:SI
-+ (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "%d,rm"))
-+ (zero_extend:SI (match_operand:HI 2 "nonimmediate_operand" "rm, d"))))
-+ (clobber (reg:HI ACC0_HI_REGNO))
-+ (clobber (reg:HI ACC1_HI_REGNO))]
-+ ""
-+ "@
-+ mulu\\t%A0, %2, %1
-+ mulu\\t%A0, %1, %2"
-+ [(set_attr "type" "mul,mul")])
-+
-+(define_insn "mulhisi3"
-+ [(set (match_operand:SI 0 "ubicom32_acc_lo_register_operand" "=l, l")
-+ (mult:SI
-+ (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "%d,rm"))
-+ (sign_extend:SI (match_operand:HI 2 "nonimmediate_operand" "rm, d"))))
-+ (clobber (reg:HI ACC0_HI_REGNO))
-+ (clobber (reg:HI ACC1_HI_REGNO))]
-+ ""
-+ "@
-+ muls\\t%A0, %2, %1
-+ muls\\t%A0, %1, %2"
-+ [(set_attr "type" "mul,mul")])
-+
-+(define_expand "mulsi3"
-+ [(set (match_operand:SI 0 "ubicom32_acc_hi_register_operand" "")
-+ (mult:SI (match_operand:SI 1 "ubicom32_arith_operand" "")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "")))]
-+ ""
-+ "{
-+ if (ubicom32_emit_mult_sequence (operands))
-+ DONE;
-+ }")
-+
-+(define_insn "umulsidi3"
-+ [(set (match_operand:DI 0 "ubicom32_acc_hi_register_operand" "=h, h")
-+ (mult:DI
-+ (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%d,rm"))
-+ (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm, d"))))]
-+ "(ubicom32_v4)"
-+ "@
-+ mulu.4\\t%A0, %2, %1
-+ mulu.4\\t%A0, %1, %2"
-+ [(set_attr "type" "mul,mul")])
-+
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "nonimmediate_operand" ""))
-+ (set (match_operand:DI 2 "ubicom32_acc_hi_register_operand" "")
-+ (mult:DI
-+ (zero_extend:DI (match_dup 0))
-+ (zero_extend:DI (match_operand:SI 3 "ubicom32_data_register_operand" ""))))]
-+ "(peep2_reg_dead_p (2, operands[0])
-+ || REGNO (operands[0]) == REGNO (operands[2])
-+ || REGNO (operands[0]) == REGNO (operands[2]) + 1)
-+ && ! rtx_equal_p (operands[0], operands[3])"
-+ [(set (match_dup 2)
-+ (mult:DI
-+ (zero_extend:DI (match_dup 1))
-+ (zero_extend:DI (match_dup 3))))]
-+ "")
-+
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "nonimmediate_operand" ""))
-+ (set (match_operand:DI 2 "ubicom32_acc_hi_register_operand" "")
-+ (mult:DI
-+ (zero_extend:DI (match_operand:SI 3 "ubicom32_data_register_operand" ""))
-+ (zero_extend:DI (match_dup 0))))]
-+ "(peep2_reg_dead_p (2, operands[0])
-+ || REGNO (operands[0]) == REGNO (operands[2])
-+ || REGNO (operands[0]) == REGNO (operands[2]) + 1)
-+ && ! rtx_equal_p (operands[0], operands[3])"
-+ [(set (match_dup 2)
-+ (mult:DI
-+ (zero_extend:DI (match_dup 1))
-+ (zero_extend:DI (match_dup 3))))]
-+ "")
-+
-+(define_insn "umulsidi3_const"
-+ [(set (match_operand:DI 0 "ubicom32_acc_hi_register_operand" "=h")
-+ (mult:DI
-+ (zero_extend:DI (match_operand:SI 1 "ubicom32_data_register_operand" "%d"))
-+ (match_operand 2 "const_int_operand" "I")))]
-+ "(ubicom32_v4 && satisfies_constraint_I (operands[2]))"
-+ "mulu.4\\t%A0, %2, %1"
-+ [(set_attr "type" "mul")])
-+
-+(define_insn "mulsidi3"
-+ [(set (match_operand:DI 0 "ubicom32_acc_hi_register_operand" "=h, h")
-+ (mult:DI
-+ (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%d,rm"))
-+ (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm, d"))))]
-+ "(ubicom32_v4)"
-+ "@
-+ muls.4\\t%A0, %2, %1
-+ muls.4\\t%A0, %1, %2"
-+ [(set_attr "type" "mul,mul")])
-+
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "nonimmediate_operand" ""))
-+ (set (match_operand:DI 2 "ubicom32_acc_hi_register_operand" "")
-+ (mult:DI
-+ (sign_extend:DI (match_dup 0))
-+ (sign_extend:DI (match_operand:SI 3 "ubicom32_data_register_operand" ""))))]
-+ "(peep2_reg_dead_p (2, operands[0])
-+ || REGNO (operands[0]) == REGNO (operands[2])
-+ || REGNO (operands[0]) == REGNO (operands[2]) + 1)
-+ && ! rtx_equal_p (operands[0], operands[3])"
-+ [(set (match_dup 2)
-+ (mult:DI
-+ (sign_extend:DI (match_dup 1))
-+ (sign_extend:DI (match_dup 3))))]
-+ "")
-+
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "nonimmediate_operand" ""))
-+ (set (match_operand:DI 2 "ubicom32_acc_hi_register_operand" "")
-+ (mult:DI
-+ (sign_extend:DI (match_operand:SI 3 "ubicom32_data_register_operand" ""))
-+ (sign_extend:DI (match_dup 0))))]
-+ "(peep2_reg_dead_p (2, operands[0])
-+ || REGNO (operands[0]) == REGNO (operands[2])
-+ || REGNO (operands[0]) == REGNO (operands[2]) + 1)
-+ && ! rtx_equal_p (operands[0], operands[3])"
-+ [(set (match_dup 2)
-+ (mult:DI
-+ (sign_extend:DI (match_dup 1))
-+ (sign_extend:DI (match_dup 3))))]
-+ "")
-+
-+(define_insn "mulsidi3_const"
-+ [(set (match_operand:DI 0 "ubicom32_acc_hi_register_operand" "=h")
-+ (mult:DI
-+ (sign_extend:DI (match_operand:SI 1 "ubicom32_data_register_operand" "%d"))
-+ (match_operand 2 "const_int_operand" "I")))]
-+ "(ubicom32_v4 && satisfies_constraint_I (operands[2]))"
-+ "muls.4\\t%A0, %2, %1"
-+ [(set_attr "type" "mul")])
-+
-+(define_expand "andqi3"
-+ [(parallel
-+ [(set (match_operand:QI 0 "memory_operand" "")
-+ (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
-+ (match_operand:QI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "(ubicom32_v4)"
-+ "{
-+ if (!memory_operand (operands[0], QImode))
-+ FAIL;
-+
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (QImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (QImode, operands[2]);
-+ }")
-+
-+(define_insn "andqi3_and1"
-+ [(set (match_operand:QI 0 "memory_operand" "=m, m")
-+ (and:QI (match_operand:QI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:QI 2 "ubicom32_arith_operand" "rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4)"
-+ "@
-+ and.1\\t%0, %2, %1
-+ and.1\\t%0, %1, %2")
-+
-+(define_insn "andqi3_and1_ccszn"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (and:QI (match_operand:QI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:QI 2 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))
-+ (set (match_operand:QI 0 "memory_operand" "=m, m")
-+ (and:QI (match_dup 1)
-+ (match_dup 2)))]
-+ "(ubicom32_v4
-+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
-+ "@
-+ and.1\\t%0, %2, %1
-+ and.1\\t%0, %1, %2")
-+
-+(define_insn "andqi3_and1_ccszn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (and:QI (match_operand:QI 0 "nonimmediate_operand" "%d,rm")
-+ (match_operand:QI 1 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))]
-+ "(ubicom32_v4
-+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
-+ "@
-+ and.1\\t#0, %1, %0
-+ and.1\\t#0, %0, %1")
-+
-+(define_insn "and1_ccszn_null_1"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:QI
-+ (and:SI (match_operand:SI 0 "ubicom32_data_register_operand" "%d")
-+ (match_operand:SI 1 "ubicom32_arith_operand" "rI"))
-+ 3)
-+ (const_int 0)))]
-+ "(ubicom32_v4
-+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
-+ "and.1\\t#0, %1, %0")
-+
-+(define_insn "and1_ccszn_null_2"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:QI
-+ (and:SI (match_operand:SI 0 "ubicom32_data_register_operand" "d")
-+ (subreg:SI
-+ (match_operand:QI 1 "memory_operand" "m")
-+ 0))
-+ 3)
-+ (const_int 0)))]
-+ "(ubicom32_v4
-+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
-+ "and.1\\t#0, %1, %0")
-+
-+(define_insn "and1_ccszn_null_3"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:QI
-+ (and:SI (subreg:SI
-+ (match_operand:QI 0 "memory_operand" "m")
-+ 0)
-+ (match_operand:SI 1 "ubicom32_data_register_operand" "d"))
-+ 3)
-+ (const_int 0)))]
-+ "(ubicom32_v4
-+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
-+ "and.1\\t#0, %0, %1")
-+
-+(define_expand "andhi3"
-+ [(parallel
-+ [(set (match_operand:HI 0 "memory_operand" "")
-+ (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
-+ (match_operand:HI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ ""
-+ "{
-+ if (!memory_operand (operands[0], HImode))
-+ FAIL;
-+
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (HImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (HImode, operands[2]);
-+ }")
-+
-+(define_insn "andhi3_and2"
-+ [(set (match_operand:HI 0 "memory_operand" "=m, m")
-+ (and:HI (match_operand:HI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:HI 2 "ubicom32_arith_operand" "rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "@
-+ and.2\\t%0, %2, %1
-+ and.2\\t%0, %1, %2")
-+
-+(define_insn "andhi3_and2_ccszn"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (and:HI (match_operand:HI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:HI 2 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))
-+ (set (match_operand:HI 0 "memory_operand" "=m, m")
-+ (and:HI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "@
-+ and.2\\t%0, %2, %1
-+ and.2\\t%0, %1, %2")
-+
-+(define_insn "andhi3_and2_ccszn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (and:HI (match_operand:HI 0 "nonimmediate_operand" "%d,rm")
-+ (match_operand:HI 1 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "@
-+ and.2\\t#0, %1, %0
-+ and.2\\t#0, %0, %1")
-+
-+(define_insn "and2_ccszn_null_1"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:HI
-+ (and:SI (match_operand:SI 0 "ubicom32_data_register_operand" "%d")
-+ (match_operand:SI 1 "ubicom32_arith_operand" "rI"))
-+ 2)
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "and.2\\t#0, %1, %0")
-+
-+(define_insn "and2_ccszn_null_2"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:HI
-+ (and:SI (match_operand:SI 0 "ubicom32_data_register_operand" "d")
-+ (subreg:SI
-+ (match_operand:HI 1 "memory_operand" "m")
-+ 0))
-+ 2)
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "and.2\\t#0, %1, %0")
-+
-+(define_insn "and2_ccszn_null_3"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:HI
-+ (and:SI (subreg:SI
-+ (match_operand:HI 0 "memory_operand" "m")
-+ 0)
-+ (match_operand:SI 1 "ubicom32_data_register_operand" "d"))
-+ 2)
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "and.2\\t#0, %0, %1")
-+
-+(define_expand "andsi3"
-+ [(parallel
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
-+ (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
-+ (match_operand:SI 2 "ubicom32_and_or_si3_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ ""
-+ "{
-+ do
-+ {
-+ /* Is this a bfextu? */
-+ if (ubicom32_data_register_operand (operands[0], SImode)
-+ && CONST_INT_P (operands[2])
-+ && exact_log2 (INTVAL (operands[2]) + 1) != -1)
-+ break;
-+
-+ /* Is this a bclr? */
-+ if (CONST_INT_P (operands[2])
-+ && exact_log2 (~INTVAL (operands[2])) != -1)
-+ break;
-+
-+ /* Must be an and.4 */
-+ if (!ubicom32_data_register_operand (operands[1], SImode))
-+ operands[1] = copy_to_mode_reg (SImode, operands[1]);
-+
-+ if (!ubicom32_arith_operand (operands[2], SImode))
-+ operands[2] = copy_to_mode_reg (SImode, operands[2]);
-+ }
-+ while (0);
-+ }")
-+
-+(define_insn "andsi3_bfextu"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (and:SI (match_operand:SI 1 "nonimmediate_operand" "%rm")
-+ (match_operand:SI 2 "const_int_operand" "O")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(satisfies_constraint_O (operands[2]))"
-+ "*
-+ {
-+ operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2]) + 1));
-+
-+ return \"bfextu\\t%0, %1, %3\";
-+ }")
-+
-+(define_insn "andsi3_bfextu_ccwz"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (and:SI (match_operand:SI 1 "nonimmediate_operand" "%rm")
-+ (match_operand:SI 2 "const_int_operand" "O"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (and:SI (match_dup 1)
-+ (match_dup 2)))]
-+ "(satisfies_constraint_O (operands[2])
-+ && ubicom32_match_cc_mode(insn, CCWZmode))"
-+ "*
-+ {
-+ operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2]) + 1));
-+
-+ return \"bfextu\\t%0, %1, %3\";
-+ }")
-+
-+(define_insn "andsi3_bfextu_ccwz_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (and:SI (match_operand:SI 0 "nonimmediate_operand" "%rm")
-+ (match_operand:SI 1 "const_int_operand" "O"))
-+ (const_int 0)))
-+ (clobber (match_scratch:SI 2 "=d"))]
-+ "(satisfies_constraint_O (operands[1])
-+ && ubicom32_match_cc_mode(insn, CCWZmode))"
-+ "*
-+ {
-+ operands[3] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1));
-+
-+ return \"bfextu\\t%2, %0, %3\";
-+ }")
-+
-+(define_insn "andsi3_bclr"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (and:SI (match_operand:SI 1 "ubicom32_arith_operand" "%rmI")
-+ (match_operand:SI 2 "const_int_operand" "n")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(exact_log2 (~INTVAL (operands[2])) != -1)"
-+ "bclr\\t%0, %1, #%D2")
-+
-+(define_insn "andsi3_and4"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
-+ (and:SI (match_operand:SI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "@
-+ and.4\\t%0, %2, %1
-+ and.4\\t%0, %1, %2")
-+
-+(define_insn "andsi3_and4_ccwzn"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (and:SI (match_operand:SI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
-+ (and:SI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "@
-+ and.4\\t%0, %2, %1
-+ and.4\\t%0, %1, %2")
-+
-+(define_insn "andsi3_and4_ccwzn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (and:SI (match_operand:SI 0 "nonimmediate_operand" "%d,rm")
-+ (match_operand:SI 1 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "@
-+ and.4\\t#0, %1, %0
-+ and.4\\t#0, %0, %1")
-+
-+(define_insn "andsi3_lsr4_ccwz_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (and:SI (match_operand:SI 0 "nonimmediate_operand" "%rm")
-+ (match_operand:SI 1 "const_int_operand" "n"))
-+ (const_int 0)))
-+ (clobber (match_scratch:SI 2 "=d"))]
-+ "(exact_log2 ((~(INTVAL (operands[1]))) + 1) != -1
-+ && ubicom32_match_cc_mode(insn, CCWZmode))"
-+ "*
-+ {
-+ operands[3] = GEN_INT (exact_log2 ((~(INTVAL (operands[1]))) + 1));
-+
-+ return \"lsr.4\\t%2, %0, %3\";
-+ }")
-+
-+; We really would like the combiner to recognize this scenario and deal with
-+; it but unfortunately it tries to canonicalize zero_extract ops on MEMs
-+; into QImode operations and we can't match them in any useful way.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))
-+ (set (reg:CCWZ CC_REGNO)
-+ (compare:CCWZ
-+ (and:SI (match_operand:SI 2 "nonimmediate_operand" "")
-+ (match_dup 0))
-+ (const_int 0)))]
-+ "(exact_log2 (INTVAL (operands[1])) != -1
-+ && peep2_reg_dead_p (2, operands[0]))"
-+ [(set (reg:CCWZ CC_REGNO)
-+ (compare:CCWZ
-+ (zero_extract:SI
-+ (match_dup 2)
-+ (const_int 1)
-+ (match_dup 3))
-+ (const_int 0)))]
-+ "{
-+ operands[3] = GEN_INT (exact_log2 (INTVAL (operands[1])));
-+ }")
-+
-+(define_expand "anddi3"
-+ [(parallel
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "")
-+ (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
-+ (match_operand:DI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ ""
-+ "{
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (DImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (DImode, operands[2]);
-+ }")
-+
-+(define_insn_and_split "anddi3_and4"
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,&r, d,rm, m, m")
-+ (and:DI (match_operand:DI 1 "nonimmediate_operand" "%d,rm, 0, 0, d,rm")
-+ (match_operand:DI 2 "ubicom32_arith_operand" "rmI, d,rmI, d,rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "#"
-+ "reload_completed"
-+ [(parallel [(set (match_dup 3)
-+ (and:SI (match_dup 4)
-+ (match_dup 5)))
-+ (clobber (reg:CC CC_REGNO))])
-+ (parallel [(set (match_dup 6)
-+ (and:SI (match_dup 7)
-+ (match_dup 8)))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "{
-+ operands[3] = gen_lowpart (SImode, operands[0]);
-+ operands[4] = gen_lowpart (SImode, operands[1]);
-+ operands[5] = gen_lowpart (SImode, operands[2]);
-+ operands[6] = gen_highpart (SImode, operands[0]);
-+ operands[7] = gen_highpart (SImode, operands[1]);
-+ operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_expand "iorqi3"
-+ [(parallel
-+ [(set (match_operand:QI 0 "memory_operand" "")
-+ (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
-+ (match_operand:QI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "(ubicom32_v4)"
-+ "{
-+ if (!memory_operand (operands[0], QImode))
-+ FAIL;
-+
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (QImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (QImode, operands[2]);
-+ }")
-+
-+(define_insn "iorqi3_or1"
-+ [(set (match_operand:QI 0 "memory_operand" "=m, m")
-+ (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:QI 2 "ubicom32_arith_operand" "rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4)"
-+ "@
-+ or.1\\t%0, %2, %1
-+ or.1\\t%0, %1, %2")
-+
-+(define_expand "iorhi3"
-+ [(parallel
-+ [(set (match_operand:HI 0 "memory_operand" "")
-+ (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
-+ (match_operand:HI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ ""
-+ "{
-+ if (!memory_operand (operands[0], HImode))
-+ FAIL;
-+
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (HImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (HImode, operands[2]);
-+ }")
-+
-+(define_insn "iorhi3_or2"
-+ [(set (match_operand:HI 0 "memory_operand" "=m, m")
-+ (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:HI 2 "ubicom32_arith_operand" "rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "@
-+ or.2\\t%0, %2, %1
-+ or.2\\t%0, %1, %2")
-+
-+(define_expand "iorsi3"
-+ [(parallel
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
-+ (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
-+ (match_operand:SI 2 "ubicom32_and_or_si3_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ ""
-+ "{
-+ do
-+ {
-+ /* Is this a bset? */
-+ if (CONST_INT_P (operands[2])
-+ && exact_log2 (INTVAL (operands[2])) != -1)
-+ break;
-+
-+ /* Must be an or.4 */
-+ if (!ubicom32_data_register_operand (operands[1], SImode))
-+ operands[1] = copy_to_mode_reg (SImode, operands[1]);
-+
-+ if (!ubicom32_arith_operand (operands[2], SImode))
-+ operands[2] = copy_to_mode_reg (SImode, operands[2]);
-+ }
-+ while (0);
-+ }")
-+
-+(define_insn "iorsi3_bset"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (ior:SI (match_operand:SI 1 "ubicom32_arith_operand" "%rmI")
-+ (match_operand 2 "const_int_operand" "n")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(exact_log2 (INTVAL (operands[2])) != -1)"
-+ "bset\\t%0, %1, #%d2")
-+
-+(define_insn "iorsi3_or4"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
-+ (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "@
-+ or.4\\t%0, %2, %1
-+ or.4\\t%0, %1, %2")
-+
-+(define_insn "iorsi3_ccwzn"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
-+ (ior:SI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "@
-+ or.4\\t%0, %2, %1
-+ or.4\\t%0, %1, %2")
-+
-+(define_insn "iorsi3_ccwzn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (ior:SI (match_operand:SI 0 "nonimmediate_operand" "%d,rm")
-+ (match_operand:SI 1 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "@
-+ or.4\\t#0, %1, %0
-+ or.4\\t#0, %0, %1")
-+
-+(define_expand "iordi3"
-+ [(parallel
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "")
-+ (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
-+ (match_operand:DI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ ""
-+ "{
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (DImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (DImode, operands[2]);
-+ }")
-+
-+(define_insn_and_split "iordi3_or4"
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,&r, d,rm, m, m")
-+ (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%d,rm, 0, 0, d,rm")
-+ (match_operand:DI 2 "ubicom32_arith_operand" "rmI, d,rmI, d,rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "#"
-+ "reload_completed"
-+ [(parallel [(set (match_dup 3)
-+ (ior:SI (match_dup 4)
-+ (match_dup 5)))
-+ (clobber (reg:CC CC_REGNO))])
-+ (parallel [(set (match_dup 6)
-+ (ior:SI (match_dup 7)
-+ (match_dup 8)))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "{
-+ operands[3] = gen_lowpart (SImode, operands[0]);
-+ operands[4] = gen_lowpart (SImode, operands[1]);
-+ operands[5] = gen_lowpart (SImode, operands[2]);
-+ operands[6] = gen_highpart (SImode, operands[0]);
-+ operands[7] = gen_highpart (SImode, operands[1]);
-+ operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_expand "xorqi3"
-+ [(parallel
-+ [(set (match_operand:QI 0 "memory_operand" "")
-+ (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
-+ (match_operand:QI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "(ubicom32_v4)"
-+ "{
-+ if (!memory_operand (operands[0], QImode))
-+ FAIL;
-+
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (QImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (QImode, operands[2]);
-+ }")
-+
-+(define_insn "xorqi3_xor1"
-+ [(set (match_operand:QI 0 "memory_operand" "=m, m")
-+ (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:QI 2 "ubicom32_arith_operand" "rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4)"
-+ "@
-+ xor.1\\t%0, %2, %1
-+ xor.1\\t%0, %1, %2")
-+
-+(define_insn "xorqi3_xor1_ccszn"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:QI 2 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))
-+ (set (match_operand:QI 0 "memory_operand" "=m, m")
-+ (xor:QI (match_dup 1)
-+ (match_dup 2)))]
-+ "(ubicom32_v4
-+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
-+ "@
-+ xor.1\\t%0, %2, %1
-+ xor.1\\t%0, %1, %2")
-+
-+(define_insn "xorqi3_xor1_ccszn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (xor:QI (match_operand:QI 0 "nonimmediate_operand" "%d,rm")
-+ (match_operand:QI 1 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))]
-+ "(ubicom32_v4
-+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
-+ "@
-+ xor.1\\t#0, %1, %0
-+ xor.1\\t#0, %0, %1")
-+
-+(define_insn "xor1_ccszn_null_1"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:QI
-+ (xor:SI (match_operand:SI 0 "ubicom32_data_register_operand" "%d")
-+ (match_operand:SI 1 "ubicom32_arith_operand" "rI"))
-+ 3)
-+ (const_int 0)))]
-+ "(ubicom32_v4
-+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
-+ "xor.1\\t#0, %1, %0")
-+
-+(define_insn "xor1_ccszn_null_2"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:QI
-+ (xor:SI (match_operand:SI 0 "ubicom32_data_register_operand" "d")
-+ (subreg:SI
-+ (match_operand:QI 1 "memory_operand" "m")
-+ 0))
-+ 3)
-+ (const_int 0)))]
-+ "(ubicom32_v4
-+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
-+ "xor.1\\t#0, %1, %0")
-+
-+(define_insn "xor1_ccwzn_null_3"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:QI
-+ (xor:SI (subreg:SI
-+ (match_operand:QI 0 "memory_operand" "m")
-+ 0)
-+ (match_operand:SI 1 "ubicom32_data_register_operand" "d"))
-+ 3)
-+ (const_int 0)))]
-+ "(ubicom32_v4
-+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
-+ "xor.1\\t#0, %0, %1")
-+
-+(define_expand "xorhi3"
-+ [(parallel
-+ [(set (match_operand:HI 0 "memory_operand" "")
-+ (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
-+ (match_operand:HI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ ""
-+ "{
-+ if (!memory_operand (operands[0], HImode))
-+ FAIL;
-+
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (HImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (HImode, operands[2]);
-+ }")
-+
-+(define_insn "xorhi3_xor2"
-+ [(set (match_operand:HI 0 "memory_operand" "=m, m")
-+ (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:HI 2 "ubicom32_arith_operand" "rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "@
-+ xor.2\\t%0, %2, %1
-+ xor.2\\t%0, %1, %2")
-+
-+(define_insn "xorhi3_xor2_ccszn"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:HI 2 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))
-+ (set (match_operand:HI 0 "memory_operand" "=m, m")
-+ (xor:HI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "@
-+ xor.2\\t%0, %2, %1
-+ xor.2\\t%0, %1, %2")
-+
-+(define_insn "xorhi3_xor2_ccszn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (xor:HI (match_operand:HI 0 "nonimmediate_operand" "%d,rm")
-+ (match_operand:HI 1 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "@
-+ xor.2\\t#0, %1, %0
-+ xor.2\\t#0, %0, %1")
-+
-+(define_insn "xor2_ccszn_null_1"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:HI
-+ (xor:SI (match_operand:SI 0 "ubicom32_data_register_operand" "%d")
-+ (match_operand:SI 1 "ubicom32_arith_operand" "rI"))
-+ 2)
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "xor.2\\t#0, %1, %0")
-+
-+(define_insn "xor2_ccszn_null_2"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:HI
-+ (xor:SI (match_operand:SI 0 "ubicom32_data_register_operand" "d")
-+ (subreg:SI
-+ (match_operand:HI 1 "memory_operand" "m")
-+ 0))
-+ 2)
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "xor.2\\t#0, %1, %0")
-+
-+(define_insn "xor2_ccszn_null_3"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:HI
-+ (xor:SI (subreg:SI
-+ (match_operand:HI 0 "memory_operand" "m")
-+ 0)
-+ (match_operand:SI 1 "ubicom32_data_register_operand" "d"))
-+ 2)
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "xor.2\\t#0, %0, %1")
-+
-+(define_insn "xorsi3"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
-+ (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "@
-+ xor.4\\t%0, %2, %1
-+ xor.4\\t%0, %1, %2")
-+
-+(define_insn "xorsi3_ccwzn"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
-+ (xor:SI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "@
-+ xor.4\\t%0, %2, %1
-+ xor.4\\t%0, %1, %2")
-+
-+(define_insn "xorsi3_ccwzn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (xor:SI (match_operand:SI 0 "nonimmediate_operand" "%d,rm")
-+ (match_operand:SI 1 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "@
-+ xor.4\\t#0, %1, %0
-+ xor.4\\t#0, %0, %1")
-+
-+(define_expand "xordi3"
-+ [(parallel
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "")
-+ (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
-+ (match_operand:DI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ ""
-+ "{
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (DImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (DImode, operands[2]);
-+ }")
-+
-+(define_insn_and_split "xordi3_xor4"
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,&r, d,rm, m, m")
-+ (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%d,rm, 0, 0, d,rm")
-+ (match_operand:DI 2 "ubicom32_arith_operand" "rmI, d,rmI, d,rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "#"
-+ "reload_completed"
-+ [(parallel [(set (match_dup 3)
-+ (xor:SI (match_dup 4)
-+ (match_dup 5)))
-+ (clobber (reg:CC CC_REGNO))])
-+ (parallel [(set (match_dup 6)
-+ (xor:SI (match_dup 7)
-+ (match_dup 8)))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "{
-+ operands[3] = gen_lowpart (SImode, operands[0]);
-+ operands[4] = gen_lowpart (SImode, operands[1]);
-+ operands[5] = gen_lowpart (SImode, operands[2]);
-+ operands[6] = gen_highpart (SImode, operands[0]);
-+ operands[7] = gen_highpart (SImode, operands[1]);
-+ operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_insn "not2_2"
-+ [(set (match_operand:HI 0 "memory_operand" "=m")
-+ (subreg:HI
-+ (not:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI"))
-+ 2))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "not.2\\t%0, %1")
-+
-+(define_insn "one_cmplsi2"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (not:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "not.4\\t%0, %1")
-+
-+(define_insn "one_cmplsi2_ccwzn"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (not:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (not:SI (match_dup 1)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "not.4\\t%0, %1")
-+
-+(define_insn "one_cmplsi2_ccwzn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (not:SI (match_operand:SI 0 "ubicom32_arith_operand" "rmI"))
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "not.4\\t#0, %0")
-+
-+(define_insn_and_split "one_cmpldi2"
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "=&rm")
-+ (not:DI (match_operand:DI 1 "nonimmediate_operand" "rmI0")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "#"
-+ ""
-+ [(parallel [(set (match_dup 2)
-+ (not:SI (match_dup 3)))
-+ (clobber (reg:CC CC_REGNO))])
-+ (parallel [(set (match_dup 4)
-+ (not:SI (match_dup 5)))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "{
-+ operands[2] = gen_lowpart (SImode, operands[0]);
-+ operands[3] = gen_lowpart (SImode, operands[1]);
-+ operands[4] = gen_highpart (SImode, operands[0]);
-+ operands[5] = gen_highpart (SImode, operands[1]);
-+ }"
-+ [(set_attr "length" "8")])
-+
-+; Conditional jump instructions
-+
-+(define_expand "beq"
-+ [(set (pc)
-+ (if_then_else (eq (match_dup 1)
-+ (const_int 0))
-+ (label_ref (match_operand 0 "" ""))
-+ (pc)))]
-+ ""
-+ "{
-+ operands[1] = ubicom32_gen_compare_reg (EQ, ubicom32_compare_op0,
-+ ubicom32_compare_op1);
-+ }")
-+
-+(define_expand "bne"
-+ [(set (pc)
-+ (if_then_else (ne (match_dup 1)
-+ (const_int 0))
-+ (label_ref (match_operand 0 "" ""))
-+ (pc)))]
-+ ""
-+ "{
-+ operands[1] = ubicom32_gen_compare_reg (NE, ubicom32_compare_op0,
-+ ubicom32_compare_op1);
-+ }")
-+
-+(define_expand "bgt"
-+ [(set (pc)
-+ (if_then_else (gt (match_dup 1)
-+ (const_int 0))
-+ (label_ref (match_operand 0 "" ""))
-+ (pc)))]
-+ ""
-+ "{
-+ operands[1] = ubicom32_gen_compare_reg (GT, ubicom32_compare_op0,
-+ ubicom32_compare_op1);
-+ }")
-+
-+(define_expand "ble"
-+ [(set (pc)
-+ (if_then_else (le (match_dup 1)
-+ (const_int 0))
-+ (label_ref (match_operand 0 "" ""))
-+ (pc)))]
-+ ""
-+ "{
-+ operands[1] = ubicom32_gen_compare_reg (LE, ubicom32_compare_op0,
-+ ubicom32_compare_op1);
-+ }")
-+
-+(define_expand "bge"
-+ [(set (pc)
-+ (if_then_else (ge (match_dup 1)
-+ (const_int 0))
-+ (label_ref (match_operand 0 "" ""))
-+ (pc)))]
-+ ""
-+ "{
-+ operands[1] = ubicom32_gen_compare_reg (GE, ubicom32_compare_op0,
-+ ubicom32_compare_op1);
-+ }")
-+
-+(define_expand "blt"
-+ [(set (pc)
-+ (if_then_else (lt (match_dup 1)
-+ (const_int 0))
-+ (label_ref (match_operand 0 "" ""))
-+ (pc)))]
-+ ""
-+ "{
-+ operands[1] = ubicom32_gen_compare_reg (LT, ubicom32_compare_op0,
-+ ubicom32_compare_op1);
-+ }")
-+
-+(define_expand "bgtu"
-+ [(set (pc)
-+ (if_then_else (gtu (match_dup 1)
-+ (const_int 0))
-+ (label_ref (match_operand 0 "" ""))
-+ (pc)))]
-+ ""
-+ "{
-+ operands[1] = ubicom32_gen_compare_reg (GTU, ubicom32_compare_op0,
-+ ubicom32_compare_op1);
-+ }")
-+
-+(define_expand "bleu"
-+ [(set (pc)
-+ (if_then_else (leu (match_dup 1)
-+ (const_int 0))
-+ (label_ref (match_operand 0 "" ""))
-+ (pc)))]
-+ ""
-+ "{
-+ operands[1] = ubicom32_gen_compare_reg (LEU, ubicom32_compare_op0,
-+ ubicom32_compare_op1);
-+ }")
-+
-+(define_expand "bgeu"
-+ [(set (pc)
-+ (if_then_else (geu (match_dup 1)
-+ (const_int 0))
-+ (label_ref (match_operand 0 "" ""))
-+ (pc)))]
-+ ""
-+ "{
-+ operands[1] = ubicom32_gen_compare_reg (GEU, ubicom32_compare_op0,
-+ ubicom32_compare_op1);
-+ }")
-+
-+(define_expand "bltu"
-+ [(set (pc)
-+ (if_then_else (ltu (match_dup 1)
-+ (const_int 0))
-+ (label_ref (match_operand 0 "" ""))
-+ (pc)))]
-+ ""
-+ "{
-+ operands[1] = ubicom32_gen_compare_reg (LTU, ubicom32_compare_op0,
-+ ubicom32_compare_op1);
-+ }")
-+
-+(define_insn "jcc"
-+ [(set (pc)
-+ (if_then_else (match_operator 1 "comparison_operator"
-+ [(match_operand 2 "ubicom32_cc_register_operand" "")
-+ (const_int 0)])
-+ (label_ref (match_operand 0 "" ""))
-+ (pc)))]
-+ ""
-+ "*
-+ {
-+ ubicom32_output_cond_jump (insn, operands[1], operands[0]);
-+ return \"\";
-+ }")
-+
-+; Reverse branch - reverse our comparison condition so that we can
-+; branch in the opposite sense.
-+;
-+(define_insn_and_split "jcc_reverse"
-+ [(set (pc)
-+ (if_then_else (match_operator 1 "comparison_operator"
-+ [(match_operand 2 "ubicom32_cc_register_operand" "")
-+ (const_int 0)])
-+ (pc)
-+ (label_ref (match_operand 0 "" ""))))]
-+ ""
-+ "#"
-+ "reload_completed"
-+ [(set (pc)
-+ (if_then_else (match_dup 3)
-+ (label_ref (match_dup 0))
-+ (pc)))]
-+ "{
-+ rtx cc_reg;
-+
-+ cc_reg = gen_rtx_REG (GET_MODE (operands[2]), CC_REGNO);
-+ operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[1])),
-+ GET_MODE (operands[1]),
-+ cc_reg,
-+ const0_rtx);
-+ }")
-+
-+(define_insn "jump"
-+ [(set (pc)
-+ (label_ref (match_operand 0 "" "")))]
-+ ""
-+ "jmpt\\t%l0")
-+
-+(define_expand "indirect_jump"
-+ [(parallel [(set (pc)
-+ (match_operand:SI 0 "register_operand" ""))
-+ (clobber (match_dup 0))])]
-+ ""
-+ "")
-+
-+(define_insn "indirect_jump_internal"
-+ [(set (pc)
-+ (match_operand:SI 0 "register_operand" "a"))
-+ (clobber (match_dup 0))]
-+ ""
-+ "calli\\t%0,0(%0)")
-+
-+; Program Space: The table contains instructions, typically jumps.
-+; CALL An,TABLE_SIZE(PC) ;An = Jump Table Base Address.
-+; <Jump Table is Here> ;An -> Here.
-+; LEA Ak, (An,Dn) ;Ak -> Table Entry
-+; JMP/CALL (Ak)
-+
-+(define_expand "tablejump"
-+ [(parallel [(set (pc)
-+ (match_operand:SI 0 "nonimmediate_operand" ""))
-+ (use (label_ref (match_operand 1 "" "")))])]
-+ ""
-+ "")
-+
-+(define_insn "tablejump_internal"
-+ [(set (pc)
-+ (match_operand:SI 0 "nonimmediate_operand" "rm"))
-+ (use (label_ref (match_operand 1 "" "")))]
-+ ""
-+ "ret\\t%0")
-+
-+; Call subroutine with no return value.
-+;
-+(define_expand "call"
-+ [(call (match_operand:QI 0 "general_operand" "")
-+ (match_operand:SI 1 "general_operand" ""))]
-+ ""
-+ "{
-+ if (TARGET_FDPIC)
-+ {
-+ ubicom32_expand_call_fdpic (operands);
-+ DONE;
-+ }
-+
-+ if (! ubicom32_call_address_operand (XEXP (operands[0], 0), VOIDmode))
-+ XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
-+ }")
-+
-+; We expand to a simple form that doesn't clobber the link register and
-+; then split to a form that does. This allows the RTL optimizers that
-+; run before the splitter to have the opportunity to eliminate the call
-+; without marking A5 as being clobbered and this in turn avoids saves
-+; and returns in a number of cases.
-+;
-+(define_insn_and_split "call_1"
-+ [(call (mem:QI (match_operand:SI 0 "ubicom32_call_address_operand" "a,S"))
-+ (match_operand:SI 1 "general_operand" "g,g"))]
-+ "! TARGET_FDPIC"
-+ "#"
-+ ""
-+ [(parallel
-+ [(call (mem:QI (match_dup 0))
-+ (match_dup 1))
-+ (clobber (reg:SI LINK_REGNO))])]
-+ "")
-+
-+(define_insn "call_slow"
-+ [(call (mem:QI (match_operand:SI 0 "ubicom32_call_address_operand" "a,S"))
-+ (match_operand:SI 1 "general_operand" "g,g"))
-+ (clobber (reg:SI LINK_REGNO))]
-+ "(! TARGET_FDPIC && ! TARGET_FASTCALL)"
-+ "@
-+ calli\\ta5, 0(%0)
-+ moveai\\ta5, #%%hi(%C0)\;calli\\ta5, %%lo(%C0)(a5)")
-+
-+(define_insn "call_fast"
-+ [(call (mem:QI (match_operand:SI 0 "ubicom32_call_address_operand" "a,S"))
-+ (match_operand:SI 1 "general_operand" "g,g"))
-+ (clobber (reg:SI LINK_REGNO))]
-+ "(! TARGET_FDPIC && TARGET_FASTCALL)"
-+ "@
-+ calli\\ta5, 0(%0)
-+ call\\ta5, %C0")
-+
-+; We expand to a simple form that doesn't clobber the link register and
-+; then split to a form that does. This allows the RTL optimizers that
-+; run before the splitter to have the opportunity to eliminate the call
-+; without marking A5 as being clobbered and this in turn avoids saves
-+; and returns in a number of cases.
-+;
-+(define_insn_and_split "call_fdpic"
-+ [(call (mem:QI (match_operand:SI 0 "ubicom32_call_address_operand" "a,S"))
-+ (match_operand:SI 1 "general_operand" "g,g"))
-+ (use (match_operand:SI 2 "ubicom32_fdpic_operand" "Z,Z"))]
-+ "TARGET_FDPIC"
-+ "#"
-+ ""
-+ [(parallel
-+ [(call (mem:QI (match_dup 0))
-+ (match_dup 1))
-+ (use (match_dup 2))
-+ (clobber (reg:SI LINK_REGNO))])]
-+ "")
-+
-+(define_insn "call_fdpic_clobber"
-+ [(call (mem:QI (match_operand:SI 0 "ubicom32_call_address_operand" "a,S"))
-+ (match_operand:SI 1 "general_operand" "g,g"))
-+ (use (match_operand:SI 2 "ubicom32_fdpic_operand" "Z,Z"))
-+ (clobber (reg:SI LINK_REGNO))]
-+ "TARGET_FDPIC"
-+ "@
-+ move.4\\ta5, 0(%0)\;move.4\\t%2, 4(%0)\;calli\\ta5, 0(a5)
-+ call\\ta5, %C0")
-+
-+; Call subroutine, returning value in operand 0
-+; (which must be a hard register).
-+;
-+(define_expand "call_value"
-+ [(set (match_operand 0 "" "")
-+ (call (match_operand:QI 1 "general_operand" "")
-+ (match_operand:SI 2 "general_operand" "")))]
-+ ""
-+ "{
-+ if (TARGET_FDPIC)
-+ {
-+ ubicom32_expand_call_value_fdpic (operands);
-+ DONE;
-+ }
-+
-+ if (! ubicom32_call_address_operand (XEXP (operands[1], 0), VOIDmode))
-+ XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
-+ }")
-+
-+; We expand to a simple form that doesn't clobber the link register and
-+; then split to a form that does. This allows the RTL optimizers that
-+; run before the splitter to have the opportunity to eliminate the call
-+; without marking A5 as being clobbered and this in turn avoids saves
-+; and returns in a number of cases.
-+;
-+(define_insn_and_split "call_value_1"
-+ [(set (match_operand 0 "register_operand" "=r,r")
-+ (call (mem:QI (match_operand:SI 1 "ubicom32_call_address_operand" "a,S"))
-+ (match_operand:SI 2 "general_operand" "g,g")))]
-+ "! TARGET_FDPIC"
-+ "#"
-+ ""
-+ [(parallel
-+ [(set (match_dup 0)
-+ (call (mem:QI (match_dup 1))
-+ (match_dup 2)))
-+ (clobber (reg:SI LINK_REGNO))])]
-+ "")
-+
-+(define_insn "call_value_slow"
-+ [(set (match_operand 0 "register_operand" "=r,r")
-+ (call (mem:QI (match_operand:SI 1 "ubicom32_call_address_operand" "a,S"))
-+ (match_operand:SI 2 "general_operand" "g,g")))
-+ (clobber (reg:SI LINK_REGNO))]
-+ "(! TARGET_FDPIC && ! TARGET_FASTCALL)"
-+ "@
-+ calli\\ta5, 0(%1)
-+ moveai\\ta5, #%%hi(%C1)\;calli\\ta5, %%lo(%C1)(a5)")
-+
-+(define_insn "call_value_fast"
-+ [(set (match_operand 0 "register_operand" "=r,r")
-+ (call (mem:QI (match_operand:SI 1 "ubicom32_call_address_operand" "a,S"))
-+ (match_operand:SI 2 "general_operand" "g,g")))
-+ (clobber (reg:SI LINK_REGNO))]
-+ "(! TARGET_FDPIC && TARGET_FASTCALL)"
-+ "@
-+ calli\\ta5, 0(%1)
-+ call\\ta5, %C1")
-+
-+; We expand to a simple form that doesn't clobber the link register and
-+; then split to a form that does. This allows the RTL optimizers that
-+; run before the splitter to have the opportunity to eliminate the call
-+; without marking A5 as being clobbered and this in turn avoids saves
-+; and returns in a number of cases.
-+;
-+(define_insn_and_split "call_value_fdpic"
-+ [(set (match_operand 0 "register_operand" "=r,r")
-+ (call (mem:QI (match_operand:SI 1 "ubicom32_call_address_operand" "a,S"))
-+ (match_operand:SI 2 "general_operand" "g,g")))
-+ (use (match_operand:SI 3 "ubicom32_fdpic_operand" "Z,Z"))]
-+ "TARGET_FDPIC"
-+ "#"
-+ ""
-+ [(parallel
-+ [(set (match_dup 0)
-+ (call (mem:QI (match_dup 1))
-+ (match_dup 2)))
-+ (use (match_dup 3))
-+ (clobber (reg:SI LINK_REGNO))])]
-+ "")
-+
-+(define_insn "call_value_fdpic_clobber"
-+ [(set (match_operand 0 "register_operand" "=r,r")
-+ (call (mem:QI (match_operand:SI 1 "ubicom32_call_address_operand" "a,S"))
-+ (match_operand:SI 2 "general_operand" "g,g")))
-+ (use (match_operand:SI 3 "ubicom32_fdpic_operand" "Z,Z"))
-+ (clobber (reg:SI LINK_REGNO))]
-+ "TARGET_FDPIC"
-+ "@
-+ move.4\\ta5, 0(%1)\;move.4\\t%3, 4(%1)\;calli\\ta5, 0(a5)
-+ call\\ta5, %C1")
-+
-+(define_expand "untyped_call"
-+ [(parallel [(call (match_operand 0 "" "")
-+ (const_int 0))
-+ (match_operand 1 "" "")
-+ (match_operand 2 "" "")])]
-+ ""
-+ "{
-+ int i;
-+
-+ emit_call_insn (gen_call (operands[0], const0_rtx));
-+
-+ for (i = 0; i < XVECLEN (operands[2], 0); i++)
-+ {
-+ rtx set = XVECEXP (operands[2], 0, i);
-+ emit_move_insn (SET_DEST (set), SET_SRC (set));
-+ }
-+ DONE;
-+ }")
-+
-+(define_insn "lsl1_1"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (ashift:SI (subreg:SI
-+ (match_operand:QI 1 "memory_operand" "m")
-+ 0)
-+ (match_operand:SI 2 "ubicom32_arith_operand" "dM")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4)"
-+ "lsl.1\\t%0, %1, %2")
-+
-+; The combiner gets rather creative about left shifts of sub-word memory
-+; operands because it's uncertain about whether the memory is sign or
-+; zero extended. It only wants zero-extended behaviour and so throws
-+; in an extra and operation.
-+;
-+(define_insn "lsl1_2"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (and:SI
-+ (ashift:SI (subreg:SI
-+ (match_operand:QI 1 "memory_operand" "m")
-+ 0)
-+ (match_operand:SI 2 "const_int_operand" "M"))
-+ (match_operand:SI 3 "const_int_operand" "n")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4
-+ && INTVAL (operands[3]) == (0xff << INTVAL (operands[2])))"
-+ "lsl.1\\t%0, %1, %2")
-+
-+(define_insn "lsl2_1"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (ashift:SI (subreg:SI
-+ (match_operand:HI 1 "memory_operand" "m")
-+ 0)
-+ (match_operand:SI 2 "ubicom32_arith_operand" "dM")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4)"
-+ "lsl.2\\t%0, %1, %2")
-+
-+; The combiner gets rather creative about left shifts of sub-word memory
-+; operands because it's uncertain about whether the memory is sign or
-+; zero extended. It only wants zero-extended behaviour and so throws
-+; in an extra and operation.
-+;
-+(define_insn "lsl2_2"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (and:SI
-+ (ashift:SI (subreg:SI
-+ (match_operand:HI 1 "memory_operand" "m")
-+ 0)
-+ (match_operand:SI 2 "const_int_operand" "M"))
-+ (match_operand:SI 3 "const_int_operand" "n")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4
-+ && INTVAL (operands[3]) == (0xffff << INTVAL (operands[2])))"
-+ "lsl.2\\t%0, %1, %2")
-+
-+(define_insn "ashlsi3"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (ashift:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "dM")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "lsl.4\\t%0, %1, %2")
-+
-+(define_insn "lshlsi3_ccwz"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (ashift:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "dM"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (ashift:SI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCWZmode)"
-+ "lsl.4\\t%0, %1, %2")
-+
-+(define_insn "lshlsi3_ccwz_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (ashift:SI (match_operand:SI 0 "ubicom32_arith_operand" "rmI")
-+ (match_operand:SI 1 "ubicom32_arith_operand" "dM"))
-+ (const_int 0)))
-+ (clobber (match_scratch:SI 2 "=d"))]
-+ "ubicom32_match_cc_mode(insn, CCWZmode)"
-+ "lsl.4\\t%2, %0, %1")
-+
-+; The combiner finds this canonical form for what is in essence a right
-+; shift.
-+;
-+(define_insn "asr1_2"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (sign_extract:SI (match_operand:QI 1 "memory_operand" "m")
-+ (match_operand:SI 2 "const_int_operand" "M")
-+ (match_operand:SI 3 "const_int_operand" "M")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4
-+ && (INTVAL (operands[2]) + INTVAL (operands[3]) == 8))"
-+ "asr.1\\t%0, %1, %3")
-+
-+; The combiner finds this canonical form for what is in essence a right
-+; shift.
-+;
-+(define_insn "asr2_2"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (sign_extract:SI (match_operand:HI 1 "memory_operand" "m")
-+ (match_operand:SI 2 "const_int_operand" "M")
-+ (match_operand:SI 3 "const_int_operand" "M")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4
-+ && (INTVAL (operands[2]) + INTVAL (operands[3]) == 16))"
-+ "asr.2\\t%0, %1, %3")
-+
-+(define_insn "ashrsi3"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (ashiftrt:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmJ")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "dM")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "asr.4\\t%0, %1, %2")
-+
-+(define_insn "ashrsi3_ccwzn"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (ashiftrt:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmJ")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "dM"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (ashiftrt:SI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "asr.4\\t%0, %1, %2")
-+
-+(define_insn "ashrsi3_ccwzn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (ashiftrt:SI (match_operand:SI 0 "ubicom32_arith_operand" "rmJ")
-+ (match_operand:SI 1 "ubicom32_arith_operand" "dM"))
-+ (const_int 0)))
-+ (clobber (match_scratch:SI 2 "=d"))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "asr.4\\t%2, %0, %1")
-+
-+(define_insn "lsr1_1"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (lshiftrt:SI (subreg:SI
-+ (match_operand:QI 1 "memory_operand" "m")
-+ 0)
-+ (match_operand:SI 2 "ubicom32_arith_operand" "dM")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4)"
-+ "lsr.1\\t%0, %1, %2")
-+
-+; The combiner finds this canonical form for what is in essence a right
-+; shift.
-+;
-+(define_insn "lsr1_2"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (zero_extract:SI (match_operand:QI 1 "memory_operand" "m")
-+ (match_operand:SI 2 "const_int_operand" "M")
-+ (match_operand:SI 3 "const_int_operand" "M")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4
-+ && (INTVAL (operands[2]) + INTVAL (operands[3]) == 8))"
-+ "lsr.1\\t%0, %1, %3")
-+
-+(define_insn "lsr2_1"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (lshiftrt:SI (subreg:SI
-+ (match_operand:HI 1 "memory_operand" "m")
-+ 0)
-+ (match_operand:SI 2 "ubicom32_arith_operand" "dM")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4)"
-+ "lsr.2\\t%0, %1, %2")
-+
-+; The combiner finds this canonical form for what is in essence a right
-+; shift.
-+;
-+(define_insn "lsr2_2"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (zero_extract:SI (match_operand:HI 1 "memory_operand" "m")
-+ (match_operand:SI 2 "const_int_operand" "M")
-+ (match_operand:SI 3 "const_int_operand" "M")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4
-+ && (INTVAL (operands[2]) + INTVAL (operands[3]) == 16))"
-+ "lsr.2\\t%0, %1, %3")
-+
-+(define_insn "lshrsi3"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (lshiftrt:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "dM")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "lsr.4\\t%0, %1, %2")
-+
-+(define_insn "lshrsi3_ccwz"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (lshiftrt:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "dM"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (lshiftrt:SI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCWZmode)"
-+ "lsr.4\\t%0, %1, %2")
-+
-+(define_insn "lshrsi3_ccwz_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (lshiftrt:SI (match_operand:SI 0 "ubicom32_arith_operand" "rmI")
-+ (match_operand:SI 1 "ubicom32_arith_operand" "dM"))
-+ (const_int 0)))
-+ (clobber (match_scratch:SI 2 "=d"))]
-+ "ubicom32_match_cc_mode(insn, CCWZmode)"
-+ "lsr.4\\t%2, %0, %1")
-+
-+(define_expand "prologue"
-+ [(const_int 0)]
-+ ""
-+ "{
-+ ubicom32_expand_prologue ();
-+ DONE;
-+ }")
-+
-+(define_expand "epilogue"
-+ [(return)]
-+ ""
-+ "{
-+ ubicom32_expand_epilogue ();
-+ DONE;
-+ }")
-+
-+(define_expand "return"
-+ [(return)]
-+ ""
-+ "{
-+ ubicom32_expand_epilogue ();
-+ DONE;
-+ }")
-+
-+(define_expand "_eh_return"
-+ [(use (match_operand:SI 0 "register_operand" "r"))
-+ (use (match_operand:SI 1 "register_operand" "r"))]
-+ ""
-+ "{
-+ ubicom32_expand_eh_return (operands);
-+ DONE;
-+ }")
-+
-+; XXX - it looks almost certain that we could make return_internal use a Dn
-+; register too. In that instance we'd have to use a ret instruction
-+; rather than a calli but it might save cycles.
-+;
-+(define_insn "return_internal"
-+ [(const_int 2)
-+ (return)
-+ (use (match_operand:SI 0 "ubicom32_mem_or_address_register_operand" "rm"))]
-+ ""
-+ "*
-+ {
-+ if (REG_P (operands[0]) && REGNO (operands[0]) == LINK_REGNO
-+ && ubicom32_can_use_calli_to_ret)
-+ return \"calli\\t%0, 0(%0)\";
-+
-+ return \"ret\\t%0\";
-+ }")
-+
-+(define_insn "return_from_post_modify_sp"
-+ [(parallel
-+ [(const_int 2)
-+ (return)
-+ (use (mem:SI (post_modify:SI
-+ (reg:SI SP_REGNO)
-+ (plus:SI (reg:SI SP_REGNO)
-+ (match_operand:SI 0 "const_int_operand" "n")))))])]
-+ "INTVAL (operands[0]) >= 4 && INTVAL (operands[0]) <= 7 * 4"
-+ "ret\\t(sp)%E0++")
-+
-+;(define_insn "eh_return_internal"
-+; [(const_int 4)
-+; (return)
-+; (use (reg:SI 34))]
-+; ""
-+; "ret\\ta2")
-+
-+; No operation, needed in case the user uses -g but not -O.
-+(define_expand "nop"
-+ [(const_int 0)]
-+ ""
-+ "")
-+
-+(define_insn "nop_internal"
-+ [(const_int 0)]
-+ ""
-+ "nop")
-+
-+; The combiner will generate this pattern given shift and add operations.
-+; The canonical form that the combiner wants to use appears to be multiplies
-+; instead of shifts even if the compiled sources use shifts.
-+;
-+(define_insn "shmrg1_add"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (plus:SI
-+ (mult:SI (match_operand:SI 1 "ubicom32_data_register_operand" "d")
-+ (const_int 256))
-+ (zero_extend:SI
-+ (match_operand:QI 2 "ubicom32_arith_operand" "rmI"))))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "shmrg.1\\t%0, %2, %1")
-+
-+; The combiner will generate this pattern given shift and or operations.
-+;
-+(define_insn "shmrg1_ior"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (ior:SI
-+ (ashift:SI (match_operand:SI 1 "ubicom32_data_register_operand" "d")
-+ (const_int 8))
-+ (zero_extend:SI
-+ (match_operand:QI 2 "ubicom32_arith_operand" "rmI"))))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "shmrg.1\\t%0, %2, %1")
-+
-+; The combiner will generate this pattern given shift and add operations.
-+; The canonical form that the combiner wants to use appears to be multiplies
-+; instead of shifts even if the compiled sources use shifts.
-+;
-+(define_insn "shmrg2_add"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (plus:SI
-+ (mult:SI (match_operand:SI 1 "ubicom32_data_register_operand" "d")
-+ (const_int 65536))
-+ (zero_extend:SI
-+ (match_operand:HI 2 "ubicom32_arith_operand" "rmI"))))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "shmrg.2\\t%0, %2, %1")
-+
-+; The combiner will generate this pattern given shift and or operations.
-+;
-+(define_insn "shmrg2_ior"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (ior:SI
-+ (ashift:SI (match_operand:SI 1 "ubicom32_data_register_operand" "d")
-+ (const_int 16))
-+ (zero_extend:SI
-+ (match_operand:HI 2 "ubicom32_arith_operand" "rmI"))))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "shmrg.2\\t%0, %2, %1")
-+
-+; Match the case where we load a word from the stack but then discard the
-+; upper 16 bits. We turn this into a zero-extended load of that useful
-+; 16 bits direct from the stack where possible.
-+;
-+
-+; XXX - do these peephole2 ops actually work after the CCmode conversion?
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (mem:SI (plus:SI (reg:SI SP_REGNO)
-+ (match_operand:SI 1 "const_int_operand" ""))))
-+ (set (match_operand:SI 2 "nonimmediate_operand" "")
-+ (zero_extend:SI (match_operand:HI 3 "register_operand" "")))]
-+ "(INTVAL (operands[1]) <= 252
-+ && REGNO (operands[3]) == REGNO (operands[0])
-+ && ((peep2_reg_dead_p (2, operands[0])
-+ && ! reg_mentioned_p (operands[0], operands[2]))
-+ || rtx_equal_p (operands[0], operands[2])))"
-+ [(set (match_dup 2)
-+ (zero_extend:SI (mem:HI (plus:SI (reg:SI SP_REGNO)
-+ (match_dup 4)))))]
-+ "{
-+ operands[4] = GEN_INT (INTVAL (operands[1]) + 2);
-+ }")
-+
-+; Match the case where we load a word from the stack but then discard the
-+; upper 16 bits. We turn this into a 16-bit load of that useful
-+; 16 bits direct from the stack where possible.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (mem:SI (plus:SI (reg:SI SP_REGNO)
-+ (match_operand:SI 1 "const_int_operand" ""))))
-+ (set (match_operand:HI 2 "nonimmediate_operand" "")
-+ (match_operand:HI 3 "register_operand" ""))]
-+ "(INTVAL (operands[1]) <= 252
-+ && REGNO (operands[3]) == REGNO (operands[0])
-+ && ((peep2_reg_dead_p (2, operands[0])
-+ && ! reg_mentioned_p (operands[0], operands[2]))
-+ || rtx_equal_p (operands[0], operands[2])))"
-+ [(set (match_dup 2)
-+ (mem:HI (plus:SI (reg:SI SP_REGNO)
-+ (match_dup 4))))]
-+ "{
-+ operands[4] = GEN_INT (INTVAL (operands[1]) + 2);
-+ }")
-+
-+; Match the case where we load a word from the stack but then discard the
-+; upper 24 bits. We turn this into a zero-extended load of that useful
-+; 8 bits direct from the stack where possible.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (mem:SI (plus:SI (reg:SI SP_REGNO)
-+ (match_operand:SI 1 "const_int_operand" ""))))
-+ (set (match_operand:SI 2 "nonimmediate_operand" "")
-+ (zero_extend:SI (match_operand:QI 3 "register_operand" "")))]
-+ "(INTVAL (operands[1]) <= 124
-+ && REGNO (operands[3]) == REGNO (operands[0])
-+ && ((peep2_reg_dead_p (2, operands[0])
-+ && ! reg_mentioned_p (operands[0], operands[2]))
-+ || rtx_equal_p (operands[0], operands[2])))"
-+ [(set (match_dup 2)
-+ (zero_extend:SI (mem:QI (plus:SI (reg:SI SP_REGNO)
-+ (match_dup 4)))))]
-+ "{
-+ operands[4] = GEN_INT (INTVAL (operands[1]) + 3);
-+ }")
-+
-+; Match the case where we load a word from the stack but then discard the
-+; upper 24 bits. We turn this into an 8-bit load of that useful
-+; 8 bits direct from the stack where possible.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (mem:SI (plus:SI (reg:SI SP_REGNO)
-+ (match_operand:SI 1 "const_int_operand" ""))))
-+ (set (match_operand:QI 2 "nonimmediate_operand" "")
-+ (match_operand:QI 3 "register_operand" ""))]
-+ "(INTVAL (operands[1]) <= 124
-+ && REGNO (operands[3]) == REGNO (operands[0])
-+ && ((peep2_reg_dead_p (2, operands[0])
-+ && ! reg_mentioned_p (operands[0], operands[2]))
-+ || rtx_equal_p (operands[0], operands[2])))"
-+ [(set (match_dup 2)
-+ (mem:QI (plus:SI (reg:SI SP_REGNO)
-+ (match_dup 4))))]
-+ "{
-+ operands[4] = GEN_INT (INTVAL (operands[1]) + 3);
-+ }")
-+
---- /dev/null
-+++ b/gcc/config/ubicom32/ubicom32.opt
-@@ -0,0 +1,27 @@
-+mdebug-address
-+Target RejectNegative Report Undocumented Mask(DEBUG_ADDRESS)
-+Debug addresses
-+
-+mdebug-context
-+Target RejectNegative Report Undocumented Mask(DEBUG_CONTEXT)
-+Debug contexts
-+
-+march=
-+Target Report Var(ubicom32_arch_name) Init("ubicom32v4") Joined
-+Specify the name of the target architecture
-+
-+mfdpic
-+Target Report Mask(FDPIC)
-+Enable Function Descriptor PIC mode
-+
-+minline-plt
-+Target Report Mask(INLINE_PLT)
-+Enable inlining of PLT in function calls
-+
-+mfastcall
-+Target Report Mask(FASTCALL)
-+Enable default fast (call) calling sequence for smaller applications
-+
-+mipos-abi
-+Target Report Mask(IPOS_ABI)
-+Enable the ipOS ABI in which D10-D13 are caller-clobbered
---- /dev/null
-+++ b/gcc/config/ubicom32/uclinux.h
-@@ -0,0 +1,67 @@
-+/* Definitions of target machine for Ubicom32-uclinux
-+
-+ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
-+ 2009 Free Software Foundation, Inc.
-+ Contributed by Ubicom, Inc.
-+
-+ This file is part of GCC.
-+
-+ GCC is free software; you can redistribute it and/or modify it
-+ under the terms of the GNU General Public License as published
-+ by the Free Software Foundation; either version 3, or (at your
-+ option) any later version.
-+
-+ GCC is distributed in the hope that it will be useful, but WITHOUT
-+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
-+ License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with GCC; see the file COPYING3. If not see
-+ <http://www.gnu.org/licenses/>. */
-+
-+/* Don't assume anything about the header files. */
-+#define NO_IMPLICIT_EXTERN_C
-+
-+#undef LIB_SPEC
-+#define LIB_SPEC \
-+ "%{pthread:-lpthread} " \
-+ "%{!shared:%{!symbolic: -lc}} "
-+
-+
-+#undef LINK_GCC_C_SEQUENCE_SPEC
-+#define LINK_GCC_C_SEQUENCE_SPEC \
-+ "%{!shared:--start-group} %G %L %{!shared:--end-group}%{shared:%G} "
-+
-+#undef STARTFILE_SPEC
-+#define STARTFILE_SPEC \
-+ "%{!shared: crt1%O%s}" \
-+ " crti%O%s crtbegin%O%s"
-+
-+#undef ENDFILE_SPEC
-+#define ENDFILE_SPEC "crtend%O%s crtn%O%s"
-+
-+/* This macro applies on top of OBJECT_FORMAT_ELF and indicates that
-+ we want to support both flat and ELF output. */
-+#define OBJECT_FORMAT_FLAT
-+
-+#undef DRIVER_SELF_SPECS
-+#define DRIVER_SELF_SPECS \
-+ "%{!mno-fastcall:-mfastcall}"
-+
-+/* taken from linux.h */
-+/* The GNU C++ standard library requires that these macros be defined. */
-+#undef CPLUSPLUS_CPP_SPEC
-+#define CPLUSPLUS_CPP_SPEC "-D_GNU_SOURCE %(cpp)"
-+
-+#define TARGET_OS_CPP_BUILTINS() \
-+ do { \
-+ builtin_define_std ("__UBICOM32__"); \
-+ builtin_define_std ("__ubicom32__"); \
-+ builtin_define ("__gnu_linux__"); \
-+ builtin_define_std ("linux"); \
-+ builtin_define_std ("unix"); \
-+ builtin_assert ("system=linux"); \
-+ builtin_assert ("system=unix"); \
-+ builtin_assert ("system=posix"); \
-+ } while (0)
---- /dev/null
-+++ b/gcc/config/ubicom32/xm-ubicom32.h
-@@ -0,0 +1,36 @@
-+/* Configuration for Ubicom's Ubicom32 architecture.
-+ Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Free Software
-+ Foundation, Inc.
-+ Contributed by Ubicom Inc.
-+
-+This file is part of GNU CC.
-+
-+GNU CC is free software; you can redistribute it and/or modify
-+it under the terms of the GNU General Public License as published by
-+the Free Software Foundation; either version 2, or (at your option)
-+any later version.
-+
-+GNU CC is distributed in the hope that it will be useful,
-+but WITHOUT ANY WARRANTY; without even the implied warranty of
-+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+GNU General Public License for more details.
-+
-+You should have received a copy of the GNU General Public License
-+along with GNU CC; see the file COPYING. If not, write to
-+the Free Software Foundation, 59 Temple Place - Suite 330,
-+Boston, MA 02111-1307, USA. */
-+
-+/* #defines that need visibility everywhere. */
-+#define FALSE 0
-+#define TRUE 1
-+
-+/* This describes the machine the compiler is hosted on. */
-+#define HOST_BITS_PER_CHAR 8
-+#define HOST_BITS_PER_SHORT 16
-+#define HOST_BITS_PER_INT 32
-+#define HOST_BITS_PER_LONG 32
-+#define HOST_BITS_PER_LONGLONG 64
-+
-+/* Arguments to use with `exit'. */
-+#define SUCCESS_EXIT_CODE 0
-+#define FATAL_EXIT_CODE 33
---- a/gcc/config.gcc
-+++ b/gcc/config.gcc
-@@ -2321,6 +2321,34 @@ spu-*-elf*)
- c_target_objs="${c_target_objs} spu-c.o"
- cxx_target_objs="${cxx_target_objs} spu-c.o"
- ;;
-+ubicom32-*-elf)
-+ xm_file=ubicom32/xm-ubicom32.h
-+ tm_file="${tm_file} ubicom32/elf.h" # still need dbxelf.h elfos.h
-+ tmake_file=ubicom32/t-ubicom32
-+ ;;
-+ubicom32-*-uclinux*)
-+ xm_file=ubicom32/xm-ubicom32.h
-+ tm_file="${tm_file} ubicom32/elf.h ubicom32/uclinux.h" # still need dbxelf.h elfos.h linux.h
-+ tm_defines="${tm_defines} UCLIBC_DEFAULT=1"
-+ extra_options="${extra_options} linux.opt"
-+ tmake_file=ubicom32/t-ubicom32-uclinux
-+ use_collect2=no
-+ ;;
-+ubicom32-*-linux-uclibc)
-+ xm_file=ubicom32/xm-ubicom32.h
-+ tm_file="${tm_file} ubicom32/elf.h linux.h ubicom32/linux.h" # still need dbxelf.h elfos.h
-+ tmake_file="t-slibgcc-elf-ver ubicom32/t-ubicom32-linux"
-+ extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
-+ use_collect2=no
-+ ;;
-+ubicom32-*-linux*)
-+ xm_file=ubicom32/xm-ubicom32.h
-+ tm_file="${tm_file} ubicom32/elf.h linux.h ubicom32/linux.h" # still need dbxelf.h elfos.h
-+ tmake_file="t-slibgcc-elf-ver ubicom32/t-ubicom32-linux"
-+ tm_defines="${tm_defines} UCLIBC_DEFAULT=1"
-+ extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
-+ use_collect2=no
-+ ;;
- v850e1-*-*)
- target_cpu_default="TARGET_CPU_v850e1"
- tm_file="dbxelf.h elfos.h svr4.h v850/v850.h"
---- a/libgcc/config.host
-+++ b/libgcc/config.host
-@@ -551,6 +551,15 @@ sparc64-*-netbsd*)
- ;;
- spu-*-elf*)
- ;;
-+ubicom32*-*-elf*)
-+ ;;
-+ubicom32*-*-uclinux*)
-+ ;;
-+ubicom32*-*-linux*)
-+ # No need to build crtbeginT.o on uClibc systems. Should probably
-+ # be moved to the OS specific section above.
-+ extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
-+ ;;
- v850e1-*-*)
- ;;
- v850e-*-*)
+++ /dev/null
---- a/gcc/config/arm/linux-elf.h
-+++ b/gcc/config/arm/linux-elf.h
-@@ -60,7 +60,7 @@
- %{shared:-lc} \
- %{!shared:%{profile:-lc_p}%{!profile:-lc}}"
-
--#define LIBGCC_SPEC "%{msoft-float:-lfloat} %{mfloat-abi=soft*:-lfloat} -lgcc"
-+#define LIBGCC_SPEC "-lgcc"
-
- #define GLIBC_DYNAMIC_LINKER "/lib/ld-linux.so.2"
-
---- a/gcc/config/arm/t-linux
-+++ b/gcc/config/arm/t-linux
-@@ -4,7 +4,10 @@ TARGET_LIBGCC2_CFLAGS = -fomit-frame-poi
-
- LIB1ASMSRC = arm/lib1funcs.asm
- LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_lnx _clzsi2 _clzdi2 \
-- _arm_addsubdf3 _arm_addsubsf3
-+ _arm_addsubdf3 _arm_addsubsf3 \
-+ _negdf2 _addsubdf3 _muldivdf3 _cmpdf2 _unorddf2 _fixdfsi _fixunsdfsi \
-+ _truncdfsf2 _negsf2 _addsubsf3 _muldivsf3 _cmpsf2 _unordsf2 \
-+ _fixsfsi _fixunssfsi _floatdidf _floatundidf _floatdisf _floatundisf
-
- # MULTILIB_OPTIONS = mhard-float/msoft-float
- # MULTILIB_DIRNAMES = hard-float soft-float
+++ /dev/null
---- a/libgcc/Makefile.in
-+++ b/libgcc/Makefile.in
-@@ -729,11 +729,12 @@ $(libgcov-objects): %$(objext): $(gcc_sr
-
- # Static libraries.
- libgcc.a: $(libgcc-objects)
-+libgcc_pic.a: $(libgcc-s-objects)
- libgcov.a: $(libgcov-objects)
- libunwind.a: $(libunwind-objects)
- libgcc_eh.a: $(libgcc-eh-objects)
-
--libgcc.a libgcov.a libunwind.a libgcc_eh.a:
-+libgcc.a libgcov.a libunwind.a libgcc_eh.a libgcc_pic.a:
- -rm -f $@
-
- objects="$(objects)"; \
-@@ -755,7 +756,7 @@ libgcc_s$(SHLIB_EXT): libunwind$(SHLIB_E
- endif
-
- ifeq ($(enable_shared),yes)
--all: libgcc_eh.a libgcc_s$(SHLIB_EXT)
-+all: libgcc_eh.a libgcc_pic.a libgcc_s$(SHLIB_EXT)
- ifneq ($(LIBUNWIND),)
- all: libunwind$(SHLIB_EXT)
- endif
-@@ -928,6 +929,10 @@ install-shared:
- chmod 644 $(DESTDIR)$(inst_libdir)/libgcc_eh.a
- $(RANLIB) $(DESTDIR)$(inst_libdir)/libgcc_eh.a
-
-+ $(INSTALL_DATA) libgcc_pic.a $(mapfile) $(DESTDIR)$(inst_libdir)/
-+ chmod 644 $(DESTDIR)$(inst_libdir)/libgcc_pic.a
-+ $(RANLIB) $(DESTDIR)$(inst_libdir)/libgcc_pic.a
-+
- $(subst @multilib_dir@,$(MULTIDIR),$(subst \
- @shlib_base_name@,libgcc_s,$(subst \
- @shlib_slibdir_qual@,$(MULTIOSSUBDIR),$(SHLIB_INSTALL))))
+++ /dev/null
-
- This patch brings over a few features from MirBSD:
- * -fhonour-copts
- If this option is not given, it's warned (depending
- on environment variables). This is to catch errors
- of misbuilt packages which override CFLAGS themselves.
- * -Werror-maybe-reset
- Has the effect of -Wno-error if GCC_NO_WERROR is
- set and not '0', a no-operation otherwise. This is
- to be able to use -Werror in "make" but prevent
- GNU autoconf generated configure scripts from
- freaking out.
- * Make -fno-strict-aliasing and -fno-delete-null-pointer-checks
- the default for -O2/-Os, because they trigger gcc bugs
- and can delete code with security implications.
-
- This patch was authored by Thorsten Glaser <tg at mirbsd.de>
- with copyright assignment to the FSF in effect.
-
---- a/gcc/c-opts.c
-+++ b/gcc/c-opts.c
-@@ -105,6 +105,9 @@ static size_t deferred_count;
- /* Number of deferred options scanned for -include. */
- static size_t include_cursor;
-
-+/* Check if a port honours COPTS. */
-+static int honour_copts = 0;
-+
- static void set_Wimplicit (int);
- static void handle_OPT_d (const char *);
- static void set_std_cxx98 (int);
-@@ -454,6 +457,14 @@ c_common_handle_option (size_t scode, co
- enable_warning_as_error ("implicit-function-declaration", value, CL_C | CL_ObjC);
- break;
-
-+ case OPT_Werror_maybe_reset:
-+ {
-+ char *ev = getenv ("GCC_NO_WERROR");
-+ if ((ev != NULL) && (*ev != '0'))
-+ cpp_opts->warnings_are_errors = 0;
-+ }
-+ break;
-+
- case OPT_Wformat:
- set_Wformat (value);
- break;
-@@ -690,6 +701,12 @@ c_common_handle_option (size_t scode, co
- flag_exceptions = value;
- break;
-
-+ case OPT_fhonour_copts:
-+ if (c_language == clk_c) {
-+ honour_copts++;
-+ }
-+ break;
-+
- case OPT_fimplement_inlines:
- flag_implement_inlines = value;
- break;
-@@ -1209,6 +1226,47 @@ c_common_init (void)
- return false;
- }
-
-+ if (c_language == clk_c) {
-+ char *ev = getenv ("GCC_HONOUR_COPTS");
-+ int evv;
-+ if (ev == NULL)
-+ evv = -1;
-+ else if ((*ev == '0') || (*ev == '\0'))
-+ evv = 0;
-+ else if (*ev == '1')
-+ evv = 1;
-+ else if (*ev == '2')
-+ evv = 2;
-+ else if (*ev == 's')
-+ evv = -1;
-+ else {
-+ warning (0, "unknown GCC_HONOUR_COPTS value, assuming 1");
-+ evv = 1; /* maybe depend this on something like MIRBSD_NATIVE? */
-+ }
-+ if (evv == 1) {
-+ if (honour_copts == 0) {
-+ error ("someone does not honour COPTS at all in lenient mode");
-+ return false;
-+ } else if (honour_copts != 1) {
-+ warning (0, "someone does not honour COPTS correctly, passed %d times",
-+ honour_copts);
-+ }
-+ } else if (evv == 2) {
-+ if (honour_copts == 0) {
-+ error ("someone does not honour COPTS at all in strict mode");
-+ return false;
-+ } else if (honour_copts != 1) {
-+ error ("someone does not honour COPTS correctly, passed %d times",
-+ honour_copts);
-+ return false;
-+ }
-+ } else if (evv == 0) {
-+ if (honour_copts != 1)
-+ inform (0, "someone does not honour COPTS correctly, passed %d times",
-+ honour_copts);
-+ }
-+ }
-+
- return true;
- }
-
---- a/gcc/c.opt
-+++ b/gcc/c.opt
-@@ -215,6 +215,10 @@ Werror-implicit-function-declaration
- C ObjC RejectNegative Warning
- This switch is deprecated; use -Werror=implicit-function-declaration instead
-
-+Werror-maybe-reset
-+C ObjC C++ ObjC++
-+; Documented in common.opt
-+
- Wfloat-equal
- C ObjC C++ ObjC++ Var(warn_float_equal) Warning
- Warn if testing floating point numbers for equality
-@@ -613,6 +617,9 @@ C++ ObjC++ Optimization
- fhonor-std
- C++ ObjC++
-
-+fhonour-copts
-+C ObjC C++ ObjC++ RejectNegative
-+
- fhosted
- C ObjC
- Assume normal C execution environment
---- a/gcc/common.opt
-+++ b/gcc/common.opt
-@@ -102,6 +102,10 @@ Werror=
- Common Joined
- Treat specified warning as error
-
-+Werror-maybe-reset
-+Common
-+If environment variable GCC_NO_WERROR is set, act as -Wno-error
-+
- Wextra
- Common Warning
- Print extra (possibly unwanted) warnings
-@@ -573,6 +577,9 @@ fguess-branch-probability
- Common Report Var(flag_guess_branch_prob) Optimization
- Enable guessing of branch probabilities
-
-+fhonour-copts
-+Common RejectNegative
-+
- ; Nonzero means ignore `#ident' directives. 0 means handle them.
- ; Generate position-independent code for executables if possible
- ; On SVR4 targets, it also controls whether or not to emit a
---- a/gcc/opts.c
-+++ b/gcc/opts.c
-@@ -898,9 +898,6 @@ decode_options (unsigned int argc, const
- flag_schedule_insns_after_reload = opt2;
- #endif
- flag_regmove = opt2;
-- flag_strict_aliasing = opt2;
-- flag_strict_overflow = opt2;
-- flag_delete_null_pointer_checks = opt2;
- flag_reorder_blocks = opt2;
- flag_reorder_functions = opt2;
- flag_tree_vrp = opt2;
-@@ -924,6 +921,9 @@ decode_options (unsigned int argc, const
-
- /* -O3 optimizations. */
- opt3 = (optimize >= 3);
-+ flag_strict_aliasing = opt3;
-+ flag_strict_overflow = opt3;
-+ flag_delete_null_pointer_checks = opt3;
- flag_predictive_commoning = opt3;
- flag_inline_functions = opt3;
- flag_unswitch_loops = opt3;
-@@ -1603,6 +1603,17 @@ common_handle_option (size_t scode, cons
- enable_warning_as_error (arg, value, lang_mask);
- break;
-
-+ case OPT_Werror_maybe_reset:
-+ {
-+ char *ev = getenv ("GCC_NO_WERROR");
-+ if ((ev != NULL) && (*ev != '0'))
-+ warnings_are_errors = 0;
-+ }
-+ break;
-+
-+ case OPT_fhonour_copts:
-+ break;
-+
- case OPT_Wextra:
- set_Wextra (value);
- break;
---- a/gcc/doc/cppopts.texi
-+++ b/gcc/doc/cppopts.texi
-@@ -164,6 +164,11 @@ in older programs. This warning is on b
- Make all warnings into hard errors. Source code which triggers warnings
- will be rejected.
-
-+ at item -Werror-maybe-reset
-+ at opindex Werror-maybe-reset
-+Act like @samp{-Wno-error} if the @env{GCC_NO_WERROR} environment
-+variable is set to anything other than 0 or empty.
-+
- @item -Wsystem-headers
- @opindex Wsystem-headers
- Issue warnings for code in system headers. These are normally unhelpful
---- a/gcc/doc/invoke.texi
-+++ b/gcc/doc/invoke.texi
-@@ -234,7 +234,7 @@ Objective-C and Objective-C++ Dialects}.
- -Wconversion -Wcoverage-mismatch -Wno-deprecated @gol
- -Wno-deprecated-declarations -Wdisabled-optimization @gol
- -Wno-div-by-zero -Wempty-body -Wenum-compare -Wno-endif-labels @gol
---Werror -Werror=* @gol
-+-Werror -Werror=* -Werror-maybe-reset @gol
- -Wfatal-errors -Wfloat-equal -Wformat -Wformat=2 @gol
- -Wno-format-contains-nul -Wno-format-extra-args -Wformat-nonliteral @gol
- -Wformat-security -Wformat-y2k @gol
-@@ -4182,6 +4182,22 @@ This option is only supported for C and
- @option{-Wall} and by @option{-pedantic}, which can be disabled with
- @option{-Wno-pointer-sign}.
-
-+ at item -Werror-maybe-reset
-+ at opindex Werror-maybe-reset
-+Act like @samp{-Wno-error} if the @env{GCC_NO_WERROR} environment
-+variable is set to anything other than 0 or empty.
-+
-+ at item -fhonour-copts
-+ at opindex fhonour-copts
-+If @env{GCC_HONOUR_COPTS} is set to 1, abort if this option is not
-+given at least once, and warn if it is given more than once.
-+If @env{GCC_HONOUR_COPTS} is set to 2, abort if this option is not
-+given exactly once.
-+If @env{GCC_HONOUR_COPTS} is set to 0 or unset, warn if this option
-+is not given exactly once.
-+The warning is quelled if @env{GCC_HONOUR_COPTS} is set to @samp{s}.
-+This flag and environment variable only affect the C language.
-+
- @item -Wstack-protector
- @opindex Wstack-protector
- @opindex Wno-stack-protector
-@@ -5720,7 +5736,7 @@ so, the first branch is redirected to ei
- second branch or a point immediately following it, depending on whether
- the condition is known to be true or false.
-
--Enabled at levels @option{-O2}, @option{-O3}, @option{-Os}.
-+Enabled at levels @option{-O3}.
-
- @item -fsplit-wide-types
- @opindex fsplit-wide-types
-@@ -5865,7 +5881,7 @@ safely dereference null pointers. Use
- @option{-fno-delete-null-pointer-checks} to disable this optimization
- for programs which depend on that behavior.
-
--Enabled at levels @option{-O2}, @option{-O3}, @option{-Os}.
-+Enabled at levels @option{-O3}.
-
- @item -fexpensive-optimizations
- @opindex fexpensive-optimizations
---- a/gcc/java/jvspec.c
-+++ b/gcc/java/jvspec.c
-@@ -670,6 +670,7 @@ lang_specific_pre_link (void)
- class name. Append dummy `.c' that can be stripped by set_input so %b
- is correct. */
- set_input (concat (main_class_name, "main.c", NULL));
-+ putenv ("GCC_HONOUR_COPTS=s"); /* XXX hack! */
- err = do_spec (jvgenmain_spec);
- if (err == 0)
- {
+++ /dev/null
---- a/gcc/config/arm/arm-protos.h
-+++ b/gcc/config/arm/arm-protos.h
-@@ -43,10 +43,10 @@ extern unsigned int arm_dbx_register_num
- extern void arm_output_fn_unwind (FILE *, bool);
-
-
--#ifdef RTX_CODE
- extern bool arm_vector_mode_supported_p (enum machine_mode);
- extern int arm_hard_regno_mode_ok (unsigned int, enum machine_mode);
- extern int const_ok_for_arm (HOST_WIDE_INT);
-+#ifdef RTX_CODE
- extern int arm_split_constant (RTX_CODE, enum machine_mode, rtx,
- HOST_WIDE_INT, rtx, rtx, int);
- extern RTX_CODE arm_canonicalize_comparison (RTX_CODE, enum machine_mode,
+++ /dev/null
---- a/gcc/config.gcc
-+++ b/gcc/config.gcc
-@@ -1506,6 +1506,7 @@ m68k-*-linux*) # Motorola m68k's runnin
- if test x$sjlj != x1; then
- tmake_file="$tmake_file m68k/t-slibgcc-elf-ver"
- fi
-+ tmake_file="m68k/t-floatlib m68k/t-m68kbare m68k/t-m68kelf"
- ;;
- m68k-*-rtems*)
- default_m68k_cpu=68020
+++ /dev/null
->From d0557763b0713a4c006bd2405eede3924569cafd Mon Sep 17 00:00:00 2001
-From: Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
-Date: Mon, 5 Jul 2010 11:28:49 +0100
-Subject: [PATCH 2/2] Fix PR44392
-
----
- gcc/config/arm/arm.md | 43 +++++++++++++++++++------------------------
- 1 files changed, 19 insertions(+), 24 deletions(-)
-
-diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
-index 2096ec6..f0348f3 100644
---- a/gcc/config/arm/arm.md
-+++ b/gcc/config/arm/arm.md
-@@ -11318,34 +11318,29 @@
- (define_expand "bswapsi2"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
- (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
--"TARGET_EITHER"
-+"TARGET_EITHER && (arm_arch6 || !optimize_size)"
- "
-- if (!arm_arch6)
-- {
-- if (!optimize_size)
-- {
-- rtx op2 = gen_reg_rtx (SImode);
-- rtx op3 = gen_reg_rtx (SImode);
-+ if (!arm_arch6)
-+ {
-+ rtx op2 = gen_reg_rtx (SImode);
-+ rtx op3 = gen_reg_rtx (SImode);
-
-- if (TARGET_THUMB)
-- {
-- rtx op4 = gen_reg_rtx (SImode);
-- rtx op5 = gen_reg_rtx (SImode);
-+ if (TARGET_THUMB)
-+ {
-+ rtx op4 = gen_reg_rtx (SImode);
-+ rtx op5 = gen_reg_rtx (SImode);
-
-- emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
-- op2, op3, op4, op5));
-- }
-- else
-- {
-- emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
-- op2, op3));
-- }
-+ emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
-+ op2, op3, op4, op5));
-+ }
-+ else
-+ {
-+ emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
-+ op2, op3));
-+ }
-
-- DONE;
-- }
-- else
-- FAIL;
-- }
-+ DONE;
-+ }
- "
- )
-
---
-1.6.2
-
+++ /dev/null
---- a/contrib/regression/objs-gcc.sh
-+++ b/contrib/regression/objs-gcc.sh
-@@ -106,6 +106,10 @@
- then
- make all-gdb all-dejagnu all-ld || exit 1
- make install-gdb install-dejagnu install-ld || exit 1
-+elif [ $H_REAL_TARGET = $H_REAL_HOST -a $H_REAL_TARGET = i686-pc-linux-uclibc ]
-+ then
-+ make all-gdb all-dejagnu all-ld || exit 1
-+ make install-gdb install-dejagnu install-ld || exit 1
- elif [ $H_REAL_TARGET = $H_REAL_HOST ] ; then
- make bootstrap || exit 1
- make install || exit 1
---- a/libjava/classpath/ltconfig
-+++ b/libjava/classpath/ltconfig
-@@ -603,7 +603,7 @@
-
- # Transform linux* to *-*-linux-gnu*, to support old configure scripts.
- case $host_os in
--linux-gnu*) ;;
-+linux-gnu*|linux-uclibc*) ;;
- linux*) host=`echo $host | sed 's/^\(.*-.*-linux\)\(.*\)$/\1-gnu\2/'`
- esac
-
-@@ -1251,7 +1251,7 @@
- ;;
-
- # This must be Linux ELF.
--linux-gnu*)
-+linux*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
+++ /dev/null
---- a/boehm-gc/include/gc.h
-+++ b/boehm-gc/include/gc.h
-@@ -503,7 +503,7 @@
- #if defined(__linux__) || defined(__GLIBC__)
- # include <features.h>
- # if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1 || __GLIBC__ > 2) \
-- && !defined(__ia64__)
-+ && !defined(__ia64__) && !defined(__UCLIBC__)
- # ifndef GC_HAVE_BUILTIN_BACKTRACE
- # define GC_HAVE_BUILTIN_BACKTRACE
- # endif
+++ /dev/null
---- a/libstdc++-v3/include/c_global/cstdio
-+++ b/libstdc++-v3/include/c_global/cstdio
-@@ -139,7 +139,7 @@
-
- _GLIBCXX_END_NAMESPACE
-
--#if _GLIBCXX_USE_C99
-+#if _GLIBCXX_USE_C99 || defined __UCLIBC__
-
- #undef snprintf
- #undef vfscanf
+++ /dev/null
---- a/libmudflap/mf-hooks2.c
-+++ b/libmudflap/mf-hooks2.c
-@@ -421,7 +421,7 @@
- {
- TRACE ("%s\n", __PRETTY_FUNCTION__);
- MF_VALIDATE_EXTENT(s, n, __MF_CHECK_WRITE, "bzero region");
-- bzero (s, n);
-+ memset (s, 0, n);
- }
-
-
-@@ -431,7 +431,7 @@
- TRACE ("%s\n", __PRETTY_FUNCTION__);
- MF_VALIDATE_EXTENT(src, n, __MF_CHECK_READ, "bcopy src");
- MF_VALIDATE_EXTENT(dest, n, __MF_CHECK_WRITE, "bcopy dest");
-- bcopy (src, dest, n);
-+ memmove (dest, src, n);
- }
-
-
-@@ -441,7 +441,7 @@
- TRACE ("%s\n", __PRETTY_FUNCTION__);
- MF_VALIDATE_EXTENT(s1, n, __MF_CHECK_READ, "bcmp 1st arg");
- MF_VALIDATE_EXTENT(s2, n, __MF_CHECK_READ, "bcmp 2nd arg");
-- return bcmp (s1, s2, n);
-+ return n == 0 ? 0 : memcmp (s1, s2, n);
- }
-
-
-@@ -450,7 +450,7 @@
- size_t n = strlen (s);
- TRACE ("%s\n", __PRETTY_FUNCTION__);
- MF_VALIDATE_EXTENT(s, CLAMPADD(n, 1), __MF_CHECK_READ, "index region");
-- return index (s, c);
-+ return strchr (s, c);
- }
-
-
-@@ -459,7 +459,7 @@
- size_t n = strlen (s);
- TRACE ("%s\n", __PRETTY_FUNCTION__);
- MF_VALIDATE_EXTENT(s, CLAMPADD(n, 1), __MF_CHECK_READ, "rindex region");
-- return rindex (s, c);
-+ return strrchr (s, c);
- }
-
- /* XXX: stpcpy, memccpy */
+++ /dev/null
---- a/configure
-+++ b/configure
-@@ -2688,6 +2688,9 @@ case "${target}" in
- ip2k-*-*)
- noconfigdirs="$noconfigdirs target-libiberty target-libstdc++-v3 ${libgcj}"
- ;;
-+ ubicom32-*-*)
-+ noconfigdirs="$noconfigdirs target-libffi"
-+ ;;
- *-*-linux* | *-*-gnu* | *-*-k*bsd*-gnu | *-*-kopensolaris*-gnu)
- noconfigdirs="$noconfigdirs target-newlib target-libgloss"
- ;;
---- /dev/null
-+++ b/gcc/config/ubicom32/constraints.md
-@@ -0,0 +1,149 @@
-+; Constraint definitions for Ubicom32
-+
-+; Copyright (C) 2009 Free Software Foundation, Inc.
-+; Contributed by Ubicom, Inc.
-+
-+; This file is part of GCC.
-+
-+; GCC is free software; you can redistribute it and/or modify it
-+; under the terms of the GNU General Public License as published
-+; by the Free Software Foundation; either version 3, or (at your
-+; option) any later version.
-+
-+; GCC is distributed in the hope that it will be useful, but WITHOUT
-+; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-+; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
-+; License for more details.
-+
-+; You should have received a copy of the GNU General Public License
-+; along with GCC; see the file COPYING3. If not see
-+; <http://www.gnu.org/licenses/>.
-+
-+(define_register_constraint "a" "ALL_ADDRESS_REGS"
-+ "An An register.")
-+
-+(define_register_constraint "d" "DATA_REGS"
-+ "A Dn register.")
-+
-+(define_register_constraint "h" "ACC_REGS"
-+ "An accumulator register.")
-+
-+(define_register_constraint "l" "ACC_LO_REGS"
-+ "An accn_lo register.")
-+
-+(define_register_constraint "Z" "FDPIC_REG"
-+ "The FD-PIC GOT pointer: A0.")
-+
-+(define_constraint "I"
-+ "An 8-bit signed constant value."
-+ (and (match_code "const_int")
-+ (match_test "(ival >= -128) && (ival <= 127)")))
-+
-+(define_constraint "Q"
-+ "An 8-bit signed constant value represented as unsigned."
-+ (and (match_code "const_int")
-+ (match_test "(ival >= 0x00) && (ival <= 0xff)")))
-+
-+(define_constraint "R"
-+ "An 8-bit signed constant value represented as unsigned."
-+ (and (match_code "const_int")
-+ (match_test "((ival >= 0x0000) && (ival <= 0x007f)) || ((ival >= 0xff80) && (ival <= 0xffff))")))
-+
-+(define_constraint "J"
-+ "A 7-bit unsigned constant value."
-+ (and (match_code "const_int")
-+ (match_test "(ival >= 0) && (ival <= 127)")))
-+
-+(define_constraint "K"
-+ "A 7-bit unsigned constant value shifted << 1."
-+ (and (match_code "const_int")
-+ (match_test "(ival >= 0) && (ival <= 254) && ((ival & 1) == 0)")))
-+
-+(define_constraint "L"
-+ "A 7-bit unsigned constant value shifted << 2."
-+ (and (match_code "const_int")
-+ (match_test "(ival >= 0) && (ival <= 508) && ((ival & 3) == 0)")))
-+
-+(define_constraint "M"
-+ "A 5-bit unsigned constant value."
-+ (and (match_code "const_int")
-+ (match_test "(ival >= 0) && (ival <= 31)")))
-+
-+(define_constraint "N"
-+ "A signed 16 bit constant value."
-+ (and (match_code "const_int")
-+ (match_test "(ival >= -32768) && (ival <= 32767)")))
-+
-+(define_constraint "O"
-+ "An exact bitmask of contiguous 1 bits starting at bit 0."
-+ (and (match_code "const_int")
-+ (match_test "exact_log2 (ival + 1) != -1")))
-+
-+(define_constraint "P"
-+ "A 7-bit negative constant value shifted << 2."
-+ (and (match_code "const_int")
-+ (match_test "(ival >= -504) && (ival <= 0) && ((ival & 3) == 0)")))
-+
-+(define_constraint "S"
-+ "A symbolic reference."
-+ (match_code "symbol_ref"))
-+
-+(define_constraint "Y"
-+ "An FD-PIC symbolic reference."
-+ (and (match_test "TARGET_FDPIC")
-+ (match_test "GET_CODE (op) == UNSPEC")
-+ (ior (match_test "XINT (op, 1) == UNSPEC_FDPIC_GOT")
-+ (match_test "XINT (op, 1) == UNSPEC_FDPIC_GOT_FUNCDESC"))))
-+
-+(define_memory_constraint "T1"
-+ "A memory operand that can be used for .1 instruction."
-+ (and (match_test "memory_operand (op, GET_MODE(op))")
-+ (match_test "GET_MODE (op) == QImode")))
-+
-+(define_memory_constraint "T2"
-+ "A memory operand that can be used for .2 instruction."
-+ (and (match_test "memory_operand (op, GET_MODE(op))")
-+ (match_test "GET_MODE (op) == HImode")))
-+
-+(define_memory_constraint "T4"
-+ "A memory operand that can be used for .4 instruction."
-+ (and (match_test "memory_operand (op, GET_MODE(op))")
-+ (ior (match_test "GET_MODE (op) == SImode")
-+ (match_test "GET_MODE (op) == DImode")
-+ (match_test "GET_MODE (op) == SFmode"))))
-+
-+(define_memory_constraint "U1"
-+ "An offsettable memory operand that can be used for .1 instruction."
-+ (and (match_test "memory_operand (op, GET_MODE(op))")
-+ (match_test "GET_MODE (op) == QImode")
-+ (match_test "GET_CODE (XEXP (op, 0)) != POST_INC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_INC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != POST_DEC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_DEC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != POST_MODIFY")
-+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_MODIFY")))
-+
-+(define_memory_constraint "U2"
-+ "An offsettable memory operand that can be used for .2 instruction."
-+ (and (match_test "memory_operand (op, GET_MODE(op))")
-+ (match_test "GET_MODE (op) == HImode")
-+ (match_test "GET_CODE (XEXP (op, 0)) != POST_INC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_INC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != POST_DEC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_DEC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != POST_MODIFY")
-+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_MODIFY")))
-+
-+(define_memory_constraint "U4"
-+ "An offsettable memory operand that can be used for .4 instruction."
-+ (and (match_test "memory_operand (op, GET_MODE(op))")
-+ (ior (match_test "GET_MODE (op) == SImode")
-+ (match_test "GET_MODE (op) == DImode")
-+ (match_test "GET_MODE (op) == SFmode"))
-+ (match_test "GET_CODE (XEXP (op, 0)) != POST_INC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_INC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != POST_DEC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_DEC")
-+ (match_test "GET_CODE (XEXP (op, 0)) != POST_MODIFY")
-+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_MODIFY")))
-+
---- /dev/null
-+++ b/gcc/config/ubicom32/crti.S
-@@ -0,0 +1,54 @@
-+/* Specialized code needed to support construction and destruction of
-+ file-scope objects in C++ and Java code, and to support exception handling.
-+ Copyright (C) 1999 Free Software Foundation, Inc.
-+ Contributed by Charles-Antoine Gauthier (charles.gauthier@iit.nrc.ca).
-+
-+This file is part of GCC.
-+
-+GCC is free software; you can redistribute it and/or modify
-+it under the terms of the GNU General Public License as published by
-+the Free Software Foundation; either version 2, or (at your option)
-+any later version.
-+
-+GCC is distributed in the hope that it will be useful,
-+but WITHOUT ANY WARRANTY; without even the implied warranty of
-+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+GNU General Public License for more details.
-+
-+You should have received a copy of the GNU General Public License
-+along with GCC; see the file COPYING. If not, write to
-+the Free Software Foundation, 59 Temple Place - Suite 330,
-+Boston, MA 02111-1307, USA. */
-+
-+/* As a special exception, if you link this library with files
-+ compiled with GCC to produce an executable, this does not cause
-+ the resulting executable to be covered by the GNU General Public License.
-+ This exception does not however invalidate any other reasons why
-+ the executable file might be covered by the GNU General Public License. */
-+
-+/*
-+ * This file just supplies function prologues for the .init and .fini
-+ * sections. It is linked in before crtbegin.o.
-+ */
-+ .file "crti.o"
-+ .ident "GNU C crti.o"
-+
-+ .section .init
-+ .align 2
-+ .globl _init
-+ .type _init, @function
-+_init:
-+ move.4 -4(sp)++, a5
-+#ifdef __UBICOM32_FDPIC__
-+ move.4 -4(sp)++, a0
-+#endif
-+
-+ .section .fini
-+ .align 2
-+ .globl _fini
-+ .type _fini, @function
-+_fini:
-+ move.4 -4(sp)++, a5
-+#ifdef __UBICOM32_FDPIC__
-+ move.4 -4(sp)++, a0
-+#endif
---- /dev/null
-+++ b/gcc/config/ubicom32/crtn.S
-@@ -0,0 +1,47 @@
-+/* Specialized code needed to support construction and destruction of
-+ file-scope objects in C++ and Java code, and to support exception handling.
-+ Copyright (C) 1999 Free Software Foundation, Inc.
-+ Contributed by Charles-Antoine Gauthier (charles.gauthier@iit.nrc.ca).
-+
-+This file is part of GCC.
-+
-+GCC is free software; you can redistribute it and/or modify
-+it under the terms of the GNU General Public License as published by
-+the Free Software Foundation; either version 2, or (at your option)
-+any later version.
-+
-+GCC is distributed in the hope that it will be useful,
-+but WITHOUT ANY WARRANTY; without even the implied warranty of
-+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+GNU General Public License for more details.
-+
-+You should have received a copy of the GNU General Public License
-+along with GCC; see the file COPYING. If not, write to
-+the Free Software Foundation, 59 Temple Place - Suite 330,
-+Boston, MA 02111-1307, USA. */
-+
-+/* As a special exception, if you link this library with files
-+ compiled with GCC to produce an executable, this does not cause
-+ the resulting executable to be covered by the GNU General Public License.
-+ This exception does not however invalidate any other reasons why
-+ the executable file might be covered by the GNU General Public License. */
-+
-+/*
-+ * This file supplies function epilogues for the .init and .fini sections.
-+ * It is linked in after all other files.
-+ */
-+
-+ .file "crtn.o"
-+ .ident "GNU C crtn.o"
-+
-+ .section .init
-+#ifdef __UBICOM32_FDPIC__
-+ move.4 a0, (sp)4++
-+#endif
-+ ret (sp)4++
-+
-+ .section .fini
-+#ifdef __UBICOM32_FDPIC__
-+ move.4 a0, (sp)4++
-+#endif
-+ ret (sp)4++
---- /dev/null
-+++ b/gcc/config/ubicom32/elf.h
-@@ -0,0 +1,29 @@
-+#undef STARTFILE_SPEC
-+#define STARTFILE_SPEC "\
-+%{msim:%{!shared:crt0%O%s}} \
-+crti%O%s crtbegin%O%s"
-+
-+#undef ENDFILE_SPEC
-+#define ENDFILE_SPEC "crtend%O%s crtn%O%s"
-+
-+#ifdef __UBICOM32_FDPIC__
-+#define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC) \
-+ asm (SECTION_OP); \
-+ asm ("move.4 a0, 0(sp);\n\t" \
-+ "call a5," USER_LABEL_PREFIX #FUNC ";"); \
-+ asm (TEXT_SECTION_ASM_OP);
-+#endif
-+
-+#undef SUBTARGET_DRIVER_SELF_SPECS
-+#define SUBTARGET_DRIVER_SELF_SPECS \
-+ "%{mfdpic:-msim} "
-+
-+#define NO_IMPLICIT_EXTERN_C
-+
-+/*
-+ * We need this to compile crtbegin/crtend. This should really be picked
-+ * up from elfos.h but at the moment including elfos.h causes other more
-+ * serous linker issues.
-+ */
-+#define INIT_SECTION_ASM_OP "\t.section\t.init"
-+#define FINI_SECTION_ASM_OP "\t.section\t.fini"
---- /dev/null
-+++ b/gcc/config/ubicom32/linux.h
-@@ -0,0 +1,80 @@
-+/* Definitions of target machine for Ubicom32-uclinux
-+
-+ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
-+ 2009 Free Software Foundation, Inc.
-+ Contributed by Ubicom, Inc.
-+
-+ This file is part of GCC.
-+
-+ GCC is free software; you can redistribute it and/or modify it
-+ under the terms of the GNU General Public License as published
-+ by the Free Software Foundation; either version 3, or (at your
-+ option) any later version.
-+
-+ GCC is distributed in the hope that it will be useful, but WITHOUT
-+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
-+ License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with GCC; see the file COPYING3. If not see
-+ <http://www.gnu.org/licenses/>. */
-+
-+/* Don't assume anything about the header files. */
-+#define NO_IMPLICIT_EXTERN_C
-+
-+#undef LIB_SPEC
-+#define LIB_SPEC \
-+ "%{pthread:-lpthread} " \
-+ "-lc"
-+
-+#undef LINK_GCC_C_SEQUENCE_SPEC
-+#define LINK_GCC_C_SEQUENCE_SPEC \
-+ "%{static:--start-group} %G %L %{static:--end-group} " \
-+ "%{!static: %G}"
-+
-+#undef STARTFILE_SPEC
-+#define STARTFILE_SPEC \
-+ "%{!shared: %{pg|p|profile:gcrt1%O%s;pie:Scrt1%O%s;:crt1%O%s}} " \
-+ "crtreloc%O%s crti%O%s %{shared|pie:crtbeginS%O%s;:crtbegin%O%s}"
-+
-+#undef ENDFILE_SPEC
-+#define ENDFILE_SPEC \
-+ "%{shared|pie:crtendS%O%s;:crtend%O%s} crtn%O%s"
-+
-+/* taken from linux.h */
-+/* The GNU C++ standard library requires that these macros be defined. */
-+#undef CPLUSPLUS_CPP_SPEC
-+#define CPLUSPLUS_CPP_SPEC "-D_GNU_SOURCE %(cpp)"
-+
-+#define TARGET_OS_CPP_BUILTINS() \
-+ do { \
-+ builtin_define_std ("__UBICOM32__"); \
-+ builtin_define_std ("__ubicom32__"); \
-+ builtin_define ("__gnu_linux__"); \
-+ builtin_define_std ("linux"); \
-+ builtin_define_std ("unix"); \
-+ builtin_assert ("system=linux"); \
-+ builtin_assert ("system=unix"); \
-+ builtin_assert ("system=posix"); \
-+ } while (0)
-+
-+#define OBJECT_FORMAT_ELF
-+
-+
-+#undef DRIVER_SELF_SPECS
-+#define DRIVER_SELF_SPECS \
-+ "%{!mno-fdpic:-mfdpic}"
-+
-+#undef LINK_SPEC
-+#define LINK_SPEC "%{mfdpic: -m elf32ubicom32fdpic -z text } %{shared} %{pie} \
-+ %{static:-dn -Bstatic} \
-+ %{shared:-G -Bdynamic} \
-+ %{!shared: %{!static: \
-+ %{rdynamic:-export-dynamic} \
-+ %{!dynamic-linker:-dynamic-linker /lib/ld-uClibc.so.0}} \
-+ %{static}} "
-+
-+/*
-+#define MD_UNWIND_SUPPORT "config/bfin/linux-unwind.h"
-+*/
---- /dev/null
-+++ b/gcc/config/ubicom32/predicates.md
-@@ -0,0 +1,327 @@
-+; Predicate definitions for Ubicom32.
-+
-+; Copyright (C) 2009 Free Software Foundation, Inc.
-+; Contributed by Ubicom, Inc.
-+
-+; This file is part of GCC.
-+
-+; GCC is free software; you can redistribute it and/or modify it
-+; under the terms of the GNU General Public License as published
-+; by the Free Software Foundation; either version 3, or (at your
-+; option) any later version.
-+
-+; GCC is distributed in the hope that it will be useful, but WITHOUT
-+; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-+; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
-+; License for more details.
-+
-+; You should have received a copy of the GNU General Public License
-+; along with GCC; see the file COPYING3. If not see
-+; <http://www.gnu.org/licenses/>.
-+
-+(define_predicate "ubicom32_move_operand"
-+ (match_code "const_int, const_double, const, mem, subreg, reg, lo_sum")
-+{
-+ if (CONST_INT_P (op))
-+ return true;
-+
-+ if (GET_CODE (op) == CONST_DOUBLE)
-+ return true;
-+
-+ if (GET_CODE (op) == CONST)
-+ return memory_address_p (mode, op);
-+
-+ if (GET_MODE (op) != mode)
-+ return false;
-+
-+ if (MEM_P (op))
-+ return memory_address_p (mode, XEXP (op, 0));
-+
-+ if (GET_CODE (op) == SUBREG) {
-+ op = SUBREG_REG (op);
-+
-+ if (REG_P (op))
-+ return true;
-+
-+ if (! MEM_P (op))
-+ return false;
-+
-+ /* Paradoxical SUBREG. */
-+ if (GET_MODE_SIZE (mode) > GET_MODE_SIZE (GET_MODE (op)))
-+ return false;
-+
-+ return memory_address_p (GET_MODE (op), XEXP (op, 0));
-+ }
-+
-+ return register_operand (op, mode);
-+})
-+
-+;; Returns true if OP is either a symbol reference or a sum of a
-+;; symbol reference and a constant.
-+
-+(define_predicate "ubicom32_symbolic_address_operand"
-+ (match_code "symbol_ref, label_ref, const")
-+{
-+ switch (GET_CODE (op))
-+ {
-+ case SYMBOL_REF:
-+ case LABEL_REF:
-+ return true;
-+
-+ case CONST:
-+ op = XEXP (op, 0);
-+ return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
-+ || GET_CODE (XEXP (op, 0)) == LABEL_REF)
-+ && CONST_INT_P (XEXP (op, 1)));
-+
-+ default:
-+ return false;
-+ }
-+})
-+
-+;; Return true if operand is the uClinux FD-PIC register.
-+
-+(define_predicate "ubicom32_fdpic_operand"
-+ (match_code "reg")
-+{
-+ if (! TARGET_FDPIC)
-+ return false;
-+
-+ if (!REG_P (op))
-+ return false;
-+
-+ if (GET_MODE (op) != mode && mode != VOIDmode)
-+ return false;
-+
-+ if (REGNO (op) != FDPIC_REGNUM && REGNO (op) < FIRST_PSEUDO_REGISTER)
-+ return false;
-+
-+ return true;
-+})
-+
-+(define_predicate "ubicom32_fdpic_got_offset_operand"
-+ (match_code "unspec")
-+{
-+ if (! TARGET_FDPIC)
-+ return false;
-+
-+ if (GET_CODE (op) != UNSPEC)
-+ return false;
-+
-+ if (XINT (op, 1) != UNSPEC_FDPIC_GOT
-+ && XINT (op, 1) != UNSPEC_FDPIC_GOT_FUNCDESC)
-+ return false;
-+
-+ return true;
-+})
-+
-+(define_predicate "ubicom32_arith_operand"
-+ (match_code "subreg, reg, const_int, lo_sum, mem")
-+{
-+ return (ubicom32_move_operand (op, mode)
-+ && ! ubicom32_symbolic_address_operand (op, mode)
-+ && (! CONST_INT_P (op)
-+ || satisfies_constraint_I (op)));
-+})
-+
-+(define_predicate "ubicom32_arith_operand_dot1"
-+ (match_code "subreg, reg, const_int, lo_sum, mem")
-+{
-+ return (ubicom32_move_operand (op, mode)
-+ && ! ubicom32_symbolic_address_operand (op, mode)
-+ && (! CONST_INT_P (op)
-+ || satisfies_constraint_Q (op)));
-+})
-+
-+(define_predicate "ubicom32_arith_operand_dot2"
-+ (match_code "subreg, reg, const_int, lo_sum, mem")
-+{
-+ return (ubicom32_move_operand (op, mode)
-+ && ! ubicom32_symbolic_address_operand (op, mode)
-+ && (! CONST_INT_P (op)
-+ || satisfies_constraint_R (op)));
-+})
-+
-+(define_predicate "ubicom32_compare_operand"
-+ (match_code "subreg, reg, const_int, lo_sum, mem")
-+{
-+ return (ubicom32_move_operand (op, mode)
-+ && ! ubicom32_symbolic_address_operand (op, mode)
-+ && (! CONST_INT_P (op)
-+ || satisfies_constraint_N (op)));
-+})
-+
-+(define_predicate "ubicom32_compare_operator"
-+ (match_code "compare"))
-+
-+(define_predicate "ubicom32_and_or_si3_operand"
-+ (match_code "subreg, reg, const_int, lo_sum, mem")
-+{
-+ return (ubicom32_arith_operand (op, mode)
-+ || (CONST_INT_P (op)
-+ && ((exact_log2 (INTVAL (op) + 1) != -1
-+ && exact_log2 (INTVAL (op) + 1) <= 31)
-+ || (exact_log2 (INTVAL (op)) != -1
-+ && exact_log2 (INTVAL (op)) <= 31)
-+ || (exact_log2 (~INTVAL (op)) != -1
-+ && exact_log2 (~INTVAL (op)) <= 31))));
-+})
-+
-+(define_predicate "ubicom32_and_or_hi3_operand"
-+ (match_code "subreg, reg, const_int, lo_sum, mem")
-+{
-+ return (ubicom32_arith_operand (op, mode)
-+ || (CONST_INT_P (op)
-+ && exact_log2 (INTVAL (op) + 1) != -1
-+ && exact_log2 (INTVAL (op) + 1) <= 15));
-+})
-+
-+(define_predicate "ubicom32_mem_or_address_register_operand"
-+ (match_code "subreg, reg, mem")
-+{
-+ unsigned int regno;
-+
-+ if (MEM_P (op)
-+ && memory_operand (op, mode))
-+ return true;
-+
-+ if (REG_P (op))
-+ regno = REGNO (op);
-+ else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
-+ {
-+ int offset;
-+ if (REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER)
-+ offset = SUBREG_BYTE (op) / (GET_MODE_SIZE (GET_MODE (op)));
-+ else
-+ offset = subreg_regno_offset (REGNO (SUBREG_REG (op)),
-+ GET_MODE (SUBREG_REG (op)),
-+ SUBREG_BYTE (op),
-+ GET_MODE (op));
-+ regno = REGNO (SUBREG_REG (op)) + offset;
-+ }
-+ else
-+ return false;
-+
-+ return (regno >= FIRST_PSEUDO_REGISTER
-+ || REGNO_REG_CLASS (regno) == FDPIC_REG
-+ || REGNO_REG_CLASS (regno) == ADDRESS_REGS);
-+})
-+
-+(define_predicate "ubicom32_data_register_operand"
-+ (match_code "subreg, reg")
-+{
-+ unsigned int regno;
-+
-+ if (REG_P (op))
-+ regno = REGNO (op);
-+ else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
-+ {
-+ int offset;
-+ if (REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER)
-+ offset = SUBREG_BYTE (op) / (GET_MODE_SIZE (GET_MODE (op)));
-+ else
-+ offset = subreg_regno_offset (REGNO (SUBREG_REG (op)),
-+ GET_MODE (SUBREG_REG (op)),
-+ SUBREG_BYTE (op),
-+ GET_MODE (op));
-+ regno = REGNO (SUBREG_REG (op)) + offset;
-+ }
-+ else
-+ return false;
-+
-+ return ((regno >= FIRST_PSEUDO_REGISTER
-+ && regno != REGNO (virtual_stack_vars_rtx))
-+ || REGNO_REG_CLASS (regno) == DATA_REGS);
-+})
-+
-+(define_predicate "ubicom32_address_register_operand"
-+ (match_code "subreg, reg")
-+{
-+ unsigned int regno;
-+
-+ if (REG_P (op))
-+ regno = REGNO (op);
-+ else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
-+ {
-+ int offset;
-+ if (REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER)
-+ offset = SUBREG_BYTE (op) / (GET_MODE_SIZE (GET_MODE (op)));
-+ else
-+ offset = subreg_regno_offset (REGNO (SUBREG_REG (op)),
-+ GET_MODE (SUBREG_REG (op)),
-+ SUBREG_BYTE (op),
-+ GET_MODE (op));
-+ regno = REGNO (SUBREG_REG (op)) + offset;
-+ }
-+ else
-+ return false;
-+
-+ return (regno >= FIRST_PSEUDO_REGISTER
-+ || REGNO_REG_CLASS (regno) == FDPIC_REG
-+ || REGNO_REG_CLASS (regno) == ADDRESS_REGS);
-+})
-+
-+(define_predicate "ubicom32_acc_lo_register_operand"
-+ (match_code "subreg, reg")
-+{
-+ unsigned int regno;
-+
-+ if (REG_P (op))
-+ regno = REGNO (op);
-+ else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
-+ {
-+ int offset;
-+ if (REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER)
-+ offset = SUBREG_BYTE (op) / (GET_MODE_SIZE (GET_MODE (op)));
-+ else
-+ offset = subreg_regno_offset (REGNO (SUBREG_REG (op)),
-+ GET_MODE (SUBREG_REG (op)),
-+ SUBREG_BYTE (op),
-+ GET_MODE (op));
-+ regno = REGNO (SUBREG_REG (op)) + offset;
-+ }
-+ else
-+ return false;
-+
-+ return ((regno >= FIRST_PSEUDO_REGISTER
-+ && regno != REGNO (virtual_stack_vars_rtx))
-+ || REGNO_REG_CLASS (regno) == ACC_LO_REGS);
-+})
-+
-+(define_predicate "ubicom32_acc_hi_register_operand"
-+ (match_code "subreg, reg")
-+{
-+ unsigned int regno;
-+
-+ if (REG_P (op))
-+ regno = REGNO (op);
-+ else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
-+ {
-+ int offset;
-+ if (REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER)
-+ offset = SUBREG_BYTE (op) / (GET_MODE_SIZE (GET_MODE (op)));
-+ else
-+ offset = subreg_regno_offset (REGNO (SUBREG_REG (op)),
-+ GET_MODE (SUBREG_REG (op)),
-+ SUBREG_BYTE (op),
-+ GET_MODE (op));
-+ regno = REGNO (SUBREG_REG (op)) + offset;
-+ }
-+ else
-+ return false;
-+
-+ return ((regno >= FIRST_PSEUDO_REGISTER
-+ && regno != REGNO (virtual_stack_vars_rtx))
-+ || REGNO_REG_CLASS (regno) == ACC_REGS);
-+})
-+
-+(define_predicate "ubicom32_call_address_operand"
-+ (match_code "symbol_ref, subreg, reg")
-+{
-+ return (GET_CODE (op) == SYMBOL_REF || REG_P (op));
-+})
-+
-+(define_special_predicate "ubicom32_cc_register_operand"
-+ (and (match_code "reg")
-+ (match_test "REGNO (op) == CC_REGNUM")))
-+
---- /dev/null
-+++ b/gcc/config/ubicom32/t-ubicom32
-@@ -0,0 +1,52 @@
-+# Name of assembly file containing libgcc1 functions.
-+# This entry must be present, but it can be empty if the target does
-+# not need any assembler functions to support its code generation.
-+CROSS_LIBGCC1 =
-+
-+# Alternatively if assembler functions *are* needed then define the
-+# entries below:
-+# CROSS_LIBGCC1 = libgcc1-asm.a
-+
-+LIB2FUNCS_EXTRA = \
-+ $(srcdir)/config/udivmodsi4.c \
-+ $(srcdir)/config/divmod.c \
-+ $(srcdir)/config/udivmod.c
-+
-+# If any special flags are necessary when building libgcc2 put them here.
-+#
-+# TARGET_LIBGCC2_CFLAGS =
-+
-+# 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
-+
-+fp-bit.c: $(srcdir)/config/fp-bit.c
-+ echo '#define FLOAT' > fp-bit.c
-+ cat $(srcdir)/config/fp-bit.c >> fp-bit.c
-+
-+dp-bit.c: $(srcdir)/config/fp-bit.c
-+ cat $(srcdir)/config/fp-bit.c > dp-bit.c
-+
-+# Commented out to speed up compiler development!
-+#
-+# MULTILIB_OPTIONS = march=ubicom32v1/march=ubicom32v2/march=ubicom32v3/march=ubicom32v4
-+# MULTILIB_DIRNAMES = ubicom32v1 ubicom32v2 ubicom32v3 ubicom32v4
-+
-+MULTILIB_OPTIONS = march=ubicom32v3/march=ubicom32v4
-+MULTILIB_OPTIONS += mfdpic
-+MULTILIB_OPTIONS += mno-ipos-abi/mipos-abi
-+MULTILIB_OPTIONS += fno-leading-underscore/fleading-underscore
-+
-+# Assemble startup files.
-+$(T)crti.o: $(srcdir)/config/ubicom32/crti.S $(GCC_PASSES)
-+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) \
-+ -c -o $(T)crti.o -x assembler-with-cpp $(srcdir)/config/ubicom32/crti.S
-+
-+$(T)crtn.o: $(srcdir)/config/ubicom32/crtn.S $(GCC_PASSES)
-+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) \
-+ -c -o $(T)crtn.o -x assembler-with-cpp $(srcdir)/config/ubicom32/crtn.S
-+
-+# these parts are required because uClibc ldso needs them to link.
-+# they are not in the specfile so they will not be included automatically.
-+EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o crtbeginS.o crtendS.o crti.o crtn.o
---- /dev/null
-+++ b/gcc/config/ubicom32/t-ubicom32-linux
-@@ -0,0 +1,35 @@
-+# Name of assembly file containing libgcc1 functions.
-+# This entry must be present, but it can be empty if the target does
-+# not need any assembler functions to support its code generation.
-+CROSS_LIBGCC1 =
-+
-+# Alternatively if assembler functions *are* needed then define the
-+# entries below:
-+# CROSS_LIBGCC1 = libgcc1-asm.a
-+
-+LIB2FUNCS_EXTRA = \
-+ $(srcdir)/config/udivmodsi4.c \
-+ $(srcdir)/config/divmod.c \
-+ $(srcdir)/config/udivmod.c
-+
-+# If any special flags are necessary when building libgcc2 put them here.
-+#
-+# TARGET_LIBGCC2_CFLAGS =
-+
-+# 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
-+
-+fp-bit.c: $(srcdir)/config/fp-bit.c
-+ echo '#define FLOAT' > fp-bit.c
-+ cat $(srcdir)/config/fp-bit.c >> fp-bit.c
-+
-+dp-bit.c: $(srcdir)/config/fp-bit.c
-+ cat $(srcdir)/config/fp-bit.c > dp-bit.c
-+
-+# We only support v3 and v4 ISAs for uClinux.
-+
-+MULTILIB_OPTIONS = march=ubicom32v3/march=ubicom32v4
-+
-+#EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o crtbeginS.o crtendS.o
---- /dev/null
-+++ b/gcc/config/ubicom32/t-ubicom32-uclinux
-@@ -0,0 +1,35 @@
-+# Name of assembly file containing libgcc1 functions.
-+# This entry must be present, but it can be empty if the target does
-+# not need any assembler functions to support its code generation.
-+CROSS_LIBGCC1 =
-+
-+# Alternatively if assembler functions *are* needed then define the
-+# entries below:
-+# CROSS_LIBGCC1 = libgcc1-asm.a
-+
-+LIB2FUNCS_EXTRA = \
-+ $(srcdir)/config/udivmodsi4.c \
-+ $(srcdir)/config/divmod.c \
-+ $(srcdir)/config/udivmod.c
-+
-+# If any special flags are necessary when building libgcc2 put them here.
-+#
-+# TARGET_LIBGCC2_CFLAGS =
-+
-+# 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
-+
-+fp-bit.c: $(srcdir)/config/fp-bit.c
-+ echo '#define FLOAT' > fp-bit.c
-+ cat $(srcdir)/config/fp-bit.c >> fp-bit.c
-+
-+dp-bit.c: $(srcdir)/config/fp-bit.c
-+ cat $(srcdir)/config/fp-bit.c > dp-bit.c
-+
-+# We only support v3 and v4 ISAs for uClinux.
-+
-+MULTILIB_OPTIONS = march=ubicom32v3/march=ubicom32v4
-+
-+EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o # crtbeginS.o crtendS.o
---- /dev/null
-+++ b/gcc/config/ubicom32/ubicom32-modes.def
-@@ -0,0 +1,30 @@
-+/* Definitions of target machine for GNU compiler, Ubicom32 architecture.
-+ Copyright (C) 2009 Free Software Foundation, Inc.
-+ Contributed by Ubicom, Inc.
-+
-+ This file is part of GCC.
-+
-+ GCC is free software; you can redistribute it and/or modify it
-+ under the terms of the GNU General Public License as published
-+ by the Free Software Foundation; either version 3, or (at your
-+ option) any later version.
-+
-+ GCC is distributed in the hope that it will be useful, but WITHOUT
-+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
-+ License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with GCC; see the file COPYING3. If not see
-+ <http://www.gnu.org/licenses/>. */
-+
-+/* Some insns set all condition code flags, some only set the Z and N flags, and
-+ some only set the Z flag. */
-+
-+CC_MODE (CCW);
-+CC_MODE (CCWZN);
-+CC_MODE (CCWZ);
-+CC_MODE (CCS);
-+CC_MODE (CCSZN);
-+CC_MODE (CCSZ);
-+
---- /dev/null
-+++ b/gcc/config/ubicom32/ubicom32-protos.h
-@@ -0,0 +1,84 @@
-+/* Function prototypes for Ubicom IP3000.
-+
-+ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
-+ 2009 Free Software Foundation, Inc.
-+ Contributed by Ubicom, Inc.
-+
-+ This file is part of GNU CC.
-+
-+ GNU CC is free software; you can redistribute it and/or modify it under
-+ the terms of the GNU General Public License as published by the Free
-+ Software Foundation; either version 2, or (at your option) any later
-+ version.
-+
-+ GNU CC is distributed in the hope that it will be useful, but WITHOUT
-+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-+ for more details.
-+
-+ You should have received a copy of the GNU General Public License along
-+ with GNU CC; see the file COPYING. If not, write to the Free Software
-+ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-+
-+#ifdef RTX_CODE
-+
-+#ifdef TREE_CODE
-+extern void ubicom32_va_start (tree, rtx);
-+#endif /* TREE_CODE */
-+
-+extern void ubicom32_print_operand (FILE *, rtx, int);
-+extern void ubicom32_print_operand_address (FILE *, rtx);
-+
-+extern void ubicom32_conditional_register_usage (void);
-+extern enum reg_class ubicom32_preferred_reload_class (rtx, enum reg_class);
-+extern int ubicom32_regno_ok_for_index_p (int, int);
-+extern void ubicom32_expand_movsi (rtx *);
-+extern void ubicom32_expand_addsi3 (rtx *);
-+extern int ubicom32_emit_mult_sequence (rtx *);
-+extern void ubicom32_emit_move_const_int (rtx, rtx);
-+extern bool ubicom32_legitimate_constant_p (rtx);
-+extern bool ubicom32_legitimate_address_p (enum machine_mode, rtx, int);
-+extern rtx ubicom32_legitimize_address (rtx, rtx, enum machine_mode);
-+extern rtx ubicom32_legitimize_reload_address (rtx, enum machine_mode, int, int);
-+extern void ubicom32_canonicalize_comparison (enum rtx_code *code, rtx *op0, rtx *op1);
-+extern int ubicom32_mode_dependent_address_p (rtx);
-+extern void ubicom32_output_cond_jump (rtx, rtx, rtx);
-+extern void ubicom32_expand_eh_return (rtx *);
-+extern void ubicom32_expand_call_fdpic (rtx *);
-+extern void ubicom32_expand_call_value_fdpic (rtx *);
-+extern enum machine_mode ubicom32_select_cc_mode (RTX_CODE, rtx, rtx);
-+extern rtx ubicom32_gen_compare_reg (RTX_CODE, rtx, rtx);
-+extern int ubicom32_shiftable_const_int (int);
-+#endif /* RTX_CODE */
-+
-+#ifdef TREE_CODE
-+extern void init_cumulative_args (CUMULATIVE_ARGS *cum,
-+ tree fntype,
-+ struct rtx_def *libname,
-+ int indirect);
-+extern struct rtx_def *function_arg (CUMULATIVE_ARGS *,
-+ enum machine_mode, tree, int);
-+extern struct rtx_def *function_incoming_arg (CUMULATIVE_ARGS *,
-+ enum machine_mode,
-+ tree, int);
-+extern int function_arg_partial_nregs (CUMULATIVE_ARGS *,
-+ enum machine_mode, tree, int);
-+extern struct rtx_def *ubicom32_va_arg (tree, tree);
-+extern int ubicom32_reg_parm_stack_space (tree);
-+#endif /* TREE_CODE */
-+
-+extern struct rtx_def * ubicom32_builtin_saveregs (void);
-+extern void asm_file_start (FILE *);
-+extern void ubicom32_expand_prologue (void);
-+extern void ubicom32_expand_epilogue (void);
-+extern int ubicom32_initial_elimination_offset (int, int);
-+extern int ubicom32_regno_ok_for_base_p (int, int);
-+extern bool ubicom32_hard_regno_mode_ok (unsigned int, enum machine_mode);
-+extern int ubicom32_can_use_return_insn_p (void);
-+extern rtx ubicom32_return_addr_rtx (int, rtx);
-+extern void ubicom32_optimization_options (int, int);
-+extern void ubicom32_override_options (void);
-+extern bool ubicom32_match_cc_mode (rtx, enum machine_mode);
-+
-+extern int ubicom32_reorg_completed;
-+
---- /dev/null
-+++ b/gcc/config/ubicom32/ubicom32.c
-@@ -0,0 +1,2881 @@
-+/* Subroutines for insn-output.c for Ubicom32
-+
-+ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
-+ 2009 Free Software Foundation, Inc.
-+ Contributed by Ubicom, Inc.
-+
-+ This file is part of GCC.
-+
-+ GCC is free software; you can redistribute it and/or modify it
-+ under the terms of the GNU General Public License as published
-+ by the Free Software Foundation; either version 3, or (at your
-+ option) any later version.
-+
-+ GCC is distributed in the hope that it will be useful, but WITHOUT
-+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
-+ License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with GCC; see the file COPYING3. If not see
-+ <http://www.gnu.org/licenses/>. */
-+
-+#include "config.h"
-+#include "system.h"
-+#include "coretypes.h"
-+#include "tm.h"
-+#include "rtl.h"
-+#include "tree.h"
-+#include "regs.h"
-+#include "hard-reg-set.h"
-+#include "real.h"
-+#include "insn-config.h"
-+#include "conditions.h"
-+#include "insn-flags.h"
-+#include "output.h"
-+#include "insn-attr.h"
-+#include "insn-codes.h"
-+#include "flags.h"
-+#include "recog.h"
-+#include "expr.h"
-+#include "function.h"
-+#include "obstack.h"
-+#include "toplev.h"
-+#include "tm_p.h"
-+#include "tm-constrs.h"
-+#include "basic-block.h"
-+#include "integrate.h"
-+#include "target.h"
-+#include "target-def.h"
-+#include "reload.h"
-+#include "df.h"
-+#include "langhooks.h"
-+#include "optabs.h"
-+
-+static tree ubicom32_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
-+static void ubicom32_layout_frame (void);
-+static void ubicom32_function_prologue (FILE *, HOST_WIDE_INT);
-+static void ubicom32_function_epilogue (FILE *, HOST_WIDE_INT);
-+static bool ubicom32_rtx_costs (rtx, int, int, int *, bool speed);
-+static bool ubicom32_fixed_condition_code_regs (unsigned int *,
-+ unsigned int *);
-+static enum machine_mode ubicom32_cc_modes_compatible (enum machine_mode,
-+ enum machine_mode);
-+static int ubicom32_naked_function_p (void);
-+static void ubicom32_machine_dependent_reorg (void);
-+static bool ubicom32_assemble_integer (rtx, unsigned int, int);
-+static void ubicom32_asm_init_sections (void);
-+static int ubicom32_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,tree,
-+ bool);
-+static bool ubicom32_pass_by_reference (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
-+ enum machine_mode mode, const_tree type,
-+ bool named ATTRIBUTE_UNUSED);
-+static bool ubicom32_callee_copies (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
-+ enum machine_mode mode, const_tree type,
-+ bool named ATTRIBUTE_UNUSED);
-+
-+static bool ubicom32_return_in_memory (const_tree type,
-+ const_tree fntype ATTRIBUTE_UNUSED);
-+static bool ubicom32_is_base_reg (rtx, int);
-+static void ubicom32_init_builtins (void);
-+static rtx ubicom32_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
-+static tree ubicom32_fold_builtin (tree, tree, bool);
-+static int ubicom32_get_valid_offset_mask (enum machine_mode);
-+static bool ubicom32_cannot_force_const_mem (rtx);
-+
-+/* Case values threshold */
-+int ubicom32_case_values_threshold = 6;
-+
-+/* Nonzero if this chip supports the Ubicom32 v3 ISA. */
-+int ubicom32_v3 = 1;
-+
-+/* Nonzero if this chip supports the Ubicom32 v4 ISA. */
-+int ubicom32_v4 = 1;
-+
-+/* Valid attributes:
-+ naked - don't generate function prologue/epilogue and `ret' command. */
-+const struct attribute_spec ubicom32_attribute_table[] =
-+{
-+ /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
-+ { "naked", 0, 0, true, false, false, ubicom32_handle_fndecl_attribute },
-+ { NULL, 0, 0, false, false, false, NULL }
-+};
-+
-+#undef TARGET_ASM_FUNCTION_PROLOGUE
-+#define TARGET_ASM_FUNCTION_PROLOGUE ubicom32_function_prologue
-+
-+#undef TARGET_ASM_FUNCTION_EPILOGUE
-+#define TARGET_ASM_FUNCTION_EPILOGUE ubicom32_function_epilogue
-+
-+#undef TARGET_ATTRIBUTE_TABLE
-+#define TARGET_ATTRIBUTE_TABLE ubicom32_attribute_table
-+
-+/* All addresses cost the same amount. */
-+#undef TARGET_ADDRESS_COST
-+#define TARGET_ADDRESS_COST hook_int_rtx_bool_0
-+
-+#undef TARGET_RTX_COSTS
-+#define TARGET_RTX_COSTS ubicom32_rtx_costs
-+
-+#undef TARGET_FIXED_CONDITION_CODE_REGS
-+#define TARGET_FIXED_CONDITION_CODE_REGS ubicom32_fixed_condition_code_regs
-+
-+#undef TARGET_CC_MODES_COMPATIBLE
-+#define TARGET_CC_MODES_COMPATIBLE ubicom32_cc_modes_compatible
-+
-+#undef TARGET_MACHINE_DEPENDENT_REORG
-+#define TARGET_MACHINE_DEPENDENT_REORG ubicom32_machine_dependent_reorg
-+
-+#undef TARGET_ASM_INTEGER
-+#define TARGET_ASM_INTEGER ubicom32_assemble_integer
-+
-+#undef TARGET_ASM_INIT_SECTIONS
-+#define TARGET_ASM_INIT_SECTIONS ubicom32_asm_init_sections
-+
-+#undef TARGET_ARG_PARTIAL_BYTES
-+#define TARGET_ARG_PARTIAL_BYTES ubicom32_arg_partial_bytes
-+
-+#undef TARGET_PASS_BY_REFERENCE
-+#define TARGET_PASS_BY_REFERENCE ubicom32_pass_by_reference
-+
-+#undef TARGET_CALLEE_COPIES
-+#define TARGET_CALLEE_COPIES ubicom32_callee_copies
-+
-+#undef TARGET_RETURN_IN_MEMORY
-+#define TARGET_RETURN_IN_MEMORY ubicom32_return_in_memory
-+
-+#undef TARGET_INIT_BUILTINS
-+#define TARGET_INIT_BUILTINS ubicom32_init_builtins
-+
-+#undef TARGET_EXPAND_BUILTIN
-+#define TARGET_EXPAND_BUILTIN ubicom32_expand_builtin
-+
-+#undef TARGET_FOLD_BUILTIN
-+#define TARGET_FOLD_BUILTIN ubicom32_fold_builtin
-+
-+#undef TARGET_CANNOT_FORCE_CONST_MEM
-+#define TARGET_CANNOT_FORCE_CONST_MEM ubicom32_cannot_force_const_mem
-+
-+struct gcc_target targetm = TARGET_INITIALIZER;
-+
-+static char save_regs[FIRST_PSEUDO_REGISTER];
-+static int nregs;
-+static int frame_size;
-+int ubicom32_stack_size = 0; /* size of allocated stack (including frame) */
-+int ubicom32_can_use_calli_to_ret;
-+
-+#define STACK_UNIT_BOUNDARY (STACK_BOUNDARY / BITS_PER_UNIT)
-+#define ROUND_CALL_BLOCK_SIZE(BYTES) \
-+ (((BYTES) + (STACK_UNIT_BOUNDARY - 1)) & ~(STACK_UNIT_BOUNDARY - 1))
-+
-+/* In case of a PRE_INC, POST_INC, PRE_DEC, POST_DEC memory reference, we
-+ must report the mode of the memory reference from PRINT_OPERAND to
-+ PRINT_OPERAND_ADDRESS. */
-+enum machine_mode output_memory_reference_mode;
-+
-+/* Flag for some split insns from the ubicom32.md. */
-+int ubicom32_reorg_completed;
-+
-+enum reg_class const ubicom32_regclass_map[FIRST_PSEUDO_REGISTER] =
-+{
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ DATA_REGS,
-+ FDPIC_REG,
-+ ADDRESS_REGS,
-+ ADDRESS_REGS,
-+ ADDRESS_REGS,
-+ ADDRESS_REGS,
-+ ADDRESS_REGS,
-+ ADDRESS_REGS,
-+ ADDRESS_REGS,
-+ ACC_REGS,
-+ ACC_LO_REGS,
-+ ACC_REGS,
-+ ACC_LO_REGS,
-+ SOURCE3_REG,
-+ ADDRESS_REGS,
-+ NO_REGS, /* CC_REG must be NO_REGS */
-+ SPECIAL_REGS,
-+ SPECIAL_REGS,
-+ SPECIAL_REGS,
-+ SPECIAL_REGS,
-+ SPECIAL_REGS,
-+ SPECIAL_REGS,
-+ SPECIAL_REGS,
-+ SPECIAL_REGS
-+};
-+
-+rtx ubicom32_compare_op0;
-+rtx ubicom32_compare_op1;
-+
-+/* Handle command line option overrides. */
-+
-+void
-+ubicom32_override_options (void)
-+{
-+ flag_pic = 0;
-+
-+ if (strcmp (ubicom32_arch_name, "ubicom32v1") == 0) {
-+ /* If we have a version 1 architecture then we want to avoid using jump
-+ tables. */
-+ ubicom32_case_values_threshold = 30000;
-+ ubicom32_v3 = 0;
-+ ubicom32_v4 = 0;
-+ } else if (strcmp (ubicom32_arch_name, "ubicom32v2") == 0) {
-+ ubicom32_v3 = 0;
-+ ubicom32_v4 = 0;
-+ } else if (strcmp (ubicom32_arch_name, "ubicom32v3") == 0) {
-+ ubicom32_v3 = 1;
-+ ubicom32_v4 = 0;
-+ } else if (strcmp (ubicom32_arch_name, "ubicom32v4") == 0) {
-+ ubicom32_v3 = 1;
-+ ubicom32_v4 = 1;
-+ }
-+
-+ /* There is no single unaligned SI op for PIC code. Sometimes we
-+ need to use ".4byte" and sometimes we need to use ".picptr".
-+ See ubicom32_assemble_integer for details. */
-+ if (TARGET_FDPIC)
-+ targetm.asm_out.unaligned_op.si = 0;
-+}
-+
-+void
-+ubicom32_conditional_register_usage (void)
-+{
-+ /* If we're using the old ipOS ABI we need to make D10 through D13
-+ caller-clobbered. */
-+ if (TARGET_IPOS_ABI)
-+ {
-+ call_used_regs[D10_REGNUM] = 1;
-+ call_used_regs[D11_REGNUM] = 1;
-+ call_used_regs[D12_REGNUM] = 1;
-+ call_used_regs[D13_REGNUM] = 1;
-+ }
-+}
-+
-+/* We have some number of optimizations that don't really work for the Ubicom32
-+ architecture so we deal with them here. */
-+
-+void
-+ubicom32_optimization_options (int level ATTRIBUTE_UNUSED,
-+ int size ATTRIBUTE_UNUSED)
-+{
-+ /* The tree IVOPTs pass seems to do really bad things for the Ubicom32
-+ architecture - it tends to turn things that would happily use pre/post
-+ increment/decrement into operations involving unecessary loop
-+ indicies. */
-+ flag_ivopts = 0;
-+
-+ /* We have problems where DSE at the RTL level misses partial stores
-+ to the stack. For now we disable it to avoid this. */
-+ flag_dse = 0;
-+}
-+
-+/* Print operand X using operand code CODE to assembly language output file
-+ FILE. */
-+
-+void
-+ubicom32_print_operand (FILE *file, rtx x, int code)
-+{
-+ switch (code)
-+ {
-+ case 'A':
-+ /* Identify the correct accumulator to use. */
-+ if (REGNO (x) == ACC0_HI_REGNUM || REGNO (x) == ACC0_LO_REGNUM)
-+ fprintf (file, "acc0");
-+ else if (REGNO (x) == ACC1_HI_REGNUM || REGNO (x) == ACC1_LO_REGNUM)
-+ fprintf (file, "acc1");
-+ else
-+ abort ();
-+ break;
-+
-+ case 'b':
-+ case 'B':
-+ {
-+ enum machine_mode mode;
-+
-+ mode = GET_MODE (XEXP (x, 0));
-+
-+ /* These are normal and reversed branches. */
-+ switch (code == 'b' ? GET_CODE (x) : reverse_condition (GET_CODE (x)))
-+ {
-+ case NE:
-+ fprintf (file, "ne");
-+ break;
-+
-+ case EQ:
-+ fprintf (file, "eq");
-+ break;
-+
-+ case GE:
-+ if (mode == CCSZNmode || mode == CCWZNmode)
-+ fprintf (file, "pl");
-+ else
-+ fprintf (file, "ge");
-+ break;
-+
-+ case GT:
-+ fprintf (file, "gt");
-+ break;
-+
-+ case LE:
-+ fprintf (file, "le");
-+ break;
-+
-+ case LT:
-+ if (mode == CCSZNmode || mode == CCWZNmode)
-+ fprintf (file, "mi");
-+ else
-+ fprintf (file, "lt");
-+ break;
-+
-+ case GEU:
-+ fprintf (file, "cs");
-+ break;
-+
-+ case GTU:
-+ fprintf (file, "hi");
-+ break;
-+
-+ case LEU:
-+ fprintf (file, "ls");
-+ break;
-+
-+ case LTU:
-+ fprintf (file, "cc");
-+ break;
-+
-+ default:
-+ abort ();
-+ }
-+ }
-+ break;
-+
-+ case 'C':
-+ /* This is used for the operand to a call instruction;
-+ if it's a REG, enclose it in parens, else output
-+ the operand normally. */
-+ if (REG_P (x))
-+ {
-+ fputc ('(', file);
-+ ubicom32_print_operand (file, x, 0);
-+ fputc (')', file);
-+ }
-+ else
-+ ubicom32_print_operand (file, x, 0);
-+ break;
-+
-+ case 'd':
-+ /* Bit operations we need bit numbers. */
-+ fprintf (file, "%d", exact_log2 (INTVAL (x)));
-+ break;
-+
-+ case 'D':
-+ /* Bit operations we need bit numbers. */
-+ fprintf (file, "%d", exact_log2 (~ INTVAL (x)));
-+ break;
-+
-+ case 'E':
-+ /* For lea, which we use to add address registers.
-+ We don't want the '#' on a constant. */
-+ if (CONST_INT_P (x))
-+ {
-+ fprintf (file, "%ld", INTVAL (x));
-+ break;
-+ }
-+ /* FALL THROUGH */
-+
-+ default:
-+ switch (GET_CODE (x))
-+ {
-+ case MEM:
-+ output_memory_reference_mode = GET_MODE (x);
-+ output_address (XEXP (x, 0));
-+ break;
-+
-+ case PLUS:
-+ output_address (x);
-+ break;
-+
-+ case REG:
-+ fprintf (file, "%s", reg_names[REGNO (x)]);
-+ break;
-+
-+ case SUBREG:
-+ fprintf (file, "%s", reg_names[subreg_regno (x)]);
-+ break;
-+
-+ /* This will only be single precision.... */
-+ case CONST_DOUBLE:
-+ {
-+ unsigned long val;
-+ REAL_VALUE_TYPE rv;
-+
-+ REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
-+ REAL_VALUE_TO_TARGET_SINGLE (rv, val);
-+ fprintf (file, "0x%lx", val);
-+ break;
-+ }
-+
-+ case CONST_INT:
-+ case SYMBOL_REF:
-+ case CONST:
-+ case LABEL_REF:
-+ case CODE_LABEL:
-+ case LO_SUM:
-+ ubicom32_print_operand_address (file, x);
-+ break;
-+
-+ case HIGH:
-+ fprintf (file, "#%%hi(");
-+ ubicom32_print_operand_address (file, XEXP (x, 0));
-+ fprintf (file, ")");
-+ break;
-+
-+ case UNSPEC:
-+ switch (XINT (x, 1))
-+ {
-+ case UNSPEC_FDPIC_GOT:
-+ fprintf (file, "#%%got_lo(");
-+ ubicom32_print_operand_address (file, XVECEXP (x, 0, 0));
-+ fprintf (file, ")");
-+ break;
-+
-+ case UNSPEC_FDPIC_GOT_FUNCDESC:
-+ fprintf (file, "#%%got_funcdesc_lo(");
-+ ubicom32_print_operand_address (file, XVECEXP (x, 0, 0));
-+ fprintf (file, ")");
-+ break;
-+
-+ default:
-+ abort ();
-+ }
-+ break;
-+
-+ default:
-+ abort ();
-+ }
-+ break;
-+ }
-+}
-+
-+/* Output assembly language output for the address ADDR to FILE. */
-+
-+void
-+ubicom32_print_operand_address (FILE *file, rtx addr)
-+{
-+ switch (GET_CODE (addr))
-+ {
-+ case POST_INC:
-+ ubicom32_print_operand_address (file, XEXP (addr, 0));
-+ fprintf (file, "%d++", GET_MODE_SIZE (output_memory_reference_mode));
-+ break;
-+
-+ case PRE_INC:
-+ fprintf (file, "%d", GET_MODE_SIZE (output_memory_reference_mode));
-+ ubicom32_print_operand_address (file, XEXP (addr, 0));
-+ fprintf (file, "++");
-+ break;
-+
-+ case POST_DEC:
-+ ubicom32_print_operand_address (file, XEXP (addr, 0));
-+ fprintf (file, "%d++", -GET_MODE_SIZE (output_memory_reference_mode));
-+ break;
-+
-+ case PRE_DEC:
-+ fprintf (file, "%d", -GET_MODE_SIZE (output_memory_reference_mode));
-+ ubicom32_print_operand_address (file, XEXP (addr, 0));
-+ fprintf (file, "++");
-+ break;
-+
-+ case POST_MODIFY:
-+ ubicom32_print_operand_address (file, XEXP (addr, 0));
-+ fprintf (file, "%ld++", INTVAL (XEXP (XEXP (addr,1), 1)));
-+ break;
-+
-+ case PRE_MODIFY:
-+ fprintf (file, "%ld", INTVAL (XEXP (XEXP (addr,1), 1)));
-+ ubicom32_print_operand_address (file, XEXP (addr, 0));
-+ fprintf (file, "++");
-+ break;
-+
-+ case REG:
-+ fputc ('(', file);
-+ fprintf (file, "%s", reg_names[REGNO (addr)]);
-+ fputc (')', file);
-+ break;
-+
-+ case PLUS:
-+ {
-+ rtx base = XEXP (addr, 0);
-+ rtx index = XEXP (addr, 1);
-+
-+ /* Switch around addresses of the form index * scaling + base. */
-+ if (! ubicom32_is_base_reg (base, 1))
-+ {
-+ rtx tmp = base;
-+ base = index;
-+ index = tmp;
-+ }
-+
-+ if (CONST_INT_P (index))
-+ {
-+ fprintf (file, "%ld", INTVAL (index));
-+ fputc ('(', file);
-+ fputs (reg_names[REGNO (base)], file);
-+ }
-+ else if (GET_CODE (index) == MULT
-+ || REG_P (index))
-+ {
-+ if (GET_CODE (index) == MULT)
-+ index = XEXP (index, 0);
-+ fputc ('(', file);
-+ fputs (reg_names[REGNO (base)], file);
-+ fputc (',', file);
-+ fputs (reg_names[REGNO (index)], file);
-+ }
-+ else
-+ abort ();
-+
-+ fputc (')', file);
-+ break;
-+ }
-+
-+ case LO_SUM:
-+ fprintf (file, "%%lo(");
-+ ubicom32_print_operand (file, XEXP (addr, 1), 'L');
-+ fprintf (file, ")(");
-+ ubicom32_print_operand (file, XEXP (addr, 0), 0);
-+ fprintf (file, ")");
-+ break;
-+
-+ case CONST_INT:
-+ fputc ('#', file);
-+ output_addr_const (file, addr);
-+ break;
-+
-+ default:
-+ output_addr_const (file, addr);
-+ break;
-+ }
-+}
-+
-+/* X and Y are two things to compare using CODE. Emit the compare insn and
-+ return the rtx for the cc reg in the proper mode. */
-+
-+rtx
-+ubicom32_gen_compare_reg (enum rtx_code code, rtx x, rtx y)
-+{
-+ enum machine_mode mode = SELECT_CC_MODE (code, x, y);
-+ rtx cc_reg;
-+
-+ cc_reg = gen_rtx_REG (mode, CC_REGNUM);
-+
-+ emit_insn (gen_rtx_SET (VOIDmode, cc_reg,
-+ gen_rtx_COMPARE (mode, x, y)));
-+
-+ return cc_reg;
-+}
-+
-+/* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
-+ return the mode to be used for the comparison. */
-+
-+enum machine_mode
-+ubicom32_select_cc_mode (enum rtx_code op, rtx x, rtx y)
-+{
-+ /* Is this a short compare? */
-+ if (GET_MODE (x) == QImode
-+ || GET_MODE (x) == HImode
-+ || GET_MODE (y) == QImode
-+ || GET_MODE (y) == HImode)
-+ {
-+ switch (op)
-+ {
-+ case EQ :
-+ case NE :
-+ return CCSZmode;
-+
-+ case GE:
-+ case LT:
-+ if (y == const0_rtx)
-+ return CCSZNmode;
-+
-+ default :
-+ return CCSmode;
-+ }
-+ }
-+
-+ /* We have a word compare. */
-+ switch (op)
-+ {
-+ case EQ :
-+ case NE :
-+ return CCWZmode;
-+
-+ case GE :
-+ case LT :
-+ if (y == const0_rtx)
-+ return CCWZNmode;
-+
-+ default :
-+ return CCWmode;
-+ }
-+}
-+
-+/* Return TRUE or FALSE depending on whether the first SET in INSN
-+ has source and destination with matching CC modes, and that the
-+ CC mode is at least as constrained as REQ_MODE. */
-+bool
-+ubicom32_match_cc_mode (rtx insn, enum machine_mode req_mode)
-+{
-+ rtx set;
-+ enum machine_mode set_mode;
-+
-+ set = PATTERN (insn);
-+ if (GET_CODE (set) == PARALLEL)
-+ set = XVECEXP (set, 0, 0);
-+ gcc_assert (GET_CODE (set) == SET);
-+ gcc_assert (GET_CODE (SET_SRC (set)) == COMPARE);
-+
-+ /* SET_MODE is the mode we have in the instruction. This must either
-+ be the same or less restrictive that the required mode REQ_MODE. */
-+ set_mode = GET_MODE (SET_DEST (set));
-+
-+ switch (req_mode)
-+ {
-+ case CCSZmode:
-+ if (set_mode != CCSZmode)
-+ return 0;
-+ break;
-+
-+ case CCSZNmode:
-+ if (set_mode != CCSZmode
-+ && set_mode != CCSZNmode)
-+ return 0;
-+ break;
-+
-+ case CCSmode:
-+ if (set_mode != CCSmode
-+ && set_mode != CCSZmode
-+ && set_mode != CCSZNmode)
-+ return 0;
-+ break;
-+
-+ case CCWZmode:
-+ if (set_mode != CCWZmode)
-+ return 0;
-+ break;
-+
-+ case CCWZNmode:
-+ if (set_mode != CCWZmode
-+ && set_mode != CCWZNmode)
-+ return 0;
-+ break;
-+
-+ case CCWmode:
-+ if (set_mode != CCWmode
-+ && set_mode != CCWZmode
-+ && set_mode != CCWZNmode)
-+ return 0;
-+ break;
-+
-+ default:
-+ gcc_unreachable ();
-+ }
-+
-+ return (GET_MODE (SET_SRC (set)) == set_mode);
-+}
-+
-+/* Replace the comparison OP0 CODE OP1 by a semantically equivalent one
-+ that we can implement more efficiently. */
-+
-+void
-+ubicom32_canonicalize_comparison (enum rtx_code *code, rtx *op0, rtx *op1)
-+{
-+ /* If we have a REG and a MEM then compare the MEM with the REG and not
-+ the other way round. */
-+ if (REG_P (*op0) && MEM_P (*op1))
-+ {
-+ rtx tem = *op0;
-+ *op0 = *op1;
-+ *op1 = tem;
-+ *code = swap_condition (*code);
-+ return;
-+ }
-+
-+ /* If we have a REG and a CONST_INT then we may want to reverse things
-+ if the constant can be represented as an "I" constraint. */
-+ if (REG_P (*op0) && CONST_INT_P (*op1) && satisfies_constraint_I (*op1))
-+ {
-+ rtx tem = *op0;
-+ *op0 = *op1;
-+ *op1 = tem;
-+ *code = swap_condition (*code);
-+ return;
-+ }
-+}
-+
-+/* Return the fixed registers used for condition codes. */
-+
-+static bool
-+ubicom32_fixed_condition_code_regs (unsigned int *p1, unsigned int *p2)
-+{
-+ *p1 = CC_REGNUM;
-+ *p2 = INVALID_REGNUM;
-+
-+ return true;
-+}
-+
-+/* If two condition code modes are compatible, return a condition code
-+ mode which is compatible with both. Otherwise, return
-+ VOIDmode. */
-+
-+static enum machine_mode
-+ubicom32_cc_modes_compatible (enum machine_mode m1, enum machine_mode m2)
-+{
-+ if (m1 == m2)
-+ return m1;
-+
-+ if (GET_MODE_CLASS (m1) != MODE_CC || GET_MODE_CLASS (m2) != MODE_CC)
-+ return VOIDmode;
-+
-+ switch (m1)
-+ {
-+ case CCWmode:
-+ if (m2 == CCWZNmode || m2 == CCWZmode)
-+ return m1;
-+
-+ return VOIDmode;
-+
-+ case CCWZNmode:
-+ if (m2 == CCWmode)
-+ return m2;
-+
-+ if (m2 == CCWZmode)
-+ return m1;
-+
-+ return VOIDmode;
-+
-+ case CCWZmode:
-+ if (m2 == CCWmode || m2 == CCWZNmode)
-+ return m2;
-+
-+ return VOIDmode;
-+
-+ case CCSmode:
-+ if (m2 == CCSZNmode || m2 == CCSZmode)
-+ return m1;
-+
-+ return VOIDmode;
-+
-+ case CCSZNmode:
-+ if (m2 == CCSmode)
-+ return m2;
-+
-+ if (m2 == CCSZmode)
-+ return m1;
-+
-+ return VOIDmode;
-+
-+ case CCSZmode:
-+ if (m2 == CCSmode || m2 == CCSZNmode)
-+ return m2;
-+
-+ return VOIDmode;
-+
-+ default:
-+ gcc_unreachable ();
-+ }
-+}
-+
-+static rtx
-+ubicom32_legitimize_fdpic_address_symbol (rtx orig, rtx reg, rtx fdpic_reg)
-+{
-+ int unspec;
-+ rtx got_offs;
-+ rtx got_offs_scaled;
-+ rtx plus_scaled;
-+ rtx tmp;
-+ rtx new_rtx;
-+
-+ gcc_assert (reg != 0);
-+
-+ if (GET_CODE (orig) == SYMBOL_REF
-+ && SYMBOL_REF_FUNCTION_P (orig))
-+ unspec = UNSPEC_FDPIC_GOT_FUNCDESC;
-+ else
-+ unspec = UNSPEC_FDPIC_GOT;
-+
-+ got_offs = gen_reg_rtx (SImode);
-+ tmp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, orig), unspec);
-+ emit_move_insn (got_offs, tmp);
-+
-+ got_offs_scaled = gen_rtx_MULT (SImode, got_offs, GEN_INT (4));
-+ plus_scaled = gen_rtx_PLUS (Pmode, fdpic_reg, got_offs_scaled);
-+ new_rtx = gen_const_mem (Pmode, plus_scaled);
-+ emit_move_insn (reg, new_rtx);
-+
-+ return reg;
-+}
-+
-+static rtx
-+ubicom32_legitimize_fdpic_address (rtx orig, rtx reg, rtx fdpic_reg)
-+{
-+ rtx addr = orig;
-+ rtx new_rtx = orig;
-+
-+ if (GET_CODE (addr) == CONST || GET_CODE (addr) == PLUS)
-+ {
-+ rtx base;
-+
-+ if (GET_CODE (addr) == CONST)
-+ {
-+ addr = XEXP (addr, 0);
-+ gcc_assert (GET_CODE (addr) == PLUS);
-+ }
-+
-+ base = ubicom32_legitimize_fdpic_address_symbol (XEXP (addr, 0), reg, fdpic_reg);
-+ return gen_rtx_PLUS (Pmode, base, XEXP (addr, 1));
-+ }
-+
-+ return new_rtx;
-+}
-+
-+/* Code generation. */
-+
-+void
-+ubicom32_expand_movsi (rtx *operands)
-+{
-+ if (GET_CODE (operands[1]) == SYMBOL_REF
-+ || (GET_CODE (operands[1]) == CONST
-+ && GET_CODE (XEXP (operands[1], 0)) == PLUS
-+ && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
-+ || CONSTANT_ADDRESS_P (operands[1]))
-+ {
-+ if (TARGET_FDPIC)
-+ {
-+ rtx tmp;
-+ rtx fdpic_reg;
-+
-+ gcc_assert (can_create_pseudo_p ());
-+ tmp = gen_reg_rtx (Pmode);
-+ fdpic_reg = get_hard_reg_initial_val (SImode, FDPIC_REGNUM);
-+ if (GET_CODE (operands[1]) == SYMBOL_REF
-+ || GET_CODE (operands[1]) == LABEL_REF)
-+ operands[1] = ubicom32_legitimize_fdpic_address_symbol (operands[1], tmp, fdpic_reg);
-+ else
-+ operands[1] = ubicom32_legitimize_fdpic_address (operands[1], tmp, fdpic_reg);
-+ }
-+ else
-+ {
-+ rtx tmp;
-+ enum machine_mode mode;
-+
-+ /* We want to avoid reusing operand 0 if we can because it limits
-+ our ability to optimize later. */
-+ tmp = ! can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
-+
-+ mode = GET_MODE (operands[0]);
-+ emit_insn (gen_rtx_SET (VOIDmode, tmp,
-+ gen_rtx_HIGH (mode, operands[1])));
-+ operands[1] = gen_rtx_LO_SUM (mode, tmp, operands[1]);
-+ if (can_create_pseudo_p() && ! REG_P (operands[0]))
-+ {
-+ tmp = gen_reg_rtx (mode);
-+ emit_insn (gen_rtx_SET (VOIDmode, tmp, operands[1]));
-+ operands[1] = tmp;
-+ }
-+ }
-+ }
-+}
-+
-+/* Emit code for addsi3. */
-+
-+void
-+ubicom32_expand_addsi3 (rtx *operands)
-+{
-+ rtx op, clob;
-+
-+ if (can_create_pseudo_p ())
-+ {
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (SImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (SImode, operands[2]);
-+ }
-+
-+ /* Emit the instruction. */
-+
-+ op = gen_rtx_SET (VOIDmode, operands[0],
-+ gen_rtx_PLUS (SImode, operands[1], operands[2]));
-+
-+ if (! can_create_pseudo_p ())
-+ {
-+ /* Reload doesn't know about the flags register, and doesn't know that
-+ it doesn't want to clobber it. We can only do this with PLUS. */
-+ emit_insn (op);
-+ }
-+ else
-+ {
-+ clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM));
-+ emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, op, clob)));
-+ }
-+}
-+
-+/* Emit code for mulsi3. Return 1 if we have generated all the code
-+ necessary to do the multiplication. */
-+
-+int
-+ubicom32_emit_mult_sequence (rtx *operands)
-+{
-+ if (! ubicom32_v4)
-+ {
-+ rtx a1, a1_1, a2;
-+ rtx b1, b1_1, b2;
-+ rtx mac_lo_rtx;
-+ rtx t1, t2, t3;
-+
-+ /* Give up if we cannot create new pseudos. */
-+ if (!can_create_pseudo_p())
-+ return 0;
-+
-+ /* Synthesize 32-bit multiplication using 16-bit operations:
-+
-+ a1 = highpart (a)
-+ a2 = lowpart (a)
-+
-+ b1 = highpart (b)
-+ b2 = lowpart (b)
-+
-+ c = (a1 * b1) << 32 + (a1 * b2) << 16 + (a2 * b1) << 16 + a2 * b2
-+ = 0 + (a1 * b2) << 16 + (a2 * b1) << 16 + a2 * b2
-+ ^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^ ^^^^^^^
-+ Signed Signed Unsigned */
-+
-+ if (!ubicom32_data_register_operand (operands[1], GET_MODE (operands[1])))
-+ {
-+ rtx op1;
-+
-+ op1 = gen_reg_rtx (SImode);
-+ emit_move_insn (op1, operands[1]);
-+ operands[1] = op1;
-+ }
-+
-+ if (!ubicom32_data_register_operand (operands[2], GET_MODE (operands[2])))
-+ {
-+ rtx op2;
-+
-+ op2 = gen_reg_rtx (SImode);
-+ emit_move_insn (op2, operands[2]);
-+ operands[2] = op2;
-+ }
-+
-+ /* a1 = highpart (a) */
-+ a1 = gen_reg_rtx (HImode);
-+ a1_1 = gen_reg_rtx (SImode);
-+ emit_insn (gen_ashrsi3 (a1_1, operands[1], GEN_INT (16)));
-+ emit_move_insn (a1, gen_lowpart (HImode, a1_1));
-+
-+ /* a2 = lowpart (a) */
-+ a2 = gen_reg_rtx (HImode);
-+ emit_move_insn (a2, gen_lowpart (HImode, operands[1]));
-+
-+ /* b1 = highpart (b) */
-+ b1 = gen_reg_rtx (HImode);
-+ b1_1 = gen_reg_rtx (SImode);
-+ emit_insn (gen_ashrsi3 (b1_1, operands[2], GEN_INT (16)));
-+ emit_move_insn (b1, gen_lowpart (HImode, b1_1));
-+
-+ /* b2 = lowpart (b) */
-+ b2 = gen_reg_rtx (HImode);
-+ emit_move_insn (b2, gen_lowpart (HImode, operands[2]));
-+
-+ /* t1 = (a1 * b2) << 16 */
-+ t1 = gen_reg_rtx (SImode);
-+ mac_lo_rtx = gen_rtx_REG (SImode, ACC0_LO_REGNUM);
-+ emit_insn (gen_mulhisi3 (mac_lo_rtx, a1, b2));
-+ emit_insn (gen_ashlsi3 (t1, mac_lo_rtx, GEN_INT (16)));
-+
-+ /* t2 = (a2 * b1) << 16 */
-+ t2 = gen_reg_rtx (SImode);
-+ emit_insn (gen_mulhisi3 (mac_lo_rtx, a2, b1));
-+ emit_insn (gen_ashlsi3 (t2, mac_lo_rtx, GEN_INT (16)));
-+
-+ /* mac_lo = a2 * b2 */
-+ emit_insn (gen_umulhisi3 (mac_lo_rtx, a2, b2));
-+
-+ /* t3 = t1 + t2 */
-+ t3 = gen_reg_rtx (SImode);
-+ emit_insn (gen_addsi3 (t3, t1, t2));
-+
-+ /* c = t3 + mac_lo_rtx */
-+ emit_insn (gen_addsi3 (operands[0], mac_lo_rtx, t3));
-+
-+ return 1;
-+ }
-+ else
-+ {
-+ rtx acc_rtx;
-+
-+ /* Give up if we cannot create new pseudos. */
-+ if (!can_create_pseudo_p())
-+ return 0;
-+
-+ if (!ubicom32_data_register_operand (operands[1], GET_MODE (operands[1])))
-+ {
-+ rtx op1;
-+
-+ op1 = gen_reg_rtx (SImode);
-+ emit_move_insn (op1, operands[1]);
-+ operands[1] = op1;
-+ }
-+
-+ if (!ubicom32_data_register_operand (operands[2], GET_MODE (operands[2])))
-+ {
-+ rtx op2;
-+
-+ op2 = gen_reg_rtx (SImode);
-+ emit_move_insn (op2, operands[2]);
-+ operands[2] = op2;
-+ }
-+
-+ acc_rtx = gen_reg_rtx (DImode);
-+ emit_insn (gen_umulsidi3 (acc_rtx, operands[1], operands[2]));
-+ emit_move_insn (operands[0], gen_lowpart (SImode, acc_rtx));
-+
-+ return 1;
-+ }
-+}
-+
-+/* Move the integer value VAL into OPERANDS[0]. */
-+
-+void
-+ubicom32_emit_move_const_int (rtx dest, rtx imm)
-+{
-+ rtx xoperands[2];
-+
-+ xoperands[0] = dest;
-+ xoperands[1] = imm;
-+
-+ /* Treat mem destinations separately. Values must be explicitly sign
-+ extended. */
-+ if (MEM_P (dest))
-+ {
-+ rtx low_hword_mem;
-+ rtx low_hword_addr;
-+
-+ /* Emit shorter sequence for signed 7-bit quantities. */
-+ if (satisfies_constraint_I (imm))
-+ {
-+ output_asm_insn ("move.4\t%0, %1", xoperands);
-+ return;
-+ }
-+
-+ /* Special case for pushing constants. */
-+ if (GET_CODE (XEXP (dest, 0)) == PRE_DEC
-+ && XEXP (XEXP (dest, 0), 0) == stack_pointer_rtx)
-+ {
-+ output_asm_insn ("movei\t-4(sp)++, #%%hi(%E1)", xoperands);
-+ output_asm_insn ("movei\t2(sp), #%%lo(%E1)", xoperands);
-+ return;
-+ }
-+
-+ /* See if we can add 2 to the original address. This is only
-+ possible if the original address is of the form REG or
-+ REG+const. */
-+ low_hword_addr = plus_constant (XEXP (dest, 0), 2);
-+ if (ubicom32_legitimate_address_p (HImode, low_hword_addr, 1))
-+ {
-+ low_hword_mem = gen_rtx_MEM (HImode, low_hword_addr);
-+ MEM_COPY_ATTRIBUTES (low_hword_mem, dest);
-+ output_asm_insn ("movei\t%0, #%%hi(%E1)", xoperands);
-+ xoperands[0] = low_hword_mem;
-+ output_asm_insn ("movei\t%0, #%%lo(%E1)", xoperands);
-+ return;
-+ }
-+
-+ /* The original address is too complex. We need to use a
-+ scratch memory by (sp) and move that to the original
-+ destination. */
-+ if (! reg_mentioned_p (stack_pointer_rtx, dest))
-+ {
-+ output_asm_insn ("movei\t-4(sp)++, #%%hi(%E1)", xoperands);
-+ output_asm_insn ("movei\t2(sp), #%%lo(%E1)", xoperands);
-+ output_asm_insn ("move.4\t%0, (sp)4++", xoperands);
-+ return;
-+ }
-+
-+ /* Our address mentions the stack pointer so we need to
-+ use our scratch data register here as well as scratch
-+ memory. */
-+ output_asm_insn ("movei\t-4(sp)++, #%%hi(%E1)", xoperands);
-+ output_asm_insn ("movei\t2(sp), #%%lo(%E1)", xoperands);
-+ output_asm_insn ("move.4\td15, (sp)4++", xoperands);
-+ output_asm_insn ("move.4\t%0, d15", xoperands);
-+ return;
-+ }
-+
-+ /* Move into registers are zero extended by default. */
-+ if (! REG_P (dest))
-+ abort ();
-+
-+ if (satisfies_constraint_N (imm))
-+ {
-+ output_asm_insn ("movei\t%0, %1", xoperands);
-+ return;
-+ }
-+
-+ if (INTVAL (xoperands[1]) >= 0xff80
-+ && INTVAL (xoperands[1]) < 0x10000)
-+ {
-+ xoperands[1] = GEN_INT (INTVAL (xoperands[1]) - 0x10000);
-+ output_asm_insn ("move.2\t%0, %1", xoperands);
-+ return;
-+ }
-+
-+ if ((REGNO_REG_CLASS (REGNO (xoperands[0])) == ADDRESS_REGS
-+ || REGNO_REG_CLASS (REGNO (xoperands[0])) == FDPIC_REG)
-+ && ((INTVAL (xoperands[1]) & 0x80000000) == 0))
-+ {
-+ output_asm_insn ("moveai\t%0, #%%hi(%E1)", xoperands);
-+ if ((INTVAL (xoperands[1]) & 0x7f) != 0)
-+ output_asm_insn ("lea.1\t%0, %%lo(%E1)(%0)", xoperands);
-+ return;
-+ }
-+
-+ if ((INTVAL (xoperands[1]) & 0xffff0000) == 0)
-+ {
-+ output_asm_insn ("movei\t%0, #%%lo(%E1)", xoperands);
-+ output_asm_insn ("move.2\t%0, %0", xoperands);
-+ return;
-+ }
-+
-+ /* This is very expensive. The constant is so large that we
-+ need to use the stack to do the load. */
-+ output_asm_insn ("movei\t-4(sp)++, #%%hi(%E1)", xoperands);
-+ output_asm_insn ("movei\t2(sp), #%%lo(%E1)", xoperands);
-+ output_asm_insn ("move.4\t%0, (sp)4++", xoperands);
-+}
-+
-+/* Stack layout. Prologue/Epilogue. */
-+
-+static int save_regs_size;
-+
-+static void
-+ubicom32_layout_frame (void)
-+{
-+ int regno;
-+
-+ memset ((char *) &save_regs[0], 0, sizeof (save_regs));
-+ nregs = 0;
-+ frame_size = get_frame_size ();
-+
-+ if (frame_pointer_needed || df_regs_ever_live_p (FRAME_POINTER_REGNUM))
-+ {
-+ save_regs[FRAME_POINTER_REGNUM] = 1;
-+ ++nregs;
-+ }
-+
-+ if (current_function_is_leaf && ! df_regs_ever_live_p (LINK_REGNO))
-+ ubicom32_can_use_calli_to_ret = 1;
-+ else
-+ {
-+ ubicom32_can_use_calli_to_ret = 0;
-+ save_regs[LINK_REGNO] = 1;
-+ ++nregs;
-+ }
-+
-+ /* Figure out which register(s) needs to be saved. */
-+ for (regno = 0; regno <= LAST_ADDRESS_REGNUM; regno++)
-+ if (df_regs_ever_live_p(regno)
-+ && ! call_used_regs[regno]
-+ && ! fixed_regs[regno]
-+ && ! save_regs[regno])
-+ {
-+ save_regs[regno] = 1;
-+ ++nregs;
-+ }
-+
-+ save_regs_size = 4 * nregs;
-+}
-+
-+static void
-+ubicom32_emit_add_movsi (int regno, int adj)
-+{
-+ rtx x;
-+ rtx reg = gen_rtx_REG (SImode, regno);
-+
-+ adj += 4;
-+ if (adj > 8 * 4)
-+ {
-+ x = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
-+ GEN_INT (-adj)));
-+ RTX_FRAME_RELATED_P (x) = 1;
-+ x = emit_move_insn (gen_rtx_MEM (SImode, stack_pointer_rtx), reg);
-+ }
-+ else
-+ {
-+ rtx addr = gen_rtx_PRE_MODIFY (Pmode, stack_pointer_rtx,
-+ gen_rtx_PLUS (Pmode, stack_pointer_rtx,
-+ GEN_INT (-adj)));
-+ x = emit_move_insn (gen_rtx_MEM (SImode, addr), reg);
-+ }
-+ RTX_FRAME_RELATED_P (x) = 1;
-+}
-+
-+void
-+ubicom32_expand_prologue (void)
-+{
-+ rtx x;
-+ int regno;
-+ int outgoing_args_size = crtl->outgoing_args_size;
-+ int adj;
-+
-+ if (ubicom32_naked_function_p ())
-+ return;
-+
-+ ubicom32_builtin_saveregs ();
-+
-+ ubicom32_layout_frame ();
-+ adj = (outgoing_args_size + get_frame_size () + save_regs_size
-+ + crtl->args.pretend_args_size);
-+
-+ if (!adj)
-+ ;
-+ else if (outgoing_args_size + save_regs_size < 508
-+ && get_frame_size () + save_regs_size > 508)
-+ {
-+ int i = 0;
-+ x = gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
-+ GEN_INT (-adj));
-+ x = emit_insn (x);
-+ RTX_FRAME_RELATED_P (x) = 1;
-+
-+ for (regno = LAST_ADDRESS_REGNUM; regno >= 0; --regno)
-+ if (save_regs[regno] && regno != LINK_REGNO)
-+ {
-+ x = gen_rtx_MEM (SImode,
-+ gen_rtx_PLUS (Pmode,
-+ stack_pointer_rtx,
-+ GEN_INT (i * 4 + outgoing_args_size)));
-+ x = emit_move_insn (x, gen_rtx_REG (SImode, regno));
-+ RTX_FRAME_RELATED_P (x) = 1;
-+ ++i;
-+ }
-+ if (save_regs[LINK_REGNO])
-+ {
-+ x = gen_rtx_MEM (SImode,
-+ gen_rtx_PLUS (Pmode,
-+ stack_pointer_rtx,
-+ GEN_INT (i * 4 + outgoing_args_size)));
-+ x = emit_move_insn (x, gen_rtx_REG (SImode, LINK_REGNO));
-+ RTX_FRAME_RELATED_P (x) = 1;
-+ }
-+ }
-+ else
-+ {
-+ int regno;
-+ int adj = get_frame_size () + crtl->args.pretend_args_size;
-+ int i = 0;
-+
-+ if (save_regs[LINK_REGNO])
-+ {
-+ ubicom32_emit_add_movsi (LINK_REGNO, adj);
-+ ++i;
-+ }
-+
-+ for (regno = 0; regno <= LAST_ADDRESS_REGNUM; ++regno)
-+ if (save_regs[regno] && regno != LINK_REGNO)
-+ {
-+ if (i)
-+ {
-+ rtx mem = gen_rtx_MEM (SImode,
-+ gen_rtx_PRE_DEC (Pmode,
-+ stack_pointer_rtx));
-+ x = emit_move_insn (mem, gen_rtx_REG (SImode, regno));
-+ RTX_FRAME_RELATED_P (x) = 1;
-+ }
-+ else
-+ ubicom32_emit_add_movsi (regno, adj);
-+ ++i;
-+ }
-+
-+ if (outgoing_args_size || (!i && adj))
-+ {
-+ x = gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
-+ GEN_INT (-outgoing_args_size - (i ? 0 : adj)));
-+ x = emit_insn (x);
-+ RTX_FRAME_RELATED_P (x) = 1;
-+ }
-+ }
-+
-+ if (frame_pointer_needed)
-+ {
-+ int fp_adj = save_regs_size + outgoing_args_size;
-+ x = gen_addsi3 (frame_pointer_rtx, stack_pointer_rtx,
-+ GEN_INT (fp_adj));
-+ x = emit_insn (x);
-+ RTX_FRAME_RELATED_P (x) = 1;
-+ }
-+}
-+
-+void
-+ubicom32_expand_epilogue (void)
-+{
-+ rtx x;
-+ int regno;
-+ int outgoing_args_size = crtl->outgoing_args_size;
-+ int adj;
-+ int i;
-+
-+ if (ubicom32_naked_function_p ())
-+ {
-+ emit_jump_insn (gen_return_internal (gen_rtx_REG (SImode,
-+ LINK_REGNO)));
-+ return;
-+ }
-+
-+ if (cfun->calls_alloca)
-+ {
-+ x = gen_addsi3 (stack_pointer_rtx, frame_pointer_rtx,
-+ GEN_INT (-save_regs_size));
-+ emit_insn (x);
-+ outgoing_args_size = 0;
-+ }
-+
-+ if (outgoing_args_size)
-+ {
-+ x = gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
-+ GEN_INT (outgoing_args_size));
-+ emit_insn (x);
-+ }
-+
-+ i = 0;
-+ for (regno = LAST_ADDRESS_REGNUM; regno >= 0; --regno)
-+ if (save_regs[regno] && regno != LINK_REGNO)
-+ {
-+ x = gen_rtx_MEM (SImode, gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
-+ emit_move_insn (gen_rtx_REG (SImode, regno), x);
-+ ++i;
-+ }
-+
-+ /* Do we have to adjust the stack after we've finished restoring regs? */
-+ adj = get_frame_size() + crtl->args.pretend_args_size;
-+ if (cfun->stdarg)
-+ adj += UBICOM32_FUNCTION_ARG_REGS * UNITS_PER_WORD;
-+
-+#if 0
-+ if (crtl->calls_eh_return && 0)
-+ {
-+ if (save_regs[LINK_REGNO])
-+ {
-+ x = gen_rtx_MEM (SImode, gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
-+ emit_move_insn (gen_rtx_REG (SImode, LINK_REGNO), x);
-+ }
-+
-+ if (adj)
-+ {
-+ x = gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
-+ GEN_INT (adj));
-+ x = emit_insn (x);
-+ }
-+
-+ /* Perform the additional bump for __throw. */
-+ emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
-+ EH_RETURN_STACKADJ_RTX));
-+ emit_jump_insn (gen_eh_return_internal ());
-+ return;
-+ }
-+#endif
-+
-+ if (save_regs[LINK_REGNO])
-+ {
-+ if (adj >= 4 && adj <= (6 * 4))
-+ {
-+ x = GEN_INT (adj + 4);
-+ emit_jump_insn (gen_return_from_post_modify_sp (x));
-+ return;
-+ }
-+
-+ if (adj == 0)
-+ {
-+ x = gen_rtx_MEM (SImode, gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
-+ emit_jump_insn (gen_return_internal (x));
-+ return;
-+ }
-+
-+ x = gen_rtx_MEM (SImode, gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
-+ emit_move_insn (gen_rtx_REG (SImode, LINK_REGNO), x);
-+ }
-+
-+ if (adj)
-+ {
-+ x = gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
-+ GEN_INT (adj));
-+ x = emit_insn (x);
-+ adj = 0;
-+ }
-+
-+ /* Given that we've just done all the hard work here we may as well use
-+ a calli to return. */
-+ ubicom32_can_use_calli_to_ret = 1;
-+ emit_jump_insn (gen_return_internal (gen_rtx_REG (SImode, LINK_REGNO)));
-+}
-+
-+void
-+ubicom32_expand_call_fdpic (rtx *operands)
-+{
-+ rtx c;
-+ rtx addr;
-+ rtx fdpic_reg = get_hard_reg_initial_val (SImode, FDPIC_REGNUM);
-+
-+ addr = XEXP (operands[0], 0);
-+
-+ c = gen_call_fdpic (addr, operands[1], fdpic_reg);
-+ emit_call_insn (c);
-+}
-+
-+void
-+ubicom32_expand_call_value_fdpic (rtx *operands)
-+{
-+ rtx c;
-+ rtx addr;
-+ rtx fdpic_reg = get_hard_reg_initial_val (SImode, FDPIC_REGNUM);
-+
-+ addr = XEXP (operands[1], 0);
-+
-+ c = gen_call_value_fdpic (operands[0], addr, operands[2], fdpic_reg);
-+ emit_call_insn (c);
-+}
-+
-+void
-+ubicom32_expand_eh_return (rtx *operands)
-+{
-+ if (REG_P (operands[0])
-+ || REGNO (operands[0]) != EH_RETURN_STACKADJ_REGNO)
-+ {
-+ rtx sp = EH_RETURN_STACKADJ_RTX;
-+ emit_move_insn (sp, operands[0]);
-+ operands[0] = sp;
-+ }
-+
-+ if (REG_P (operands[1])
-+ || REGNO (operands[1]) != EH_RETURN_HANDLER_REGNO)
-+ {
-+ rtx ra = EH_RETURN_HANDLER_RTX;
-+ emit_move_insn (ra, operands[1]);
-+ operands[1] = ra;
-+ }
-+}
-+
-+/* Compute the offsets between eliminable registers. */
-+
-+int
-+ubicom32_initial_elimination_offset (int from, int to)
-+{
-+ ubicom32_layout_frame ();
-+ if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
-+ return save_regs_size + crtl->outgoing_args_size;
-+
-+ if (from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
-+ return get_frame_size ()/* + save_regs_size */;
-+
-+ if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
-+ return get_frame_size ()
-+ + crtl->outgoing_args_size
-+ + save_regs_size;
-+
-+ return 0;
-+}
-+
-+/* Return 1 if it is appropriate to emit `ret' instructions in the
-+ body of a function. Do this only if the epilogue is simple, needing a
-+ couple of insns. Prior to reloading, we can't tell how many registers
-+ must be saved, so return 0 then. Return 0 if there is no frame
-+ marker to de-allocate.
-+
-+ If NON_SAVING_SETJMP is defined and true, then it is not possible
-+ for the epilogue to be simple, so return 0. This is a special case
-+ since NON_SAVING_SETJMP will not cause regs_ever_live to change
-+ until final, but jump_optimize may need to know sooner if a
-+ `return' is OK. */
-+
-+int
-+ubicom32_can_use_return_insn_p (void)
-+{
-+ if (! reload_completed || frame_pointer_needed)
-+ return 0;
-+
-+ return 1;
-+}
-+
-+/* Attributes and CC handling. */
-+
-+/* Handle an attribute requiring a FUNCTION_DECL; arguments as in
-+ struct attribute_spec.handler. */
-+static tree
-+ubicom32_handle_fndecl_attribute (tree *node, tree name,
-+ tree args ATTRIBUTE_UNUSED,
-+ int flags ATTRIBUTE_UNUSED,
-+ bool *no_add_attrs)
-+{
-+ if (TREE_CODE (*node) != FUNCTION_DECL)
-+ {
-+ warning ("'%s' attribute only applies to functions",
-+ IDENTIFIER_POINTER (name));
-+ *no_add_attrs = true;
-+ }
-+
-+ return NULL_TREE;
-+}
-+
-+/* A C expression that places additional restrictions on the register class to
-+ use when it is necessary to copy value X into a register in class CLASS.
-+ The value is a register class; perhaps CLASS, or perhaps another, smaller
-+ class. On many machines, the following definition is safe:
-+
-+ #define PREFERRED_RELOAD_CLASS(X,CLASS) CLASS
-+
-+ Sometimes returning a more restrictive class makes better code. For
-+ example, on the 68000, when X is an integer constant that is in range for a
-+ `moveq' instruction, the value of this macro is always `DATA_REGS' as long
-+ as CLASS includes the data registers. Requiring a data register guarantees
-+ that a `moveq' will be used.
-+
-+ If X is a `const_double', by returning `NO_REGS' you can force X into a
-+ memory constant. This is useful on certain machines where immediate
-+ floating values cannot be loaded into certain kinds of registers. */
-+
-+enum reg_class
-+ubicom32_preferred_reload_class (rtx x, enum reg_class class)
-+{
-+ /* If a symbolic constant, HIGH or a PLUS is reloaded,
-+ it is most likely being used as an address, so
-+ prefer ADDRESS_REGS. If 'class' is not a superset
-+ of ADDRESS_REGS, e.g. DATA_REGS, then reject this reload. */
-+ if (GET_CODE (x) == PLUS
-+ || GET_CODE (x) == HIGH
-+ || GET_CODE (x) == LABEL_REF
-+ || GET_CODE (x) == SYMBOL_REF
-+ || GET_CODE (x) == CONST)
-+ {
-+ if (reg_class_subset_p (ALL_ADDRESS_REGS, class))
-+ return ALL_ADDRESS_REGS;
-+
-+ return NO_REGS;
-+ }
-+
-+ return class;
-+}
-+
-+/* Function arguments and varargs. */
-+
-+int
-+ubicom32_reg_parm_stack_space (tree fndecl)
-+{
-+ return 0;
-+
-+ if (fndecl
-+ && TYPE_ARG_TYPES (TREE_TYPE (fndecl)) != 0
-+ && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (TREE_TYPE (fndecl))))
-+ != void_type_node))
-+ return UBICOM32_FUNCTION_ARG_REGS * UNITS_PER_WORD;
-+
-+ return 0;
-+}
-+
-+/* Flush the argument registers to the stack for a stdarg function;
-+ return the new argument pointer. */
-+
-+rtx
-+ubicom32_builtin_saveregs (void)
-+{
-+ int regno;
-+
-+ if (! cfun->stdarg)
-+ return 0;
-+
-+ for (regno = UBICOM32_FUNCTION_ARG_REGS - 1; regno >= 0; --regno)
-+ emit_move_insn (gen_rtx_MEM (SImode,
-+ gen_rtx_PRE_DEC (SImode,
-+ stack_pointer_rtx)),
-+ gen_rtx_REG (SImode, regno));
-+
-+ return stack_pointer_rtx;
-+}
-+
-+void
-+ubicom32_va_start (tree valist, rtx nextarg)
-+{
-+ std_expand_builtin_va_start (valist, nextarg);
-+}
-+
-+rtx
-+ubicom32_va_arg (tree valist, tree type)
-+{
-+ HOST_WIDE_INT size, rsize;
-+ tree addr, incr, tmp;
-+ rtx addr_rtx;
-+ int indirect = 0;
-+
-+ /* Round up sizeof(type) to a word. */
-+ size = int_size_in_bytes (type);
-+ rsize = (size + UNITS_PER_WORD - 1) & -UNITS_PER_WORD;
-+
-+ /* Large types are passed by reference. */
-+ if (size > 8)
-+ {
-+ indirect = 1;
-+ size = rsize = UNITS_PER_WORD;
-+ }
-+
-+ incr = valist;
-+ addr = incr = save_expr (incr);
-+
-+ /* FIXME Nat's version - is it correct? */
-+ tmp = fold_convert (ptr_type_node, size_int (rsize));
-+ tmp = build2 (PLUS_EXPR, ptr_type_node, incr, tmp);
-+ incr = fold (tmp);
-+
-+ /* FIXME Nat's version - is it correct? */
-+ incr = build2 (MODIFY_EXPR, ptr_type_node, valist, incr);
-+
-+ TREE_SIDE_EFFECTS (incr) = 1;
-+ expand_expr (incr, const0_rtx, VOIDmode, EXPAND_NORMAL);
-+
-+ addr_rtx = expand_expr (addr, NULL, Pmode, EXPAND_NORMAL);
-+
-+ if (size < UNITS_PER_WORD)
-+ emit_insn (gen_addsi3 (addr_rtx, addr_rtx,
-+ GEN_INT (UNITS_PER_WORD - size)));
-+
-+ if (indirect)
-+ {
-+ addr_rtx = force_reg (Pmode, addr_rtx);
-+ addr_rtx = gen_rtx_MEM (Pmode, addr_rtx);
-+ set_mem_alias_set (addr_rtx, get_varargs_alias_set ());
-+ }
-+
-+ return addr_rtx;
-+}
-+
-+void
-+init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype, rtx libname,
-+ int indirect ATTRIBUTE_UNUSED)
-+{
-+ cum->nbytes = 0;
-+
-+ if (!libname)
-+ {
-+ cum->stdarg = (TYPE_ARG_TYPES (fntype) != 0
-+ && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
-+ != void_type_node));
-+ }
-+}
-+
-+/* Return an RTX to represent where a value in mode MODE will be passed
-+ to a function. If the result is 0, the argument will be pushed. */
-+
-+rtx
-+function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
-+ int named ATTRIBUTE_UNUSED)
-+{
-+ rtx result = 0;
-+ int size, align;
-+ int nregs = UBICOM32_FUNCTION_ARG_REGS;
-+
-+ /* Figure out the size of the object to be passed. */
-+ if (mode == BLKmode)
-+ size = int_size_in_bytes (type);
-+ else
-+ size = GET_MODE_SIZE (mode);
-+
-+ /* Figure out the alignment of the object to be passed. */
-+ align = size;
-+
-+ cum->nbytes = (cum->nbytes + 3) & ~3;
-+
-+ /* Don't pass this arg via a register if all the argument registers
-+ are used up. */
-+ if (cum->nbytes >= nregs * UNITS_PER_WORD)
-+ return 0;
-+
-+ /* Don't pass this arg via a register if it would be split between
-+ registers and memory. */
-+ result = gen_rtx_REG (mode, cum->nbytes / UNITS_PER_WORD);
-+
-+ return result;
-+}
-+
-+rtx
-+function_incoming_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
-+ int named ATTRIBUTE_UNUSED)
-+{
-+ if (cfun->stdarg)
-+ return 0;
-+
-+ return function_arg (cum, mode, type, named);
-+}
-+
-+
-+/* Implement hook TARGET_ARG_PARTIAL_BYTES.
-+
-+ Returns the number of bytes at the beginning of an argument that
-+ must be put in registers. The value must be zero for arguments
-+ that are passed entirely in registers or that are entirely pushed
-+ on the stack. */
-+static int
-+ubicom32_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
-+ tree type, bool named ATTRIBUTE_UNUSED)
-+{
-+ int size, diff;
-+
-+ int nregs = UBICOM32_FUNCTION_ARG_REGS;
-+
-+ /* round up to full word */
-+ cum->nbytes = (cum->nbytes + 3) & ~3;
-+
-+ if (targetm.calls.pass_by_reference (cum, mode, type, named))
-+ return 0;
-+
-+ /* number of bytes left in registers */
-+ diff = nregs*UNITS_PER_WORD - cum->nbytes;
-+
-+ /* regs all used up */
-+ if (diff <= 0)
-+ return 0;
-+
-+ /* Figure out the size of the object to be passed. */
-+ if (mode == BLKmode)
-+ size = int_size_in_bytes (type);
-+ else
-+ size = GET_MODE_SIZE (mode);
-+
-+ /* enough space left in regs for size */
-+ if (size <= diff)
-+ return 0;
-+
-+ /* put diff bytes in regs and rest on stack */
-+ return diff;
-+
-+}
-+
-+static bool
-+ubicom32_pass_by_reference (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
-+ enum machine_mode mode, const_tree type,
-+ bool named ATTRIBUTE_UNUSED)
-+{
-+ int size;
-+
-+ if (type)
-+ size = int_size_in_bytes (type);
-+ else
-+ size = GET_MODE_SIZE (mode);
-+
-+ return size <= 0 || size > 8;
-+}
-+
-+static bool
-+ubicom32_callee_copies (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
-+ enum machine_mode mode, const_tree type,
-+ bool named ATTRIBUTE_UNUSED)
-+{
-+ int size;
-+
-+ if (type)
-+ size = int_size_in_bytes (type);
-+ else
-+ size = GET_MODE_SIZE (mode);
-+
-+ return size <= 0 || size > 8;
-+}
-+
-+static bool
-+ubicom32_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
-+{
-+ int size, mode;
-+
-+ if (!type)
-+ return true;
-+
-+ size = int_size_in_bytes(type);
-+ if (size > 8)
-+ return true;
-+
-+ mode = TYPE_MODE(type);
-+ if (mode == BLKmode)
-+ return true;
-+
-+ return false;
-+}
-+
-+/* Return true if a given register number REGNO is acceptable for machine
-+ mode MODE. */
-+bool
-+ubicom32_hard_regno_mode_ok (unsigned int regno, enum machine_mode mode)
-+{
-+ /* If we're not at least a v3 ISA then ACC0_HI is only 16 bits. */
-+ if (! ubicom32_v3)
-+ {
-+ if (regno == ACC0_HI_REGNUM)
-+ return (mode == QImode || mode == HImode);
-+ }
-+
-+ /* Only the flags reg can hold CCmode. */
-+ if (GET_MODE_CLASS (mode) == MODE_CC)
-+ return regno == CC_REGNUM;
-+
-+ /* We restrict the choice of DImode registers to only being address,
-+ data or accumulator regs. We also restrict them to only start on
-+ even register numbers so we never have to worry about partial
-+ overlaps between operands in instructions. */
-+ if (GET_MODE_SIZE (mode) > 4)
-+ {
-+ switch (REGNO_REG_CLASS (regno))
-+ {
-+ case ADDRESS_REGS:
-+ case DATA_REGS:
-+ case ACC_REGS:
-+ return (regno & 1) == 0;
-+
-+ default:
-+ return false;
-+ }
-+ }
-+
-+ return true;
-+}
-+
-+/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
-+ and check its validity for a certain class.
-+ We have two alternate definitions for each of them.
-+ The usual definition accepts all pseudo regs; the other rejects
-+ them unless they have been allocated suitable hard regs.
-+ The symbol REG_OK_STRICT causes the latter definition to be used.
-+
-+ Most source files want to accept pseudo regs in the hope that
-+ they will get allocated to the class that the insn wants them to be in.
-+ Source files for reload pass need to be strict.
-+ After reload, it makes no difference, since pseudo regs have
-+ been eliminated by then.
-+
-+ These assume that REGNO is a hard or pseudo reg number.
-+ They give nonzero only if REGNO is a hard reg of the suitable class
-+ or a pseudo reg currently allocated to a suitable hard reg.
-+ Since they use reg_renumber, they are safe only once reg_renumber
-+ has been allocated, which happens in local-alloc.c. */
-+
-+int
-+ubicom32_regno_ok_for_base_p (int regno, int strict)
-+{
-+ if ((regno >= FIRST_ADDRESS_REGNUM && regno <= STACK_POINTER_REGNUM)
-+ || (!strict
-+ && (regno >= FIRST_PSEUDO_REGISTER
-+ || regno == ARG_POINTER_REGNUM))
-+ || (strict && (reg_renumber
-+ && reg_renumber[regno] >= FIRST_ADDRESS_REGNUM
-+ && reg_renumber[regno] <= STACK_POINTER_REGNUM)))
-+ return 1;
-+
-+ return 0;
-+}
-+
-+int
-+ubicom32_regno_ok_for_index_p (int regno, int strict)
-+{
-+ if ((regno >= FIRST_DATA_REGNUM && regno <= LAST_DATA_REGNUM)
-+ || (!strict && regno >= FIRST_PSEUDO_REGISTER)
-+ || (strict && (reg_renumber
-+ && reg_renumber[regno] >= FIRST_DATA_REGNUM
-+ && reg_renumber[regno] <= LAST_DATA_REGNUM)))
-+ return 1;
-+
-+ return 0;
-+}
-+
-+/* Returns 1 if X is a valid index register. STRICT is 1 if only hard
-+ registers should be accepted. Accept either REG or SUBREG where a
-+ register is valid. */
-+
-+static bool
-+ubicom32_is_index_reg (rtx x, int strict)
-+{
-+ if ((REG_P (x) && ubicom32_regno_ok_for_index_p (REGNO (x), strict))
-+ || (GET_CODE (x) == SUBREG && REG_P (SUBREG_REG (x))
-+ && ubicom32_regno_ok_for_index_p (REGNO (SUBREG_REG (x)), strict)))
-+ return true;
-+
-+ return false;
-+}
-+
-+/* Return 1 if X is a valid index for a memory address. */
-+
-+static bool
-+ubicom32_is_index_expr (enum machine_mode mode, rtx x, int strict)
-+{
-+ /* Immediate index must be an unsigned 7-bit offset multiple of 1, 2
-+ or 4 depending on mode. */
-+ if (CONST_INT_P (x))
-+ {
-+ switch (mode)
-+ {
-+ case QImode:
-+ return satisfies_constraint_J (x);
-+
-+ case HImode:
-+ return satisfies_constraint_K (x);
-+
-+ case SImode:
-+ case SFmode:
-+ return satisfies_constraint_L (x);
-+
-+ case DImode:
-+ return satisfies_constraint_L (x)
-+ && satisfies_constraint_L (GEN_INT (INTVAL (x) + 4));
-+
-+ default:
-+ return false;
-+ }
-+ }
-+
-+ if (mode != SImode && mode != HImode && mode != QImode)
-+ return false;
-+
-+ /* Register index scaled by mode of operand: REG + REG * modesize.
-+ Valid scaled index registers are:
-+
-+ SImode (mult (dreg) 4))
-+ HImode (mult (dreg) 2))
-+ QImode (mult (dreg) 1)) */
-+ if (GET_CODE (x) == MULT
-+ && ubicom32_is_index_reg (XEXP (x, 0), strict)
-+ && CONST_INT_P (XEXP (x, 1))
-+ && INTVAL (XEXP (x, 1)) == (HOST_WIDE_INT)GET_MODE_SIZE (mode))
-+ return true;
-+
-+ /* REG + REG addressing is allowed for QImode. */
-+ if (ubicom32_is_index_reg (x, strict) && mode == QImode)
-+ return true;
-+
-+ return false;
-+}
-+
-+static bool
-+ubicom32_is_valid_offset (enum machine_mode mode, HOST_WIDE_INT offs)
-+{
-+ if (offs < 0)
-+ return false;
-+
-+ switch (mode)
-+ {
-+ case QImode:
-+ return offs <= 127;
-+
-+ case HImode:
-+ return offs <= 254;
-+
-+ case SImode:
-+ case SFmode:
-+ return offs <= 508;
-+
-+ case DImode:
-+ return offs <= 504;
-+
-+ default:
-+ return false;
-+ }
-+}
-+
-+static int
-+ubicom32_get_valid_offset_mask (enum machine_mode mode)
-+{
-+ switch (mode)
-+ {
-+ case QImode:
-+ return 127;
-+
-+ case HImode:
-+ return 255;
-+
-+ case SImode:
-+ case SFmode:
-+ return 511;
-+
-+ case DImode:
-+ return 255;
-+
-+ default:
-+ return 0;
-+ }
-+}
-+
-+/* Returns 1 if X is a valid base register. STRICT is 1 if only hard
-+ registers should be accepted. Accept either REG or SUBREG where a
-+ register is valid. */
-+
-+static bool
-+ubicom32_is_base_reg (rtx x, int strict)
-+{
-+ if ((REG_P (x) && ubicom32_regno_ok_for_base_p (REGNO (x), strict))
-+ || (GET_CODE (x) == SUBREG && REG_P (SUBREG_REG (x))
-+ && ubicom32_regno_ok_for_base_p (REGNO (SUBREG_REG (x)), strict)))
-+ return true;
-+
-+ return false;
-+}
-+
-+static bool
-+ubicom32_cannot_force_const_mem (rtx x ATTRIBUTE_UNUSED)
-+{
-+ return TARGET_FDPIC;
-+}
-+
-+/* Determine if X is a legitimate constant. */
-+
-+bool
-+ubicom32_legitimate_constant_p (rtx x)
-+{
-+ /* Among its other duties, LEGITIMATE_CONSTANT_P decides whether
-+ a constant can be entered into reg_equiv_constant[]. If we return true,
-+ reload can create new instances of the constant whenever it likes.
-+
-+ The idea is therefore to accept as many constants as possible (to give
-+ reload more freedom) while rejecting constants that can only be created
-+ at certain times. In particular, anything with a symbolic component will
-+ require use of the pseudo FDPIC register, which is only available before
-+ reload. */
-+ if (TARGET_FDPIC)
-+ {
-+ if (GET_CODE (x) == SYMBOL_REF
-+ || (GET_CODE (x) == CONST
-+ && GET_CODE (XEXP (x, 0)) == PLUS
-+ && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF)
-+ || CONSTANT_ADDRESS_P (x))
-+ return false;
-+
-+ return true;
-+ }
-+
-+ /* For non-PIC code anything goes! */
-+ return true;
-+}
-+
-+/* Address validation. */
-+
-+bool
-+ubicom32_legitimate_address_p (enum machine_mode mode, rtx x, int strict)
-+{
-+ if (TARGET_DEBUG_ADDRESS)
-+ {
-+ fprintf (stderr, "\n==> GO_IF_LEGITIMATE_ADDRESS%s\n",
-+ (strict) ? " (STRICT)" : "");
-+ debug_rtx (x);
-+ }
-+
-+ if (CONSTANT_ADDRESS_P (x))
-+ return false;
-+
-+ if (ubicom32_is_base_reg (x, strict))
-+ return true;
-+
-+ if ((GET_CODE (x) == POST_INC
-+ || GET_CODE (x) == PRE_INC
-+ || GET_CODE (x) == POST_DEC
-+ || GET_CODE (x) == PRE_DEC)
-+ && REG_P (XEXP (x, 0))
-+ && ubicom32_is_base_reg (XEXP (x, 0), strict)
-+ && mode != DImode)
-+ return true;
-+
-+ if ((GET_CODE (x) == PRE_MODIFY || GET_CODE (x) == POST_MODIFY)
-+ && ubicom32_is_base_reg (XEXP (x, 0), strict)
-+ && GET_CODE (XEXP (x, 1)) == PLUS
-+ && rtx_equal_p (XEXP (x, 0), XEXP (XEXP (x, 1), 0))
-+ && CONST_INT_P (XEXP (XEXP (x, 1), 1))
-+ && mode != DImode)
-+ {
-+ HOST_WIDE_INT disp = INTVAL (XEXP (XEXP (x, 1), 1));
-+ switch (mode)
-+ {
-+ case QImode:
-+ return disp >= -8 && disp <= 7;
-+
-+ case HImode:
-+ return disp >= -16 && disp <= 14 && ! (disp & 1);
-+
-+ case SImode:
-+ return disp >= -32 && disp <= 28 && ! (disp & 3);
-+
-+ default:
-+ return false;
-+ }
-+ }
-+
-+ /* Accept base + index * scale. */
-+ if (GET_CODE (x) == PLUS
-+ && ubicom32_is_base_reg (XEXP (x, 0), strict)
-+ && ubicom32_is_index_expr (mode, XEXP (x, 1), strict))
-+ return true;
-+
-+ /* Accept index * scale + base. */
-+ if (GET_CODE (x) == PLUS
-+ && ubicom32_is_base_reg (XEXP (x, 1), strict)
-+ && ubicom32_is_index_expr (mode, XEXP (x, 0), strict))
-+ return true;
-+
-+ if (! TARGET_FDPIC)
-+ {
-+ /* Accept (lo_sum (reg) (symbol_ref)) that can be used as a mem+7bits
-+ displacement operand:
-+
-+ moveai a1, #%hi(SYM)
-+ move.4 d3, %lo(SYM)(a1) */
-+ if (GET_CODE (x) == LO_SUM
-+ && ubicom32_is_base_reg (XEXP (x, 0), strict)
-+ && (GET_CODE (XEXP (x, 1)) == SYMBOL_REF
-+ || GET_CODE (XEXP (x, 1)) == LABEL_REF /* FIXME: wrong */)
-+ && mode != DImode)
-+ return true;
-+ }
-+
-+ if (TARGET_DEBUG_ADDRESS)
-+ fprintf (stderr, "\nNot a legitimate address.\n");
-+
-+ return false;
-+}
-+
-+rtx
-+ubicom32_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
-+ enum machine_mode mode)
-+{
-+ if (mode == BLKmode)
-+ return NULL_RTX;
-+
-+ if (GET_CODE (x) == PLUS
-+ && REG_P (XEXP (x, 0))
-+ && ! REGNO_PTR_FRAME_P (REGNO (XEXP (x, 0)))
-+ && CONST_INT_P (XEXP (x, 1))
-+ && ! ubicom32_is_valid_offset (mode, INTVAL (XEXP (x, 1))))
-+ {
-+ rtx base;
-+ rtx plus;
-+ rtx new_rtx;
-+ HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
-+ HOST_WIDE_INT low = val & ubicom32_get_valid_offset_mask (mode);
-+ HOST_WIDE_INT high = val ^ low;
-+
-+ if (val < 0)
-+ return NULL_RTX;
-+
-+ if (! low)
-+ return NULL_RTX;
-+
-+ /* Reload the high part into a base reg; leave the low part
-+ in the mem directly. */
-+ base = XEXP (x, 0);
-+ if (! ubicom32_is_base_reg (base, 0))
-+ base = copy_to_mode_reg (Pmode, base);
-+
-+ plus = expand_simple_binop (Pmode, PLUS,
-+ gen_int_mode (high, Pmode),
-+ base, NULL, 0, OPTAB_WIDEN);
-+ new_rtx = plus_constant (plus, low);
-+
-+ return new_rtx;
-+ }
-+
-+ return NULL_RTX;
-+}
-+
-+/* Try a machine-dependent way of reloading an illegitimate address AD
-+ operand. If we find one, push the reload and and return the new address.
-+
-+ MODE is the mode of the enclosing MEM. OPNUM is the operand number
-+ and TYPE is the reload type of the current reload. */
-+
-+rtx
-+ubicom32_legitimize_reload_address (rtx ad, enum machine_mode mode,
-+ int opnum, int type)
-+{
-+ /* Is this an address that we've already fixed up? If it is then
-+ recognize it and move on. */
-+ if (GET_CODE (ad) == PLUS
-+ && GET_CODE (XEXP (ad, 0)) == PLUS
-+ && REG_P (XEXP (XEXP (ad, 0), 0))
-+ && CONST_INT_P (XEXP (XEXP (ad, 0), 1))
-+ && CONST_INT_P (XEXP (ad, 1)))
-+ {
-+ push_reload (XEXP (ad, 0), NULL_RTX, &XEXP (ad, 0), NULL,
-+ BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
-+ opnum, (enum reload_type) type);
-+ return ad;
-+ }
-+
-+ /* Have we got an address where the offset is simply out of range? If
-+ yes then reload the range as a high part and smaller offset. */
-+ if (GET_CODE (ad) == PLUS
-+ && REG_P (XEXP (ad, 0))
-+ && REGNO (XEXP (ad, 0)) < FIRST_PSEUDO_REGISTER
-+ && REGNO_OK_FOR_BASE_P (REGNO (XEXP (ad, 0)))
-+ && CONST_INT_P (XEXP (ad, 1))
-+ && ! ubicom32_is_valid_offset (mode, INTVAL (XEXP (ad, 1))))
-+ {
-+ rtx temp;
-+ rtx new_rtx;
-+
-+ HOST_WIDE_INT val = INTVAL (XEXP (ad, 1));
-+ HOST_WIDE_INT low = val & ubicom32_get_valid_offset_mask (mode);
-+ HOST_WIDE_INT high = val ^ low;
-+
-+ /* Reload the high part into a base reg; leave the low part
-+ in the mem directly. */
-+ temp = gen_rtx_PLUS (Pmode, XEXP (ad, 0), GEN_INT (high));
-+ new_rtx = gen_rtx_PLUS (Pmode, temp, GEN_INT (low));
-+
-+ push_reload (XEXP (new_rtx, 0), NULL_RTX, &XEXP (new_rtx, 0), NULL,
-+ BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
-+ opnum, (enum reload_type) type);
-+ return new_rtx;
-+ }
-+
-+ /* If we're presented with an pre/post inc/dec then we must force this
-+ to be done in an address register. The register allocator should
-+ work this out for itself but at times ends up trying to use the wrong
-+ class. If we get the wrong class then reload will end up generating
-+ at least 3 instructions whereas this way we can hopefully keep it to
-+ just 2. */
-+ if ((GET_CODE (ad) == POST_INC
-+ || GET_CODE (ad) == PRE_INC
-+ || GET_CODE (ad) == POST_DEC
-+ || GET_CODE (ad) == PRE_DEC)
-+ && REG_P (XEXP (ad, 0))
-+ && REGNO (XEXP (ad, 0)) < FIRST_PSEUDO_REGISTER
-+ && ! REGNO_OK_FOR_BASE_P (REGNO (XEXP (ad, 0))))
-+ {
-+ push_reload (XEXP (ad, 0), XEXP (ad, 0), &XEXP (ad, 0), &XEXP (ad, 0),
-+ BASE_REG_CLASS, GET_MODE (XEXP (ad, 0)), GET_MODE (XEXP (ad, 0)), 0, 0,
-+ opnum, RELOAD_OTHER);
-+ return ad;
-+ }
-+
-+ return NULL_RTX;
-+}
-+
-+/* Compute a (partial) cost for rtx X. Return true if the complete
-+ cost has been computed, and false if subexpressions should be
-+ scanned. In either case, *TOTAL contains the cost result. */
-+
-+static bool
-+ubicom32_rtx_costs (rtx x, int code, int outer_code, int *total,
-+ bool speed ATTRIBUTE_UNUSED)
-+{
-+ enum machine_mode mode = GET_MODE (x);
-+
-+ switch (code)
-+ {
-+ case CONST_INT:
-+ /* Very short constants often fold into instructions so
-+ we pretend that they don't cost anything! This is
-+ really important as regards zero values as otherwise
-+ the compiler has a nasty habit of wanting to reuse
-+ zeroes that are in regs but that tends to pessimize
-+ the code. */
-+ if (satisfies_constraint_I (x))
-+ {
-+ *total = 0;
-+ return true;
-+ }
-+
-+ /* Bit clearing costs nothing */
-+ if (outer_code == AND
-+ && exact_log2 (~INTVAL (x)) != -1)
-+ {
-+ *total = 0;
-+ return true;
-+ }
-+
-+ /* Masking the lower set of bits costs nothing. */
-+ if (outer_code == AND
-+ && exact_log2 (INTVAL (x) + 1) != -1)
-+ {
-+ *total = 0;
-+ return true;
-+ }
-+
-+ /* Bit setting costs nothing. */
-+ if (outer_code == IOR
-+ && exact_log2 (INTVAL (x)) != -1)
-+ {
-+ *total = 0;
-+ return true;
-+ }
-+
-+ /* Larger constants that can be loaded via movei aren't too
-+ bad. If we're just doing a set they cost nothing extra. */
-+ if (satisfies_constraint_N (x))
-+ {
-+ if (mode == DImode)
-+ *total = COSTS_N_INSNS (2);
-+ else
-+ *total = COSTS_N_INSNS (1);
-+ return true;
-+ }
-+
-+ if (mode == DImode)
-+ *total = COSTS_N_INSNS (5);
-+ else
-+ *total = COSTS_N_INSNS (3);
-+ return true;
-+
-+ case CONST_DOUBLE:
-+ /* We don't optimize CONST_DOUBLEs well nor do we relax them well,
-+ so their cost is very high. */
-+ *total = COSTS_N_INSNS (6);
-+ return true;
-+
-+ case CONST:
-+ case SYMBOL_REF:
-+ case MEM:
-+ *total = 0;
-+ return true;
-+
-+ case IF_THEN_ELSE:
-+ *total = COSTS_N_INSNS (1);
-+ return true;
-+
-+ case LABEL_REF:
-+ case HIGH:
-+ case LO_SUM:
-+ case BSWAP:
-+ case PLUS:
-+ case MINUS:
-+ case AND:
-+ case IOR:
-+ case XOR:
-+ case ASHIFT:
-+ case ASHIFTRT:
-+ case LSHIFTRT:
-+ case NEG:
-+ case NOT:
-+ case SIGN_EXTEND:
-+ case ZERO_EXTEND:
-+ case ZERO_EXTRACT:
-+ if (outer_code == SET)
-+ {
-+ if (mode == DImode)
-+ *total = COSTS_N_INSNS (2);
-+ else
-+ *total = COSTS_N_INSNS (1);
-+ }
-+ return true;
-+
-+ case COMPARE:
-+ if (outer_code == SET)
-+ {
-+ if (GET_MODE (XEXP (x, 0)) == DImode
-+ || GET_MODE (XEXP (x, 1)) == DImode)
-+ *total = COSTS_N_INSNS (2);
-+ else
-+ *total = COSTS_N_INSNS (1);
-+ }
-+ return true;
-+
-+ case UMOD:
-+ case UDIV:
-+ case MOD:
-+ case DIV:
-+ if (outer_code == SET)
-+ {
-+ if (mode == DImode)
-+ *total = COSTS_N_INSNS (600);
-+ else
-+ *total = COSTS_N_INSNS (200);
-+ }
-+ return true;
-+
-+ case MULT:
-+ if (outer_code == SET)
-+ {
-+ if (! ubicom32_v4)
-+ {
-+ if (mode == DImode)
-+ *total = COSTS_N_INSNS (15);
-+ else
-+ *total = COSTS_N_INSNS (5);
-+ }
-+ else
-+ {
-+ if (mode == DImode)
-+ *total = COSTS_N_INSNS (6);
-+ else
-+ *total = COSTS_N_INSNS (2);
-+ }
-+ }
-+ return true;
-+
-+ case UNSPEC:
-+ if (XINT (x, 1) == UNSPEC_FDPIC_GOT
-+ || XINT (x, 1) == UNSPEC_FDPIC_GOT_FUNCDESC)
-+ *total = 0;
-+ return true;
-+
-+ default:
-+ return false;
-+ }
-+}
-+
-+/* Return 1 if ADDR can have different meanings depending on the machine
-+ mode of the memory reference it is used for or if the address is
-+ valid for some modes but not others.
-+
-+ Autoincrement and autodecrement addresses typically have
-+ mode-dependent effects because the amount of the increment or
-+ decrement is the size of the operand being addressed. Some machines
-+ have other mode-dependent addresses. Many RISC machines have no
-+ mode-dependent addresses.
-+
-+ You may assume that ADDR is a valid address for the machine. */
-+
-+int
-+ubicom32_mode_dependent_address_p (rtx addr)
-+{
-+ if (GET_CODE (addr) == POST_INC
-+ || GET_CODE (addr) == PRE_INC
-+ || GET_CODE (addr) == POST_DEC
-+ || GET_CODE (addr) == PRE_DEC
-+ || GET_CODE (addr) == POST_MODIFY
-+ || GET_CODE (addr) == PRE_MODIFY)
-+ return 1;
-+
-+ return 0;
-+}
-+
-+static void
-+ubicom32_function_prologue (FILE *file, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
-+{
-+ fprintf (file, "/* frame/pretend: %ld/%d save_regs: %d out_args: %d %s */\n",
-+ get_frame_size (), crtl->args.pretend_args_size,
-+ save_regs_size, crtl->outgoing_args_size,
-+ current_function_is_leaf ? "leaf" : "nonleaf");
-+}
-+
-+static void
-+ubicom32_function_epilogue (FILE *file ATTRIBUTE_UNUSED,
-+ HOST_WIDE_INT size ATTRIBUTE_UNUSED)
-+{
-+ ubicom32_reorg_completed = 0;
-+}
-+
-+static void
-+ubicom32_machine_dependent_reorg (void)
-+{
-+#if 0 /* Commenting out this optimization until it is fixed */
-+ if (optimize)
-+ {
-+ compute_bb_for_insn ();
-+
-+ /* Do a very simple CSE pass over just the hard registers. */
-+ reload_cse_regs (get_insns ());
-+
-+ /* Reload_cse_regs can eliminate potentially-trapping MEMs.
-+ Remove any EH edges associated with them. */
-+ if (flag_non_call_exceptions)
-+ purge_all_dead_edges ();
-+ }
-+#endif
-+ ubicom32_reorg_completed = 1;
-+}
-+
-+void
-+ubicom32_output_cond_jump (rtx insn, rtx cond, rtx target)
-+{
-+ rtx note;
-+ int mostly_false_jump;
-+ rtx xoperands[2];
-+ rtx cc_reg;
-+
-+ note = find_reg_note (insn, REG_BR_PROB, 0);
-+ mostly_false_jump = !note || (INTVAL (XEXP (note, 0))
-+ <= REG_BR_PROB_BASE / 2);
-+
-+ xoperands[0] = target;
-+ xoperands[1] = cond;
-+ cc_reg = XEXP (cond, 0);
-+
-+ if (GET_MODE (cc_reg) == CCWmode
-+ || GET_MODE (cc_reg) == CCWZmode
-+ || GET_MODE (cc_reg) == CCWZNmode)
-+ {
-+ if (mostly_false_jump)
-+ output_asm_insn ("jmp%b1.w.f\t%0", xoperands);
-+ else
-+ output_asm_insn ("jmp%b1.w.t\t%0", xoperands);
-+ return;
-+ }
-+
-+ if (GET_MODE (cc_reg) == CCSmode
-+ || GET_MODE (cc_reg) == CCSZmode
-+ || GET_MODE (cc_reg) == CCSZNmode)
-+ {
-+ if (mostly_false_jump)
-+ output_asm_insn ("jmp%b1.s.f\t%0", xoperands);
-+ else
-+ output_asm_insn ("jmp%b1.s.t\t%0", xoperands);
-+ return;
-+ }
-+
-+ abort ();
-+}
-+
-+/* Return non-zero if FUNC is a naked function. */
-+
-+static int
-+ubicom32_naked_function_p (void)
-+{
-+ return lookup_attribute ("naked", DECL_ATTRIBUTES (current_function_decl)) != NULL_TREE;
-+}
-+
-+/* Return an RTX indicating where the return address to the
-+ calling function can be found. */
-+rtx
-+ubicom32_return_addr_rtx (int count, rtx frame ATTRIBUTE_UNUSED)
-+{
-+ if (count != 0)
-+ return NULL_RTX;
-+
-+ return get_hard_reg_initial_val (Pmode, LINK_REGNO);
-+}
-+
-+/*
-+ * ubicom32_readonly_data_section: This routtine handles code
-+ * at the start of readonly data sections
-+ */
-+static void
-+ubicom32_readonly_data_section (const void *data ATTRIBUTE_UNUSED)
-+{
-+ static int num = 0;
-+ if (in_section == readonly_data_section){
-+ fprintf (asm_out_file, "%s", DATA_SECTION_ASM_OP);
-+ if (flag_data_sections){
-+ fprintf (asm_out_file, ".rodata%d", num);
-+ fprintf (asm_out_file, ",\"a\"");
-+ }
-+ fprintf (asm_out_file, "\n");
-+ }
-+ num++;
-+}
-+
-+/*
-+ * ubicom32_text_section: not in readonly section
-+ */
-+static void
-+ubicom32_text_section(const void *data ATTRIBUTE_UNUSED)
-+{
-+ fprintf (asm_out_file, "%s\n", TEXT_SECTION_ASM_OP);
-+}
-+
-+/*
-+ * ubicom32_data_section: not in readonly section
-+ */
-+static void
-+ubicom32_data_section(const void *data ATTRIBUTE_UNUSED)
-+{
-+ fprintf (asm_out_file, "%s\n", DATA_SECTION_ASM_OP);
-+}
-+
-+/*
-+ * ubicom32_asm_init_sections: This routine implements special
-+ * section handling
-+ */
-+static void
-+ubicom32_asm_init_sections(void)
-+{
-+ text_section = get_unnamed_section(SECTION_CODE, ubicom32_text_section, NULL);
-+
-+ data_section = get_unnamed_section(SECTION_WRITE, ubicom32_data_section, NULL);
-+
-+ readonly_data_section = get_unnamed_section(0, ubicom32_readonly_data_section, NULL);
-+}
-+
-+/*
-+ * ubicom32_profiler: This routine would call
-+ * mcount to support prof and gprof if mcount
-+ * was supported. Currently, do nothing.
-+ */
-+void
-+ubicom32_profiler(void)
-+{
-+}
-+
-+/* Initialise the builtin functions. Start by initialising
-+ descriptions of different types of functions (e.g., void fn(int),
-+ int fn(void)), and then use these to define the builtins. */
-+static void
-+ubicom32_init_builtins (void)
-+{
-+ tree endlink;
-+ tree short_unsigned_endlink;
-+ tree unsigned_endlink;
-+ tree short_unsigned_ftype_short_unsigned;
-+ tree unsigned_ftype_unsigned;
-+
-+ endlink = void_list_node;
-+
-+ short_unsigned_endlink
-+ = tree_cons (NULL_TREE, short_unsigned_type_node, endlink);
-+
-+ unsigned_endlink
-+ = tree_cons (NULL_TREE, unsigned_type_node, endlink);
-+
-+ short_unsigned_ftype_short_unsigned
-+ = build_function_type (short_unsigned_type_node, short_unsigned_endlink);
-+
-+ unsigned_ftype_unsigned
-+ = build_function_type (unsigned_type_node, unsigned_endlink);
-+
-+ /* Initialise the byte swap function. */
-+ add_builtin_function ("__builtin_ubicom32_swapb_2",
-+ short_unsigned_ftype_short_unsigned,
-+ UBICOM32_BUILTIN_UBICOM32_SWAPB_2,
-+ BUILT_IN_MD, NULL,
-+ NULL_TREE);
-+
-+ /* Initialise the byte swap function. */
-+ add_builtin_function ("__builtin_ubicom32_swapb_4",
-+ unsigned_ftype_unsigned,
-+ UBICOM32_BUILTIN_UBICOM32_SWAPB_4,
-+ BUILT_IN_MD, NULL,
-+ NULL_TREE);
-+}
-+
-+/* Given a builtin function taking 2 operands (i.e., target + source),
-+ emit the RTL for the underlying instruction. */
-+static rtx
-+ubicom32_expand_builtin_2op (enum insn_code icode, tree arglist, rtx target)
-+{
-+ tree arg0;
-+ rtx op0, pat;
-+ enum machine_mode tmode, mode0;
-+
-+ /* Grab the incoming argument and emit its RTL. */
-+ arg0 = TREE_VALUE (arglist);
-+ op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
-+
-+ /* Determine the modes of the instruction operands. */
-+ tmode = insn_data[icode].operand[0].mode;
-+ mode0 = insn_data[icode].operand[1].mode;
-+
-+ /* Ensure that the incoming argument RTL is in a register of the
-+ correct mode. */
-+ if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
-+ op0 = copy_to_mode_reg (mode0, op0);
-+
-+ /* If there isn't a suitable target, emit a target register. */
-+ if (target == 0
-+ || GET_MODE (target) != tmode
-+ || !(*insn_data[icode].operand[0].predicate) (target, tmode))
-+ target = gen_reg_rtx (tmode);
-+
-+ /* Emit and return the new instruction. */
-+ pat = GEN_FCN (icode) (target, op0);
-+ if (!pat)
-+ return 0;
-+ emit_insn (pat);
-+
-+ return target;
-+}
-+
-+/* Expand a call to a builtin function. */
-+static rtx
-+ubicom32_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
-+ enum machine_mode mode ATTRIBUTE_UNUSED,
-+ int ignore ATTRIBUTE_UNUSED)
-+{
-+ tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
-+ tree arglist = CALL_EXPR_ARGS(exp);
-+ int fcode = DECL_FUNCTION_CODE (fndecl);
-+
-+ switch (fcode)
-+ {
-+ case UBICOM32_BUILTIN_UBICOM32_SWAPB_2:
-+ return ubicom32_expand_builtin_2op (CODE_FOR_bswaphi, arglist, target);
-+
-+ case UBICOM32_BUILTIN_UBICOM32_SWAPB_4:
-+ return ubicom32_expand_builtin_2op (CODE_FOR_bswapsi, arglist, target);
-+
-+ default:
-+ gcc_unreachable();
-+ }
-+
-+ /* Should really do something sensible here. */
-+ return NULL_RTX;
-+}
-+
-+/* Fold any constant argument for a swapb.2 instruction. */
-+static tree
-+ubicom32_fold_builtin_ubicom32_swapb_2 (tree fndecl, tree arglist)
-+{
-+ tree arg0;
-+
-+ arg0 = TREE_VALUE (arglist);
-+
-+ /* Optimize constant value. */
-+ if (TREE_CODE (arg0) == INTEGER_CST)
-+ {
-+ HOST_WIDE_INT v;
-+ HOST_WIDE_INT res;
-+
-+ v = TREE_INT_CST_LOW (arg0);
-+ res = ((v >> 8) & 0xff)
-+ | ((v & 0xff) << 8);
-+
-+ return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), res);
-+ }
-+
-+ return NULL_TREE;
-+}
-+
-+/* Fold any constant argument for a swapb.4 instruction. */
-+static tree
-+ubicom32_fold_builtin_ubicom32_swapb_4 (tree fndecl, tree arglist)
-+{
-+ tree arg0;
-+
-+ arg0 = TREE_VALUE (arglist);
-+
-+ /* Optimize constant value. */
-+ if (TREE_CODE (arg0) == INTEGER_CST)
-+ {
-+ unsigned HOST_WIDE_INT v;
-+ unsigned HOST_WIDE_INT res;
-+
-+ v = TREE_INT_CST_LOW (arg0);
-+ res = ((v >> 24) & 0xff)
-+ | (((v >> 16) & 0xff) << 8)
-+ | (((v >> 8) & 0xff) << 16)
-+ | ((v & 0xff) << 24);
-+
-+ return build_int_cst_wide (TREE_TYPE (TREE_TYPE (fndecl)), res, 0);
-+ }
-+
-+ return NULL_TREE;
-+}
-+
-+/* Fold any constant arguments for builtin functions. */
-+static tree
-+ubicom32_fold_builtin (tree fndecl, tree arglist, bool ignore ATTRIBUTE_UNUSED)
-+{
-+ switch (DECL_FUNCTION_CODE (fndecl))
-+ {
-+ case UBICOM32_BUILTIN_UBICOM32_SWAPB_2:
-+ return ubicom32_fold_builtin_ubicom32_swapb_2 (fndecl, arglist);
-+
-+ case UBICOM32_BUILTIN_UBICOM32_SWAPB_4:
-+ return ubicom32_fold_builtin_ubicom32_swapb_4 (fndecl, arglist);
-+
-+ default:
-+ return NULL;
-+ }
-+}
-+
-+/* Implementation of TARGET_ASM_INTEGER. When using FD-PIC, we need to
-+ tell the assembler to generate pointers to function descriptors in
-+ some cases. */
-+static bool
-+ubicom32_assemble_integer (rtx value, unsigned int size, int aligned_p)
-+{
-+ if (TARGET_FDPIC && size == UNITS_PER_WORD)
-+ {
-+ if (GET_CODE (value) == SYMBOL_REF
-+ && SYMBOL_REF_FUNCTION_P (value))
-+ {
-+ fputs ("\t.picptr\t%funcdesc(", asm_out_file);
-+ output_addr_const (asm_out_file, value);
-+ fputs (")\n", asm_out_file);
-+ return true;
-+ }
-+
-+ if (!aligned_p)
-+ {
-+ /* We've set the unaligned SI op to NULL, so we always have to
-+ handle the unaligned case here. */
-+ assemble_integer_with_op ("\t.4byte\t", value);
-+ return true;
-+ }
-+ }
-+
-+ return default_assemble_integer (value, size, aligned_p);
-+}
-+
-+/* If the constant I can be constructed by shifting a source-1 immediate
-+ by a constant number of bits then return the bit count. If not
-+ return 0. */
-+
-+int
-+ubicom32_shiftable_const_int (int i)
-+{
-+ int shift = 0;
-+
-+ /* Note that any constant that can be represented as an immediate to
-+ a movei instruction is automatically ignored here in the interests
-+ of the clarity of the output asm code. */
-+ if (i >= -32768 && i <= 32767)
-+ return 0;
-+
-+ /* Find the number of trailing zeroes. We could use __builtin_ctz
-+ here but it's not obvious if this is supported on all build
-+ compilers so we err on the side of caution. */
-+ if ((i & 0xffff) == 0)
-+ {
-+ shift += 16;
-+ i >>= 16;
-+ }
-+
-+ if ((i & 0xff) == 0)
-+ {
-+ shift += 8;
-+ i >>= 8;
-+ }
-+
-+ if ((i & 0xf) == 0)
-+ {
-+ shift += 4;
-+ i >>= 4;
-+ }
-+
-+ if ((i & 0x3) == 0)
-+ {
-+ shift += 2;
-+ i >>= 2;
-+ }
-+
-+ if ((i & 0x1) == 0)
-+ {
-+ shift += 1;
-+ i >>= 1;
-+ }
-+
-+ if (i >= -128 && i <= 127)
-+ return shift;
-+
-+ return 0;
-+}
-+
---- /dev/null
-+++ b/gcc/config/ubicom32/ubicom32.h
-@@ -0,0 +1,1564 @@
-+/* Definitions of target machine for Ubicom32
-+
-+ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
-+ 2009 Free Software Foundation, Inc.
-+ Contributed by Ubicom, Inc.
-+
-+ This file is part of GCC.
-+
-+ GCC is free software; you can redistribute it and/or modify it
-+ under the terms of the GNU General Public License as published
-+ by the Free Software Foundation; either version 3, or (at your
-+ option) any later version.
-+
-+ GCC is distributed in the hope that it will be useful, but WITHOUT
-+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
-+ License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with GCC; see the file COPYING3. If not see
-+ <http://www.gnu.org/licenses/>. */
-+
-+\f
-+
-+#define OBJECT_FORMAT_ELF
-+
-+/* Run-time target specifications. */
-+
-+/* Target CPU builtins. */
-+#define TARGET_CPU_CPP_BUILTINS() \
-+ do \
-+ { \
-+ builtin_define_std ("__UBICOM32__"); \
-+ builtin_define_std ("__ubicom32__"); \
-+ \
-+ if (TARGET_FDPIC) \
-+ { \
-+ builtin_define ("__UBICOM32_FDPIC__"); \
-+ builtin_define ("__FDPIC__"); \
-+ } \
-+ } \
-+ while (0)
-+
-+#ifndef TARGET_DEFAULT
-+#define TARGET_DEFAULT 0
-+#endif
-+
-+extern int ubicom32_case_values_threshold;
-+
-+/* Nonzero if this chip supports the Ubicom32 v3 ISA. */
-+extern int ubicom32_v3;
-+
-+/* Nonzero if this chip supports the Ubicom32 v4 ISA. */
-+extern int ubicom32_v4;
-+
-+extern int ubicom32_stack_size;
-+
-+/* Flag for whether we can use calli instead of ret in returns. */
-+extern int ubicom32_can_use_calli_to_ret;
-+
-+/* This macro is a C statement to print on `stderr' a string describing the
-+ particular machine description choice. Every machine description should
-+ define `TARGET_VERSION'. */
-+#define TARGET_VERSION fprintf (stderr, " (UBICOM32)");
-+
-+/* We don't need a frame pointer to debug things. Doing this means
-+ that gcc can turn on -fomit-frame-pointer when '-O' is specified. */
-+#define CAN_DEBUG_WITHOUT_FP
-+
-+/* We need to handle processor-specific options. */
-+#define OVERRIDE_OPTIONS ubicom32_override_options ()
-+
-+#define OPTIMIZATION_OPTIONS(LEVEL, SIZE) \
-+ ubicom32_optimization_options (LEVEL, SIZE)
-+
-+/* For Ubicom32 the least significant bit has the lowest bit number
-+ so we define this to be 0. */
-+#define BITS_BIG_ENDIAN 0
-+
-+/* For Ubicom32 the most significant byte in a word has the lowest
-+ number. */
-+#define BYTES_BIG_ENDIAN 1
-+
-+/* For Ubicom32, in a multiword object, the most signifant word has the
-+ lowest number. */
-+#define WORDS_BIG_ENDIAN 1
-+
-+/* Ubicom32 has 8 bits per byte. */
-+#define BITS_PER_UNIT 8
-+
-+/* Ubicom32 has 32 bits per word. */
-+#define BITS_PER_WORD 32
-+
-+/* Width of a word, in units (bytes). */
-+#define UNITS_PER_WORD 4
-+
-+/* Width of a pointer, in bits. */
-+#define POINTER_SIZE 32
-+
-+/* Alias for pointers. Ubicom32 is a 32-bit architecture so we use
-+ SImode. */
-+#define Pmode SImode
-+
-+/* Normal alignment required for function parameters on the stack, in
-+ bits. */
-+#define PARM_BOUNDARY 32
-+
-+/* We need to maintain the stack on a 32-bit boundary. */
-+#define STACK_BOUNDARY 32
-+
-+/* Alignment required for a function entry point, in bits. */
-+#define FUNCTION_BOUNDARY 32
-+
-+/* Alias for the machine mode used for memory references to functions being
-+ called, in `call' RTL expressions. We use byte-oriented addresses
-+ here. */
-+#define FUNCTION_MODE QImode
-+
-+/* Biggest alignment that any data type can require on this machine,
-+ in bits. */
-+#define BIGGEST_ALIGNMENT 32
-+
-+/* this default to BIGGEST_ALIGNMENT unless defined */
-+/* ART: What's the correct value here? Default is (((unsigned int)1<<28)*8)*/
-+#undef MAX_OFILE_ALIGNMENT
-+#define MAX_OFILE_ALIGNMENT (128 * 8)
-+
-+/* Alignment in bits to be given to a structure bit field that follows an empty
-+ field such as `int : 0;'. */
-+#define EMPTY_FIELD_BOUNDARY 32
-+
-+/* All structures must be a multiple of 32 bits in size. */
-+#define STRUCTURE_SIZE_BOUNDARY 32
-+
-+/* A bit-field declared as `int' forces `int' alignment for the struct. */
-+#define PCC_BITFIELD_TYPE_MATTERS 1
-+
-+/* For Ubicom32 we absolutely require that data be aligned with nominal
-+ alignment. */
-+#define STRICT_ALIGNMENT 1
-+
-+/* Make strcpy of constants fast. */
-+#define CONSTANT_ALIGNMENT(EXP, ALIGN) \
-+ (TREE_CODE (EXP) == STRING_CST \
-+ && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
-+
-+/* Define this macro as an expression for the alignment of a structure
-+ (given by STRUCT as a tree node) if the alignment computed in the
-+ usual way is COMPUTED and the alignment explicitly specified was
-+ SPECIFIED. */
-+#define DATA_ALIGNMENT(TYPE, ALIGN) \
-+ ((((ALIGN) < BITS_PER_WORD) \
-+ && (TREE_CODE (TYPE) == ARRAY_TYPE \
-+ || TREE_CODE (TYPE) == UNION_TYPE \
-+ || TREE_CODE (TYPE) == RECORD_TYPE)) ? BITS_PER_WORD : (ALIGN))
-+
-+#define LOCAL_ALIGNMENT(TYPE,ALIGN) DATA_ALIGNMENT(TYPE,ALIGN)
-+
-+/* For Ubicom32 we default to unsigned chars. */
-+#define DEFAULT_SIGNED_CHAR 0
-+
-+/* Machine-specific data register numbers. */
-+#define FIRST_DATA_REGNUM 0
-+#define D10_REGNUM 10
-+#define D11_REGNUM 11
-+#define D12_REGNUM 12
-+#define D13_REGNUM 13
-+#define LAST_DATA_REGNUM 15
-+
-+/* Machine-specific address register numbers. */
-+#define FIRST_ADDRESS_REGNUM 16
-+#define LAST_ADDRESS_REGNUM 22
-+
-+/* Register numbers used for passing a function's static chain pointer. If
-+ register windows are used, the register number as seen by the called
-+ function is `STATIC_CHAIN_INCOMING_REGNUM', while the register number as
-+ seen by the calling function is `STATIC_CHAIN_REGNUM'. If these registers
-+ are the same, `STATIC_CHAIN_INCOMING_REGNUM' need not be defined.
-+
-+ The static chain register need not be a fixed register.
-+
-+ If the static chain is passed in memory, these macros should not be defined;
-+ instead, the next two macros should be defined. */
-+#define STATIC_CHAIN_REGNUM (FIRST_ADDRESS_REGNUM + 1)
-+
-+/* The register number of the frame pointer register, which is used to access
-+ automatic variables in the stack frame. We generally eliminate this anyway
-+ for Ubicom32 but we make it A6 by default. */
-+#define FRAME_POINTER_REGNUM (LAST_ADDRESS_REGNUM)
-+
-+/* The register number of the stack pointer register, which is also be a
-+ fixed register according to `FIXED_REGISTERS'. For Ubicom32 we don't
-+ have a hardware requirement about which register this is, but by convention
-+ we use A7. */
-+#define STACK_POINTER_REGNUM (LAST_ADDRESS_REGNUM + 1)
-+
-+/* Machine-specific accumulator register numbers. */
-+#define ACC0_HI_REGNUM 24
-+#define ACC0_LO_REGNUM 25
-+#define ACC1_HI_REGNUM 26
-+#define ACC1_LO_REGNUM 27
-+
-+/* source3 register number */
-+#define SOURCE3_REGNUM 28
-+
-+/* The register number of the arg pointer register, which is used to access the
-+ function's argument list. On some machines, this is the same as the frame
-+ pointer register. On some machines, the hardware determines which register
-+ this is. On other machines, you can choose any register you wish for this
-+ purpose. If this is not the same register as the frame pointer register,
-+ then you must mark it as a fixed register according to `FIXED_REGISTERS', or
-+ arrange to be able to eliminate it. */
-+#define ARG_POINTER_REGNUM 29
-+
-+/* Pseudo-reg for condition code. */
-+#define CC_REGNUM 30
-+
-+/* Interrupt set/clear registers. */
-+#define INT_SET0_REGNUM 31
-+#define INT_SET1_REGNUM 32
-+#define INT_CLR0_REGNUM 33
-+#define INT_CLR1_REGNUM 34
-+
-+/* Scratchpad registers. */
-+#define SCRATCHPAD0_REGNUM 35
-+#define SCRATCHPAD1_REGNUM 36
-+#define SCRATCHPAD2_REGNUM 37
-+#define SCRATCHPAD3_REGNUM 38
-+
-+/* FDPIC register. */
-+#define FDPIC_REGNUM 16
-+
-+/* Number of hardware registers known to the compiler. They receive numbers 0
-+ through `FIRST_PSEUDO_REGISTER-1'; thus, the first pseudo register's number
-+ really is assigned the number `FIRST_PSEUDO_REGISTER'. */
-+#define FIRST_PSEUDO_REGISTER 39
-+
-+/* An initializer that says which registers are used for fixed purposes all
-+ throughout the compiled code and are therefore not available for general
-+ allocation. These would include the stack pointer, the frame pointer
-+ (except on machines where that can be used as a general register when no
-+ frame pointer is needed), the program counter on machines where that is
-+ considered one of the addressable registers, and any other numbered register
-+ with a standard use.
-+
-+ This information is expressed as a sequence of numbers, separated by commas
-+ and surrounded by braces. The Nth number is 1 if register N is fixed, 0
-+ otherwise.
-+
-+ The table initialized from this macro, and the table initialized by the
-+ following one, may be overridden at run time either automatically, by the
-+ actions of the macro `CONDITIONAL_REGISTER_USAGE', or by the user with the
-+ command options `-ffixed-REG', `-fcall-used-REG' and `-fcall-saved-REG'. */
-+#define FIXED_REGISTERS \
-+ { \
-+ 0, 0, 0, 0, 0, 0, 0, 0, /* d0 - d7 */ \
-+ 0, 0, 0, 0, 0, 0, 0, 1, /* d8 - d15 */ \
-+ 0, 0, 0, 0, 0, 0, 0, 1, /* a0 - a7 */ \
-+ 0, 0, /* acc0 hi/lo */ \
-+ 0, 0, /* acc1 hi/lo */ \
-+ 0, /* source3 */ \
-+ 1, /* arg */ \
-+ 1, /* cc */ \
-+ 1, 1, /* int_set[01] */ \
-+ 1, 1, /* int_clr[01] */ \
-+ 1, 1, 1, 1 /* scratchpad[0123] */ \
-+ }
-+
-+/* Like `FIXED_REGISTERS' but has 1 for each register that is clobbered (in
-+ general) by function calls as well as for fixed registers. This macro
-+ therefore identifies the registers that are not available for general
-+ allocation of values that must live across function calls.
-+
-+ If a register has 0 in `CALL_USED_REGISTERS', the compiler automatically
-+ saves it on function entry and restores it on function exit, if the register
-+ is used within the function. */
-+#define CALL_USED_REGISTERS \
-+ { \
-+ 1, 1, 1, 1, 1, 1, 1, 1, /* d0 - d7 */ \
-+ 1, 1, 0, 0, 0, 0, 1, 1, /* d8 - d15 */ \
-+ 1, 0, 0, 1, 1, 1, 0, 1, /* a0 - a7 */ \
-+ 1, 1, /* acc0 hi/lo */ \
-+ 1, 1, /* acc1 hi/lo */ \
-+ 1, /* source3 */ \
-+ 1, /* arg */ \
-+ 1, /* cc */ \
-+ 1, 1, /* int_set[01] */ \
-+ 1, 1, /* int_clr[01] */ \
-+ 1, 1, 1, 1 /* scratchpad[0123] */ \
-+ }
-+
-+/* How to refer to registers in assembler output.
-+ This sequence is indexed by compiler's hard-register-number (see above). */
-+
-+/* A C initializer containing the assembler's names for the machine registers,
-+ each one as a C string constant. This is what translates register numbers
-+ in the compiler into assembler language. */
-+#define REGISTER_NAMES \
-+ { \
-+ "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", \
-+ "d8", "d9", "d10", "d11", "d12", "d13", "d14", "d15", \
-+ "a0", "a1", "a2", "a3", "a4", "a5", "a6", "sp", \
-+ "acc0_hi", "acc0_lo", \
-+ "acc1_hi", "acc1_lo", \
-+ "source3", \
-+ "arg", \
-+ "cc", \
-+ "int_set0", "int_set1", \
-+ "int_clr0", "int_clr1", \
-+ "scratchpad0", "scratchpad1", "scratchpad2", "scratchpad3" \
-+ }
-+
-+#define CONDITIONAL_REGISTER_USAGE \
-+ ubicom32_conditional_register_usage ();
-+
-+/* Order of allocation of registers. */
-+
-+/* If defined, an initializer for a vector of integers, containing the numbers
-+ of hard registers in the order in which GNU CC should prefer to use them
-+ (from most preferred to least).
-+
-+ For Ubicom32 we try using caller-clobbered data registers first, then
-+ callee-saved data registers, then caller-clobbered address registers,
-+ then callee-saved address registers and finally everything else.
-+
-+ The caller-clobbered registers are usually slightly cheaper to use because
-+ there's no need to save/restore. */
-+#define REG_ALLOC_ORDER \
-+ { \
-+ 0, 1, 2, 3, 4, /* d0 - d4 */ \
-+ 5, 6, 7, 8, 9, /* d5 - d9 */ \
-+ 14, /* d14 */ \
-+ 10, 11, 12, 13, /* d10 - d13 */ \
-+ 19, 20, 16, 21, /* a3, a4, a0, a5 */ \
-+ 17, 18, 22, /* a1, a2, a6 */ \
-+ 24, 25, /* acc0 hi/lo */ \
-+ 26, 27, /* acc0 hi/lo */ \
-+ 28 /* source3 */ \
-+ }
-+
-+/* C expression for the number of consecutive hard registers, starting at
-+ register number REGNO, required to hold a value of mode MODE. */
-+#define HARD_REGNO_NREGS(REGNO, MODE) \
-+ ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
-+
-+/* Most registers can hold QImode, HImode and SImode values but we have to
-+ be able to indicate any hard registers that cannot hold values with some
-+ modes. */
-+#define HARD_REGNO_MODE_OK(REGNO, MODE) \
-+ ubicom32_hard_regno_mode_ok(REGNO, MODE)
-+
-+/* We can rename most registers aside from the FDPIC register if we're using
-+ FDPIC. */
-+#define HARD_REGNO_RENAME_OK(from, to) (TARGET_FDPIC ? ((to) != FDPIC_REGNUM) : 1)
-+
-+/* A C expression that is nonzero if it is desirable to choose register
-+ allocation so as to avoid move instructions between a value of mode MODE1
-+ and a value of mode MODE2.
-+
-+ If `HARD_REGNO_MODE_OK (R, MODE1)' and `HARD_REGNO_MODE_OK (R, MODE2)' are
-+ ever different for any R, then `MODES_TIEABLE_P (MODE1, MODE2)' must be
-+ zero. */
-+#define MODES_TIEABLE_P(MODE1, MODE2) 1
-+
-+/* An enumeral type that must be defined with all the register class names as
-+ enumeral values. `NO_REGS' must be first. `ALL_REGS' must be the last
-+ register class, followed by one more enumeral value, `LIM_REG_CLASSES',
-+ which is not a register class but rather tells how many classes there are.
-+
-+ Each register class has a number, which is the value of casting the class
-+ name to type `int'. The number serves as an index in many of the tables
-+ described below. */
-+
-+enum reg_class
-+{
-+ NO_REGS,
-+ DATA_REGS,
-+ FDPIC_REG,
-+ ADDRESS_REGS,
-+ ALL_ADDRESS_REGS,
-+ ACC_LO_REGS,
-+ ACC_REGS,
-+ CC_REG,
-+ DATA_ACC_REGS,
-+ SOURCE3_REG,
-+ SPECIAL_REGS,
-+ GENERAL_REGS,
-+ ALL_REGS,
-+ LIM_REG_CLASSES
-+};
-+
-+/* The number of distinct register classes. */
-+#define N_REG_CLASSES (int) LIM_REG_CLASSES
-+
-+/* An initializer containing the names of the register classes as C string
-+ constants. These names are used in writing some of the debugging dumps. */
-+
-+#define REG_CLASS_NAMES \
-+{ \
-+ "NO_REGS", \
-+ "DATA_REGS", \
-+ "FDPIC_REG", \
-+ "ADDRESS_REGS", \
-+ "ALL_ADDRESS_REGS", \
-+ "ACC_LO_REGS", \
-+ "ACC_REGS", \
-+ "CC_REG", \
-+ "DATA_ACC_REGS", \
-+ "SOURCE3_REG", \
-+ "SPECIAL_REGS", \
-+ "GENERAL_REGS", \
-+ "ALL_REGS", \
-+ "LIM_REGS" \
-+}
-+
-+/* An initializer containing the contents of the register classes, as integers
-+ which are bit masks. The Nth integer specifies the contents of class N.
-+ The way the integer MASK is interpreted is that register R is in the class
-+ if `MASK & (1 << R)' is 1.
-+
-+ When the machine has more than 32 registers, an integer does not suffice.
-+ Then the integers are replaced by sub-initializers, braced groupings
-+ containing several integers. Each sub-initializer must be suitable as an
-+ initializer for the type `HARD_REG_SET' which is defined in
-+ `hard-reg-set.h'. */
-+#define REG_CLASS_CONTENTS \
-+{ \
-+ {0x00000000, 0x00000000}, /* No regs */ \
-+ {0x0000ffff, 0x00000000}, /* DATA_REGS */ \
-+ {0x00010000, 0x00000000}, /* FDPIC_REG */ \
-+ {0x20fe0000, 0x00000000}, /* ADDRESS_REGS */ \
-+ {0x20ff0000, 0x00000000}, /* ALL_ADDRESS_REGS */ \
-+ {0x0a000000, 0x00000000}, /* ACC_LO_REGS */ \
-+ {0x0f000000, 0x00000000}, /* ACC_REGS */ \
-+ {0x40000000, 0x00000000}, /* CC_REG */ \
-+ {0x0f00ffff, 0x00000000}, /* DATA_ACC_REGS */ \
-+ {0x10000000, 0x00000000}, /* SOURGE3_REG */ \
-+ {0x80000000, 0x0000007f}, /* SPECIAL_REGS */ \
-+ {0xbfffffff, 0x0000007f}, /* GENERAL_REGS */ \
-+ {0xbfffffff, 0x0000007f} /* ALL_REGS */ \
-+}
-+
-+extern enum reg_class const ubicom32_regclass_map[FIRST_PSEUDO_REGISTER];
-+
-+/* A C expression whose value is a register class containing hard register
-+ REGNO. In general there is more than one such class; choose a class which
-+ is "minimal", meaning that no smaller class also contains the register. */
-+#define REGNO_REG_CLASS(REGNO) (ubicom32_regclass_map[REGNO])
-+
-+#define IRA_COVER_CLASSES \
-+{ \
-+ GENERAL_REGS, \
-+ LIM_REG_CLASSES \
-+}
-+
-+/* Ubicom32 base registers must be address registers since addresses can
-+ only be reached via address registers. */
-+#define BASE_REG_CLASS ALL_ADDRESS_REGS
-+
-+/* Ubicom32 index registers must be data registers since we cannot add
-+ two address registers together to form an address. */
-+#define INDEX_REG_CLASS DATA_REGS
-+
-+/* A C expression which is nonzero if register number NUM is suitable for use
-+ as a base register in operand addresses. It may be either a suitable hard
-+ register or a pseudo register that has been allocated such a hard register. */
-+
-+#ifndef REG_OK_STRICT
-+#define REGNO_OK_FOR_BASE_P(regno) \
-+ ubicom32_regno_ok_for_base_p (regno, 0)
-+#else
-+#define REGNO_OK_FOR_BASE_P(regno) \
-+ ubicom32_regno_ok_for_base_p (regno, 1)
-+#endif
-+
-+/* A C expression which is nonzero if register number NUM is suitable for use
-+ as an index register in operand addresses. It may be either a suitable hard
-+ register or a pseudo register that has been allocated such a hard register.
-+
-+ The difference between an index register and a base register is that the
-+ index register may be scaled. If an address involves the sum of two
-+ registers, neither one of them scaled, then either one may be labeled the
-+ "base" and the other the "index"; but whichever labeling is used must fit
-+ the machine's constraints of which registers may serve in each capacity.
-+ The compiler will try both labelings, looking for one that is valid, and
-+ will reload one or both registers only if neither labeling works. */
-+#ifndef REG_OK_STRICT
-+#define REGNO_OK_FOR_INDEX_P(regno) \
-+ ubicom32_regno_ok_for_index_p (regno, 0)
-+#else
-+#define REGNO_OK_FOR_INDEX_P(regno) \
-+ ubicom32_regno_ok_for_index_p (regno, 1)
-+#endif
-+
-+/* Attempt to restrict the register class we need to copy value X intoto the
-+ would-be register class CLASS. Most things are fine for Ubicom32 but we
-+ have to restrict certain types of address loads. */
-+#define PREFERRED_RELOAD_CLASS(X, CLASS) \
-+ ubicom32_preferred_reload_class (X, CLASS)
-+
-+/* A C expression for the maximum number of consecutive registers of
-+ class CLASS needed to hold a value of mode MODE. For Ubicom32 this
-+ is pretty much identical to HARD_REGNO_NREGS. */
-+#define CLASS_MAX_NREGS(CLASS, MODE) \
-+ ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
-+
-+/* For Ubicom32 the stack grows downwards when we push a word onto the stack
-+ - i.e. it moves to a smaller address. */
-+#define STACK_GROWS_DOWNWARD 1
-+
-+/* Offset from the frame pointer to the first local variable slot to
-+ be allocated. */
-+#define STARTING_FRAME_OFFSET 0
-+
-+/* Offset from the argument pointer register to the first argument's
-+ address. */
-+#define FIRST_PARM_OFFSET(FNDECL) 0
-+
-+/* A C expression whose value is RTL representing the value of the return
-+ address for the frame COUNT steps up from the current frame, after the
-+ prologue. FRAMEADDR is the frame pointer of the COUNT frame, or the frame
-+ pointer of the COUNT - 1 frame if `RETURN_ADDR_IN_PREVIOUS_FRAME' is
-+ defined.
-+
-+ The value of the expression must always be the correct address when COUNT is
-+ zero, but may be `NULL_RTX' if there is not way to determine the return
-+ address of other frames. */
-+#define RETURN_ADDR_RTX(COUNT, FRAME) \
-+ ubicom32_return_addr_rtx (COUNT, FRAME)
-+
-+/* Register That Address the Stack Frame. */
-+
-+/* We don't actually require a frame pointer in most functions with the
-+ Ubicom32 architecture so we allow it to be eliminated. */
-+#define FRAME_POINTER_REQUIRED 0
-+
-+/* Macro that defines a table of register pairs used to eliminate unecessary
-+ registers that point into the stack frame.
-+
-+ For Ubicom32 we don't generally need an arg pointer of a frame pointer
-+ so we allow the arg pointer to be replaced by either the frame pointer or
-+ the stack pointer. We also allow the frame pointer to be replaced by
-+ the stack pointer. */
-+#define ELIMINABLE_REGS \
-+{ \
-+ {ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
-+ {ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM}, \
-+ {FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM} \
-+}
-+
-+/* Let the compiler know that we want to use the ELIMINABLE_REGS macro
-+ above. */
-+#define CAN_ELIMINATE(FROM, TO) 1
-+
-+/* This macro is similar to `INITIAL_FRAME_POINTER_OFFSET'. It specifies the
-+ initial difference between the specified pair of registers. This macro must
-+ be defined if `ELIMINABLE_REGS' is defined. */
-+#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
-+ (OFFSET) = ubicom32_initial_elimination_offset (FROM, TO)
-+
-+/* If defined, the maximum amount of space required for outgoing arguments will
-+ be computed and placed into the variable
-+ `current_function_outgoing_args_size'. No space will be pushed onto the
-+ stack for each call; instead, the function prologue should increase the
-+ stack frame size by this amount.
-+
-+ Defining both `PUSH_ROUNDING' and `ACCUMULATE_OUTGOING_ARGS' is not
-+ proper. */
-+#define ACCUMULATE_OUTGOING_ARGS 1
-+
-+/* Define this macro if functions should assume that stack space has been
-+ allocated for arguments even when their values are passed in registers.
-+
-+ The value of this macro is the size, in bytes, of the area reserved for
-+ arguments passed in registers for the function represented by FNDECL.
-+
-+ This space can be allocated by the caller, or be a part of the
-+ machine-dependent stack frame: `OUTGOING_REG_PARM_STACK_SPACE' says
-+ which. */
-+#define REG_PARM_STACK_SPACE(FNDECL) ubicom32_reg_parm_stack_space(FNDECL)
-+
-+/* A C expression that should indicate the number of bytes of its own arguments
-+ that a function pops on returning, or 0 if the function pops no arguments
-+ and the caller must therefore pop them all after the function returns.
-+
-+ FUNDECL is a C variable whose value is a tree node that describes the
-+ function in question. Normally it is a node of type `FUNCTION_DECL' that
-+ describes the declaration of the function. From this it is possible to
-+ obtain the DECL_MACHINE_ATTRIBUTES of the function.
-+
-+ FUNTYPE is a C variable whose value is a tree node that describes the
-+ function in question. Normally it is a node of type `FUNCTION_TYPE' that
-+ describes the data type of the function. From this it is possible to obtain
-+ the data types of the value and arguments (if known).
-+
-+ When a call to a library function is being considered, FUNTYPE will contain
-+ an identifier node for the library function. Thus, if you need to
-+ distinguish among various library functions, you can do so by their names.
-+ Note that "library function" in this context means a function used to
-+ perform arithmetic, whose name is known specially in the compiler and was
-+ not mentioned in the C code being compiled.
-+
-+ STACK-SIZE is the number of bytes of arguments passed on the stack. If a
-+ variable number of bytes is passed, it is zero, and argument popping will
-+ always be the responsibility of the calling function.
-+
-+ On the Vax, all functions always pop their arguments, so the definition of
-+ this macro is STACK-SIZE. On the 68000, using the standard calling
-+ convention, no functions pop their arguments, so the value of the macro is
-+ always 0 in this case. But an alternative calling convention is available
-+ in which functions that take a fixed number of arguments pop them but other
-+ functions (such as `printf') pop nothing (the caller pops all). When this
-+ convention is in use, FUNTYPE is examined to determine whether a function
-+ takes a fixed number of arguments. */
-+#define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, STACK_SIZE) 0
-+
-+/* A C expression that controls whether a function argument is passed in a
-+ register, and which register.
-+
-+ The arguments are CUM, of type CUMULATIVE_ARGS, which summarizes (in a way
-+ defined by INIT_CUMULATIVE_ARGS and FUNCTION_ARG_ADVANCE) all of the previous
-+ arguments so far passed in registers; MODE, the machine mode of the argument;
-+ TYPE, the data type of the argument as a tree node or 0 if that is not known
-+ (which happens for C support library functions); and NAMED, which is 1 for an
-+ ordinary argument and 0 for nameless arguments that correspond to `...' in the
-+ called function's prototype.
-+
-+ The value of the expression should either be a `reg' RTX for the hard
-+ register in which to pass the argument, or zero to pass the argument on the
-+ stack.
-+
-+ For machines like the Vax and 68000, where normally all arguments are
-+ pushed, zero suffices as a definition.
-+
-+ The usual way to make the ANSI library `stdarg.h' work on a machine where
-+ some arguments are usually passed in registers, is to cause nameless
-+ arguments to be passed on the stack instead. This is done by making
-+ `FUNCTION_ARG' return 0 whenever NAMED is 0.
-+
-+ You may use the macro `MUST_PASS_IN_STACK (MODE, TYPE)' in the definition of
-+ this macro to determine if this argument is of a type that must be passed in
-+ the stack. If `REG_PARM_STACK_SPACE' is not defined and `FUNCTION_ARG'
-+ returns non-zero for such an argument, the compiler will abort. If
-+ `REG_PARM_STACK_SPACE' is defined, the argument will be computed in the
-+ stack and then loaded into a register. */
-+#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
-+ function_arg (&CUM, MODE, TYPE, NAMED)
-+
-+#define FUNCTION_INCOMING_ARG(CUM, MODE, TYPE, NAMED) \
-+ function_incoming_arg (&CUM, MODE, TYPE, NAMED)
-+
-+/* A C expression for the number of words, at the beginning of an argument,
-+ must be put in registers. The value must be zero for arguments that are
-+ passed entirely in registers or that are entirely pushed on the stack.
-+
-+ On some machines, certain arguments must be passed partially in registers
-+ and partially in memory. On these machines, typically the first N words of
-+ arguments are passed in registers, and the rest on the stack. If a
-+ multi-word argument (a `double' or a structure) crosses that boundary, its
-+ first few words must be passed in registers and the rest must be pushed.
-+ This macro tells the compiler when this occurs, and how many of the words
-+ should go in registers.
-+
-+ `FUNCTION_ARG' for these arguments should return the first register to be
-+ used by the caller for this argument; likewise `FUNCTION_INCOMING_ARG', for
-+ the called function. */
-+
-+/* A C expression that indicates when an argument must be passed by reference.
-+ If nonzero for an argument, a copy of that argument is made in memory and a
-+ pointer to the argument is passed instead of the argument itself. The
-+ pointer is passed in whatever way is appropriate for passing a pointer to
-+ that type.
-+
-+ On machines where `REG_PARM_STACK_SPACE' is not defined, a suitable
-+ definition of this macro might be
-+ #define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \
-+ MUST_PASS_IN_STACK (MODE, TYPE) */
-+
-+/* If defined, a C expression that indicates when it is the called function's
-+ responsibility to make a copy of arguments passed by invisible reference.
-+ Normally, the caller makes a copy and passes the address of the copy to the
-+ routine being called. When FUNCTION_ARG_CALLEE_COPIES is defined and is
-+ nonzero, the caller does not make a copy. Instead, it passes a pointer to
-+ the "live" value. The called function must not modify this value. If it
-+ can be determined that the value won't be modified, it need not make a copy;
-+ otherwise a copy must be made. */
-+
-+/* 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
-+ `int' suffices and can hold the number of bytes of argument so far.
-+
-+ There is no need to record in `CUMULATIVE_ARGS' anything about the arguments
-+ that have been passed on the stack. The compiler has other variables to
-+ keep track of that. For target machines on which all arguments are passed
-+ on the stack, there is no need to store anything in `CUMULATIVE_ARGS';
-+ however, the data structure must exist and should not be empty, so use
-+ `int'. */
-+struct cum_arg
-+{
-+ int nbytes;
-+ int reg;
-+ int stdarg;
-+};
-+#define CUMULATIVE_ARGS struct cum_arg
-+
-+/* A C statement (sans semicolon) for initializing the variable CUM for the
-+ state at the beginning of the argument list. The variable has type
-+ `CUMULATIVE_ARGS'. The value of FNTYPE is the tree node for the data type
-+ of the function which will receive the args, or 0 if the args are to a
-+ compiler support library function. The value of INDIRECT is nonzero when
-+ processing an indirect call, for example a call through a function pointer.
-+ The value of INDIRECT is zero for a call to an explicitly named function, a
-+ library function call, or when `INIT_CUMULATIVE_ARGS' is used to find
-+ arguments for the function being compiled.
-+
-+ When processing a call to a compiler support library function, LIBNAME
-+ identifies which one. It is a `symbol_ref' rtx which contains the name of
-+ the function, as a string. LIBNAME is 0 when an ordinary C function call is
-+ being processed. Thus, each time this macro is called, either LIBNAME or
-+ FNTYPE is nonzero, but never both of them at once. */
-+
-+#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT, NAMED_ARGS) \
-+ init_cumulative_args (&(CUM), FNTYPE, LIBNAME, INDIRECT);
-+
-+/* A C statement (sans semicolon) to update the summarizer variable CUM to
-+ advance past an argument in the argument list. The values MODE, TYPE and
-+ NAMED describe that argument. Once this is done, the variable CUM is
-+ suitable for analyzing the *following* argument with `FUNCTION_ARG', etc.
-+
-+ This macro need not do anything if the argument in question was passed on
-+ the stack. The compiler knows how to track the amount of stack space used
-+ for arguments without any special help. */
-+#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
-+ ((CUM).nbytes += ((MODE) != BLKmode \
-+ ? (GET_MODE_SIZE (MODE) + 3) & ~3 \
-+ : (int_size_in_bytes (TYPE) + 3) & ~3))
-+
-+/* For the Ubicom32 we define the upper function argument register here. */
-+#define UBICOM32_FUNCTION_ARG_REGS 10
-+
-+/* A C expression that is nonzero if REGNO is the number of a hard register in
-+ which function arguments are sometimes passed. This does *not* include
-+ implicit arguments such as the static chain and the structure-value address.
-+ On many machines, no registers can be used for this purpose since all
-+ function arguments are pushed on the stack. */
-+#define FUNCTION_ARG_REGNO_P(N) ((N) < UBICOM32_FUNCTION_ARG_REGS)
-+
-+\f
-+/* How Scalar Function Values are Returned. */
-+
-+/* The number of the hard register that is used to return a scalar value from a
-+ function call. */
-+#define RETURN_VALUE_REGNUM 0
-+
-+/* A C expression to create an RTX representing the place where a function
-+ returns a value of data type VALTYPE. VALTYPE is a tree node representing a
-+ data type. Write `TYPE_MODE (VALTYPE)' to get the machine mode used to
-+ represent that type. On many machines, only the mode is relevant.
-+ (Actually, on most machines, scalar values are returned in the same place
-+ regardless of mode).
-+
-+ If `PROMOTE_FUNCTION_RETURN' is defined, you must apply the same promotion
-+ rules specified in `PROMOTE_MODE' if VALTYPE is a scalar type.
-+
-+ If the precise function being called is known, FUNC is a tree node
-+ (`FUNCTION_DECL') for it; otherwise, FUNC is a null pointer. This makes it
-+ possible to use a different value-returning convention for specific
-+ functions when all their calls are known.
-+
-+ `FUNCTION_VALUE' is not used for return vales with aggregate data types,
-+ because these are returned in another way. See `STRUCT_VALUE_REGNUM' and
-+ related macros, below. */
-+#define FUNCTION_VALUE(VALTYPE, FUNC) \
-+ gen_rtx_REG (TYPE_MODE (VALTYPE), FIRST_DATA_REGNUM)
-+
-+/* A C expression to create an RTX representing the place where a library
-+ function returns a value of mode MODE.
-+
-+ Note that "library function" in this context means a compiler support
-+ routine, used to perform arithmetic, whose name is known specially by the
-+ compiler and was not mentioned in the C code being compiled.
-+
-+ The definition of `LIBRARY_VALUE' need not be concerned aggregate data
-+ types, because none of the library functions returns such types. */
-+#define LIBCALL_VALUE(MODE) gen_rtx_REG (MODE, FIRST_DATA_REGNUM)
-+
-+/* A C expression that is nonzero if REGNO is the number of a hard register in
-+ which the values of called function may come back.
-+
-+ A register whose use for returning values is limited to serving as the
-+ second of a pair (for a value of type `double', say) need not be recognized
-+ by this macro. So for most machines, this definition suffices:
-+
-+ #define FUNCTION_VALUE_REGNO_P(N) ((N) == RETURN)
-+
-+ If the machine has register windows, so that the caller and the called
-+ function use different registers for the return value, this macro should
-+ recognize only the caller's register numbers. */
-+#define FUNCTION_VALUE_REGNO_P(N) ((N) == FIRST_DATA_REGNUM)
-+
-+\f
-+/* How Large Values are Returned. */
-+
-+/* A C expression which can inhibit the returning of certain function values in
-+ registers, based on the type of value. A nonzero value says to return the
-+ function value in memory, just as large structures are always returned.
-+ Here TYPE will be a C expression of type `tree', representing the data type
-+ of the value.
-+
-+ Note that values of mode `BLKmode' must be explicitly handled by this macro.
-+ Also, the option `-fpcc-struct-return' takes effect regardless of this
-+ macro. On most systems, it is possible to leave the macro undefined; this
-+ causes a default definition to be used, whose value is the constant 1 for
-+ `BLKmode' values, and 0 otherwise.
-+
-+ Do not use this macro to indicate that structures and unions should always
-+ be returned in memory. You should instead use `DEFAULT_PCC_STRUCT_RETURN'
-+ to indicate this. */
-+#define RETURN_IN_MEMORY(TYPE) \
-+ (int_size_in_bytes (TYPE) > 8 || TYPE_MODE (TYPE) == BLKmode)
-+
-+/* Define this macro to be 1 if all structure and union return values must be
-+ in memory. Since this results in slower code, this should be defined only
-+ if needed for compatibility with other compilers or with an ABI. If you
-+ define this macro to be 0, then the conventions used for structure and union
-+ return values are decided by the `RETURN_IN_MEMORY' macro.
-+
-+ If not defined, this defaults to the value 1. */
-+#define DEFAULT_PCC_STRUCT_RETURN 0
-+
-+/* If the structure value address is not passed in a register, define
-+ `STRUCT_VALUE' as an expression returning an RTX for the place
-+ where the address is passed. If it returns 0, the address is
-+ passed as an "invisible" first argument. */
-+#define STRUCT_VALUE 0
-+
-+/* Define this macro as a C expression that is nonzero if the return
-+ instruction or the function epilogue ignores the value of the stack pointer;
-+ in other words, if it is safe to delete an instruction to adjust the stack
-+ pointer before a return from the function.
-+
-+ Note that this macro's value is relevant only for functions for which frame
-+ pointers are maintained. It is never safe to delete a final stack
-+ adjustment in a function that has no frame pointer, and the compiler knows
-+ this regardless of `EXIT_IGNORE_STACK'. */
-+#define EXIT_IGNORE_STACK 1
-+
-+/* A C statement or compound statement to output to FILE some assembler code to
-+ call the profiling subroutine `mcount'. Before calling, the assembler code
-+ must load the address of a counter variable into a register where `mcount'
-+ expects to find the address. The name of this variable is `LP' followed by
-+ the number LABELNO, so you would generate the name using `LP%d' in a
-+ `fprintf'.
-+
-+ The details of how the address should be passed to `mcount' are determined
-+ by your operating system environment, not by GNU CC. To figure them out,
-+ compile a small program for profiling using the system's installed C
-+ compiler and look at the assembler code that results.
-+
-+ This declaration must be present, but it can be an abort if profiling is
-+ not implemented. */
-+
-+#define FUNCTION_PROFILER(file, labelno) ubicom32_profiler(file, labelno)
-+
-+/* A C statement to output, on the stream FILE, assembler code for a block of
-+ data that contains the constant parts of a trampoline. This code should not
-+ include a label--the label is taken care of automatically. */
-+#if 0
-+#define TRAMPOLINE_TEMPLATE(FILE) \
-+ do { \
-+ fprintf (FILE, "\tadd -4,sp\n"); \
-+ fprintf (FILE, "\t.long 0x0004fffa\n"); \
-+ fprintf (FILE, "\tmov (0,sp),a0\n"); \
-+ fprintf (FILE, "\tadd 4,sp\n"); \
-+ fprintf (FILE, "\tmov (13,a0),a1\n"); \
-+ fprintf (FILE, "\tmov (17,a0),a0\n"); \
-+ fprintf (FILE, "\tjmp (a0)\n"); \
-+ fprintf (FILE, "\t.long 0\n"); \
-+ fprintf (FILE, "\t.long 0\n"); \
-+ } while (0)
-+#endif
-+
-+/* A C expression for the size in bytes of the trampoline, as an integer. */
-+#define TRAMPOLINE_SIZE 0x1b
-+
-+/* Alignment required for trampolines, in bits.
-+
-+ If you don't define this macro, the value of `BIGGEST_ALIGNMENT' is used for
-+ aligning trampolines. */
-+#define TRAMPOLINE_ALIGNMENT 32
-+
-+/* A C statement to initialize the variable parts of a trampoline. ADDR is an
-+ RTX for the address of the trampoline; FNADDR is an RTX for the address of
-+ the nested function; STATIC_CHAIN is an RTX for the static chain value that
-+ should be passed to the function when it is called. */
-+#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
-+{ \
-+ emit_move_insn (gen_rtx_MEM (SImode, plus_constant ((TRAMP), 0x14)), \
-+ (CXT)); \
-+ emit_move_insn (gen_rtx_MEM (SImode, plus_constant ((TRAMP), 0x18)), \
-+ (FNADDR)); \
-+}
-+
-+/* Ubicom32 supports pre and post increment/decrement addressing. */
-+#define HAVE_POST_INCREMENT 1
-+#define HAVE_PRE_INCREMENT 1
-+#define HAVE_POST_DECREMENT 1
-+#define HAVE_PRE_DECREMENT 1
-+
-+/* Ubicom32 supports pre and post address side-effects with constants
-+ other than the size of the memory operand. */
-+#define HAVE_PRE_MODIFY_DISP 1
-+#define HAVE_POST_MODIFY_DISP 1
-+
-+/* A C expression that is 1 if the RTX X is a constant which is a valid
-+ address. On most machines, this can be defined as `CONSTANT_P (X)',
-+ but a few machines are more restrictive in which constant addresses
-+ are supported.
-+
-+ `CONSTANT_P' accepts integer-values expressions whose values are not
-+ explicitly known, such as `symbol_ref', `label_ref', and `high'
-+ expressions and `const' arithmetic expressions, in addition to
-+ `const_int' and `const_double' expressions. */
-+#define CONSTANT_ADDRESS_P(X) \
-+ (GET_CODE (X) == LABEL_REF \
-+ || (GET_CODE (X) == CONST \
-+ && GET_CODE (XEXP (X, 0)) == PLUS \
-+ && GET_CODE (XEXP (XEXP (X, 0), 0)) == LABEL_REF))
-+
-+/* Ubicom32 supports a maximum of 2 registers in a valid memory address.
-+ One is always an address register while a second, optional, one may be a
-+ data register. */
-+#define MAX_REGS_PER_ADDRESS 2
-+
-+/* A C compound statement with a conditional `goto LABEL;' executed if X (an
-+ RTX) is a legitimate memory address on the target machine for a memory
-+ operand of mode MODE.
-+
-+ It usually pays to define several simpler macros to serve as subroutines for
-+ this one. Otherwise it may be too complicated to understand.
-+
-+ This macro must exist in two variants: a strict variant and a non-strict
-+ one. The strict variant is used in the reload pass. It must be defined so
-+ that any pseudo-register that has not been allocated a hard register is
-+ considered a memory reference. In contexts where some kind of register is
-+ required, a pseudo-register with no hard register must be rejected.
-+
-+ The non-strict variant is used in other passes. It must be defined to
-+ accept all pseudo-registers in every context where some kind of register is
-+ required.
-+
-+ Compiler source files that want to use the strict variant of this macro
-+ define the macro `REG_OK_STRICT'. You should use an `#ifdef REG_OK_STRICT'
-+ conditional to define the strict variant in that case and the non-strict
-+ variant otherwise.
-+
-+ Subroutines to check for acceptable registers for various purposes (one for
-+ base registers, one for index registers, and so on) are typically among the
-+ subroutines used to define `GO_IF_LEGITIMATE_ADDRESS'. Then only these
-+ subroutine macros need have two variants; the higher levels of macros may be
-+ the same whether strict or not.
-+
-+ Normally, constant addresses which are the sum of a `symbol_ref' and an
-+ integer are stored inside a `const' RTX to mark them as constant.
-+ Therefore, there is no need to recognize such sums specifically as
-+ legitimate addresses. Normally you would simply recognize any `const' as
-+ legitimate.
-+
-+ Usually `PRINT_OPERAND_ADDRESS' is not prepared to handle constant sums that
-+ are not marked with `const'. It assumes that a naked `plus' indicates
-+ indexing. If so, then you *must* reject such naked constant sums as
-+ illegitimate addresses, so that none of them will be given to
-+ `PRINT_OPERAND_ADDRESS'.
-+
-+ On some machines, whether a symbolic address is legitimate depends on the
-+ section that the address refers to. On these machines, define the macro
-+ `ENCODE_SECTION_INFO' to store the information into the `symbol_ref', and
-+ then check for it here. When you see a `const', you will have to look
-+ inside it to find the `symbol_ref' in order to determine the section.
-+
-+ The best way to modify the name string is by adding text to the beginning,
-+ with suitable punctuation to prevent any ambiguity. Allocate the new name
-+ in `saveable_obstack'. You will have to modify `ASM_OUTPUT_LABELREF' to
-+ remove and decode the added text and output the name accordingly, and define
-+ `STRIP_NAME_ENCODING' to access the original name string.
-+
-+ You can check the information stored here into the `symbol_ref' in the
-+ definitions of the macros `GO_IF_LEGITIMATE_ADDRESS' and
-+ `PRINT_OPERAND_ADDRESS'. */
-+/* On the ubicom32, the value in the address register must be
-+ in the same memory space/segment as the effective address.
-+
-+ This is problematical for reload since it does not understand
-+ that base+index != index+base in a memory reference. */
-+
-+#ifdef REG_OK_STRICT
-+#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
-+ if (ubicom32_legitimate_address_p (MODE, X, 1)) goto ADDR;
-+#else
-+#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
-+ if (ubicom32_legitimate_address_p (MODE, X, 0)) goto ADDR;
-+#endif
-+
-+/* Try machine-dependent ways of modifying an illegitimate address
-+ to be legitimate. If we find one, return the new, valid address.
-+ This macro is used in only one place: `memory_address' in explow.c.
-+
-+ OLDX is the address as it was before break_out_memory_refs was called.
-+ In some cases it is useful to look at this to decide what needs to be done.
-+
-+ MODE and WIN are passed so that this macro can use
-+ GO_IF_LEGITIMATE_ADDRESS.
-+
-+ It is always safe for this macro to do nothing. It exists to recognize
-+ opportunities to optimize the output.
-+
-+ On RS/6000, first check for the sum of a register with a constant
-+ integer that is out of range. If so, generate code to add the
-+ constant with the low-order 16 bits masked to the register and force
-+ this result into another register (this can be done with `cau').
-+ Then generate an address of REG+(CONST&0xffff), allowing for the
-+ possibility of bit 16 being a one.
-+
-+ Then check for the sum of a register and something not constant, try to
-+ load the other things into a register and return the sum. */
-+
-+#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \
-+{ \
-+ rtx result = ubicom32_legitimize_address ((X), (OLDX), (MODE)); \
-+ if (result != NULL_RTX) \
-+ { \
-+ (X) = result; \
-+ goto WIN; \
-+ } \
-+}
-+
-+/* Try a machine-dependent way of reloading an illegitimate address
-+ operand. If we find one, push the reload and jump to WIN. This
-+ macro is used in only one place: `find_reloads_address' in reload.c. */
-+#define LEGITIMIZE_RELOAD_ADDRESS(AD, MODE, OPNUM, TYPE, IND, WIN) \
-+{ \
-+ rtx new_rtx = ubicom32_legitimize_reload_address ((AD), (MODE), (OPNUM), (int)(TYPE)); \
-+ if (new_rtx) \
-+ { \
-+ (AD) = new_rtx; \
-+ goto WIN; \
-+ } \
-+}
-+
-+/* A C statement or compound statement with a conditional `goto LABEL;'
-+ executed if memory address X (an RTX) can have different meanings depending
-+ on the machine mode of the memory reference it is used for or if the address
-+ is valid for some modes but not others.
-+
-+ Autoincrement and autodecrement addresses typically have mode-dependent
-+ effects because the amount of the increment or decrement is the size of the
-+ operand being addressed. Some machines have other mode-dependent addresses.
-+ Many RISC machines have no mode-dependent addresses.
-+
-+ You may assume that ADDR is a valid address for the machine. */
-+#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL) \
-+ if (ubicom32_mode_dependent_address_p (ADDR)) \
-+ goto LABEL;
-+
-+/* A C expression that is nonzero if X is a legitimate constant for an
-+ immediate operand on the target machine. You can assume that X
-+ satisfies `CONSTANT_P', so you need not check this. In fact, `1' is
-+ a suitable definition for this macro on machines where anything
-+ `CONSTANT_P' is valid. */
-+#define LEGITIMATE_CONSTANT_P(X) \
-+ ubicom32_legitimate_constant_p ((X))
-+
-+/* Moves between registers are pretty-much single instructions for
-+ Ubicom32. We make this the default "2" that gcc likes. */
-+#define REGISTER_MOVE_COST(MODE, FROM, TO) 2
-+
-+/* This is a little bit of magic from the S390 port that wins 2% on code
-+ size when building the Linux kernel! Unfortunately while it wins on
-+ that size the user-space apps built using FD-PIC don't improve and the
-+ performance is lower because we put more pressure on the caches. We may
-+ want this back on some future CPU that has higher cache performance. */
-+/* #define IRA_HARD_REGNO_ADD_COST_MULTIPLIER(regno) 0.5 */
-+
-+/* Moves between registers and memory are more expensive than between
-+ registers because we have caches and write buffers that slow things
-+ down! */
-+#define MEMORY_MOVE_COST(MODE, CLASS, IN) 2
-+
-+/* A fall-through branch is very low cost but anything that changes the PC
-+ incurs a major pipeline hazard. We don't make the full extent of this
-+ hazard visible because we hope that multiple threads will absorb much
-+ of the cost and so we don't want a jump being replaced with, say, 7
-+ instructions. */
-+#define BRANCH_COST(SPEED_P, PREDICTABLE_P) \
-+ ((PREDICTABLE_P) ? 1 : 3)
-+
-+/* Define this macro as a C expression which is nonzero if accessing less than
-+ a word of memory (i.e. a `char' or a `short') is no faster than accessing a
-+ word of memory, i.e., if such access require more than one instruction or if
-+ there is no difference in cost between byte and (aligned) word loads.
-+
-+ When this macro is not defined, the compiler will access a field by finding
-+ the smallest containing object; when it is defined, a fullword load will be
-+ used if alignment permits. Unless bytes accesses are faster than word
-+ accesses, using word accesses is preferable since it may eliminate
-+ subsequent memory access if subsequent accesses occur to other fields in the
-+ same word of the structure, but to different bytes. */
-+#define SLOW_BYTE_ACCESS 0
-+
-+/* The number of scalar move insns which should be generated instead of a
-+ string move insn or a library call. Increasing the value will always make
-+ code faster, but eventually incurs high cost in increased code size.
-+
-+ If you don't define this, a reasonable default is used. */
-+/* According to expr.c, a value of around 6 should minimize code size. */
-+#define MOVE_RATIO(SPEED) 6
-+
-+/* We're much better off calling a constant function address with the
-+ Ubicom32 architecture because we have an opcode for doing so. Don't
-+ let the compiler extract function addresses as common subexpressions
-+ into an address register. */
-+#define NO_FUNCTION_CSE
-+
-+#define SELECT_CC_MODE(OP, X, Y) ubicom32_select_cc_mode (OP, X, Y)
-+
-+#define REVERSIBLE_CC_MODE(MODE) 1
-+
-+/* Canonicalize a comparison from one we don't have to one we do have. */
-+#define CANONICALIZE_COMPARISON(CODE, OP0, OP1) \
-+ ubicom32_canonicalize_comparison (&(CODE), &(OP0), &(OP1))
-+
-+/* Dividing the output into sections. */
-+
-+/* A C expression whose value is a string containing the assembler operation
-+ that should precede instructions and read-only data. Normally `".text"' is
-+ right. */
-+#define TEXT_SECTION_ASM_OP "\t.section .text"
-+
-+/* A C expression whose value is a string containing the assembler operation to
-+ identify the following data as writable initialized data. Normally
-+ `".data"' is right. */
-+#define DATA_SECTION_ASM_OP "\t.section .data"
-+
-+
-+/* If defined, a C expression whose value is a string containing the
-+ assembler operation to identify the following data as
-+ uninitialized global data. If not defined, and neither
-+ `ASM_OUTPUT_BSS' nor `ASM_OUTPUT_ALIGNED_BSS' are defined,
-+ uninitialized global data will be output in the data section if
-+ `-fno-common' is passed, otherwise `ASM_OUTPUT_COMMON' will be
-+ used. */
-+#define BSS_SECTION_ASM_OP "\t.section .bss"
-+
-+/* This is how we tell the assembler that a symbol is weak. */
-+
-+#define ASM_WEAKEN_LABEL(FILE, NAME) \
-+ do \
-+ { \
-+ fputs ("\t.weak\t", (FILE)); \
-+ assemble_name ((FILE), (NAME)); \
-+ fputc ('\n', (FILE)); \
-+ } \
-+ while (0)
-+
-+/* The Overall Framework of an Assembler File. */
-+
-+#undef SET_ASM_OP
-+#define SET_ASM_OP "\t.set\t"
-+
-+/* A C string constant describing how to begin a comment in the target
-+ assembler language. The compiler assumes that the comment will end at the
-+ end of the line. */
-+#define ASM_COMMENT_START ";"
-+
-+/* A C string constant for text to be output before each `asm' statement or
-+ group of consecutive ones. Normally this is `"#APP"', which is a comment
-+ that has no effect on most assemblers but tells the GNU assembler that it
-+ must check the lines that follow for all valid assembler constructs. */
-+#define ASM_APP_ON "#APP\n"
-+
-+/* A C string constant for text to be output after each `asm' statement or
-+ group of consecutive ones. Normally this is `"#NO_APP"', which tells the
-+ GNU assembler to resume making the time-saving assumptions that are valid
-+ for ordinary compiler output. */
-+#define ASM_APP_OFF "#NO_APP\n"
-+
-+/* Like `ASM_OUTPUT_BSS' except takes the required alignment as a separate,
-+ explicit argument. If you define this macro, it is used in place of
-+ `ASM_OUTPUT_BSS', and gives you more flexibility in handling the required
-+ alignment of the variable. The alignment is specified as the number of
-+ bits.
-+
-+ Try to use function `asm_output_aligned_bss' defined in file `varasm.c' when
-+ defining this macro. */
-+#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
-+ asm_output_aligned_bss ((FILE), (DECL), (NAME), (SIZE), (ALIGN))
-+
-+/* A C expression to assign to OUTVAR (which is a variable of type `char *') a
-+ newly allocated string made from the string NAME and the number NUMBER, with
-+ some suitable punctuation added. Use `alloca' to get space for the string.
-+
-+ The string will be used as an argument to `ASM_OUTPUT_LABELREF' to produce
-+ an assembler label for an internal static variable whose name is NAME.
-+ Therefore, the string must be such as to result in valid assembler code.
-+ The argument NUMBER is different each time this macro is executed; it
-+ prevents conflicts between similarly-named internal static variables in
-+ different scopes.
-+
-+ Ideally this string should not be a valid C identifier, to prevent any
-+ conflict with the user's own symbols. Most assemblers allow periods or
-+ percent signs in assembler symbols; putting at least one of these between
-+ the name and the number will suffice. */
-+#define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \
-+ ((OUTPUT) = (char *) alloca (strlen ((NAME)) + 10), \
-+ sprintf ((OUTPUT), "%s___%d", (NAME), (LABELNO)))
-+
-+#define ASM_GENERATE_INTERNAL_LABEL(STRING, PREFIX, NUM) \
-+ sprintf (STRING, "*.%s%ld", PREFIX, (long)(NUM))
-+/* A C statement to store into the string STRING a label whose name
-+ is made from the string PREFIX and the number NUM.
-+
-+ This string, when output subsequently by `assemble_name', should
-+ produce the output that `(*targetm.asm_out.internal_label)' would produce
-+ with the same PREFIX and NUM.
-+
-+ If the string begins with `*', then `assemble_name' will output
-+ the rest of the string unchanged. It is often convenient for
-+ `ASM_GENERATE_INTERNAL_LABEL' to use `*' in this way. If the
-+ string doesn't start with `*', then `ASM_OUTPUT_LABELREF' gets to
-+ output the string, and may change it. (Of course,
-+ `ASM_OUTPUT_LABELREF' is also part of your machine description, so
-+ you should know what it does on your machine.) */
-+
-+/* This says how to output assembler code to declare an
-+ uninitialized external linkage data object. Under SVR4,
-+ the linker seems to want the alignment of data objects
-+ to depend on their types. We do exactly that here. */
-+
-+#define COMMON_ASM_OP "\t.comm\t"
-+
-+#undef ASM_OUTPUT_COMMON
-+#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \
-+ do \
-+ { \
-+ fprintf ((FILE), "%s", COMMON_ASM_OP); \
-+ assemble_name ((FILE), (NAME)); \
-+ fprintf ((FILE), ", %u\n", (SIZE)); \
-+ } \
-+ while (0)
-+
-+/* This says how to output assembler code to declare an
-+ uninitialized internal linkage data object. Under SVR4,
-+ the linker seems to want the alignment of data objects
-+ to depend on their types. We do exactly that here. */
-+#define LOCAL_ASM_OP "\t.lcomm\t"
-+
-+#undef ASM_OUTPUT_LOCAL
-+#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \
-+ do \
-+ { \
-+ fprintf ((FILE), "%s", LOCAL_ASM_OP); \
-+ assemble_name ((FILE), (NAME)); \
-+ fprintf ((FILE), ", %u\n", (SIZE)); \
-+ } \
-+ while (0)
-+
-+/* Globalizing directive for a label. */
-+#define GLOBAL_ASM_OP ".global\t"
-+
-+/* Output the operand of an instruction. */
-+#define PRINT_OPERAND(FILE, X, CODE) \
-+ ubicom32_print_operand(FILE, X, CODE)
-+
-+/* Output the address of an operand. */
-+#define PRINT_OPERAND_ADDRESS(FILE, ADDR) \
-+ ubicom32_print_operand_address (FILE, ADDR)
-+
-+/* A C expression to output to STREAM some assembler code which will push hard
-+ register number REGNO onto the stack. The code need not be optimal, since
-+ this macro is used only when profiling. */
-+#define ASM_OUTPUT_REG_PUSH(FILE, REGNO)
-+
-+/* A C expression to output to STREAM some assembler code which will pop hard
-+ register number REGNO off of the stack. The code need not be optimal, since
-+ this macro is used only when profiling. */
-+#define ASM_OUTPUT_REG_POP(FILE, REGNO)
-+
-+/* This macro should be provided on machines where the addresses in a dispatch
-+ table are relative to the table's own address.
-+
-+ The definition should be a C statement to output to the stdio stream STREAM
-+ an assembler pseudo-instruction to generate a difference between two labels.
-+ VALUE and REL are the numbers of two internal labels. The definitions of
-+ these labels are output using `ASM_OUTPUT_INTERNAL_LABEL', and they must be
-+ printed in the same way here. For example,
-+
-+ fprintf (STREAM, "\t.word L%d-L%d\n", VALUE, REL) */
-+#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
-+ fprintf (FILE, "\t%s .L%d-.L%d\n", ".long", VALUE, REL)
-+
-+/* This macro should be provided on machines where the addresses in a dispatch
-+ table are absolute.
-+
-+ The definition should be a C statement to output to the stdio stream STREAM
-+ an assembler pseudo-instruction to generate a reference to a label. VALUE
-+ is the number of an internal label whose definition is output using
-+ `ASM_OUTPUT_INTERNAL_LABEL'. For example,
-+
-+ fprintf (STREAM, "\t.word L%d\n", VALUE) */
-+#define ASM_OUTPUT_ADDR_VEC_ELT(STREAM, VALUE) \
-+ fprintf (STREAM, "\t.word .L%d\n", VALUE)
-+
-+/* Switch into a generic section. */
-+#define TARGET_ASM_NAMED_SECTION default_elf_asm_named_section
-+
-+/* Assembler Commands for Alignment. */
-+
-+#define ASM_OUTPUT_SKIP(STREAM, N) fprintf (STREAM, "\t.skip %d,0\n", N)
-+/* A C statement to output to the stdio stream STREAM an assembler
-+ instruction to advance the location counter by NBYTES bytes.
-+ Those bytes should be zero when loaded. NBYTES will be a C
-+ expression of type `int'. */
-+
-+/* A C statement to output to the stdio stream STREAM an assembler command to
-+ advance the location counter to a multiple of 2 to the POWER bytes. POWER
-+ will be a C expression of type `int'. */
-+#define ASM_OUTPUT_ALIGN(FILE, LOG) \
-+ if ((LOG) != 0) \
-+ fprintf (FILE, "\t.align %d\n", (LOG))
-+
-+/* A C expression that returns the DBX register number for the compiler
-+ register number REGNO. In simple cases, the value of this expression may be
-+ REGNO itself. But sometimes there are some registers that the compiler
-+ knows about and DBX does not, or vice versa. In such cases, some register
-+ may need to have one number in the compiler and another for DBX.
-+
-+ If two registers have consecutive numbers inside GNU CC, and they can be
-+ used as a pair to hold a multiword value, then they *must* have consecutive
-+ numbers after renumbering with `DBX_REGISTER_NUMBER'. Otherwise, debuggers
-+ will be unable to access such a pair, because they expect register pairs to
-+ be consecutive in their own numbering scheme.
-+
-+ If you find yourself defining `DBX_REGISTER_NUMBER' in way that does not
-+ preserve register pairs, then what you must do instead is redefine the
-+ actual register numbering scheme.
-+
-+ This declaration is required. */
-+#define DBX_REGISTER_NUMBER(REGNO) REGNO
-+
-+/* A C expression that returns the integer offset value for an automatic
-+ variable having address X (an RTL expression). The default computation
-+ assumes that X is based on the frame-pointer and gives the offset from the
-+ frame-pointer. This is required for targets that produce debugging output
-+ for DBX or COFF-style debugging output for SDB and allow the frame-pointer
-+ to be eliminated when the `-g' options is used. */
-+#define DEBUGGER_AUTO_OFFSET(X) \
-+ ((GET_CODE (X) == PLUS ? INTVAL (XEXP (X, 1)) : 0) \
-+ + (frame_pointer_needed \
-+ ? 0 : -initial_elimination_offset (FRAME_POINTER_REGNUM, \
-+ STACK_POINTER_REGNUM)))
-+
-+/* A C expression that returns the integer offset value for an argument having
-+ address X (an RTL expression). The nominal offset is OFFSET. */
-+#define DEBUGGER_ARG_OFFSET(OFFSET, X) \
-+ ((GET_CODE (X) == PLUS ? OFFSET : 0) \
-+ + (frame_pointer_needed \
-+ ? 0 : -initial_elimination_offset (ARG_POINTER_REGNUM, \
-+ STACK_POINTER_REGNUM)))
-+
-+/* A C expression that returns the type of debugging output GNU CC produces
-+ when the user specifies `-g' or `-ggdb'. Define this if you have arranged
-+ for GNU CC to support more than one format of debugging output. Currently,
-+ the allowable values are `DBX_DEBUG', `SDB_DEBUG', `DWARF_DEBUG',
-+ `DWARF2_DEBUG', and `XCOFF_DEBUG'.
-+
-+ The value of this macro only affects the default debugging output; the user
-+ can always get a specific type of output by using `-gstabs', `-gcoff',
-+ `-gdwarf-1', `-gdwarf-2', or `-gxcoff'.
-+
-+ Defined in svr4.h.
-+*/
-+#undef PREFERRED_DEBUGGING_TYPE
-+#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
-+
-+/* Define this macro if GNU CC should produce dwarf version 2 format debugging
-+ output in response to the `-g' option.
-+
-+ To support optional call frame debugging information, you must also define
-+ `INCOMING_RETURN_ADDR_RTX' and either set `RTX_FRAME_RELATED_P' on the
-+ prologue insns if you use RTL for the prologue, or call `dwarf2out_def_cfa'
-+ and `dwarf2out_reg_save' as appropriate from `FUNCTION_PROLOGUE' if you
-+ don't.
-+
-+ Defined in svr4.h. */
-+
-+#define DWARF2_DEBUGGING_INFO 1
-+/*#define DWARF2_UNWIND_INFO 1*/
-+#define DWARF2_UNWIND_INFO 0
-+#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (Pmode, LINK_REGNO)
-+#define INCOMING_FRAME_SP_OFFSET 0
-+#define DWARF_FRAME_RETURN_COLUMN DWARF_FRAME_REGNUM (LINK_REGNO)
-+#define EH_RETURN_FIRST 9
-+#define EH_RETURN_DATA_REGNO(N) ((N) < 2 ? (N) + EH_RETURN_FIRST : INVALID_REGNUM)
-+
-+/* The EH_RETURN_STACKADJ_RTX macro returns RTL which describes the
-+ location used to store the amount to ajdust the stack. This is
-+ usually a registers that is available from end of the function's body
-+ to the end of the epilogue. Thus, this cannot be a register used as a
-+ temporary by the epilogue.
-+
-+ This must be an integer register. */
-+#define EH_RETURN_STACKADJ_REGNO 11
-+#define EH_RETURN_STACKADJ_RTX \
-+ gen_rtx_REG (Pmode, EH_RETURN_STACKADJ_REGNO)
-+
-+/* The EH_RETURN_HANDLER_RTX macro returns RTL which describes the
-+ location used to store the address the processor should jump to
-+ catch exception. This is usually a registers that is available from
-+ end of the function's body to the end of the epilogue. Thus, this
-+ cannot be a register used as a temporary by the epilogue.
-+
-+ This must be an address register. */
-+#define EH_RETURN_HANDLER_REGNO 18
-+#define EH_RETURN_HANDLER_RTX \
-+ gen_rtx_REG (Pmode, EH_RETURN_HANDLER_REGNO)
-+
-+/* #define DWARF2_DEBUGGING_INFO */
-+
-+/* Define this macro if GNU CC should produce dwarf version 2-style
-+ line numbers. This usually requires extending the assembler to
-+ support them, and #defining DWARF2_LINE_MIN_INSN_LENGTH in the
-+ assembler configuration header files. */
-+/* #define DWARF2_ASM_LINE_DEBUG_INFO 1 */
-+
-+
-+/* An alias for a machine mode name. This is the machine mode that elements
-+ of a jump-table have. */
-+#define CASE_VECTOR_MODE Pmode
-+
-+/* Smallest number of different values for which it is best to use a
-+ jump-table instead of a tree of conditional branches. For most Ubicom32
-+ targets this is quite small, but for the v1 architecture implementations
-+ we had very little data memory and so heavily prefer the tree approach
-+ rather than the jump tables. */
-+#define CASE_VALUES_THRESHOLD ubicom32_case_values_threshold
-+
-+/* Register operations within the Ubicom32 architecture always operate on
-+ the whole register word and not just the sub-bits required for the opcode
-+ mode size. */
-+#define WORD_REGISTER_OPERATIONS
-+
-+/* The maximum number of bytes that a single instruction can move quickly from
-+ memory to memory. */
-+#define MOVE_MAX 4
-+
-+/* A C expression that is nonzero if on this machine the number of bits
-+ actually used for the count of a shift operation is equal to the number of
-+ bits needed to represent the size of the object being shifted. When this
-+ macro is non-zero, the compiler will assume that it is safe to omit a
-+ sign-extend, zero-extend, and certain bitwise `and' instructions that
-+ truncates the count of a shift operation. On machines that have
-+ instructions that act on bitfields at variable positions, which may include
-+ `bit test' instructions, a nonzero `SHIFT_COUNT_TRUNCATED' also enables
-+ deletion of truncations of the values that serve as arguments to bitfield
-+ instructions.
-+
-+ If both types of instructions truncate the count (for shifts) and position
-+ (for bitfield operations), or if no variable-position bitfield instructions
-+ exist, you should define this macro.
-+
-+ However, on some machines, such as the 80386 and the 680x0, truncation only
-+ applies to shift operations and not the (real or pretended) bitfield
-+ operations. Define `SHIFT_COUNT_TRUNCATED' to be zero on such machines.
-+ Instead, add patterns to the `md' file that include the implied truncation
-+ of the shift instructions.
-+
-+ You need not define this macro if it would always have the value of zero. */
-+#define SHIFT_COUNT_TRUNCATED 1
-+
-+/* A C expression which is nonzero if on this machine it is safe to "convert"
-+ an integer of INPREC bits to one of OUTPREC bits (where OUTPREC is smaller
-+ than INPREC) by merely operating on it as if it had only OUTPREC bits.
-+
-+ On many machines, this expression can be 1.
-+
-+ When `TRULY_NOOP_TRUNCATION' returns 1 for a pair of sizes for modes for
-+ which `MODES_TIEABLE_P' is 0, suboptimal code can result. If this is the
-+ case, making `TRULY_NOOP_TRUNCATION' return 0 in such cases may improve
-+ things. */
-+#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
-+
-+/* A C string constant that tells the GNU CC driver program options to pass
-+ to the assembler. It can also specify how to translate options you give
-+ to GNU CC into options for GNU CC to pass to the assembler. See the
-+ file `sun3.h' for an example of this.
-+
-+ Defined in svr4.h. */
-+#undef ASM_SPEC
-+#define ASM_SPEC \
-+ "%{march=*:-m%*} %{!march=*:-mubicom32v4} %{mfdpic:-mfdpic}"
-+
-+#define LINK_SPEC "\
-+%{h*} %{v:-V} \
-+%{b} \
-+%{mfdpic:-melf32ubicom32fdpic -z text} \
-+%{static:-dn -Bstatic} \
-+%{shared:-G -Bdynamic} \
-+%{symbolic:-Bsymbolic} \
-+%{G*} \
-+%{YP,*} \
-+%{Qy:} %{!Qn:-Qy}"
-+
-+#undef STARTFILE_SPEC
-+#undef ENDFILE_SPEC
-+
-+/* The svr4.h LIB_SPEC with -leval and --*group tacked on */
-+
-+#undef LIB_SPEC
-+#define LIB_SPEC "%{!shared:%{!symbolic:--start-group -lc -leval -lgcc --end-group}}"
-+
-+#undef HAVE_GAS_SHF_MERGE
-+#define HAVE_GAS_SHF_MERGE 0
-+
-+#define HANDLE_SYSV_PRAGMA 1
-+#undef HANDLE_PRAGMA_PACK
-+
-+typedef void (*ubicom32_func_ptr) (void);
-+
-+/* Define builtins for selected special-purpose instructions. */
-+enum ubicom32_builtins
-+{
-+ UBICOM32_BUILTIN_UBICOM32_SWAPB_2,
-+ UBICOM32_BUILTIN_UBICOM32_SWAPB_4
-+};
-+
-+extern rtx ubicom32_compare_op0;
-+extern rtx ubicom32_compare_op1;
-+
-+#define TYPE_ASM_OP "\t.type\t"
-+#define TYPE_OPERAND_FMT "@%s"
-+
-+#ifndef ASM_DECLARE_RESULT
-+#define ASM_DECLARE_RESULT(FILE, RESULT)
-+#endif
-+
-+/* These macros generate the special .type and .size directives which
-+ are used to set the corresponding fields of the linker symbol table
-+ entries in an ELF object file under SVR4. These macros also output
-+ the starting labels for the relevant functions/objects. */
-+
-+/* Write the extra assembler code needed to declare a function properly.
-+ Some svr4 assemblers need to also have something extra said about the
-+ function's return value. We allow for that here. */
-+
-+#ifndef ASM_DECLARE_FUNCTION_NAME
-+#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \
-+ do \
-+ { \
-+ ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "function"); \
-+ ASM_DECLARE_RESULT (FILE, DECL_RESULT (DECL)); \
-+ ASM_OUTPUT_LABEL (FILE, NAME); \
-+ } \
-+ while (0)
-+#endif
---- /dev/null
-+++ b/gcc/config/ubicom32/ubicom32.md
-@@ -0,0 +1,3753 @@
-+; GCC machine description for Ubicom32
-+;
-+; Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Free Software
-+; Foundation, Inc.
-+; Contributed by Ubicom, Inc.
-+;
-+; This file is part of GCC.
-+;
-+; GCC is free software; you can redistribute it and/or modify
-+; it under the terms of the GNU General Public License as published by
-+; the Free Software Foundation; either version 3, or (at your option)
-+; any later version.
-+;
-+; GCC is distributed in the hope that it will be useful,
-+; but WITHOUT ANY WARRANTY; without even the implied warranty of
-+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+; GNU General Public License for more details.
-+;
-+; You should have received a copy of the GNU General Public License
-+; along with GCC; see the file COPYING3. If not see
-+; <http://www.gnu.org/licenses/>.
-+
-+(define_constants
-+ [(AUX_DATA_REGNO 15)
-+ (LINK_REGNO 21)
-+ (SP_REGNO 23)
-+ (ACC0_HI_REGNO 24)
-+ (ACC1_HI_REGNO 26)
-+ (CC_REGNO 30)])
-+
-+(define_constants
-+ [(UNSPEC_FDPIC_GOT 0)
-+ (UNSPEC_FDPIC_GOT_FUNCDESC 1)])
-+
-+(define_constants
-+ [(UNSPEC_VOLATILE_LOAD_FDPIC_FUNCDESC 0)])
-+
-+;; Types of instructions (for scheduling purposes).
-+
-+(define_attr "type" "mul,addr,other"
-+ (const_string "other"))
-+
-+; Define instruction scheduling characteristics. We can only issue
-+; one instruction per clock so we don't need to define CPU units.
-+;
-+(define_automaton "ubicom32")
-+
-+(define_cpu_unit "i_pipeline" "ubicom32");
-+
-+; We have a 4 cycle hazard associated with address calculations which
-+; seems rather tricky to avoid so we go with a defensive assumption
-+; that almost anything can be used to generate addresses.
-+;
-+;(define_insn_reservation "ubicom32_other" 4
-+; (eq_attr "type" "other")
-+; "i_pipeline")
-+
-+; Some moves don't generate hazards.
-+;
-+;(define_insn_reservation "ubicom32_addr" 1
-+; (eq_attr "type" "addr")
-+; "i_pipeline")
-+
-+; We need 3 cycles between a multiply instruction and any use of the
-+; matching accumulator register(s).
-+;
-+(define_insn_reservation "ubicom32_mul" 4
-+ (eq_attr "type" "mul")
-+ "i_pipeline")
-+
-+(define_attr "length" ""
-+ (const_int 4))
-+
-+(include "predicates.md")
-+(include "constraints.md")
-+
-+; 8-bit move with no change to the flags reg.
-+;
-+(define_insn "movqi"
-+ [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
-+ (match_operand:QI 1 "ubicom32_move_operand" "g"))]
-+ ""
-+ "move.1\\t%0, %1")
-+
-+; Combiner-generated 8-bit move with the zero flag set accordingly.
-+;
-+(define_insn "movqi_ccszn"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:QI 0 "nonimmediate_operand" "rm")
-+ (const_int 0)))
-+ (set (match_operand:QI 1 "nonimmediate_operand" "=rm")
-+ (match_dup 0))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "ext.1\\t%1, %0")
-+
-+; Combine isn't very good at merging some types of operations so we
-+; have to make do with a peephole. It's not as effective but it's better
-+; than doing nothing.
-+;
-+(define_peephole2
-+ [(set (match_operand:QI 0 "nonimmediate_operand" "")
-+ (match_operand:QI 1 "nonimmediate_operand" ""))
-+ (set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (match_operator 3 "ubicom32_compare_operator"
-+ [(match_dup 0)
-+ (const_int 0)]))]
-+ "(GET_MODE (operands[2]) == CCSZNmode
-+ || GET_MODE (operands[2]) == CCSZmode)"
-+ [(parallel
-+ [(set (match_dup 2)
-+ (match_op_dup 3
-+ [(match_dup 1)
-+ (const_int 0)]))
-+ (set (match_dup 0)
-+ (match_dup 1))])]
-+ "")
-+
-+; Combine isn't very good at merging some types of operations so we
-+; have to make do with a peephole. It's not as effective but it's better
-+; than doing nothing.
-+;
-+(define_peephole2
-+ [(set (match_operand:QI 0 "nonimmediate_operand" "")
-+ (match_operand:QI 1 "nonimmediate_operand" ""))
-+ (set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (match_operator 3 "ubicom32_compare_operator"
-+ [(match_dup 1)
-+ (const_int 0)]))]
-+ "(GET_MODE (operands[2]) == CCSZNmode
-+ || GET_MODE (operands[2]) == CCSZmode)"
-+ [(parallel
-+ [(set (match_dup 2)
-+ (match_op_dup 3
-+ [(match_dup 1)
-+ (const_int 0)]))
-+ (set (match_dup 0)
-+ (match_dup 1))])]
-+ "")
-+
-+; 16-bit move with no change to the flags reg.
-+;
-+(define_insn "movhi"
-+ [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
-+ (match_operand:HI 1 "ubicom32_move_operand" "g"))]
-+ ""
-+ "*
-+ {
-+ if (CONST_INT_P (operands[1]))
-+ return \"movei\\t%0, %1\";
-+
-+ return \"move.2\\t%0, %1\";
-+ }")
-+
-+; Combiner-generated 16-bit move with the zero flag set accordingly.
-+;
-+(define_insn "movhi_ccszn"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:HI 0 "nonimmediate_operand" "rm")
-+ (const_int 0)))
-+ (set (match_operand:HI 1 "nonimmediate_operand" "=rm")
-+ (match_dup 0))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "ext.2\\t%1, %0")
-+
-+; Combine isn't very good at merging some types of operations so we
-+; have to make do with a peephole. It's not as effective but it's better
-+; than doing nothing.
-+;
-+(define_peephole2
-+ [(set (match_operand:HI 0 "nonimmediate_operand" "")
-+ (match_operand:HI 1 "nonimmediate_operand" ""))
-+ (set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (match_operator 3 "ubicom32_compare_operator"
-+ [(match_dup 0)
-+ (const_int 0)]))]
-+ "(GET_MODE (operands[2]) == CCSZNmode
-+ || GET_MODE (operands[2]) == CCSZmode)"
-+ [(parallel
-+ [(set (match_dup 2)
-+ (match_op_dup 3
-+ [(match_dup 1)
-+ (const_int 0)]))
-+ (set (match_dup 0)
-+ (match_dup 1))])]
-+ "")
-+
-+; Combine isn't very good at merging some types of operations so we
-+; have to make do with a peephole. It's not as effective but it's better
-+; than doing nothing.
-+;
-+(define_peephole2
-+ [(set (match_operand:HI 0 "nonimmediate_operand" "")
-+ (match_operand:HI 1 "nonimmediate_operand" ""))
-+ (set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (match_operator 3 "ubicom32_compare_operator"
-+ [(match_dup 1)
-+ (const_int 0)]))]
-+ "(GET_MODE (operands[2]) == CCSZNmode
-+ || GET_MODE (operands[2]) == CCSZmode)"
-+ [(parallel
-+ [(set (match_dup 2)
-+ (match_op_dup 3
-+ [(match_dup 1)
-+ (const_int 0)]))
-+ (set (match_dup 0)
-+ (match_dup 1))])]
-+ "")
-+
-+; 32-bit move with no change to the flags reg.
-+;
-+(define_expand "movsi"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
-+ (match_operand:SI 1 "general_operand" ""))]
-+ ""
-+ "{
-+ /* Convert any complexities in operand 1 into something that can just
-+ fall into the default expander code. */
-+ ubicom32_expand_movsi (operands);
-+ }")
-+
-+(define_insn "movsi_high"
-+ [(set (match_operand:SI 0 "ubicom32_address_register_operand" "=a")
-+ (high:SI (match_operand:SI 1 "ubicom32_symbolic_address_operand" "s")))]
-+ ""
-+ "moveai\\t%0, #%%hi(%E1)")
-+
-+(define_insn "movsi_lo_sum"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (lo_sum:SI (match_operand:SI 1 "ubicom32_address_register_operand" "a")
-+ (match_operand:SI 2 "immediate_operand" "s")))]
-+ ""
-+ "lea.1\\t%0, %%lo(%E2)(%1)")
-+
-+(define_insn "movsi_internal"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (match_operand:SI 1 "ubicom32_move_operand" "rmnY"))]
-+ ""
-+ "*
-+ {
-+ if (CONST_INT_P (operands[1]))
-+ {
-+ ubicom32_emit_move_const_int (operands[0], operands[1]);
-+ return \"\";
-+ }
-+
-+ if (GET_CODE (operands[1]) == CONST_DOUBLE)
-+ {
-+ HOST_WIDE_INT i = CONST_DOUBLE_LOW (operands[1]);
-+
-+ ubicom32_emit_move_const_int (operands[0], GEN_INT (i));
-+ return \"\";
-+ }
-+
-+ if (ubicom32_address_register_operand (operands[0], VOIDmode)
-+ && register_operand (operands[1], VOIDmode))
-+ {
-+ if (ubicom32_address_register_operand (operands[1], VOIDmode))
-+ return \"lea.1\\t%0, 0(%1)\";
-+
-+ /* Use movea here to utilize the hazard bypass in the >= v4 ISA. */
-+ if (ubicom32_v4)
-+ return \"movea\\t%0, %1\";
-+
-+ return \"move.4\\t%0, %1\";
-+ }
-+
-+ return \"move.4\\t%0, %1\";
-+ }")
-+
-+; If we're not dependent on the state of the condition codes we can construct
-+; constants of value 2^n by using a bset.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(exact_log2 (INTVAL (operands[1])) > 14
-+ && peep2_regno_dead_p (0, CC_REGNO))"
-+ [(parallel
-+ [(set (match_dup 0)
-+ (ior:SI (const_int 0)
-+ (match_dup 1)))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "")
-+
-+; If we're not dependent on the state of the condition codes we can construct
-+; constants of value ~(2^n) by using a bclr.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(exact_log2 (~INTVAL (operands[1])) > 14
-+ && peep2_regno_dead_p (0, CC_REGNO))"
-+ [(parallel
-+ [(set (match_dup 0)
-+ (and:SI (const_int -1)
-+ (match_dup 1)))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "")
-+
-+; For 32-bit constants that have bits 0 through 24 and bit 31 set the same
-+; we can use swapb.4!
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(ubicom32_v4
-+ && (INTVAL (operands[1]) & 0xffffffff) != 0xffffffff
-+ && (INTVAL (operands[1]) & 0xffffffff) != 0
-+ && ((INTVAL (operands[1]) & 0x80ffffff) == 0
-+ || (INTVAL (operands[1]) & 0x80ffffff) == 0x80ffffff))"
-+ [(set (match_dup 0)
-+ (bswap:SI (match_dup 2)))]
-+ "{
-+ operands[2] = GEN_INT (INTVAL (operands[1]) >> 24);
-+ }")
-+
-+; If this is a write of a constant to memory look to see if we can usefully
-+; transform this into 2 smaller writes.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "memory_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "! satisfies_constraint_I (operands[1])
-+ && ubicom32_legitimate_address_p (HImode, plus_constant (XEXP (operands[0], 0), 2), 1)"
-+ [(set (match_dup 4) (match_dup 2))
-+ (set (match_dup 5) (match_dup 3))]
-+ "{
-+ rtx low_hword_addr;
-+
-+ operands[2] = gen_highpart_mode (HImode, SImode, operands[1]);
-+ operands[3] = gen_lowpart (HImode, operands[1]);
-+
-+ operands[4] = gen_rtx_MEM (HImode, XEXP (operands[0], 0));
-+ MEM_COPY_ATTRIBUTES (operands[4], operands[0]);
-+
-+ low_hword_addr = plus_constant (XEXP (operands[0], 0), 2);
-+ operands[5] = gen_rtx_MEM (HImode, low_hword_addr);
-+ MEM_COPY_ATTRIBUTES (operands[5], operands[0]);
-+ }")
-+
-+; If we're writing memory and we've not found a better way to do this then
-+; try loading into a D register and then copying to memory. This will
-+; perform the fewest possible memory read/writes.
-+;
-+(define_peephole2
-+ [(match_scratch:SI 2 "d")
-+ (set (match_operand:SI 0 "memory_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "! satisfies_constraint_I (operands[1])"
-+ [(set (match_dup 2) (match_dup 1))
-+ (set (match_dup 0) (match_dup 2))]
-+ "")
-+
-+; If we're not dependent on the state of the condition codes we can construct
-+; constants of value (2^n - 1) by using an lsr.4.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(exact_log2 (INTVAL (operands[1]) + 1) > 14
-+ && peep2_regno_dead_p (0, CC_REGNO))"
-+ [(parallel
-+ [(set (match_dup 0)
-+ (lshiftrt:SI (const_int -1)
-+ (match_dup 2)))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "{
-+ operands[2] = GEN_INT (32 - exact_log2 (INTVAL (operands[1]) + 1));
-+ }")
-+
-+; If we're not dependent on the state of the condition codes we can construct
-+; constants of value (2^n - 1) by using an lsr.4.
-+;
-+(define_peephole2
-+ [(match_scratch:SI 2 "d")
-+ (set (match_operand:SI 0 "nonimmediate_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(exact_log2 (INTVAL (operands[1]) + 1) > 14
-+ && peep2_regno_dead_p (0, CC_REGNO))"
-+ [(parallel
-+ [(set (match_dup 2)
-+ (lshiftrt:SI (const_int -1)
-+ (match_dup 3)))
-+ (clobber (reg:CC CC_REGNO))])
-+ (set (match_dup 0)
-+ (match_dup 2))]
-+ "{
-+ operands[3] = GEN_INT (32 - exact_log2 (INTVAL (operands[1]) + 1));
-+ }")
-+
-+; If we're not dependent on the state of the condition codes we can construct
-+; some other constants by using an lsl.4 to shift 7 bits left by some
-+; constant.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(ubicom32_shiftable_const_int (INTVAL (operands[1]))
-+ && peep2_regno_dead_p (0, CC_REGNO))"
-+ [(parallel
-+ [(set (match_dup 0)
-+ (ashift:SI (match_dup 2)
-+ (match_dup 3)))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "{
-+ int shift = ubicom32_shiftable_const_int (INTVAL (operands[1]));
-+ operands[2] = GEN_INT (INTVAL (operands[1]) >> shift);
-+ operands[3] = GEN_INT (shift);
-+ }")
-+
-+; If we're not dependent on the state of the condition codes we can construct
-+; some other constants by using an lsl.4 to shift 7 bits left by some
-+; constant.
-+;
-+(define_peephole2
-+ [(match_scratch:SI 2 "d")
-+ (set (match_operand:SI 0 "nonimmediate_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(ubicom32_shiftable_const_int (INTVAL (operands[1]))
-+ && peep2_regno_dead_p (0, CC_REGNO))"
-+ [(parallel
-+ [(set (match_dup 2)
-+ (ashift:SI (match_dup 3)
-+ (match_dup 4)))
-+ (clobber (reg:CC CC_REGNO))])
-+ (set (match_dup 0)
-+ (match_dup 2))]
-+ "{
-+ int shift = ubicom32_shiftable_const_int (INTVAL (operands[1]));
-+ operands[3] = GEN_INT (INTVAL (operands[1]) >> shift);
-+ operands[4] = GEN_INT (shift);
-+ }")
-+
-+; For some 16-bit unsigned constants that have bit 15 set we can use
-+; swapb.2!
-+;
-+; Note that the movsi code emits the same sequence but by using a peephole2
-+; we split the pattern early enough to allow instruction scheduling to
-+; occur.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(ubicom32_v4
-+ && (INTVAL (operands[1]) & 0xffff80ff) == 0x80ff)"
-+ [(set (match_dup 0)
-+ (zero_extend:SI (bswap:HI (match_dup 2))))]
-+ "{
-+ HOST_WIDE_INT i = INTVAL (operands[1]) >> 8;
-+ if (i >= 0x80)
-+ i -= 0x100;
-+ operands[2] = GEN_INT (i);
-+ }")
-+
-+; In general for a 16-bit unsigned constant that has bit 15 set
-+; then we need a movei/move.2 pair unless we can represent it
-+; via just a move.2.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(INTVAL (operands[1]) & 0xffff8000) == 0x8000
-+ && (INTVAL (operands[1]) & 0xffff) < 0xff80"
-+ [(set (match_dup 2)
-+ (match_dup 1))
-+ (set (match_dup 0)
-+ (zero_extend:SI (match_dup 2)))]
-+ "{
-+ operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));
-+ }")
-+
-+; If we're not dependent on the state of the condition codes we can construct
-+; 32-bit constants that have bits 16 through 31 set to arbitrary values
-+; and have bits 0 through 15 set to something representable as a default
-+; source-1 immediate - we use movei/shmrg.2
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(((INTVAL (operands[1]) >= 0x8000
-+ && INTVAL (operands[1]) < 0xff80)
-+ || INTVAL (operands[1]) >= 0x10000
-+ || INTVAL (operands[1]) < -0x8000)
-+ && ((INTVAL (operands[1]) & 0xffff) >= 0xff80
-+ || (INTVAL (operands[1]) & 0xffff) < 0x80)
-+ && peep2_regno_dead_p (0, CC_REGNO))"
-+ [(set (match_dup 0)
-+ (match_dup 2))
-+ (parallel
-+ [(set (match_dup 0)
-+ (ior:SI
-+ (ashift:SI (match_dup 0)
-+ (const_int 16))
-+ (zero_extend:SI
-+ (match_dup 3))))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "{
-+ operands[2] = gen_highpart_mode (HImode, SImode, operands[1]);
-+ operands[3] = gen_lowpart (HImode, operands[1]);
-+ }")
-+
-+; Exactly the same as the peephole2 preceding except that this targets a
-+; general register instead of D register. Hopefully the later optimization
-+; passes will notice that the value ended up in a D register first here
-+; and eliminate away the other register!
-+;
-+(define_peephole2
-+ [(match_scratch:SI 2 "d")
-+ (set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(((INTVAL (operands[1]) >= 0x8000
-+ && INTVAL (operands[1]) < 0xff80)
-+ || INTVAL (operands[1]) >= 0x10000
-+ || INTVAL (operands[1]) < -0x8000)
-+ && ((INTVAL (operands[1]) & 0xffff) >= 0xff80
-+ || (INTVAL (operands[1]) & 0xffff) < 0x80)
-+ && peep2_regno_dead_p (0, CC_REGNO))"
-+ [(set (match_dup 2)
-+ (match_dup 3))
-+ (parallel
-+ [(set (match_dup 2)
-+ (ior:SI
-+ (ashift:SI (match_dup 2)
-+ (const_int 16))
-+ (zero_extend:SI
-+ (match_dup 4))))
-+ (clobber (reg:CC CC_REGNO))])
-+ (set (match_dup 0)
-+ (match_dup 2))]
-+ "{
-+ operands[3] = gen_highpart_mode (HImode, SImode, operands[1]);
-+ operands[4] = gen_lowpart (HImode, operands[1]);
-+ }")
-+
-+; If we have a load of a large integer constant which does not have bit 31
-+; set and we have a spare A reg then construct it with a moveai/lea.1 pair
-+; instead. This avoids constructing it in 3 instructions on the stack.
-+;
-+; Note that we have to be careful not to match anything that matches
-+; something we can do in a single instruction! There aren't many such
-+; constants but there are some.
-+;
-+(define_peephole2
-+ [(match_scratch:SI 2 "a")
-+ (set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))]
-+ "(! (INTVAL (operands[1]) & 0x80000000)
-+ && ((INTVAL (operands[1]) >= 0x8000
-+ && INTVAL (operands[1]) < 0xff80)
-+ || INTVAL (operands[1]) >= 0x10000))"
-+ [(set (match_dup 2)
-+ (match_dup 3))
-+ (set (match_dup 0)
-+ (plus:SI (match_dup 2)
-+ (match_dup 4)))]
-+ "{
-+ HOST_WIDE_INT i = INTVAL (operands[1]);
-+ operands[3] = GEN_INT (i & 0xffffff80);
-+ operands[4] = GEN_INT (i & 0x7f);
-+ }")
-+
-+; If we're not dependent on the state of the condition codes we can construct
-+; a 32-bit constant with a movei/movei/shmrg.2 sequence if possible.
-+;
-+(define_peephole2
-+ [(match_scratch:HI 2 "d")
-+ (set (match_operand:SI 0 "ubicom32_data_register_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))
-+ (match_dup 2)]
-+ "(INTVAL (operands[1]) & 0x80000000
-+ && INTVAL (operands[1]) < -0x8000
-+ && peep2_regno_dead_p (0, CC_REGNO))"
-+ [(set (match_dup 0)
-+ (match_dup 3))
-+ (set (match_dup 2)
-+ (match_dup 4))
-+ (parallel
-+ [(set (match_dup 0)
-+ (ior:SI
-+ (ashift:SI (match_dup 0)
-+ (const_int 16))
-+ (zero_extend:SI
-+ (match_dup 2))))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "{
-+ operands[3] = gen_highpart_mode (HImode, SImode, operands[1]);
-+ operands[4] = gen_lowpart (HImode, operands[1]);
-+ }")
-+
-+; Exactly the same as the peephole2 preceding except that this targets a
-+; general register instead of D register. Hopefully the later optimization
-+; passes will notice that the value ended up in a D register first here
-+; and eliminate away the other register!
-+;
-+(define_peephole2
-+ [(match_scratch:SI 2 "d")
-+ (match_scratch:HI 3 "d")
-+ (set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))
-+ (match_dup 3)]
-+ "(INTVAL (operands[1]) & 0x80000000
-+ && INTVAL (operands[1]) < -0x8000
-+ && peep2_regno_dead_p (0, CC_REGNO))"
-+ [(set (match_dup 2)
-+ (match_dup 4))
-+ (set (match_dup 3)
-+ (match_dup 5))
-+ (parallel
-+ [(set (match_dup 2)
-+ (ior:SI
-+ (ashift:SI (match_dup 2)
-+ (const_int 16))
-+ (zero_extend:SI
-+ (match_dup 3))))
-+ (clobber (reg:CC CC_REGNO))])
-+ (set (match_dup 0)
-+ (match_dup 2))]
-+ "{
-+ operands[4] = gen_highpart_mode (HImode, SImode, operands[1]);
-+ operands[5] = gen_lowpart (HImode, operands[1]);
-+ }")
-+
-+(define_insn "movsi_fdpic_got_offset"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (match_operand:SI 1 "ubicom32_fdpic_got_offset_operand" "Y"))]
-+ ""
-+ "movei\\t%0, %1")
-+
-+; The explicit MEM inside the UNSPEC prevents the compiler from moving
-+; the load before a branch after a NULL test, or before a store that
-+; initializes a function descriptor.
-+
-+(define_insn_and_split "load_fdpic_funcdesc"
-+ [(set (match_operand:SI 0 "ubicom32_address_register_operand" "=a")
-+ (unspec_volatile:SI [(mem:SI (match_operand:SI 1 "address_operand" "p"))]
-+ UNSPEC_VOLATILE_LOAD_FDPIC_FUNCDESC))]
-+ ""
-+ "#"
-+ "reload_completed"
-+ [(set (match_dup 0)
-+ (mem:SI (match_dup 1)))])
-+
-+; Combiner-generated 32-bit move with the zero flag set accordingly.
-+;
-+(define_insn "movsi_ccwzn"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:SI 0 "nonimmediate_operand" "rm, d")
-+ (const_int 0)))
-+ (set (match_operand:SI 1 "nonimmediate_operand" "=d,rm")
-+ (match_dup 0))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "@
-+ lsl.4\\t%1, %0, #0
-+ add.4\\t%1, #0, %0")
-+
-+; Combiner-generated 32-bit move with all flags set accordingly.
-+;
-+(define_insn "movsi_ccw"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:SI 0 "ubicom32_data_register_operand" "d")
-+ (const_int 0)))
-+ (set (match_operand:SI 1 "nonimmediate_operand" "=rm")
-+ (match_dup 0))]
-+ "ubicom32_match_cc_mode(insn, CCWmode)"
-+ "add.4\\t%1, #0, %0")
-+
-+; Combine isn't very good at merging some types of operations so we
-+; have to make do with a peephole. It's not as effective but it's better
-+; than doing nothing.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "")
-+ (match_operand:SI 1 "nonimmediate_operand" ""))
-+ (parallel
-+ [(set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (match_operator 3 "ubicom32_compare_operator"
-+ [(match_dup 0)
-+ (const_int 0)]))
-+ (clobber (match_operand:SI 4 "ubicom32_data_register_operand" ""))])]
-+ "(GET_MODE (operands[2]) == CCWZNmode
-+ || GET_MODE (operands[2]) == CCWZmode)"
-+ [(parallel
-+ [(set (match_dup 2)
-+ (match_op_dup 3
-+ [(match_dup 1)
-+ (const_int 0)]))
-+ (set (match_dup 0)
-+ (match_dup 1))])]
-+ "")
-+
-+; Combine isn't very good at merging some types of operations so we
-+; have to make do with a peephole. It's not as effective but it's better
-+; than doing nothing.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
-+ (match_operand:SI 1 "ubicom32_data_register_operand" ""))
-+ (parallel
-+ [(set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (match_operator 3 "ubicom32_compare_operator"
-+ [(match_dup 1)
-+ (const_int 0)]))
-+ (clobber (match_operand:SI 4 "ubicom32_data_register_operand" ""))])]
-+ "(GET_MODE (operands[2]) == CCWZNmode
-+ || GET_MODE (operands[2]) == CCWZmode)"
-+ [(parallel
-+ [(set (match_dup 2)
-+ (match_op_dup 3
-+ [(match_dup 1)
-+ (const_int 0)]))
-+ (set (match_dup 0)
-+ (match_dup 1))])]
-+ "")
-+
-+; Combine isn't very good at merging some types of operations so we
-+; have to make do with a peephole. It's not as effective but it's better
-+; than doing nothing.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "nonimmediate_operand" ""))
-+ (parallel
-+ [(set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (match_operator 3 "ubicom32_compare_operator"
-+ [(match_dup 0)
-+ (const_int 0)]))
-+ (set (match_operand:SI 4 "ubicom32_data_register_operand" "")
-+ (match_dup 0))])]
-+ "(peep2_reg_dead_p (2, operands[0])
-+ && (GET_MODE (operands[2]) == CCWZNmode
-+ || GET_MODE (operands[2]) == CCWZmode))"
-+ [(parallel
-+ [(set (match_dup 2)
-+ (match_op_dup 3
-+ [(match_dup 1)
-+ (const_int 0)]))
-+ (set (match_dup 4)
-+ (match_dup 1))])]
-+ "")
-+
-+; Register renaming may make a general reg into a D reg in which case
-+; we may be able to simplify a compare.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "nonimmediate_operand" ""))
-+ (parallel
-+ [(set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (match_operator 3 "ubicom32_compare_operator"
-+ [(match_dup 0)
-+ (const_int 0)]))
-+ (clobber (match_operand:SI 4 "ubicom32_data_register_operand" ""))])]
-+ "(peep2_reg_dead_p (2, operands[0])
-+ && (GET_MODE (operands[2]) == CCWZNmode
-+ || GET_MODE (operands[2]) == CCWZmode))"
-+ [(parallel
-+ [(set (match_dup 2)
-+ (match_op_dup 3
-+ [(match_dup 1)
-+ (const_int 0)]))
-+ (clobber (match_dup 4))])]
-+ "")
-+
-+(define_insn_and_split "movdi"
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
-+ (match_operand:DI 1 "general_operand" "rmi,ri"))]
-+ ""
-+ "#"
-+ "reload_completed"
-+ [(set (match_dup 2) (match_dup 3))
-+ (set (match_dup 4) (match_dup 5))]
-+ "{
-+ rtx dest_low;
-+ rtx src_low;
-+
-+ dest_low = gen_lowpart (SImode, operands[0]);
-+ src_low = gen_lowpart (SImode, operands[1]);
-+
-+ if (REG_P (operands[0])
-+ && REG_P (operands[1])
-+ && REGNO (operands[0]) < REGNO (operands[1]))
-+ {
-+ operands[2] = gen_highpart (SImode, operands[0]);
-+ operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
-+ operands[4] = dest_low;
-+ operands[5] = src_low;
-+ }
-+ else if (reg_mentioned_p (dest_low, src_low))
-+ {
-+ operands[2] = gen_highpart (SImode, operands[0]);
-+ operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
-+ operands[4] = dest_low;
-+ operands[5] = src_low;
-+ }
-+ else
-+ {
-+ operands[2] = dest_low;
-+ operands[3] = src_low;
-+ operands[4] = gen_highpart (SImode, operands[0]);
-+ operands[5] = gen_highpart_mode (SImode, DImode, operands[1]);
-+ }
-+ }"
-+ [(set_attr "length" "8")])
-+
-+; Combiner-generated 64-bit move with all flags set accordingly.
-+;
-+(define_insn "movdi_ccwzn"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:DI 0 "nonimmediate_operand" "d, m, r")
-+ (const_int 0)))
-+ (set (match_operand:DI 1 "nonimmediate_operand" "=&rm,rm,!&rm")
-+ (match_dup 0))
-+ (clobber (match_scratch:SI 2 "=X, d, d"))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "*
-+ {
-+ operands[3] = gen_lowpart (SImode, operands[0]);
-+ operands[4] = gen_lowpart (SImode, operands[1]);
-+ operands[5] = gen_highpart (SImode, operands[0]);
-+ operands[6] = gen_highpart (SImode, operands[1]);
-+
-+ if (ubicom32_data_register_operand (operands[0], VOIDmode))
-+ return \"add.4\\t%4, #0, %3\;addc\\t%6, #0, %5\";
-+
-+ return \"movei\\t%2, #0\;add.4\\t%4, %3, %2\;addc\\t%6, %5, %2\";
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_insn "movdi_ccw"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:DI 0 "nonimmediate_operand" "d, m, r")
-+ (const_int 0)))
-+ (set (match_operand:DI 1 "nonimmediate_operand" "=&rm,rm,!&rm")
-+ (match_dup 0))
-+ (clobber (match_scratch:SI 2 "=X, d, d"))]
-+ "ubicom32_match_cc_mode(insn, CCWmode)"
-+ "*
-+ {
-+ operands[3] = gen_lowpart (SImode, operands[0]);
-+ operands[4] = gen_lowpart (SImode, operands[1]);
-+ operands[5] = gen_highpart (SImode, operands[0]);
-+ operands[6] = gen_highpart (SImode, operands[1]);
-+
-+ if (ubicom32_data_register_operand (operands[0], VOIDmode))
-+ return \"add.4\\t%4, #0, %3\;addc\\t%6, #0, %5\";
-+
-+ return \"movei\\t%2, #0\;add.4\\t%4, %3, %2\;addc\\t%6, %5, %2\";
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_insn "movsf"
-+ [(set (match_operand:SF 0 "nonimmediate_operand" "=!d,*rm")
-+ (match_operand:SF 1 "ubicom32_move_operand" "rmF,rmF"))]
-+ ""
-+ "*
-+ {
-+ if (GET_CODE (operands[1]) == CONST_DOUBLE)
-+ {
-+ HOST_WIDE_INT val;
-+ REAL_VALUE_TYPE rv;
-+
-+ REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
-+ REAL_VALUE_TO_TARGET_SINGLE (rv, val);
-+
-+ ubicom32_emit_move_const_int (operands[0], GEN_INT (val));
-+ return \"\";
-+ }
-+
-+ return \"move.4\\t%0, %1\";
-+ }")
-+
-+(define_insn "zero_extendqihi2"
-+ [(set (match_operand:HI 0 "register_operand" "=r")
-+ (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
-+ ""
-+ "move.1\\t%0, %1")
-+
-+(define_insn "zero_extendqisi2"
-+ [(set (match_operand:SI 0 "register_operand" "=r")
-+ (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
-+ ""
-+ "move.1\\t%0, %1")
-+
-+(define_insn "zero_extendqisi2_ccwz_1"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "rm"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (zero_extend:SI (match_dup 1)))]
-+ "ubicom32_match_cc_mode(insn, CCWZmode)"
-+ "shmrg.1\\t%0, %1, #0")
-+
-+(define_insn "zero_extendhisi2"
-+ [(set (match_operand:SI 0 "register_operand" "=r")
-+ (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
-+ ""
-+ "move.2\\t%0, %1")
-+
-+(define_insn "zero_extendhisi2_ccwz_1"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (zero_extend:SI (match_dup 1)))]
-+ "ubicom32_match_cc_mode(insn, CCWZmode)"
-+ "shmrg.2\\t%0, %1, #0")
-+
-+(define_insn_and_split "zero_extendqidi2"
-+ [(set (match_operand:DI 0 "register_operand" "=r")
-+ (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
-+ ""
-+ "#"
-+ "reload_completed"
-+ [(set (match_dup 2)
-+ (zero_extend:SI (match_dup 1)))
-+ (set (match_dup 3)
-+ (const_int 0))]
-+ "{
-+ operands[2] = gen_lowpart (SImode, operands[0]);
-+ operands[3] = gen_highpart (SImode, operands[0]);
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_insn_and_split "zero_extendhidi2"
-+ [(set (match_operand:DI 0 "register_operand" "=r")
-+ (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
-+ ""
-+ "#"
-+ "reload_completed"
-+ [(set (match_dup 2)
-+ (zero_extend:SI (match_dup 1)))
-+ (set (match_dup 3)
-+ (const_int 0))]
-+ "{
-+ operands[2] = gen_lowpart (SImode, operands[0]);
-+ operands[3] = gen_highpart (SImode, operands[0]);
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_insn_and_split "zero_extendsidi2"
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
-+ (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
-+ ""
-+ "#"
-+ "reload_completed"
-+ [(set (match_dup 2)
-+ (match_dup 1))
-+ (set (match_dup 3)
-+ (const_int 0))]
-+ "{
-+ operands[2] = gen_lowpart (SImode, operands[0]);
-+ operands[3] = gen_highpart (SImode, operands[0]);
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_insn "extendqihi2"
-+ [(set (match_operand:HI 0 "register_operand" "=r")
-+ (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "rm")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "ext.1\\t%0, %1")
-+
-+(define_insn "extendqisi2"
-+ [(set (match_operand:SI 0 "register_operand" "=r")
-+ (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "rm")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "ext.1\\t%0, %1")
-+
-+(define_insn "extendhisi2"
-+ [(set (match_operand:SI 0 "register_operand" "=r")
-+ (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "ext.2\\t%0, %1")
-+
-+(define_insn_and_split "extendsidi2"
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "=d")
-+ (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "#"
-+ "reload_completed"
-+ [(set (match_dup 2)
-+ (match_dup 1))
-+ (parallel
-+ [(set (match_dup 3)
-+ (ashiftrt:SI (match_dup 2)
-+ (const_int 31)))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "{
-+ operands[2] = gen_lowpart (SImode, operands[0]);
-+ operands[3] = gen_highpart (SImode, operands[0]);
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_insn "bswaphi"
-+ [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
-+ (bswap:HI (match_operand:HI 1 "ubicom32_arith_operand" "rmI")))]
-+ "(ubicom32_v4)"
-+ "swapb.2\\t%0, %1");
-+
-+(define_insn "bswaphisi"
-+ [(set (match_operand:SI 0 "register_operand" "=r")
-+ (zero_extend:SI
-+ (bswap:HI (match_operand:HI 1 "ubicom32_arith_operand" "rmI"))))]
-+ "(ubicom32_v4)"
-+ "swapb.2\\t%0, %1");
-+
-+(define_insn "bswapsi"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (bswap:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")))]
-+ "(ubicom32_v4)"
-+ "swapb.4\\t%0, %1");
-+
-+(define_insn "tstqi_ext1"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:QI 0 "nonimmediate_operand" "rm")
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "ext.1\\t#0, %0")
-+
-+(define_expand "cmpqi"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:QI 0 "ubicom32_arith_operand" "")
-+ (match_operand:QI 1 "ubicom32_data_register_operand" "")))]
-+ "(ubicom32_v4)"
-+ "{
-+ ubicom32_compare_op0 = operands[0];
-+ ubicom32_compare_op1 = operands[1];
-+ DONE;
-+ }")
-+
-+(define_insn "sub1_ccs"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:QI 0 "ubicom32_arith_operand" "rmI")
-+ (match_operand:QI 1 "ubicom32_data_register_operand" "d")))]
-+ "(ubicom32_v4)"
-+ "sub.1\\t#0, %0, %1")
-+
-+; If we're testing for equality we don't have to worry about reversing conditions.
-+;
-+(define_insn "sub1_ccsz_1"
-+ [(set (reg:CCSZ CC_REGNO)
-+ (compare:CCSZ (match_operand:QI 0 "nonimmediate_operand" "rm")
-+ (match_operand:QI 1 "ubicom32_data_register_operand" "d")))]
-+ "(ubicom32_v4)"
-+ "sub.1\\t#0, %0, %1")
-+
-+(define_insn "sub1_ccsz_2"
-+ [(set (reg:CCSZ CC_REGNO)
-+ (compare:CCSZ (match_operand:QI 0 "ubicom32_data_register_operand" "d")
-+ (match_operand:QI 1 "ubicom32_arith_operand" "rmI")))]
-+ "(ubicom32_v4)"
-+ "sub.1\\t#0, %1, %0")
-+
-+; When the combiner runs it doesn't have any insight into whether or not an argument
-+; to a compare is spilled to the stack and therefore can't swap the comparison in
-+; an attempt to use sub.1 more effectively. We peephole this case here.
-+;
-+(define_peephole2
-+ [(set (match_operand:QI 0 "register_operand" "")
-+ (match_operand:QI 1 "ubicom32_arith_operand" ""))
-+ (set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (compare (match_operand:QI 3 "ubicom32_data_register_operand" "")
-+ (match_dup 0)))
-+ (set (pc)
-+ (if_then_else (match_operator 4 "comparison_operator"
-+ [(match_dup 2)
-+ (const_int 0)])
-+ (label_ref (match_operand 5 "" ""))
-+ (pc)))]
-+ "(peep2_reg_dead_p (2, operands[0])
-+ && peep2_regno_dead_p (3, CC_REGNO))"
-+ [(set (match_dup 2)
-+ (compare (match_dup 1)
-+ (match_dup 3)))
-+ (set (pc)
-+ (if_then_else (match_op_dup 6
-+ [(match_dup 2)
-+ (const_int 0)])
-+ (label_ref (match_dup 5))
-+ (pc)))]
-+ "{
-+ rtx cc_reg;
-+
-+ cc_reg = gen_rtx_REG (GET_MODE (operands[2]), CC_REGNO);
-+ operands[6] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[4])),
-+ GET_MODE (operands[4]),
-+ cc_reg,
-+ const0_rtx);
-+ }")
-+
-+(define_insn "tsthi_ext2"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:HI 0 "nonimmediate_operand" "rm")
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "ext.2\\t#0, %0")
-+
-+(define_expand "cmphi"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:HI 0 "ubicom32_arith_operand" "")
-+ (match_operand:HI 1 "ubicom32_compare_operand" "")))]
-+ ""
-+ "{
-+ do
-+ {
-+ /* Is this a cmpi? */
-+ if (CONST_INT_P (operands[1]))
-+ break;
-+
-+ /* Must be a sub.2 - if necessary copy an operand into a reg. */
-+ if (! ubicom32_data_register_operand (operands[1], HImode))
-+ operands[1] = copy_to_mode_reg (HImode, operands[1]);
-+ }
-+ while (0);
-+
-+ ubicom32_compare_op0 = operands[0];
-+ ubicom32_compare_op1 = operands[1];
-+ DONE;
-+ }")
-+
-+(define_insn "cmpi"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:HI 0 "nonimmediate_operand" "rm")
-+ (match_operand 1 "const_int_operand" "N")))]
-+ ""
-+ "cmpi\\t%0, %1")
-+
-+(define_insn "sub2_ccs"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:HI 0 "ubicom32_arith_operand" "rmI")
-+ (match_operand:HI 1 "ubicom32_data_register_operand" "d")))]
-+ ""
-+ "sub.2\\t#0, %0, %1")
-+
-+; If we're testing for equality we don't have to worry about reversing conditions.
-+;
-+(define_insn "sub2_ccsz_1"
-+ [(set (reg:CCSZ CC_REGNO)
-+ (compare:CCSZ (match_operand:HI 0 "nonimmediate_operand" "rm")
-+ (match_operand:HI 1 "ubicom32_data_register_operand" "d")))]
-+ ""
-+ "sub.2\\t#0, %0, %1")
-+
-+(define_insn "sub2_ccsz_2"
-+ [(set (reg:CCSZ CC_REGNO)
-+ (compare:CCSZ (match_operand:HI 0 "ubicom32_data_register_operand" "d")
-+ (match_operand:HI 1 "ubicom32_arith_operand" "rmI")))]
-+ ""
-+ "sub.2\\t#0, %1, %0")
-+
-+; When the combiner runs it doesn't have any insight into whether or not an argument
-+; to a compare is spilled to the stack and therefore can't swap the comparison in
-+; an attempt to use sub.2 more effectively. We peephole this case here.
-+;
-+(define_peephole2
-+ [(set (match_operand:HI 0 "register_operand" "")
-+ (match_operand:HI 1 "ubicom32_arith_operand" ""))
-+ (set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (compare (match_operand:HI 3 "ubicom32_data_register_operand" "")
-+ (match_dup 0)))
-+ (set (pc)
-+ (if_then_else (match_operator 4 "comparison_operator"
-+ [(match_dup 2)
-+ (const_int 0)])
-+ (label_ref (match_operand 5 "" ""))
-+ (pc)))]
-+ "(peep2_reg_dead_p (2, operands[0])
-+ && peep2_regno_dead_p (3, CC_REGNO))"
-+ [(set (match_dup 2)
-+ (compare (match_dup 1)
-+ (match_dup 3)))
-+ (set (pc)
-+ (if_then_else (match_op_dup 6
-+ [(match_dup 2)
-+ (const_int 0)])
-+ (label_ref (match_dup 5))
-+ (pc)))]
-+ "{
-+ rtx cc_reg;
-+
-+ cc_reg = gen_rtx_REG (GET_MODE (operands[2]), CC_REGNO);
-+ operands[6] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[4])),
-+ GET_MODE (operands[4]),
-+ cc_reg,
-+ const0_rtx);
-+ }")
-+
-+(define_insn_and_split "tstsi_lsl4"
-+ [(set (match_operand 0 "ubicom32_cc_register_operand" "=r")
-+ (match_operator 1 "ubicom32_compare_operator"
-+ [(match_operand:SI 2 "nonimmediate_operand" "rm")
-+ (const_int 0)]))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "#"
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ [(parallel
-+ [(set (match_dup 0)
-+ (match_op_dup 1
-+ [(match_dup 2)
-+ (const_int 0)]))
-+ (clobber (match_dup 3))])]
-+ "{
-+ operands[3] = gen_reg_rtx (SImode);
-+ }")
-+
-+(define_insn "tstsi_lsl4_d"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:SI 0 "nonimmediate_operand" "rm")
-+ (const_int 0)))
-+ (clobber (match_operand:SI 1 "ubicom32_data_register_operand" "=d"))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "lsl.4\\t%1, %0, #0")
-+
-+; Comparison for equality with -1.
-+;
-+(define_insn "cmpsi_not4_ccwz"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:SI 0 "nonimmediate_operand" "rm")
-+ (const_int -1)))]
-+ "ubicom32_match_cc_mode(insn, CCWZmode)"
-+ "not.4\\t#0, %0")
-+
-+(define_expand "cmpsi"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:SI 0 "ubicom32_arith_operand" "")
-+ (match_operand:SI 1 "ubicom32_compare_operand" "")))]
-+ ""
-+ "{
-+ do
-+ {
-+ /* Is this a cmpi? We can't take a memory address as cmpi takes
-+ 16-bit operands. */
-+ if (register_operand (operands[0], SImode)
-+ && CONST_INT_P (operands[1])
-+ && satisfies_constraint_N (operands[1]))
-+ break;
-+
-+ /* Must be a sub.4 - if necessary copy an operand into a reg. */
-+ if (! ubicom32_data_register_operand (operands[1], SImode))
-+ operands[1] = copy_to_mode_reg (SImode, operands[1]);
-+ }
-+ while (0);
-+
-+ ubicom32_compare_op0 = operands[0];
-+ ubicom32_compare_op1 = operands[1];
-+ DONE;
-+ }")
-+
-+(define_insn "cmpsi_cmpi"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:SI 0 "register_operand" "r")
-+ (match_operand 1 "const_int_operand" "N")))]
-+ "(satisfies_constraint_N (operands[1]))"
-+ "cmpi\\t%0, %1")
-+
-+(define_insn "cmpsi_sub4"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:SI 0 "ubicom32_arith_operand" "rmI")
-+ (match_operand:SI 1 "ubicom32_data_register_operand" "d")))]
-+ ""
-+ "sub.4\\t#0, %0, %1")
-+
-+; If we're testing for equality we don't have to worry about reversing conditions.
-+;
-+(define_insn "cmpsi_sub4_ccwz_1"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:SI 0 "nonimmediate_operand" "rm")
-+ (match_operand:SI 1 "ubicom32_data_register_operand" "d")))]
-+ "ubicom32_match_cc_mode(insn, CCWZmode)"
-+ "sub.4\\t#0, %0, %1")
-+
-+(define_insn "cmpsi_sub4_ccwz_2"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:SI 0 "ubicom32_data_register_operand" "d")
-+ (match_operand:SI 1 "nonimmediate_operand" "rm")))]
-+ "ubicom32_match_cc_mode(insn, CCWZmode)"
-+ "sub.4\\t#0, %1, %0")
-+
-+; When the combiner runs it doesn't have any insight into whether or not an argument
-+; to a compare is spilled to the stack and therefore can't swap the comparison in
-+; an attempt to use sub.4 more effectively. We peephole this case here.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "ubicom32_arith_operand" ""))
-+ (set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (compare (match_operand:SI 3 "ubicom32_data_register_operand" "")
-+ (match_dup 0)))
-+ (set (pc)
-+ (if_then_else (match_operator 4 "comparison_operator"
-+ [(match_dup 2)
-+ (const_int 0)])
-+ (label_ref (match_operand 5 "" ""))
-+ (pc)))]
-+ "(peep2_reg_dead_p (2, operands[0])
-+ && peep2_regno_dead_p (3, CC_REGNO))"
-+ [(set (match_dup 2)
-+ (compare (match_dup 1)
-+ (match_dup 3)))
-+ (set (pc)
-+ (if_then_else (match_op_dup 6
-+ [(match_dup 2)
-+ (const_int 0)])
-+ (label_ref (match_dup 5))
-+ (pc)))]
-+ "{
-+ rtx cc_reg;
-+
-+ cc_reg = gen_rtx_REG (GET_MODE (operands[2]), CC_REGNO);
-+ operands[6] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[4])),
-+ GET_MODE (operands[4]),
-+ cc_reg,
-+ const0_rtx);
-+ }")
-+
-+(define_insn_and_split "tstdi_or4"
-+ [(set (reg:CCWZ CC_REGNO)
-+ (compare:CCWZ (match_operand:DI 0 "nonimmediate_operand" "rm")
-+ (const_int 0)))]
-+ ""
-+ "#"
-+ ""
-+ [(parallel
-+ [(set (reg:CCWZ CC_REGNO)
-+ (compare:CCWZ (match_dup 0)
-+ (const_int 0)))
-+ (clobber (match_dup 1))])]
-+ "{
-+ operands[1] = gen_reg_rtx (SImode);
-+ }")
-+
-+(define_insn "tstdi_or4_d"
-+ [(set (reg:CCWZ CC_REGNO)
-+ (compare:CCWZ (match_operand:DI 0 "nonimmediate_operand" "rm")
-+ (const_int 0)))
-+ (clobber (match_operand:SI 1 "ubicom32_data_register_operand" "=d"))]
-+ ""
-+ "*
-+ {
-+ operands[2] = gen_lowpart (SImode, operands[0]);
-+ operands[3] = gen_highpart_mode (SImode, DImode, operands[0]);
-+
-+ if (ubicom32_data_register_operand (operands[0], GET_MODE (operands[0])))
-+ return \"or.4\\t#0, %2, %3\";
-+
-+ return \"move.4\\t%1, %2\;or.4\\t%1, %3, %1\";
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_expand "cmpdi"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:DI 0 "ubicom32_arith_operand" "")
-+ (match_operand:DI 1 "ubicom32_data_register_operand" "")))]
-+ ""
-+ "{
-+ ubicom32_compare_op0 = operands[0];
-+ ubicom32_compare_op1 = operands[1];
-+ DONE;
-+ }")
-+
-+(define_insn "cmpdi_sub4subc"
-+ [(set (reg CC_REGNO)
-+ (compare (match_operand:DI 0 "ubicom32_arith_operand" "rmI")
-+ (match_operand:DI 1 "ubicom32_data_register_operand" "d")))]
-+ ""
-+ "*
-+ {
-+ operands[2] = gen_lowpart (SImode, operands[0]);
-+ operands[3] = gen_lowpart (SImode, operands[1]);
-+ operands[4] = gen_highpart_mode (SImode, DImode, operands[0]);
-+ operands[5] = gen_highpart_mode (SImode, DImode, operands[1]);
-+
-+ return \"sub.4\\t#0, %2, %3\;subc\\t#0, %4, %5\";
-+ }"
-+ [(set_attr "length" "8")])
-+
-+; When the combiner runs it doesn't have any insight into whether or not an argument
-+; to a compare is spilled to the stack and therefore can't swap the comparison in
-+; an attempt to use sub.4/subc more effectively. We peephole this case here.
-+;
-+(define_peephole2
-+ [(set (match_operand:DI 0 "register_operand" "")
-+ (match_operand:DI 1 "ubicom32_arith_operand" ""))
-+ (set (match_operand 2 "ubicom32_cc_register_operand" "")
-+ (compare (match_operand:DI 3 "ubicom32_data_register_operand" "")
-+ (match_dup 0)))
-+ (set (pc)
-+ (if_then_else (match_operator 4 "comparison_operator"
-+ [(match_dup 2)
-+ (const_int 0)])
-+ (label_ref (match_operand 5 "" ""))
-+ (pc)))]
-+ "(peep2_reg_dead_p (2, operands[0])
-+ && peep2_regno_dead_p (3, CC_REGNO))"
-+ [(set (match_dup 2)
-+ (compare (match_dup 1)
-+ (match_dup 3)))
-+ (set (pc)
-+ (if_then_else (match_op_dup 6
-+ [(match_dup 2)
-+ (const_int 0)])
-+ (label_ref (match_dup 5))
-+ (pc)))]
-+ "{
-+ rtx cc_reg;
-+
-+ cc_reg = gen_rtx_REG (GET_MODE (operands[2]), CC_REGNO);
-+ operands[6] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[4])),
-+ GET_MODE (operands[4]),
-+ cc_reg,
-+ const0_rtx);
-+ }")
-+
-+(define_insn "btst"
-+ [(set (reg:CCWZ CC_REGNO)
-+ (compare:CCWZ
-+ (zero_extract:SI
-+ (match_operand:SI 0 "nonimmediate_operand" "rm")
-+ (const_int 1)
-+ (match_operand:SI 1 "ubicom32_arith_operand" "dM"))
-+ (const_int 0)))]
-+ ""
-+ "btst\\t%0, %1")
-+
-+(define_insn "bfextu_ccwz_null"
-+ [(set (reg:CCWZ CC_REGNO)
-+ (compare:CCWZ
-+ (zero_extract:SI
-+ (match_operand:SI 0 "nonimmediate_operand" "rm")
-+ (match_operand 1 "const_int_operand" "M")
-+ (const_int 0))
-+ (const_int 0)))
-+ (clobber (match_scratch:SI 2 "=d"))]
-+ ""
-+ "bfextu\\t%2, %0, %1")
-+
-+(define_expand "addqi3"
-+ [(parallel
-+ [(set (match_operand:QI 0 "memory_operand" "")
-+ (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
-+ (match_operand:QI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "(ubicom32_v4)"
-+ "{
-+ if (!memory_operand (operands[0], QImode))
-+ FAIL;
-+
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (QImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (QImode, operands[2]);
-+ }")
-+
-+(define_insn "addqi3_add1"
-+ [(set (match_operand:QI 0 "memory_operand" "=m, m")
-+ (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:QI 2 "ubicom32_arith_operand" "rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4)"
-+ "@
-+ add.1\\t%0, %2, %1
-+ add.1\\t%0, %1, %2")
-+
-+(define_insn "addqi3_add1_ccszn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (neg:QI (match_operand:QI 0 "nonimmediate_operand" "%d,rm"))
-+ (match_operand:QI 1 "ubicom32_arith_operand" "rmI, d")))]
-+ "(ubicom32_v4
-+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
-+ "@
-+ add.1\\t#0, %1, %0
-+ add.1\\t#0, %0, %1")
-+
-+(define_expand "addhi3"
-+ [(parallel
-+ [(set (match_operand:HI 0 "memory_operand" "")
-+ (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
-+ (match_operand:HI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ ""
-+ "{
-+ if (!memory_operand (operands[0], HImode))
-+ FAIL;
-+
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (HImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (HImode, operands[2]);
-+ }")
-+
-+(define_insn "addhi3_add2"
-+ [(set (match_operand:HI 0 "memory_operand" "=m, m")
-+ (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:HI 2 "ubicom32_arith_operand" "rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "@
-+ add.2\\t%0, %2, %1
-+ add.2\\t%0, %1, %2")
-+
-+(define_insn "addhi3_add2_ccszn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (neg:HI (match_operand:HI 0 "nonimmediate_operand" "%d,rm"))
-+ (match_operand:HI 1 "ubicom32_arith_operand" "rmI, d")))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "@
-+ add.2\\t#0, %1, %0
-+ add.2\\t#0, %0, %1")
-+
-+(define_expand "addsi3"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
-+ (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
-+ (match_operand:SI 2 "ubicom32_move_operand" "")))]
-+ ""
-+ "{
-+ ubicom32_expand_addsi3 (operands);
-+ DONE;
-+ }")
-+
-+; We start with an instruction pattern that can do all sorts of interesting
-+; things but we split out any uses of lea or pdec instructions because
-+; those instructions don't clobber the condition codes.
-+;
-+(define_insn_and_split "addsi3_1"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm,rm,rm,rm, rm,rm")
-+ (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%a, a, a, a, a, d,rm")
-+ (match_operand:SI 2 "ubicom32_move_operand" "L, K, J, P, d,rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "@
-+ #
-+ #
-+ #
-+ #
-+ #
-+ add.4\\t%0, %2, %1
-+ add.4\\t%0, %1, %2"
-+ "(reload_completed
-+ && ubicom32_address_register_operand (operands[1], GET_MODE (operands[1])))"
-+ [(set (match_dup 0)
-+ (plus:SI (match_dup 1)
-+ (match_dup 2)))]
-+ ""
-+)
-+
-+(define_insn "addsi3_1_ccwzn"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
-+ (plus:SI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "@
-+ add.4\\t%0, %2, %1
-+ add.4\\t%0, %1, %2")
-+
-+(define_insn "addsi3_1_ccwzn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (neg:SI (match_operand:SI 0 "nonimmediate_operand" "%d,rm"))
-+ (match_operand:SI 1 "ubicom32_arith_operand" "rmI, d")))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "@
-+ add.4\\t#0, %1, %0
-+ add.4\\t#0, %0, %1")
-+
-+(define_insn_and_split "addsi3_2"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm,rm,rm,rm,rm")
-+ (plus:SI (match_operand:SI 1 "ubicom32_address_register_operand" "%a, a, a, a, a, a")
-+ (match_operand:SI 2 "ubicom32_move_operand" "L, K, J, P, d, n")))]
-+ ""
-+ "@
-+ lea.4\\t%0, %E2(%1)
-+ lea.2\\t%0, %E2(%1)
-+ lea.1\\t%0, %E2(%1)
-+ pdec\\t%0, %n2(%1)
-+ lea.1\\t%0, (%1,%2)
-+ #"
-+ "(reload_completed
-+ && ! satisfies_constraint_L (operands[2])
-+ && ! satisfies_constraint_K (operands[2])
-+ && ! satisfies_constraint_J (operands[2])
-+ && ! satisfies_constraint_P (operands[2])
-+ && ! ubicom32_data_register_operand (operands[2], GET_MODE (operands[2])))"
-+ [(set (reg:SI AUX_DATA_REGNO)
-+ (match_dup 2))
-+ (set (match_dup 0)
-+ (plus:SI (match_dup 1)
-+ (reg:SI AUX_DATA_REGNO)))]
-+ ""
-+)
-+
-+(define_insn "lea_2"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (plus:SI (mult:SI (match_operand:SI 1 "ubicom32_data_register_operand" "d")
-+ (const_int 2))
-+ (match_operand:SI 2 "ubicom32_address_register_operand" "a")))]
-+ ""
-+ "lea.2\\t%0, (%2,%1)")
-+
-+(define_insn "lea_4"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (plus:SI (mult:SI (match_operand:SI 1 "ubicom32_data_register_operand" "d")
-+ (const_int 4))
-+ (match_operand:SI 2 "ubicom32_address_register_operand" "a")))]
-+ ""
-+ "lea.4\\t%0, (%2,%1)")
-+
-+(define_expand "adddi3"
-+ [(parallel
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "")
-+ (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
-+ (match_operand:DI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ ""
-+ "{
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (DImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (DImode, operands[2]);
-+ }")
-+
-+; We construct a 64-bit add from 32-bit operations. Note that we use the
-+; & constraint to prevent overlapping registers being allocated. We do
-+; allow identical registers though as that won't break anything.
-+;
-+(define_insn "adddi3_add4addc"
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,&r,rm, d, m, m")
-+ (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%d,rm, 0, 0, d,rm")
-+ (match_operand:DI 2 "ubicom32_arith_operand" "rmI, d, d,rmI,rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "*
-+ {
-+ operands[3] = gen_lowpart (SImode, operands[0]);
-+ operands[4] = gen_lowpart (SImode, operands[1]);
-+ operands[5] = gen_lowpart (SImode, operands[2]);
-+ operands[6] = gen_highpart (SImode, operands[0]);
-+ operands[7] = gen_highpart (SImode, operands[1]);
-+ operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
-+
-+ if (ubicom32_data_register_operand (operands[2], GET_MODE (operands[2])))
-+ return \"add.4\\t%3, %4, %5\;addc\\t%6, %7, %8\";
-+
-+ return \"add.4\\t%3, %5, %4\;addc\\t%6, %8, %7\";
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_insn "adddi3_ccwz"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%d,rm, 0, 0, d,rm")
-+ (match_operand:DI 2 "ubicom32_arith_operand" "rmI, d, d,rmI,rmI, d"))
-+ (const_int 0)))
-+ (set (match_operand:DI 0 "nonimmediate_operand" "=&r,&r,rm, d, m, m")
-+ (plus:DI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "*
-+ {
-+ operands[3] = gen_lowpart (SImode, operands[0]);
-+ operands[6] = gen_highpart (SImode, operands[0]);
-+
-+ if (ubicom32_data_register_operand (operands[1], GET_MODE (operands[1])))
-+ {
-+ operands[4] = gen_lowpart (SImode, operands[1]);
-+ operands[5] = gen_lowpart (SImode, operands[2]);
-+ operands[7] = gen_highpart (SImode, operands[1]);
-+ operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
-+ }
-+ else
-+ {
-+ operands[4] = gen_lowpart (SImode, operands[2]);
-+ operands[5] = gen_lowpart (SImode, operands[1]);
-+ operands[7] = gen_highpart (SImode, operands[2]);
-+ operands[8] = gen_highpart (SImode, operands[1]);
-+ }
-+
-+ return \"add.4\\t%3, %5, %4\;addc\\t%6, %8, %7\";
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_insn "adddi3_ccwz_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (neg:DI (match_operand:DI 0 "nonimmediate_operand" "%d,rm"))
-+ (match_operand:DI 1 "ubicom32_arith_operand" "rmI, d")))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "*
-+ {
-+ if (ubicom32_data_register_operand (operands[0], GET_MODE (operands[0])))
-+ {
-+ operands[2] = gen_lowpart (SImode, operands[0]);
-+ operands[3] = gen_lowpart (SImode, operands[1]);
-+ operands[4] = gen_highpart (SImode, operands[0]);
-+ operands[5] = gen_highpart_mode (SImode, DImode, operands[1]);
-+ }
-+ else
-+ {
-+ operands[2] = gen_lowpart (SImode, operands[1]);
-+ operands[3] = gen_lowpart (SImode, operands[0]);
-+ operands[4] = gen_highpart (SImode, operands[1]);
-+ operands[5] = gen_highpart (SImode, operands[0]);
-+ }
-+
-+ return \"add.4\\t#0, %3, %2\;addc\\t#0, %5, %4\";
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_expand "subqi3"
-+ [(parallel
-+ [(set (match_operand:QI 0 "memory_operand" "")
-+ (minus:QI (match_operand:QI 1 "ubicom32_arith_operand" "")
-+ (match_operand:QI 2 "ubicom32_data_register_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "(ubicom32_v4)"
-+ "{
-+ if (!memory_operand (operands[0], QImode))
-+ FAIL;
-+ }")
-+
-+(define_insn "subqi3_sub1"
-+ [(set (match_operand:QI 0 "memory_operand" "=m")
-+ (minus:QI (match_operand:QI 1 "ubicom32_arith_operand" "rmI")
-+ (match_operand:QI 2 "ubicom32_data_register_operand" "d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4)"
-+ "sub.1\\t%0, %1, %2")
-+
-+(define_expand "subhi3"
-+ [(parallel
-+ [(set (match_operand:HI 0 "memory_operand" "")
-+ (minus:HI (match_operand:HI 1 "ubicom32_arith_operand" "")
-+ (match_operand:HI 2 "ubicom32_data_register_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "(ubicom32_v4)"
-+ "{
-+ if (!memory_operand (operands[0], HImode))
-+ FAIL;
-+ }")
-+
-+(define_insn "subhi3_sub2"
-+ [(set (match_operand:HI 0 "memory_operand" "=m")
-+ (minus:HI (match_operand:HI 1 "ubicom32_arith_operand" "rmI")
-+ (match_operand:HI 2 "ubicom32_data_register_operand" "d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "sub.2\\t%0, %1, %2")
-+
-+(define_insn "subsi3"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (minus:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")
-+ (match_operand:SI 2 "ubicom32_data_register_operand" "d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "sub.4\\t%0, %1, %2")
-+
-+(define_insn "subsi3_ccwz"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (minus:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")
-+ (match_operand:SI 2 "ubicom32_data_register_operand" "d"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (minus:SI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "sub.4\\t%0, %1, %2")
-+
-+; We construct a 64-bit add from 32-bit operations. Note that we use the
-+; & constraint to prevent overlapping registers being allocated. We do
-+; allow identical registers though as that won't break anything.
-+;
-+(define_insn "subdi3"
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,r, d, m")
-+ (minus:DI (match_operand:DI 1 "ubicom32_arith_operand" "rmI,0,rmI,rmI")
-+ (match_operand:DI 2 "ubicom32_data_register_operand" "d,d, 0, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "*
-+ {
-+ operands[3] = gen_lowpart (SImode, operands[0]);
-+ operands[4] = gen_lowpart (SImode, operands[1]);
-+ operands[5] = gen_lowpart (SImode, operands[2]);
-+ operands[6] = gen_highpart (SImode, operands[0]);
-+ operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
-+ operands[8] = gen_highpart (SImode, operands[2]);
-+
-+ return \"sub.4\\t%3, %4, %5\;subc\\t%6, %7, %8\";
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_insn "subdi3_ccwz"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (minus:DI (match_operand:DI 1 "ubicom32_arith_operand" "rmI,rmI")
-+ (match_operand:DI 2 "ubicom32_data_register_operand" "d, d"))
-+ (const_int 0)))
-+ (set (match_operand:DI 0 "nonimmediate_operand" "=&r, m")
-+ (minus:DI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "*
-+ {
-+ operands[3] = gen_lowpart (SImode, operands[0]);
-+ operands[4] = gen_lowpart (SImode, operands[1]);
-+ operands[5] = gen_lowpart (SImode, operands[2]);
-+ operands[6] = gen_highpart (SImode, operands[0]);
-+ operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
-+ operands[8] = gen_highpart (SImode, operands[2]);
-+
-+ return \"sub.4\\t%3, %4, %5\;subc\\t%6, %7, %8\";
-+ }"
-+ [(set_attr "length" "8")])
-+
-+;(define_insn "negqi2"
-+; [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
-+; (neg:QI (match_operand:QI 1 "ubicom32_data_register_operand" "d")))
-+; (clobber (reg:CC CC_REGNO))]
-+; "(ubicom32_v4)"
-+; "sub.1\\t%0, #0, %1")
-+
-+;(define_insn "neghi2"
-+; [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
-+; (neg:HI (match_operand:HI 1 "ubicom32_data_register_operand" "d")))
-+; (clobber (reg:CC CC_REGNO))]
-+; ""
-+; "sub.2\\t%0, #0, %1")
-+
-+(define_insn "negsi2"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (neg:SI (match_operand:SI 1 "ubicom32_data_register_operand" "d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "sub.4\\t%0, #0, %1")
-+
-+(define_insn_and_split "negdi2"
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "=&rm")
-+ (neg:DI (match_operand:DI 1 "ubicom32_data_register_operand" "d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "#"
-+ "reload_completed"
-+ [(parallel [(set (match_dup 0)
-+ (minus:DI (const_int 0)
-+ (match_dup 1)))
-+ (clobber (reg:CC CC_REGNO))])]
-+ ""
-+ [(set_attr "length" "8")])
-+
-+(define_insn "umulhisi3"
-+ [(set (match_operand:SI 0 "ubicom32_acc_lo_register_operand" "=l, l")
-+ (mult:SI
-+ (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "%d,rm"))
-+ (zero_extend:SI (match_operand:HI 2 "nonimmediate_operand" "rm, d"))))
-+ (clobber (reg:HI ACC0_HI_REGNO))
-+ (clobber (reg:HI ACC1_HI_REGNO))]
-+ ""
-+ "@
-+ mulu\\t%A0, %2, %1
-+ mulu\\t%A0, %1, %2"
-+ [(set_attr "type" "mul,mul")])
-+
-+(define_insn "mulhisi3"
-+ [(set (match_operand:SI 0 "ubicom32_acc_lo_register_operand" "=l, l")
-+ (mult:SI
-+ (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "%d,rm"))
-+ (sign_extend:SI (match_operand:HI 2 "nonimmediate_operand" "rm, d"))))
-+ (clobber (reg:HI ACC0_HI_REGNO))
-+ (clobber (reg:HI ACC1_HI_REGNO))]
-+ ""
-+ "@
-+ muls\\t%A0, %2, %1
-+ muls\\t%A0, %1, %2"
-+ [(set_attr "type" "mul,mul")])
-+
-+(define_expand "mulsi3"
-+ [(set (match_operand:SI 0 "ubicom32_acc_hi_register_operand" "")
-+ (mult:SI (match_operand:SI 1 "ubicom32_arith_operand" "")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "")))]
-+ ""
-+ "{
-+ if (ubicom32_emit_mult_sequence (operands))
-+ DONE;
-+ }")
-+
-+(define_insn "umulsidi3"
-+ [(set (match_operand:DI 0 "ubicom32_acc_hi_register_operand" "=h, h")
-+ (mult:DI
-+ (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%d,rm"))
-+ (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm, d"))))]
-+ "(ubicom32_v4)"
-+ "@
-+ mulu.4\\t%A0, %2, %1
-+ mulu.4\\t%A0, %1, %2"
-+ [(set_attr "type" "mul,mul")])
-+
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "nonimmediate_operand" ""))
-+ (set (match_operand:DI 2 "ubicom32_acc_hi_register_operand" "")
-+ (mult:DI
-+ (zero_extend:DI (match_dup 0))
-+ (zero_extend:DI (match_operand:SI 3 "ubicom32_data_register_operand" ""))))]
-+ "(peep2_reg_dead_p (2, operands[0])
-+ || REGNO (operands[0]) == REGNO (operands[2])
-+ || REGNO (operands[0]) == REGNO (operands[2]) + 1)
-+ && ! rtx_equal_p (operands[0], operands[3])"
-+ [(set (match_dup 2)
-+ (mult:DI
-+ (zero_extend:DI (match_dup 1))
-+ (zero_extend:DI (match_dup 3))))]
-+ "")
-+
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "nonimmediate_operand" ""))
-+ (set (match_operand:DI 2 "ubicom32_acc_hi_register_operand" "")
-+ (mult:DI
-+ (zero_extend:DI (match_operand:SI 3 "ubicom32_data_register_operand" ""))
-+ (zero_extend:DI (match_dup 0))))]
-+ "(peep2_reg_dead_p (2, operands[0])
-+ || REGNO (operands[0]) == REGNO (operands[2])
-+ || REGNO (operands[0]) == REGNO (operands[2]) + 1)
-+ && ! rtx_equal_p (operands[0], operands[3])"
-+ [(set (match_dup 2)
-+ (mult:DI
-+ (zero_extend:DI (match_dup 1))
-+ (zero_extend:DI (match_dup 3))))]
-+ "")
-+
-+(define_insn "umulsidi3_const"
-+ [(set (match_operand:DI 0 "ubicom32_acc_hi_register_operand" "=h")
-+ (mult:DI
-+ (zero_extend:DI (match_operand:SI 1 "ubicom32_data_register_operand" "%d"))
-+ (match_operand 2 "const_int_operand" "I")))]
-+ "(ubicom32_v4 && satisfies_constraint_I (operands[2]))"
-+ "mulu.4\\t%A0, %2, %1"
-+ [(set_attr "type" "mul")])
-+
-+(define_insn "mulsidi3"
-+ [(set (match_operand:DI 0 "ubicom32_acc_hi_register_operand" "=h, h")
-+ (mult:DI
-+ (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%d,rm"))
-+ (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm, d"))))]
-+ "(ubicom32_v4)"
-+ "@
-+ muls.4\\t%A0, %2, %1
-+ muls.4\\t%A0, %1, %2"
-+ [(set_attr "type" "mul,mul")])
-+
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "nonimmediate_operand" ""))
-+ (set (match_operand:DI 2 "ubicom32_acc_hi_register_operand" "")
-+ (mult:DI
-+ (sign_extend:DI (match_dup 0))
-+ (sign_extend:DI (match_operand:SI 3 "ubicom32_data_register_operand" ""))))]
-+ "(peep2_reg_dead_p (2, operands[0])
-+ || REGNO (operands[0]) == REGNO (operands[2])
-+ || REGNO (operands[0]) == REGNO (operands[2]) + 1)
-+ && ! rtx_equal_p (operands[0], operands[3])"
-+ [(set (match_dup 2)
-+ (mult:DI
-+ (sign_extend:DI (match_dup 1))
-+ (sign_extend:DI (match_dup 3))))]
-+ "")
-+
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "nonimmediate_operand" ""))
-+ (set (match_operand:DI 2 "ubicom32_acc_hi_register_operand" "")
-+ (mult:DI
-+ (sign_extend:DI (match_operand:SI 3 "ubicom32_data_register_operand" ""))
-+ (sign_extend:DI (match_dup 0))))]
-+ "(peep2_reg_dead_p (2, operands[0])
-+ || REGNO (operands[0]) == REGNO (operands[2])
-+ || REGNO (operands[0]) == REGNO (operands[2]) + 1)
-+ && ! rtx_equal_p (operands[0], operands[3])"
-+ [(set (match_dup 2)
-+ (mult:DI
-+ (sign_extend:DI (match_dup 1))
-+ (sign_extend:DI (match_dup 3))))]
-+ "")
-+
-+(define_insn "mulsidi3_const"
-+ [(set (match_operand:DI 0 "ubicom32_acc_hi_register_operand" "=h")
-+ (mult:DI
-+ (sign_extend:DI (match_operand:SI 1 "ubicom32_data_register_operand" "%d"))
-+ (match_operand 2 "const_int_operand" "I")))]
-+ "(ubicom32_v4 && satisfies_constraint_I (operands[2]))"
-+ "muls.4\\t%A0, %2, %1"
-+ [(set_attr "type" "mul")])
-+
-+(define_expand "andqi3"
-+ [(parallel
-+ [(set (match_operand:QI 0 "memory_operand" "")
-+ (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
-+ (match_operand:QI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "(ubicom32_v4)"
-+ "{
-+ if (!memory_operand (operands[0], QImode))
-+ FAIL;
-+
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (QImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (QImode, operands[2]);
-+ }")
-+
-+(define_insn "andqi3_and1"
-+ [(set (match_operand:QI 0 "memory_operand" "=m, m")
-+ (and:QI (match_operand:QI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:QI 2 "ubicom32_arith_operand" "rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4)"
-+ "@
-+ and.1\\t%0, %2, %1
-+ and.1\\t%0, %1, %2")
-+
-+(define_insn "andqi3_and1_ccszn"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (and:QI (match_operand:QI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:QI 2 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))
-+ (set (match_operand:QI 0 "memory_operand" "=m, m")
-+ (and:QI (match_dup 1)
-+ (match_dup 2)))]
-+ "(ubicom32_v4
-+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
-+ "@
-+ and.1\\t%0, %2, %1
-+ and.1\\t%0, %1, %2")
-+
-+(define_insn "andqi3_and1_ccszn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (and:QI (match_operand:QI 0 "nonimmediate_operand" "%d,rm")
-+ (match_operand:QI 1 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))]
-+ "(ubicom32_v4
-+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
-+ "@
-+ and.1\\t#0, %1, %0
-+ and.1\\t#0, %0, %1")
-+
-+(define_insn "and1_ccszn_null_1"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:QI
-+ (and:SI (match_operand:SI 0 "ubicom32_data_register_operand" "%d")
-+ (match_operand:SI 1 "ubicom32_arith_operand" "rI"))
-+ 3)
-+ (const_int 0)))]
-+ "(ubicom32_v4
-+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
-+ "and.1\\t#0, %1, %0")
-+
-+(define_insn "and1_ccszn_null_2"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:QI
-+ (and:SI (match_operand:SI 0 "ubicom32_data_register_operand" "d")
-+ (subreg:SI
-+ (match_operand:QI 1 "memory_operand" "m")
-+ 0))
-+ 3)
-+ (const_int 0)))]
-+ "(ubicom32_v4
-+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
-+ "and.1\\t#0, %1, %0")
-+
-+(define_insn "and1_ccszn_null_3"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:QI
-+ (and:SI (subreg:SI
-+ (match_operand:QI 0 "memory_operand" "m")
-+ 0)
-+ (match_operand:SI 1 "ubicom32_data_register_operand" "d"))
-+ 3)
-+ (const_int 0)))]
-+ "(ubicom32_v4
-+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
-+ "and.1\\t#0, %0, %1")
-+
-+(define_expand "andhi3"
-+ [(parallel
-+ [(set (match_operand:HI 0 "memory_operand" "")
-+ (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
-+ (match_operand:HI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ ""
-+ "{
-+ if (!memory_operand (operands[0], HImode))
-+ FAIL;
-+
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (HImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (HImode, operands[2]);
-+ }")
-+
-+(define_insn "andhi3_and2"
-+ [(set (match_operand:HI 0 "memory_operand" "=m, m")
-+ (and:HI (match_operand:HI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:HI 2 "ubicom32_arith_operand" "rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "@
-+ and.2\\t%0, %2, %1
-+ and.2\\t%0, %1, %2")
-+
-+(define_insn "andhi3_and2_ccszn"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (and:HI (match_operand:HI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:HI 2 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))
-+ (set (match_operand:HI 0 "memory_operand" "=m, m")
-+ (and:HI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "@
-+ and.2\\t%0, %2, %1
-+ and.2\\t%0, %1, %2")
-+
-+(define_insn "andhi3_and2_ccszn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (and:HI (match_operand:HI 0 "nonimmediate_operand" "%d,rm")
-+ (match_operand:HI 1 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "@
-+ and.2\\t#0, %1, %0
-+ and.2\\t#0, %0, %1")
-+
-+(define_insn "and2_ccszn_null_1"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:HI
-+ (and:SI (match_operand:SI 0 "ubicom32_data_register_operand" "%d")
-+ (match_operand:SI 1 "ubicom32_arith_operand" "rI"))
-+ 2)
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "and.2\\t#0, %1, %0")
-+
-+(define_insn "and2_ccszn_null_2"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:HI
-+ (and:SI (match_operand:SI 0 "ubicom32_data_register_operand" "d")
-+ (subreg:SI
-+ (match_operand:HI 1 "memory_operand" "m")
-+ 0))
-+ 2)
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "and.2\\t#0, %1, %0")
-+
-+(define_insn "and2_ccszn_null_3"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:HI
-+ (and:SI (subreg:SI
-+ (match_operand:HI 0 "memory_operand" "m")
-+ 0)
-+ (match_operand:SI 1 "ubicom32_data_register_operand" "d"))
-+ 2)
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "and.2\\t#0, %0, %1")
-+
-+(define_expand "andsi3"
-+ [(parallel
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
-+ (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
-+ (match_operand:SI 2 "ubicom32_and_or_si3_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ ""
-+ "{
-+ do
-+ {
-+ /* Is this a bfextu? */
-+ if (ubicom32_data_register_operand (operands[0], SImode)
-+ && CONST_INT_P (operands[2])
-+ && exact_log2 (INTVAL (operands[2]) + 1) != -1)
-+ break;
-+
-+ /* Is this a bclr? */
-+ if (CONST_INT_P (operands[2])
-+ && exact_log2 (~INTVAL (operands[2])) != -1)
-+ break;
-+
-+ /* Must be an and.4 */
-+ if (!ubicom32_data_register_operand (operands[1], SImode))
-+ operands[1] = copy_to_mode_reg (SImode, operands[1]);
-+
-+ if (!ubicom32_arith_operand (operands[2], SImode))
-+ operands[2] = copy_to_mode_reg (SImode, operands[2]);
-+ }
-+ while (0);
-+ }")
-+
-+(define_insn "andsi3_bfextu"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (and:SI (match_operand:SI 1 "nonimmediate_operand" "%rm")
-+ (match_operand:SI 2 "const_int_operand" "O")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(satisfies_constraint_O (operands[2]))"
-+ "*
-+ {
-+ operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2]) + 1));
-+
-+ return \"bfextu\\t%0, %1, %3\";
-+ }")
-+
-+(define_insn "andsi3_bfextu_ccwz"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (and:SI (match_operand:SI 1 "nonimmediate_operand" "%rm")
-+ (match_operand:SI 2 "const_int_operand" "O"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (and:SI (match_dup 1)
-+ (match_dup 2)))]
-+ "(satisfies_constraint_O (operands[2])
-+ && ubicom32_match_cc_mode(insn, CCWZmode))"
-+ "*
-+ {
-+ operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2]) + 1));
-+
-+ return \"bfextu\\t%0, %1, %3\";
-+ }")
-+
-+(define_insn "andsi3_bfextu_ccwz_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (and:SI (match_operand:SI 0 "nonimmediate_operand" "%rm")
-+ (match_operand:SI 1 "const_int_operand" "O"))
-+ (const_int 0)))
-+ (clobber (match_scratch:SI 2 "=d"))]
-+ "(satisfies_constraint_O (operands[1])
-+ && ubicom32_match_cc_mode(insn, CCWZmode))"
-+ "*
-+ {
-+ operands[3] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1));
-+
-+ return \"bfextu\\t%2, %0, %3\";
-+ }")
-+
-+(define_insn "andsi3_bclr"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (and:SI (match_operand:SI 1 "ubicom32_arith_operand" "%rmI")
-+ (match_operand:SI 2 "const_int_operand" "n")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(exact_log2 (~INTVAL (operands[2])) != -1)"
-+ "bclr\\t%0, %1, #%D2")
-+
-+(define_insn "andsi3_and4"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
-+ (and:SI (match_operand:SI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "@
-+ and.4\\t%0, %2, %1
-+ and.4\\t%0, %1, %2")
-+
-+(define_insn "andsi3_and4_ccwzn"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (and:SI (match_operand:SI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
-+ (and:SI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "@
-+ and.4\\t%0, %2, %1
-+ and.4\\t%0, %1, %2")
-+
-+(define_insn "andsi3_and4_ccwzn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (and:SI (match_operand:SI 0 "nonimmediate_operand" "%d,rm")
-+ (match_operand:SI 1 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "@
-+ and.4\\t#0, %1, %0
-+ and.4\\t#0, %0, %1")
-+
-+(define_insn "andsi3_lsr4_ccwz_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (and:SI (match_operand:SI 0 "nonimmediate_operand" "%rm")
-+ (match_operand:SI 1 "const_int_operand" "n"))
-+ (const_int 0)))
-+ (clobber (match_scratch:SI 2 "=d"))]
-+ "(exact_log2 ((~(INTVAL (operands[1]))) + 1) != -1
-+ && ubicom32_match_cc_mode(insn, CCWZmode))"
-+ "*
-+ {
-+ operands[3] = GEN_INT (exact_log2 ((~(INTVAL (operands[1]))) + 1));
-+
-+ return \"lsr.4\\t%2, %0, %3\";
-+ }")
-+
-+; We really would like the combiner to recognize this scenario and deal with
-+; it but unfortunately it tries to canonicalize zero_extract ops on MEMs
-+; into QImode operations and we can't match them in any useful way.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (match_operand:SI 1 "const_int_operand" ""))
-+ (set (reg:CCWZ CC_REGNO)
-+ (compare:CCWZ
-+ (and:SI (match_operand:SI 2 "nonimmediate_operand" "")
-+ (match_dup 0))
-+ (const_int 0)))]
-+ "(exact_log2 (INTVAL (operands[1])) != -1
-+ && peep2_reg_dead_p (2, operands[0]))"
-+ [(set (reg:CCWZ CC_REGNO)
-+ (compare:CCWZ
-+ (zero_extract:SI
-+ (match_dup 2)
-+ (const_int 1)
-+ (match_dup 3))
-+ (const_int 0)))]
-+ "{
-+ operands[3] = GEN_INT (exact_log2 (INTVAL (operands[1])));
-+ }")
-+
-+(define_expand "anddi3"
-+ [(parallel
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "")
-+ (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
-+ (match_operand:DI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ ""
-+ "{
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (DImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (DImode, operands[2]);
-+ }")
-+
-+(define_insn_and_split "anddi3_and4"
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,&r, d,rm, m, m")
-+ (and:DI (match_operand:DI 1 "nonimmediate_operand" "%d,rm, 0, 0, d,rm")
-+ (match_operand:DI 2 "ubicom32_arith_operand" "rmI, d,rmI, d,rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "#"
-+ "reload_completed"
-+ [(parallel [(set (match_dup 3)
-+ (and:SI (match_dup 4)
-+ (match_dup 5)))
-+ (clobber (reg:CC CC_REGNO))])
-+ (parallel [(set (match_dup 6)
-+ (and:SI (match_dup 7)
-+ (match_dup 8)))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "{
-+ operands[3] = gen_lowpart (SImode, operands[0]);
-+ operands[4] = gen_lowpart (SImode, operands[1]);
-+ operands[5] = gen_lowpart (SImode, operands[2]);
-+ operands[6] = gen_highpart (SImode, operands[0]);
-+ operands[7] = gen_highpart (SImode, operands[1]);
-+ operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_expand "iorqi3"
-+ [(parallel
-+ [(set (match_operand:QI 0 "memory_operand" "")
-+ (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
-+ (match_operand:QI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "(ubicom32_v4)"
-+ "{
-+ if (!memory_operand (operands[0], QImode))
-+ FAIL;
-+
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (QImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (QImode, operands[2]);
-+ }")
-+
-+(define_insn "iorqi3_or1"
-+ [(set (match_operand:QI 0 "memory_operand" "=m, m")
-+ (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:QI 2 "ubicom32_arith_operand" "rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4)"
-+ "@
-+ or.1\\t%0, %2, %1
-+ or.1\\t%0, %1, %2")
-+
-+(define_expand "iorhi3"
-+ [(parallel
-+ [(set (match_operand:HI 0 "memory_operand" "")
-+ (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
-+ (match_operand:HI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ ""
-+ "{
-+ if (!memory_operand (operands[0], HImode))
-+ FAIL;
-+
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (HImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (HImode, operands[2]);
-+ }")
-+
-+(define_insn "iorhi3_or2"
-+ [(set (match_operand:HI 0 "memory_operand" "=m, m")
-+ (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:HI 2 "ubicom32_arith_operand" "rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "@
-+ or.2\\t%0, %2, %1
-+ or.2\\t%0, %1, %2")
-+
-+(define_expand "iorsi3"
-+ [(parallel
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
-+ (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
-+ (match_operand:SI 2 "ubicom32_and_or_si3_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ ""
-+ "{
-+ do
-+ {
-+ /* Is this a bset? */
-+ if (CONST_INT_P (operands[2])
-+ && exact_log2 (INTVAL (operands[2])) != -1)
-+ break;
-+
-+ /* Must be an or.4 */
-+ if (!ubicom32_data_register_operand (operands[1], SImode))
-+ operands[1] = copy_to_mode_reg (SImode, operands[1]);
-+
-+ if (!ubicom32_arith_operand (operands[2], SImode))
-+ operands[2] = copy_to_mode_reg (SImode, operands[2]);
-+ }
-+ while (0);
-+ }")
-+
-+(define_insn "iorsi3_bset"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (ior:SI (match_operand:SI 1 "ubicom32_arith_operand" "%rmI")
-+ (match_operand 2 "const_int_operand" "n")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(exact_log2 (INTVAL (operands[2])) != -1)"
-+ "bset\\t%0, %1, #%d2")
-+
-+(define_insn "iorsi3_or4"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
-+ (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "@
-+ or.4\\t%0, %2, %1
-+ or.4\\t%0, %1, %2")
-+
-+(define_insn "iorsi3_ccwzn"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
-+ (ior:SI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "@
-+ or.4\\t%0, %2, %1
-+ or.4\\t%0, %1, %2")
-+
-+(define_insn "iorsi3_ccwzn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (ior:SI (match_operand:SI 0 "nonimmediate_operand" "%d,rm")
-+ (match_operand:SI 1 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "@
-+ or.4\\t#0, %1, %0
-+ or.4\\t#0, %0, %1")
-+
-+(define_expand "iordi3"
-+ [(parallel
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "")
-+ (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
-+ (match_operand:DI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ ""
-+ "{
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (DImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (DImode, operands[2]);
-+ }")
-+
-+(define_insn_and_split "iordi3_or4"
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,&r, d,rm, m, m")
-+ (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%d,rm, 0, 0, d,rm")
-+ (match_operand:DI 2 "ubicom32_arith_operand" "rmI, d,rmI, d,rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "#"
-+ "reload_completed"
-+ [(parallel [(set (match_dup 3)
-+ (ior:SI (match_dup 4)
-+ (match_dup 5)))
-+ (clobber (reg:CC CC_REGNO))])
-+ (parallel [(set (match_dup 6)
-+ (ior:SI (match_dup 7)
-+ (match_dup 8)))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "{
-+ operands[3] = gen_lowpart (SImode, operands[0]);
-+ operands[4] = gen_lowpart (SImode, operands[1]);
-+ operands[5] = gen_lowpart (SImode, operands[2]);
-+ operands[6] = gen_highpart (SImode, operands[0]);
-+ operands[7] = gen_highpart (SImode, operands[1]);
-+ operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_expand "xorqi3"
-+ [(parallel
-+ [(set (match_operand:QI 0 "memory_operand" "")
-+ (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
-+ (match_operand:QI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "(ubicom32_v4)"
-+ "{
-+ if (!memory_operand (operands[0], QImode))
-+ FAIL;
-+
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (QImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (QImode, operands[2]);
-+ }")
-+
-+(define_insn "xorqi3_xor1"
-+ [(set (match_operand:QI 0 "memory_operand" "=m, m")
-+ (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:QI 2 "ubicom32_arith_operand" "rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4)"
-+ "@
-+ xor.1\\t%0, %2, %1
-+ xor.1\\t%0, %1, %2")
-+
-+(define_insn "xorqi3_xor1_ccszn"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:QI 2 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))
-+ (set (match_operand:QI 0 "memory_operand" "=m, m")
-+ (xor:QI (match_dup 1)
-+ (match_dup 2)))]
-+ "(ubicom32_v4
-+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
-+ "@
-+ xor.1\\t%0, %2, %1
-+ xor.1\\t%0, %1, %2")
-+
-+(define_insn "xorqi3_xor1_ccszn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (xor:QI (match_operand:QI 0 "nonimmediate_operand" "%d,rm")
-+ (match_operand:QI 1 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))]
-+ "(ubicom32_v4
-+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
-+ "@
-+ xor.1\\t#0, %1, %0
-+ xor.1\\t#0, %0, %1")
-+
-+(define_insn "xor1_ccszn_null_1"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:QI
-+ (xor:SI (match_operand:SI 0 "ubicom32_data_register_operand" "%d")
-+ (match_operand:SI 1 "ubicom32_arith_operand" "rI"))
-+ 3)
-+ (const_int 0)))]
-+ "(ubicom32_v4
-+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
-+ "xor.1\\t#0, %1, %0")
-+
-+(define_insn "xor1_ccszn_null_2"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:QI
-+ (xor:SI (match_operand:SI 0 "ubicom32_data_register_operand" "d")
-+ (subreg:SI
-+ (match_operand:QI 1 "memory_operand" "m")
-+ 0))
-+ 3)
-+ (const_int 0)))]
-+ "(ubicom32_v4
-+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
-+ "xor.1\\t#0, %1, %0")
-+
-+(define_insn "xor1_ccwzn_null_3"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:QI
-+ (xor:SI (subreg:SI
-+ (match_operand:QI 0 "memory_operand" "m")
-+ 0)
-+ (match_operand:SI 1 "ubicom32_data_register_operand" "d"))
-+ 3)
-+ (const_int 0)))]
-+ "(ubicom32_v4
-+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
-+ "xor.1\\t#0, %0, %1")
-+
-+(define_expand "xorhi3"
-+ [(parallel
-+ [(set (match_operand:HI 0 "memory_operand" "")
-+ (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
-+ (match_operand:HI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ ""
-+ "{
-+ if (!memory_operand (operands[0], HImode))
-+ FAIL;
-+
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (HImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (HImode, operands[2]);
-+ }")
-+
-+(define_insn "xorhi3_xor2"
-+ [(set (match_operand:HI 0 "memory_operand" "=m, m")
-+ (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:HI 2 "ubicom32_arith_operand" "rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "@
-+ xor.2\\t%0, %2, %1
-+ xor.2\\t%0, %1, %2")
-+
-+(define_insn "xorhi3_xor2_ccszn"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:HI 2 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))
-+ (set (match_operand:HI 0 "memory_operand" "=m, m")
-+ (xor:HI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "@
-+ xor.2\\t%0, %2, %1
-+ xor.2\\t%0, %1, %2")
-+
-+(define_insn "xorhi3_xor2_ccszn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (xor:HI (match_operand:HI 0 "nonimmediate_operand" "%d,rm")
-+ (match_operand:HI 1 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "@
-+ xor.2\\t#0, %1, %0
-+ xor.2\\t#0, %0, %1")
-+
-+(define_insn "xor2_ccszn_null_1"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:HI
-+ (xor:SI (match_operand:SI 0 "ubicom32_data_register_operand" "%d")
-+ (match_operand:SI 1 "ubicom32_arith_operand" "rI"))
-+ 2)
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "xor.2\\t#0, %1, %0")
-+
-+(define_insn "xor2_ccszn_null_2"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:HI
-+ (xor:SI (match_operand:SI 0 "ubicom32_data_register_operand" "d")
-+ (subreg:SI
-+ (match_operand:HI 1 "memory_operand" "m")
-+ 0))
-+ 2)
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "xor.2\\t#0, %1, %0")
-+
-+(define_insn "xor2_ccszn_null_3"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (subreg:HI
-+ (xor:SI (subreg:SI
-+ (match_operand:HI 0 "memory_operand" "m")
-+ 0)
-+ (match_operand:SI 1 "ubicom32_data_register_operand" "d"))
-+ 2)
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
-+ "xor.2\\t#0, %0, %1")
-+
-+(define_insn "xorsi3"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
-+ (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "@
-+ xor.4\\t%0, %2, %1
-+ xor.4\\t%0, %1, %2")
-+
-+(define_insn "xorsi3_ccwzn"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%d,rm")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
-+ (xor:SI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "@
-+ xor.4\\t%0, %2, %1
-+ xor.4\\t%0, %1, %2")
-+
-+(define_insn "xorsi3_ccwzn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (xor:SI (match_operand:SI 0 "nonimmediate_operand" "%d,rm")
-+ (match_operand:SI 1 "ubicom32_arith_operand" "rmI, d"))
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "@
-+ xor.4\\t#0, %1, %0
-+ xor.4\\t#0, %0, %1")
-+
-+(define_expand "xordi3"
-+ [(parallel
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "")
-+ (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
-+ (match_operand:DI 2 "ubicom32_arith_operand" "")))
-+ (clobber (reg:CC CC_REGNO))])]
-+ ""
-+ "{
-+ /* If we have a non-data reg for operand 1 then prefer that over
-+ a CONST_INT in operand 2. */
-+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
-+ && CONST_INT_P (operands[2]))
-+ operands[2] = copy_to_mode_reg (DImode, operands[2]);
-+
-+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
-+ operands[2] = copy_to_mode_reg (DImode, operands[2]);
-+ }")
-+
-+(define_insn_and_split "xordi3_xor4"
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,&r, d,rm, m, m")
-+ (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%d,rm, 0, 0, d,rm")
-+ (match_operand:DI 2 "ubicom32_arith_operand" "rmI, d,rmI, d,rmI, d")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "#"
-+ "reload_completed"
-+ [(parallel [(set (match_dup 3)
-+ (xor:SI (match_dup 4)
-+ (match_dup 5)))
-+ (clobber (reg:CC CC_REGNO))])
-+ (parallel [(set (match_dup 6)
-+ (xor:SI (match_dup 7)
-+ (match_dup 8)))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "{
-+ operands[3] = gen_lowpart (SImode, operands[0]);
-+ operands[4] = gen_lowpart (SImode, operands[1]);
-+ operands[5] = gen_lowpart (SImode, operands[2]);
-+ operands[6] = gen_highpart (SImode, operands[0]);
-+ operands[7] = gen_highpart (SImode, operands[1]);
-+ operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
-+ }"
-+ [(set_attr "length" "8")])
-+
-+(define_insn "not2_2"
-+ [(set (match_operand:HI 0 "memory_operand" "=m")
-+ (subreg:HI
-+ (not:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI"))
-+ 2))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "not.2\\t%0, %1")
-+
-+(define_insn "one_cmplsi2"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (not:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "not.4\\t%0, %1")
-+
-+(define_insn "one_cmplsi2_ccwzn"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (not:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-+ (not:SI (match_dup 1)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "not.4\\t%0, %1")
-+
-+(define_insn "one_cmplsi2_ccwzn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (not:SI (match_operand:SI 0 "ubicom32_arith_operand" "rmI"))
-+ (const_int 0)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "not.4\\t#0, %0")
-+
-+(define_insn_and_split "one_cmpldi2"
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "=&rm")
-+ (not:DI (match_operand:DI 1 "nonimmediate_operand" "rmI0")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "#"
-+ ""
-+ [(parallel [(set (match_dup 2)
-+ (not:SI (match_dup 3)))
-+ (clobber (reg:CC CC_REGNO))])
-+ (parallel [(set (match_dup 4)
-+ (not:SI (match_dup 5)))
-+ (clobber (reg:CC CC_REGNO))])]
-+ "{
-+ operands[2] = gen_lowpart (SImode, operands[0]);
-+ operands[3] = gen_lowpart (SImode, operands[1]);
-+ operands[4] = gen_highpart (SImode, operands[0]);
-+ operands[5] = gen_highpart (SImode, operands[1]);
-+ }"
-+ [(set_attr "length" "8")])
-+
-+; Conditional jump instructions
-+
-+(define_expand "beq"
-+ [(set (pc)
-+ (if_then_else (eq (match_dup 1)
-+ (const_int 0))
-+ (label_ref (match_operand 0 "" ""))
-+ (pc)))]
-+ ""
-+ "{
-+ operands[1] = ubicom32_gen_compare_reg (EQ, ubicom32_compare_op0,
-+ ubicom32_compare_op1);
-+ }")
-+
-+(define_expand "bne"
-+ [(set (pc)
-+ (if_then_else (ne (match_dup 1)
-+ (const_int 0))
-+ (label_ref (match_operand 0 "" ""))
-+ (pc)))]
-+ ""
-+ "{
-+ operands[1] = ubicom32_gen_compare_reg (NE, ubicom32_compare_op0,
-+ ubicom32_compare_op1);
-+ }")
-+
-+(define_expand "bgt"
-+ [(set (pc)
-+ (if_then_else (gt (match_dup 1)
-+ (const_int 0))
-+ (label_ref (match_operand 0 "" ""))
-+ (pc)))]
-+ ""
-+ "{
-+ operands[1] = ubicom32_gen_compare_reg (GT, ubicom32_compare_op0,
-+ ubicom32_compare_op1);
-+ }")
-+
-+(define_expand "ble"
-+ [(set (pc)
-+ (if_then_else (le (match_dup 1)
-+ (const_int 0))
-+ (label_ref (match_operand 0 "" ""))
-+ (pc)))]
-+ ""
-+ "{
-+ operands[1] = ubicom32_gen_compare_reg (LE, ubicom32_compare_op0,
-+ ubicom32_compare_op1);
-+ }")
-+
-+(define_expand "bge"
-+ [(set (pc)
-+ (if_then_else (ge (match_dup 1)
-+ (const_int 0))
-+ (label_ref (match_operand 0 "" ""))
-+ (pc)))]
-+ ""
-+ "{
-+ operands[1] = ubicom32_gen_compare_reg (GE, ubicom32_compare_op0,
-+ ubicom32_compare_op1);
-+ }")
-+
-+(define_expand "blt"
-+ [(set (pc)
-+ (if_then_else (lt (match_dup 1)
-+ (const_int 0))
-+ (label_ref (match_operand 0 "" ""))
-+ (pc)))]
-+ ""
-+ "{
-+ operands[1] = ubicom32_gen_compare_reg (LT, ubicom32_compare_op0,
-+ ubicom32_compare_op1);
-+ }")
-+
-+(define_expand "bgtu"
-+ [(set (pc)
-+ (if_then_else (gtu (match_dup 1)
-+ (const_int 0))
-+ (label_ref (match_operand 0 "" ""))
-+ (pc)))]
-+ ""
-+ "{
-+ operands[1] = ubicom32_gen_compare_reg (GTU, ubicom32_compare_op0,
-+ ubicom32_compare_op1);
-+ }")
-+
-+(define_expand "bleu"
-+ [(set (pc)
-+ (if_then_else (leu (match_dup 1)
-+ (const_int 0))
-+ (label_ref (match_operand 0 "" ""))
-+ (pc)))]
-+ ""
-+ "{
-+ operands[1] = ubicom32_gen_compare_reg (LEU, ubicom32_compare_op0,
-+ ubicom32_compare_op1);
-+ }")
-+
-+(define_expand "bgeu"
-+ [(set (pc)
-+ (if_then_else (geu (match_dup 1)
-+ (const_int 0))
-+ (label_ref (match_operand 0 "" ""))
-+ (pc)))]
-+ ""
-+ "{
-+ operands[1] = ubicom32_gen_compare_reg (GEU, ubicom32_compare_op0,
-+ ubicom32_compare_op1);
-+ }")
-+
-+(define_expand "bltu"
-+ [(set (pc)
-+ (if_then_else (ltu (match_dup 1)
-+ (const_int 0))
-+ (label_ref (match_operand 0 "" ""))
-+ (pc)))]
-+ ""
-+ "{
-+ operands[1] = ubicom32_gen_compare_reg (LTU, ubicom32_compare_op0,
-+ ubicom32_compare_op1);
-+ }")
-+
-+(define_insn "jcc"
-+ [(set (pc)
-+ (if_then_else (match_operator 1 "comparison_operator"
-+ [(match_operand 2 "ubicom32_cc_register_operand" "")
-+ (const_int 0)])
-+ (label_ref (match_operand 0 "" ""))
-+ (pc)))]
-+ ""
-+ "*
-+ {
-+ ubicom32_output_cond_jump (insn, operands[1], operands[0]);
-+ return \"\";
-+ }")
-+
-+; Reverse branch - reverse our comparison condition so that we can
-+; branch in the opposite sense.
-+;
-+(define_insn_and_split "jcc_reverse"
-+ [(set (pc)
-+ (if_then_else (match_operator 1 "comparison_operator"
-+ [(match_operand 2 "ubicom32_cc_register_operand" "")
-+ (const_int 0)])
-+ (pc)
-+ (label_ref (match_operand 0 "" ""))))]
-+ ""
-+ "#"
-+ "reload_completed"
-+ [(set (pc)
-+ (if_then_else (match_dup 3)
-+ (label_ref (match_dup 0))
-+ (pc)))]
-+ "{
-+ rtx cc_reg;
-+
-+ cc_reg = gen_rtx_REG (GET_MODE (operands[2]), CC_REGNO);
-+ operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[1])),
-+ GET_MODE (operands[1]),
-+ cc_reg,
-+ const0_rtx);
-+ }")
-+
-+(define_insn "jump"
-+ [(set (pc)
-+ (label_ref (match_operand 0 "" "")))]
-+ ""
-+ "jmpt\\t%l0")
-+
-+(define_expand "indirect_jump"
-+ [(parallel [(set (pc)
-+ (match_operand:SI 0 "register_operand" ""))
-+ (clobber (match_dup 0))])]
-+ ""
-+ "")
-+
-+(define_insn "indirect_jump_internal"
-+ [(set (pc)
-+ (match_operand:SI 0 "register_operand" "a"))
-+ (clobber (match_dup 0))]
-+ ""
-+ "calli\\t%0,0(%0)")
-+
-+; Program Space: The table contains instructions, typically jumps.
-+; CALL An,TABLE_SIZE(PC) ;An = Jump Table Base Address.
-+; <Jump Table is Here> ;An -> Here.
-+; LEA Ak, (An,Dn) ;Ak -> Table Entry
-+; JMP/CALL (Ak)
-+
-+(define_expand "tablejump"
-+ [(parallel [(set (pc)
-+ (match_operand:SI 0 "nonimmediate_operand" ""))
-+ (use (label_ref (match_operand 1 "" "")))])]
-+ ""
-+ "")
-+
-+(define_insn "tablejump_internal"
-+ [(set (pc)
-+ (match_operand:SI 0 "nonimmediate_operand" "rm"))
-+ (use (label_ref (match_operand 1 "" "")))]
-+ ""
-+ "ret\\t%0")
-+
-+; Call subroutine with no return value.
-+;
-+(define_expand "call"
-+ [(call (match_operand:QI 0 "general_operand" "")
-+ (match_operand:SI 1 "general_operand" ""))]
-+ ""
-+ "{
-+ if (TARGET_FDPIC)
-+ {
-+ ubicom32_expand_call_fdpic (operands);
-+ DONE;
-+ }
-+
-+ if (! ubicom32_call_address_operand (XEXP (operands[0], 0), VOIDmode))
-+ XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
-+ }")
-+
-+; We expand to a simple form that doesn't clobber the link register and
-+; then split to a form that does. This allows the RTL optimizers that
-+; run before the splitter to have the opportunity to eliminate the call
-+; without marking A5 as being clobbered and this in turn avoids saves
-+; and returns in a number of cases.
-+;
-+(define_insn_and_split "call_1"
-+ [(call (mem:QI (match_operand:SI 0 "ubicom32_call_address_operand" "a,S"))
-+ (match_operand:SI 1 "general_operand" "g,g"))]
-+ "! TARGET_FDPIC"
-+ "#"
-+ ""
-+ [(parallel
-+ [(call (mem:QI (match_dup 0))
-+ (match_dup 1))
-+ (clobber (reg:SI LINK_REGNO))])]
-+ "")
-+
-+(define_insn "call_slow"
-+ [(call (mem:QI (match_operand:SI 0 "ubicom32_call_address_operand" "a,S"))
-+ (match_operand:SI 1 "general_operand" "g,g"))
-+ (clobber (reg:SI LINK_REGNO))]
-+ "(! TARGET_FDPIC && ! TARGET_FASTCALL)"
-+ "@
-+ calli\\ta5, 0(%0)
-+ moveai\\ta5, #%%hi(%C0)\;calli\\ta5, %%lo(%C0)(a5)")
-+
-+(define_insn "call_fast"
-+ [(call (mem:QI (match_operand:SI 0 "ubicom32_call_address_operand" "a,S"))
-+ (match_operand:SI 1 "general_operand" "g,g"))
-+ (clobber (reg:SI LINK_REGNO))]
-+ "(! TARGET_FDPIC && TARGET_FASTCALL)"
-+ "@
-+ calli\\ta5, 0(%0)
-+ call\\ta5, %C0")
-+
-+; We expand to a simple form that doesn't clobber the link register and
-+; then split to a form that does. This allows the RTL optimizers that
-+; run before the splitter to have the opportunity to eliminate the call
-+; without marking A5 as being clobbered and this in turn avoids saves
-+; and returns in a number of cases.
-+;
-+(define_insn_and_split "call_fdpic"
-+ [(call (mem:QI (match_operand:SI 0 "ubicom32_call_address_operand" "a,S"))
-+ (match_operand:SI 1 "general_operand" "g,g"))
-+ (use (match_operand:SI 2 "ubicom32_fdpic_operand" "Z,Z"))]
-+ "TARGET_FDPIC"
-+ "#"
-+ ""
-+ [(parallel
-+ [(call (mem:QI (match_dup 0))
-+ (match_dup 1))
-+ (use (match_dup 2))
-+ (clobber (reg:SI LINK_REGNO))])]
-+ "")
-+
-+(define_insn "call_fdpic_clobber"
-+ [(call (mem:QI (match_operand:SI 0 "ubicom32_call_address_operand" "a,S"))
-+ (match_operand:SI 1 "general_operand" "g,g"))
-+ (use (match_operand:SI 2 "ubicom32_fdpic_operand" "Z,Z"))
-+ (clobber (reg:SI LINK_REGNO))]
-+ "TARGET_FDPIC"
-+ "@
-+ move.4\\ta5, 0(%0)\;move.4\\t%2, 4(%0)\;calli\\ta5, 0(a5)
-+ call\\ta5, %C0")
-+
-+; Call subroutine, returning value in operand 0
-+; (which must be a hard register).
-+;
-+(define_expand "call_value"
-+ [(set (match_operand 0 "" "")
-+ (call (match_operand:QI 1 "general_operand" "")
-+ (match_operand:SI 2 "general_operand" "")))]
-+ ""
-+ "{
-+ if (TARGET_FDPIC)
-+ {
-+ ubicom32_expand_call_value_fdpic (operands);
-+ DONE;
-+ }
-+
-+ if (! ubicom32_call_address_operand (XEXP (operands[1], 0), VOIDmode))
-+ XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
-+ }")
-+
-+; We expand to a simple form that doesn't clobber the link register and
-+; then split to a form that does. This allows the RTL optimizers that
-+; run before the splitter to have the opportunity to eliminate the call
-+; without marking A5 as being clobbered and this in turn avoids saves
-+; and returns in a number of cases.
-+;
-+(define_insn_and_split "call_value_1"
-+ [(set (match_operand 0 "register_operand" "=r,r")
-+ (call (mem:QI (match_operand:SI 1 "ubicom32_call_address_operand" "a,S"))
-+ (match_operand:SI 2 "general_operand" "g,g")))]
-+ "! TARGET_FDPIC"
-+ "#"
-+ ""
-+ [(parallel
-+ [(set (match_dup 0)
-+ (call (mem:QI (match_dup 1))
-+ (match_dup 2)))
-+ (clobber (reg:SI LINK_REGNO))])]
-+ "")
-+
-+(define_insn "call_value_slow"
-+ [(set (match_operand 0 "register_operand" "=r,r")
-+ (call (mem:QI (match_operand:SI 1 "ubicom32_call_address_operand" "a,S"))
-+ (match_operand:SI 2 "general_operand" "g,g")))
-+ (clobber (reg:SI LINK_REGNO))]
-+ "(! TARGET_FDPIC && ! TARGET_FASTCALL)"
-+ "@
-+ calli\\ta5, 0(%1)
-+ moveai\\ta5, #%%hi(%C1)\;calli\\ta5, %%lo(%C1)(a5)")
-+
-+(define_insn "call_value_fast"
-+ [(set (match_operand 0 "register_operand" "=r,r")
-+ (call (mem:QI (match_operand:SI 1 "ubicom32_call_address_operand" "a,S"))
-+ (match_operand:SI 2 "general_operand" "g,g")))
-+ (clobber (reg:SI LINK_REGNO))]
-+ "(! TARGET_FDPIC && TARGET_FASTCALL)"
-+ "@
-+ calli\\ta5, 0(%1)
-+ call\\ta5, %C1")
-+
-+; We expand to a simple form that doesn't clobber the link register and
-+; then split to a form that does. This allows the RTL optimizers that
-+; run before the splitter to have the opportunity to eliminate the call
-+; without marking A5 as being clobbered and this in turn avoids saves
-+; and returns in a number of cases.
-+;
-+(define_insn_and_split "call_value_fdpic"
-+ [(set (match_operand 0 "register_operand" "=r,r")
-+ (call (mem:QI (match_operand:SI 1 "ubicom32_call_address_operand" "a,S"))
-+ (match_operand:SI 2 "general_operand" "g,g")))
-+ (use (match_operand:SI 3 "ubicom32_fdpic_operand" "Z,Z"))]
-+ "TARGET_FDPIC"
-+ "#"
-+ ""
-+ [(parallel
-+ [(set (match_dup 0)
-+ (call (mem:QI (match_dup 1))
-+ (match_dup 2)))
-+ (use (match_dup 3))
-+ (clobber (reg:SI LINK_REGNO))])]
-+ "")
-+
-+(define_insn "call_value_fdpic_clobber"
-+ [(set (match_operand 0 "register_operand" "=r,r")
-+ (call (mem:QI (match_operand:SI 1 "ubicom32_call_address_operand" "a,S"))
-+ (match_operand:SI 2 "general_operand" "g,g")))
-+ (use (match_operand:SI 3 "ubicom32_fdpic_operand" "Z,Z"))
-+ (clobber (reg:SI LINK_REGNO))]
-+ "TARGET_FDPIC"
-+ "@
-+ move.4\\ta5, 0(%1)\;move.4\\t%3, 4(%1)\;calli\\ta5, 0(a5)
-+ call\\ta5, %C1")
-+
-+(define_expand "untyped_call"
-+ [(parallel [(call (match_operand 0 "" "")
-+ (const_int 0))
-+ (match_operand 1 "" "")
-+ (match_operand 2 "" "")])]
-+ ""
-+ "{
-+ int i;
-+
-+ emit_call_insn (gen_call (operands[0], const0_rtx));
-+
-+ for (i = 0; i < XVECLEN (operands[2], 0); i++)
-+ {
-+ rtx set = XVECEXP (operands[2], 0, i);
-+ emit_move_insn (SET_DEST (set), SET_SRC (set));
-+ }
-+ DONE;
-+ }")
-+
-+(define_insn "lsl1_1"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (ashift:SI (subreg:SI
-+ (match_operand:QI 1 "memory_operand" "m")
-+ 0)
-+ (match_operand:SI 2 "ubicom32_arith_operand" "dM")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4)"
-+ "lsl.1\\t%0, %1, %2")
-+
-+; The combiner gets rather creative about left shifts of sub-word memory
-+; operands because it's uncertain about whether the memory is sign or
-+; zero extended. It only wants zero-extended behaviour and so throws
-+; in an extra and operation.
-+;
-+(define_insn "lsl1_2"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (and:SI
-+ (ashift:SI (subreg:SI
-+ (match_operand:QI 1 "memory_operand" "m")
-+ 0)
-+ (match_operand:SI 2 "const_int_operand" "M"))
-+ (match_operand:SI 3 "const_int_operand" "n")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4
-+ && INTVAL (operands[3]) == (0xff << INTVAL (operands[2])))"
-+ "lsl.1\\t%0, %1, %2")
-+
-+(define_insn "lsl2_1"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (ashift:SI (subreg:SI
-+ (match_operand:HI 1 "memory_operand" "m")
-+ 0)
-+ (match_operand:SI 2 "ubicom32_arith_operand" "dM")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4)"
-+ "lsl.2\\t%0, %1, %2")
-+
-+; The combiner gets rather creative about left shifts of sub-word memory
-+; operands because it's uncertain about whether the memory is sign or
-+; zero extended. It only wants zero-extended behaviour and so throws
-+; in an extra and operation.
-+;
-+(define_insn "lsl2_2"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (and:SI
-+ (ashift:SI (subreg:SI
-+ (match_operand:HI 1 "memory_operand" "m")
-+ 0)
-+ (match_operand:SI 2 "const_int_operand" "M"))
-+ (match_operand:SI 3 "const_int_operand" "n")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4
-+ && INTVAL (operands[3]) == (0xffff << INTVAL (operands[2])))"
-+ "lsl.2\\t%0, %1, %2")
-+
-+(define_insn "ashlsi3"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (ashift:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "dM")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "lsl.4\\t%0, %1, %2")
-+
-+(define_insn "lshlsi3_ccwz"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (ashift:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "dM"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (ashift:SI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCWZmode)"
-+ "lsl.4\\t%0, %1, %2")
-+
-+(define_insn "lshlsi3_ccwz_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (ashift:SI (match_operand:SI 0 "ubicom32_arith_operand" "rmI")
-+ (match_operand:SI 1 "ubicom32_arith_operand" "dM"))
-+ (const_int 0)))
-+ (clobber (match_scratch:SI 2 "=d"))]
-+ "ubicom32_match_cc_mode(insn, CCWZmode)"
-+ "lsl.4\\t%2, %0, %1")
-+
-+; The combiner finds this canonical form for what is in essence a right
-+; shift.
-+;
-+(define_insn "asr1_2"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (sign_extract:SI (match_operand:QI 1 "memory_operand" "m")
-+ (match_operand:SI 2 "const_int_operand" "M")
-+ (match_operand:SI 3 "const_int_operand" "M")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4
-+ && (INTVAL (operands[2]) + INTVAL (operands[3]) == 8))"
-+ "asr.1\\t%0, %1, %3")
-+
-+; The combiner finds this canonical form for what is in essence a right
-+; shift.
-+;
-+(define_insn "asr2_2"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (sign_extract:SI (match_operand:HI 1 "memory_operand" "m")
-+ (match_operand:SI 2 "const_int_operand" "M")
-+ (match_operand:SI 3 "const_int_operand" "M")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4
-+ && (INTVAL (operands[2]) + INTVAL (operands[3]) == 16))"
-+ "asr.2\\t%0, %1, %3")
-+
-+(define_insn "ashrsi3"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (ashiftrt:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmJ")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "dM")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "asr.4\\t%0, %1, %2")
-+
-+(define_insn "ashrsi3_ccwzn"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (ashiftrt:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmJ")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "dM"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (ashiftrt:SI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "asr.4\\t%0, %1, %2")
-+
-+(define_insn "ashrsi3_ccwzn_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (ashiftrt:SI (match_operand:SI 0 "ubicom32_arith_operand" "rmJ")
-+ (match_operand:SI 1 "ubicom32_arith_operand" "dM"))
-+ (const_int 0)))
-+ (clobber (match_scratch:SI 2 "=d"))]
-+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
-+ "asr.4\\t%2, %0, %1")
-+
-+(define_insn "lsr1_1"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (lshiftrt:SI (subreg:SI
-+ (match_operand:QI 1 "memory_operand" "m")
-+ 0)
-+ (match_operand:SI 2 "ubicom32_arith_operand" "dM")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4)"
-+ "lsr.1\\t%0, %1, %2")
-+
-+; The combiner finds this canonical form for what is in essence a right
-+; shift.
-+;
-+(define_insn "lsr1_2"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (zero_extract:SI (match_operand:QI 1 "memory_operand" "m")
-+ (match_operand:SI 2 "const_int_operand" "M")
-+ (match_operand:SI 3 "const_int_operand" "M")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4
-+ && (INTVAL (operands[2]) + INTVAL (operands[3]) == 8))"
-+ "lsr.1\\t%0, %1, %3")
-+
-+(define_insn "lsr2_1"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (lshiftrt:SI (subreg:SI
-+ (match_operand:HI 1 "memory_operand" "m")
-+ 0)
-+ (match_operand:SI 2 "ubicom32_arith_operand" "dM")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4)"
-+ "lsr.2\\t%0, %1, %2")
-+
-+; The combiner finds this canonical form for what is in essence a right
-+; shift.
-+;
-+(define_insn "lsr2_2"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (zero_extract:SI (match_operand:HI 1 "memory_operand" "m")
-+ (match_operand:SI 2 "const_int_operand" "M")
-+ (match_operand:SI 3 "const_int_operand" "M")))
-+ (clobber (reg:CC CC_REGNO))]
-+ "(ubicom32_v4
-+ && (INTVAL (operands[2]) + INTVAL (operands[3]) == 16))"
-+ "lsr.2\\t%0, %1, %3")
-+
-+(define_insn "lshrsi3"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (lshiftrt:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "dM")))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "lsr.4\\t%0, %1, %2")
-+
-+(define_insn "lshrsi3_ccwz"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (lshiftrt:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")
-+ (match_operand:SI 2 "ubicom32_arith_operand" "dM"))
-+ (const_int 0)))
-+ (set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (lshiftrt:SI (match_dup 1)
-+ (match_dup 2)))]
-+ "ubicom32_match_cc_mode(insn, CCWZmode)"
-+ "lsr.4\\t%0, %1, %2")
-+
-+(define_insn "lshrsi3_ccwz_null"
-+ [(set (reg CC_REGNO)
-+ (compare
-+ (lshiftrt:SI (match_operand:SI 0 "ubicom32_arith_operand" "rmI")
-+ (match_operand:SI 1 "ubicom32_arith_operand" "dM"))
-+ (const_int 0)))
-+ (clobber (match_scratch:SI 2 "=d"))]
-+ "ubicom32_match_cc_mode(insn, CCWZmode)"
-+ "lsr.4\\t%2, %0, %1")
-+
-+(define_expand "prologue"
-+ [(const_int 0)]
-+ ""
-+ "{
-+ ubicom32_expand_prologue ();
-+ DONE;
-+ }")
-+
-+(define_expand "epilogue"
-+ [(return)]
-+ ""
-+ "{
-+ ubicom32_expand_epilogue ();
-+ DONE;
-+ }")
-+
-+(define_expand "return"
-+ [(return)]
-+ ""
-+ "{
-+ ubicom32_expand_epilogue ();
-+ DONE;
-+ }")
-+
-+(define_expand "_eh_return"
-+ [(use (match_operand:SI 0 "register_operand" "r"))
-+ (use (match_operand:SI 1 "register_operand" "r"))]
-+ ""
-+ "{
-+ ubicom32_expand_eh_return (operands);
-+ DONE;
-+ }")
-+
-+; XXX - it looks almost certain that we could make return_internal use a Dn
-+; register too. In that instance we'd have to use a ret instruction
-+; rather than a calli but it might save cycles.
-+;
-+(define_insn "return_internal"
-+ [(const_int 2)
-+ (return)
-+ (use (match_operand:SI 0 "ubicom32_mem_or_address_register_operand" "rm"))]
-+ ""
-+ "*
-+ {
-+ if (REG_P (operands[0]) && REGNO (operands[0]) == LINK_REGNO
-+ && ubicom32_can_use_calli_to_ret)
-+ return \"calli\\t%0, 0(%0)\";
-+
-+ return \"ret\\t%0\";
-+ }")
-+
-+(define_insn "return_from_post_modify_sp"
-+ [(parallel
-+ [(const_int 2)
-+ (return)
-+ (use (mem:SI (post_modify:SI
-+ (reg:SI SP_REGNO)
-+ (plus:SI (reg:SI SP_REGNO)
-+ (match_operand:SI 0 "const_int_operand" "n")))))])]
-+ "INTVAL (operands[0]) >= 4 && INTVAL (operands[0]) <= 7 * 4"
-+ "ret\\t(sp)%E0++")
-+
-+;(define_insn "eh_return_internal"
-+; [(const_int 4)
-+; (return)
-+; (use (reg:SI 34))]
-+; ""
-+; "ret\\ta2")
-+
-+; No operation, needed in case the user uses -g but not -O.
-+(define_expand "nop"
-+ [(const_int 0)]
-+ ""
-+ "")
-+
-+(define_insn "nop_internal"
-+ [(const_int 0)]
-+ ""
-+ "nop")
-+
-+; The combiner will generate this pattern given shift and add operations.
-+; The canonical form that the combiner wants to use appears to be multiplies
-+; instead of shifts even if the compiled sources use shifts.
-+;
-+(define_insn "shmrg1_add"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (plus:SI
-+ (mult:SI (match_operand:SI 1 "ubicom32_data_register_operand" "d")
-+ (const_int 256))
-+ (zero_extend:SI
-+ (match_operand:QI 2 "ubicom32_arith_operand" "rmI"))))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "shmrg.1\\t%0, %2, %1")
-+
-+; The combiner will generate this pattern given shift and or operations.
-+;
-+(define_insn "shmrg1_ior"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (ior:SI
-+ (ashift:SI (match_operand:SI 1 "ubicom32_data_register_operand" "d")
-+ (const_int 8))
-+ (zero_extend:SI
-+ (match_operand:QI 2 "ubicom32_arith_operand" "rmI"))))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "shmrg.1\\t%0, %2, %1")
-+
-+; The combiner will generate this pattern given shift and add operations.
-+; The canonical form that the combiner wants to use appears to be multiplies
-+; instead of shifts even if the compiled sources use shifts.
-+;
-+(define_insn "shmrg2_add"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (plus:SI
-+ (mult:SI (match_operand:SI 1 "ubicom32_data_register_operand" "d")
-+ (const_int 65536))
-+ (zero_extend:SI
-+ (match_operand:HI 2 "ubicom32_arith_operand" "rmI"))))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "shmrg.2\\t%0, %2, %1")
-+
-+; The combiner will generate this pattern given shift and or operations.
-+;
-+(define_insn "shmrg2_ior"
-+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
-+ (ior:SI
-+ (ashift:SI (match_operand:SI 1 "ubicom32_data_register_operand" "d")
-+ (const_int 16))
-+ (zero_extend:SI
-+ (match_operand:HI 2 "ubicom32_arith_operand" "rmI"))))
-+ (clobber (reg:CC CC_REGNO))]
-+ ""
-+ "shmrg.2\\t%0, %2, %1")
-+
-+; Match the case where we load a word from the stack but then discard the
-+; upper 16 bits. We turn this into a zero-extended load of that useful
-+; 16 bits direct from the stack where possible.
-+;
-+
-+; XXX - do these peephole2 ops actually work after the CCmode conversion?
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (mem:SI (plus:SI (reg:SI SP_REGNO)
-+ (match_operand:SI 1 "const_int_operand" ""))))
-+ (set (match_operand:SI 2 "nonimmediate_operand" "")
-+ (zero_extend:SI (match_operand:HI 3 "register_operand" "")))]
-+ "(INTVAL (operands[1]) <= 252
-+ && REGNO (operands[3]) == REGNO (operands[0])
-+ && ((peep2_reg_dead_p (2, operands[0])
-+ && ! reg_mentioned_p (operands[0], operands[2]))
-+ || rtx_equal_p (operands[0], operands[2])))"
-+ [(set (match_dup 2)
-+ (zero_extend:SI (mem:HI (plus:SI (reg:SI SP_REGNO)
-+ (match_dup 4)))))]
-+ "{
-+ operands[4] = GEN_INT (INTVAL (operands[1]) + 2);
-+ }")
-+
-+; Match the case where we load a word from the stack but then discard the
-+; upper 16 bits. We turn this into a 16-bit load of that useful
-+; 16 bits direct from the stack where possible.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (mem:SI (plus:SI (reg:SI SP_REGNO)
-+ (match_operand:SI 1 "const_int_operand" ""))))
-+ (set (match_operand:HI 2 "nonimmediate_operand" "")
-+ (match_operand:HI 3 "register_operand" ""))]
-+ "(INTVAL (operands[1]) <= 252
-+ && REGNO (operands[3]) == REGNO (operands[0])
-+ && ((peep2_reg_dead_p (2, operands[0])
-+ && ! reg_mentioned_p (operands[0], operands[2]))
-+ || rtx_equal_p (operands[0], operands[2])))"
-+ [(set (match_dup 2)
-+ (mem:HI (plus:SI (reg:SI SP_REGNO)
-+ (match_dup 4))))]
-+ "{
-+ operands[4] = GEN_INT (INTVAL (operands[1]) + 2);
-+ }")
-+
-+; Match the case where we load a word from the stack but then discard the
-+; upper 24 bits. We turn this into a zero-extended load of that useful
-+; 8 bits direct from the stack where possible.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (mem:SI (plus:SI (reg:SI SP_REGNO)
-+ (match_operand:SI 1 "const_int_operand" ""))))
-+ (set (match_operand:SI 2 "nonimmediate_operand" "")
-+ (zero_extend:SI (match_operand:QI 3 "register_operand" "")))]
-+ "(INTVAL (operands[1]) <= 124
-+ && REGNO (operands[3]) == REGNO (operands[0])
-+ && ((peep2_reg_dead_p (2, operands[0])
-+ && ! reg_mentioned_p (operands[0], operands[2]))
-+ || rtx_equal_p (operands[0], operands[2])))"
-+ [(set (match_dup 2)
-+ (zero_extend:SI (mem:QI (plus:SI (reg:SI SP_REGNO)
-+ (match_dup 4)))))]
-+ "{
-+ operands[4] = GEN_INT (INTVAL (operands[1]) + 3);
-+ }")
-+
-+; Match the case where we load a word from the stack but then discard the
-+; upper 24 bits. We turn this into an 8-bit load of that useful
-+; 8 bits direct from the stack where possible.
-+;
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (mem:SI (plus:SI (reg:SI SP_REGNO)
-+ (match_operand:SI 1 "const_int_operand" ""))))
-+ (set (match_operand:QI 2 "nonimmediate_operand" "")
-+ (match_operand:QI 3 "register_operand" ""))]
-+ "(INTVAL (operands[1]) <= 124
-+ && REGNO (operands[3]) == REGNO (operands[0])
-+ && ((peep2_reg_dead_p (2, operands[0])
-+ && ! reg_mentioned_p (operands[0], operands[2]))
-+ || rtx_equal_p (operands[0], operands[2])))"
-+ [(set (match_dup 2)
-+ (mem:QI (plus:SI (reg:SI SP_REGNO)
-+ (match_dup 4))))]
-+ "{
-+ operands[4] = GEN_INT (INTVAL (operands[1]) + 3);
-+ }")
-+
---- /dev/null
-+++ b/gcc/config/ubicom32/ubicom32.opt
-@@ -0,0 +1,27 @@
-+mdebug-address
-+Target RejectNegative Report Undocumented Mask(DEBUG_ADDRESS)
-+Debug addresses
-+
-+mdebug-context
-+Target RejectNegative Report Undocumented Mask(DEBUG_CONTEXT)
-+Debug contexts
-+
-+march=
-+Target Report Var(ubicom32_arch_name) Init("ubicom32v4") Joined
-+Specify the name of the target architecture
-+
-+mfdpic
-+Target Report Mask(FDPIC)
-+Enable Function Descriptor PIC mode
-+
-+minline-plt
-+Target Report Mask(INLINE_PLT)
-+Enable inlining of PLT in function calls
-+
-+mfastcall
-+Target Report Mask(FASTCALL)
-+Enable default fast (call) calling sequence for smaller applications
-+
-+mipos-abi
-+Target Report Mask(IPOS_ABI)
-+Enable the ipOS ABI in which D10-D13 are caller-clobbered
---- /dev/null
-+++ b/gcc/config/ubicom32/uclinux.h
-@@ -0,0 +1,67 @@
-+/* Definitions of target machine for Ubicom32-uclinux
-+
-+ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
-+ 2009 Free Software Foundation, Inc.
-+ Contributed by Ubicom, Inc.
-+
-+ This file is part of GCC.
-+
-+ GCC is free software; you can redistribute it and/or modify it
-+ under the terms of the GNU General Public License as published
-+ by the Free Software Foundation; either version 3, or (at your
-+ option) any later version.
-+
-+ GCC is distributed in the hope that it will be useful, but WITHOUT
-+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
-+ License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with GCC; see the file COPYING3. If not see
-+ <http://www.gnu.org/licenses/>. */
-+
-+/* Don't assume anything about the header files. */
-+#define NO_IMPLICIT_EXTERN_C
-+
-+#undef LIB_SPEC
-+#define LIB_SPEC \
-+ "%{pthread:-lpthread} " \
-+ "%{!shared:%{!symbolic: -lc}} "
-+
-+
-+#undef LINK_GCC_C_SEQUENCE_SPEC
-+#define LINK_GCC_C_SEQUENCE_SPEC \
-+ "%{!shared:--start-group} %G %L %{!shared:--end-group}%{shared:%G} "
-+
-+#undef STARTFILE_SPEC
-+#define STARTFILE_SPEC \
-+ "%{!shared: crt1%O%s}" \
-+ " crti%O%s crtbegin%O%s"
-+
-+#undef ENDFILE_SPEC
-+#define ENDFILE_SPEC "crtend%O%s crtn%O%s"
-+
-+/* This macro applies on top of OBJECT_FORMAT_ELF and indicates that
-+ we want to support both flat and ELF output. */
-+#define OBJECT_FORMAT_FLAT
-+
-+#undef DRIVER_SELF_SPECS
-+#define DRIVER_SELF_SPECS \
-+ "%{!mno-fastcall:-mfastcall}"
-+
-+/* taken from linux.h */
-+/* The GNU C++ standard library requires that these macros be defined. */
-+#undef CPLUSPLUS_CPP_SPEC
-+#define CPLUSPLUS_CPP_SPEC "-D_GNU_SOURCE %(cpp)"
-+
-+#define TARGET_OS_CPP_BUILTINS() \
-+ do { \
-+ builtin_define_std ("__UBICOM32__"); \
-+ builtin_define_std ("__ubicom32__"); \
-+ builtin_define ("__gnu_linux__"); \
-+ builtin_define_std ("linux"); \
-+ builtin_define_std ("unix"); \
-+ builtin_assert ("system=linux"); \
-+ builtin_assert ("system=unix"); \
-+ builtin_assert ("system=posix"); \
-+ } while (0)
---- /dev/null
-+++ b/gcc/config/ubicom32/xm-ubicom32.h
-@@ -0,0 +1,36 @@
-+/* Configuration for Ubicom's Ubicom32 architecture.
-+ Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Free Software
-+ Foundation, Inc.
-+ Contributed by Ubicom Inc.
-+
-+This file is part of GNU CC.
-+
-+GNU CC is free software; you can redistribute it and/or modify
-+it under the terms of the GNU General Public License as published by
-+the Free Software Foundation; either version 2, or (at your option)
-+any later version.
-+
-+GNU CC is distributed in the hope that it will be useful,
-+but WITHOUT ANY WARRANTY; without even the implied warranty of
-+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+GNU General Public License for more details.
-+
-+You should have received a copy of the GNU General Public License
-+along with GNU CC; see the file COPYING. If not, write to
-+the Free Software Foundation, 59 Temple Place - Suite 330,
-+Boston, MA 02111-1307, USA. */
-+
-+/* #defines that need visibility everywhere. */
-+#define FALSE 0
-+#define TRUE 1
-+
-+/* This describes the machine the compiler is hosted on. */
-+#define HOST_BITS_PER_CHAR 8
-+#define HOST_BITS_PER_SHORT 16
-+#define HOST_BITS_PER_INT 32
-+#define HOST_BITS_PER_LONG 32
-+#define HOST_BITS_PER_LONGLONG 64
-+
-+/* Arguments to use with `exit'. */
-+#define SUCCESS_EXIT_CODE 0
-+#define FATAL_EXIT_CODE 33
---- a/gcc/config.gcc
-+++ b/gcc/config.gcc
-@@ -2314,6 +2314,34 @@ spu-*-elf*)
- c_target_objs="${c_target_objs} spu-c.o"
- cxx_target_objs="${cxx_target_objs} spu-c.o"
- ;;
-+ubicom32-*-elf)
-+ xm_file=ubicom32/xm-ubicom32.h
-+ tm_file="${tm_file} ubicom32/elf.h" # still need dbxelf.h elfos.h
-+ tmake_file=ubicom32/t-ubicom32
-+ ;;
-+ubicom32-*-uclinux*)
-+ xm_file=ubicom32/xm-ubicom32.h
-+ tm_file="${tm_file} ubicom32/elf.h ubicom32/uclinux.h" # still need dbxelf.h elfos.h linux.h
-+ tm_defines="${tm_defines} UCLIBC_DEFAULT=1"
-+ extra_options="${extra_options} linux.opt"
-+ tmake_file=ubicom32/t-ubicom32-uclinux
-+ use_collect2=no
-+ ;;
-+ubicom32-*-linux-uclibc)
-+ xm_file=ubicom32/xm-ubicom32.h
-+ tm_file="${tm_file} ubicom32/elf.h linux.h ubicom32/linux.h" # still need dbxelf.h elfos.h
-+ tmake_file="t-slibgcc-elf-ver ubicom32/t-ubicom32-linux"
-+ extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
-+ use_collect2=no
-+ ;;
-+ubicom32-*-linux*)
-+ xm_file=ubicom32/xm-ubicom32.h
-+ tm_file="${tm_file} ubicom32/elf.h linux.h ubicom32/linux.h" # still need dbxelf.h elfos.h
-+ tmake_file="t-slibgcc-elf-ver ubicom32/t-ubicom32-linux"
-+ tm_defines="${tm_defines} UCLIBC_DEFAULT=1"
-+ extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
-+ use_collect2=no
-+ ;;
- v850e1-*-*)
- target_cpu_default="TARGET_CPU_v850e1"
- tm_file="dbxelf.h elfos.h svr4.h v850/v850.h"
---- a/libgcc/config.host
-+++ b/libgcc/config.host
-@@ -551,6 +551,15 @@ sparc64-*-netbsd*)
- ;;
- spu-*-elf*)
- ;;
-+ubicom32*-*-elf*)
-+ ;;
-+ubicom32*-*-uclinux*)
-+ ;;
-+ubicom32*-*-linux*)
-+ # No need to build crtbeginT.o on uClibc systems. Should probably
-+ # be moved to the OS specific section above.
-+ extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
-+ ;;
- v850e1-*-*)
- ;;
- v850e-*-*)
+++ /dev/null
---- a/gcc/config/arm/linux-elf.h
-+++ b/gcc/config/arm/linux-elf.h
-@@ -60,7 +60,7 @@
- %{shared:-lc} \
- %{!shared:%{profile:-lc_p}%{!profile:-lc}}"
-
--#define LIBGCC_SPEC "%{msoft-float:-lfloat} %{mfloat-abi=soft*:-lfloat} -lgcc"
-+#define LIBGCC_SPEC "-lgcc"
-
- #define GLIBC_DYNAMIC_LINKER "/lib/ld-linux.so.2"
-
---- a/gcc/config/arm/t-linux
-+++ b/gcc/config/arm/t-linux
-@@ -4,7 +4,10 @@
-
- LIB1ASMSRC = arm/lib1funcs.asm
- LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_lnx _clzsi2 _clzdi2 \
-- _arm_addsubdf3 _arm_addsubsf3
-+ _arm_addsubdf3 _arm_addsubsf3 \
-+ _negdf2 _addsubdf3 _muldivdf3 _cmpdf2 _unorddf2 _fixdfsi _fixunsdfsi \
-+ _truncdfsf2 _negsf2 _addsubsf3 _muldivsf3 _cmpsf2 _unordsf2 \
-+ _fixsfsi _fixunssfsi _floatdidf _floatundidf _floatdisf _floatundisf
-
- # MULTILIB_OPTIONS = mhard-float/msoft-float
- # MULTILIB_DIRNAMES = hard-float soft-float
+++ /dev/null
---- a/libgcc/Makefile.in
-+++ b/libgcc/Makefile.in
-@@ -729,11 +729,12 @@ $(libgcov-objects): %$(objext): $(gcc_sr
-
- # Static libraries.
- libgcc.a: $(libgcc-objects)
-+libgcc_pic.a: $(libgcc-s-objects)
- libgcov.a: $(libgcov-objects)
- libunwind.a: $(libunwind-objects)
- libgcc_eh.a: $(libgcc-eh-objects)
-
--libgcc.a libgcov.a libunwind.a libgcc_eh.a:
-+libgcc.a libgcov.a libunwind.a libgcc_eh.a libgcc_pic.a:
- -rm -f $@
-
- objects="$(objects)"; \
-@@ -755,7 +756,7 @@ libgcc_s$(SHLIB_EXT): libunwind$(SHLIB_E
- endif
-
- ifeq ($(enable_shared),yes)
--all: libgcc_eh.a libgcc_s$(SHLIB_EXT)
-+all: libgcc_eh.a libgcc_pic.a libgcc_s$(SHLIB_EXT)
- ifneq ($(LIBUNWIND),)
- all: libunwind$(SHLIB_EXT)
- endif
-@@ -928,6 +929,10 @@ install-shared:
- chmod 644 $(DESTDIR)$(inst_libdir)/libgcc_eh.a
- $(RANLIB) $(DESTDIR)$(inst_libdir)/libgcc_eh.a
-
-+ $(INSTALL_DATA) libgcc_pic.a $(mapfile) $(DESTDIR)$(inst_libdir)/
-+ chmod 644 $(DESTDIR)$(inst_libdir)/libgcc_pic.a
-+ $(RANLIB) $(DESTDIR)$(inst_libdir)/libgcc_pic.a
-+
- $(subst @multilib_dir@,$(MULTIDIR),$(subst \
- @shlib_base_name@,libgcc_s,$(subst \
- @shlib_slibdir_qual@,$(MULTIOSSUBDIR),$(SHLIB_INSTALL))))
+++ /dev/null
-
- This patch brings over a few features from MirBSD:
- * -fhonour-copts
- If this option is not given, it's warned (depending
- on environment variables). This is to catch errors
- of misbuilt packages which override CFLAGS themselves.
- * -Werror-maybe-reset
- Has the effect of -Wno-error if GCC_NO_WERROR is
- set and not '0', a no-operation otherwise. This is
- to be able to use -Werror in "make" but prevent
- GNU autoconf generated configure scripts from
- freaking out.
- * Make -fno-strict-aliasing and -fno-delete-null-pointer-checks
- the default for -O2/-Os, because they trigger gcc bugs
- and can delete code with security implications.
-
- This patch was authored by Thorsten Glaser <tg at mirbsd.de>
- with copyright assignment to the FSF in effect.
-
---- a/gcc/c-opts.c
-+++ b/gcc/c-opts.c
-@@ -105,6 +105,9 @@
- /* Number of deferred options scanned for -include. */
- static size_t include_cursor;
-
-+/* Check if a port honours COPTS. */
-+static int honour_copts = 0;
-+
- static void set_Wimplicit (int);
- static void handle_OPT_d (const char *);
- static void set_std_cxx98 (int);
-@@ -454,6 +457,9 @@
- enable_warning_as_error ("implicit-function-declaration", value, CL_C | CL_ObjC);
- break;
-
-+ case OPT_Werror_maybe_reset:
-+ break;
-+
- case OPT_Wformat:
- set_Wformat (value);
- break;
-@@ -690,6 +701,12 @@
- flag_exceptions = value;
- break;
-
-+ case OPT_fhonour_copts:
-+ if (c_language == clk_c) {
-+ honour_copts++;
-+ }
-+ break;
-+
- case OPT_fimplement_inlines:
- flag_implement_inlines = value;
- break;
-@@ -1209,6 +1226,47 @@
- return false;
- }
-
-+ if (c_language == clk_c) {
-+ char *ev = getenv ("GCC_HONOUR_COPTS");
-+ int evv;
-+ if (ev == NULL)
-+ evv = -1;
-+ else if ((*ev == '0') || (*ev == '\0'))
-+ evv = 0;
-+ else if (*ev == '1')
-+ evv = 1;
-+ else if (*ev == '2')
-+ evv = 2;
-+ else if (*ev == 's')
-+ evv = -1;
-+ else {
-+ warning (0, "unknown GCC_HONOUR_COPTS value, assuming 1");
-+ evv = 1; /* maybe depend this on something like MIRBSD_NATIVE? */
-+ }
-+ if (evv == 1) {
-+ if (honour_copts == 0) {
-+ error ("someone does not honour COPTS at all in lenient mode");
-+ return false;
-+ } else if (honour_copts != 1) {
-+ warning (0, "someone does not honour COPTS correctly, passed %d times",
-+ honour_copts);
-+ }
-+ } else if (evv == 2) {
-+ if (honour_copts == 0) {
-+ error ("someone does not honour COPTS at all in strict mode");
-+ return false;
-+ } else if (honour_copts != 1) {
-+ error ("someone does not honour COPTS correctly, passed %d times",
-+ honour_copts);
-+ return false;
-+ }
-+ } else if (evv == 0) {
-+ if (honour_copts != 1)
-+ inform (0, "someone does not honour COPTS correctly, passed %d times",
-+ honour_copts);
-+ }
-+ }
-+
- return true;
- }
-
---- a/gcc/c.opt
-+++ b/gcc/c.opt
-@@ -215,6 +215,10 @@
- C ObjC RejectNegative Warning
- This switch is deprecated; use -Werror=implicit-function-declaration instead
-
-+Werror-maybe-reset
-+C ObjC C++ ObjC++
-+; Documented in common.opt
-+
- Wfloat-equal
- C ObjC C++ ObjC++ Var(warn_float_equal) Warning
- Warn if testing floating point numbers for equality
-@@ -609,6 +613,9 @@
- fhonor-std
- C++ ObjC++
-
-+fhonour-copts
-+C ObjC C++ ObjC++ RejectNegative
-+
- fhosted
- C ObjC
- Assume normal C execution environment
---- a/gcc/common.opt
-+++ b/gcc/common.opt
-@@ -102,6 +102,10 @@
- Common Joined
- Treat specified warning as error
-
-+Werror-maybe-reset
-+Common
-+If environment variable GCC_NO_WERROR is set, act as -Wno-error
-+
- Wextra
- Common Warning
- Print extra (possibly unwanted) warnings
-@@ -573,6 +577,9 @@
- Common Report Var(flag_guess_branch_prob) Optimization
- Enable guessing of branch probabilities
-
-+fhonour-copts
-+Common RejectNegative
-+
- ; Nonzero means ignore `#ident' directives. 0 means handle them.
- ; Generate position-independent code for executables if possible
- ; On SVR4 targets, it also controls whether or not to emit a
---- a/gcc/opts.c
-+++ b/gcc/opts.c
-@@ -896,8 +896,6 @@
- flag_schedule_insns_after_reload = opt2;
- #endif
- flag_regmove = opt2;
-- flag_strict_aliasing = opt2;
-- flag_strict_overflow = opt2;
- flag_reorder_blocks = opt2;
- flag_reorder_functions = opt2;
- flag_tree_vrp = opt2;
-@@ -922,6 +919,8 @@
-
- /* -O3 optimizations. */
- opt3 = (optimize >= 3);
-+ flag_strict_aliasing = opt3;
-+ flag_strict_overflow = opt3;
- flag_predictive_commoning = opt3;
- flag_inline_functions = opt3;
- flag_unswitch_loops = opt3;
-@@ -1601,6 +1601,17 @@
- enable_warning_as_error (arg, value, lang_mask);
- break;
-
-+ case OPT_Werror_maybe_reset:
-+ {
-+ char *ev = getenv ("GCC_NO_WERROR");
-+ if ((ev != NULL) && (*ev != '0'))
-+ warnings_are_errors = 0;
-+ }
-+ break;
-+
-+ case OPT_fhonour_copts:
-+ break;
-+
- case OPT_Wlarger_than_:
- /* This form corresponds to -Wlarger-than-.
- Kept for backward compatibility.
---- a/gcc/doc/cppopts.texi
-+++ b/gcc/doc/cppopts.texi
-@@ -164,6 +164,11 @@
- Make all warnings into hard errors. Source code which triggers warnings
- will be rejected.
-
-+ at item -Werror-maybe-reset
-+ at opindex Werror-maybe-reset
-+Act like @samp{-Wno-error} if the @env{GCC_NO_WERROR} environment
-+variable is set to anything other than 0 or empty.
-+
- @item -Wsystem-headers
- @opindex Wsystem-headers
- Issue warnings for code in system headers. These are normally unhelpful
---- a/gcc/doc/invoke.texi
-+++ b/gcc/doc/invoke.texi
-@@ -234,7 +234,7 @@
- -Wconversion -Wcoverage-mismatch -Wno-deprecated @gol
- -Wno-deprecated-declarations -Wdisabled-optimization @gol
- -Wno-div-by-zero -Wempty-body -Wenum-compare -Wno-endif-labels @gol
---Werror -Werror=* @gol
-+-Werror -Werror=* -Werror-maybe-reset @gol
- -Wfatal-errors -Wfloat-equal -Wformat -Wformat=2 @gol
- -Wno-format-contains-nul -Wno-format-extra-args -Wformat-nonliteral @gol
- -Wformat-security -Wformat-y2k @gol
-@@ -4161,6 +4161,22 @@
- @option{-Wall} and by @option{-pedantic}, which can be disabled with
- @option{-Wno-pointer-sign}.
-
-+ at item -Werror-maybe-reset
-+ at opindex Werror-maybe-reset
-+Act like @samp{-Wno-error} if the @env{GCC_NO_WERROR} environment
-+variable is set to anything other than 0 or empty.
-+
-+ at item -fhonour-copts
-+ at opindex fhonour-copts
-+If @env{GCC_HONOUR_COPTS} is set to 1, abort if this option is not
-+given at least once, and warn if it is given more than once.
-+If @env{GCC_HONOUR_COPTS} is set to 2, abort if this option is not
-+given exactly once.
-+If @env{GCC_HONOUR_COPTS} is set to 0 or unset, warn if this option
-+is not given exactly once.
-+The warning is quelled if @env{GCC_HONOUR_COPTS} is set to @samp{s}.
-+This flag and environment variable only affect the C language.
-+
- @item -Wstack-protector
- @opindex Wstack-protector
- @opindex Wno-stack-protector
-@@ -5699,7 +5715,7 @@
- second branch or a point immediately following it, depending on whether
- the condition is known to be true or false.
-
--Enabled at levels @option{-O2}, @option{-O3}, @option{-Os}.
-+Enabled at levels @option{-O3}.
-
- @item -fsplit-wide-types
- @opindex fsplit-wide-types
---- a/gcc/java/jvspec.c
-+++ b/gcc/java/jvspec.c
-@@ -670,6 +670,7 @@
- class name. Append dummy `.c' that can be stripped by set_input so %b
- is correct. */
- set_input (concat (main_class_name, "main.c", NULL));
-+ putenv ("GCC_HONOUR_COPTS=s"); /* XXX hack! */
- err = do_spec (jvgenmain_spec);
- if (err == 0)
- {
+++ /dev/null
---- gcc-4.4.0/gcc/config/arm/arm-protos.h 2009-02-20 16:20:38.000000000 +0100
-+++ gcc-4.4.0.new/gcc/config/arm/arm-protos.h 2009-04-22 16:00:58.000000000 +0200
-@@ -43,10 +43,10 @@
- extern void arm_output_fn_unwind (FILE *, bool);
-
-
--#ifdef RTX_CODE
- extern bool arm_vector_mode_supported_p (enum machine_mode);
- extern int arm_hard_regno_mode_ok (unsigned int, enum machine_mode);
- extern int const_ok_for_arm (HOST_WIDE_INT);
-+#ifdef RTX_CODE
- extern int arm_split_constant (RTX_CODE, enum machine_mode, rtx,
- HOST_WIDE_INT, rtx, rtx, int);
- extern RTX_CODE arm_canonicalize_comparison (RTX_CODE, enum machine_mode,
+++ /dev/null
-Index: gcc-4.4.2/gcc/config.gcc
-===================================================================
---- gcc-4.4.2.orig/gcc/config.gcc 2009-10-21 16:19:39.000000000 +0200
-+++ gcc-4.4.2/gcc/config.gcc 2009-10-21 16:19:40.000000000 +0200
-@@ -1506,6 +1506,7 @@
- if test x$sjlj != x1; then
- tmake_file="$tmake_file m68k/t-slibgcc-elf-ver"
- fi
-+ tmake_file="m68k/t-floatlib m68k/t-m68kbare m68k/t-m68kelf"
- ;;
- m68k-*-rtems*)
- default_m68k_cpu=68020