From afc6a12d27897300849b80af4d17bcb0c21e7a9b Mon Sep 17 00:00:00 2001 From: Imre Kaloz Date: Sat, 2 Jul 2011 07:43:26 +0000 Subject: [toolchain]: nuke support for older gcc versions, except for 4.4.6 (needed for avr32 and ubicom32) git-svn-id: svn://svn.openwrt.org/openwrt/trunk@27351 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- toolchain/gcc/Config.in | 11 - toolchain/gcc/Config.version | 26 - toolchain/gcc/common.mk | 12 +- .../4.3.3+cs/000-codesourcery_2009q1_203.patch | 57486 ------------------- toolchain/gcc/patches/4.3.3+cs/105-libtool.patch | 84 - .../patches/4.3.3+cs/106-fix_linker_error.patch | 11 - .../patches/4.3.3+cs/301-missing-execinfo_h.patch | 11 - .../gcc/patches/4.3.3+cs/302-c99-snprintf.patch | 13 - .../4.3.3+cs/305-libmudflap-susv3-legacy.patch | 49 - .../gcc/patches/4.3.3+cs/410-fix_pr37436.patch | 71 - .../gcc/patches/4.3.3+cs/420-fix_pr26515.patch | 13 - .../4.3.3+cs/810-arm-softfloat-libgcc.patch | 25 - .../gcc/patches/4.3.3+cs/820-libgcc_pic.patch | 36 - .../gcc/patches/4.3.3+cs/910-mbsd_multi.patch | 270 - .../993-arm_insn-opinit-RTX_CODE-fixup.patch | 32 - .../4.3.3+cs/998-gcc-4.3.0-fix-header.00.patch | 13 - toolchain/gcc/patches/4.3.3+cs/999-coldfire.patch | 10 - toolchain/gcc/patches/4.3.5/100-uclibc-conf.patch | 33 - .../patches/4.3.5/104-gnuhurd-uclibc-conf.patch | 12 - toolchain/gcc/patches/4.3.5/105-libtool.patch | 79 - .../gcc/patches/4.3.5/106-fix_linker_error.patch | 11 - .../gcc/patches/4.3.5/301-missing-execinfo_h.patch | 11 - toolchain/gcc/patches/4.3.5/302-c99-snprintf.patch | 11 - .../4.3.5/305-libmudflap-susv3-legacy.patch | 47 - toolchain/gcc/patches/4.3.5/410-fix_pr37436.patch | 71 - .../patches/4.3.5/810-arm-softfloat-libgcc.patch | 25 - toolchain/gcc/patches/4.3.5/820-libgcc_pic.patch | 36 - toolchain/gcc/patches/4.3.5/910-mbsd_multi.patch | 270 - .../gcc/patches/4.3.5/930-avr32_support.patch | 22417 -------- .../4.3.5/993-arm_insn-opinit-RTX_CODE-fixup.patch | 37 - toolchain/gcc/patches/4.3.5/995-short-enums.diff | 36 - .../4.3.5/998-gcc-4.3.0-fix-header.00.patch | 13 - toolchain/gcc/patches/4.3.5/999-coldfire.patch | 10 - .../4.4.1+cs/000-codesourcery_2010_71.patch | 29759 ---------- .../gcc/patches/4.4.1+cs/100-uclibc-conf.patch | 33 - .../patches/4.4.1+cs/106-fix_linker_error.patch | 12 - .../patches/4.4.1+cs/301-missing-execinfo_h.patch | 11 - .../gcc/patches/4.4.1+cs/302-c99-snprintf.patch | 11 - .../4.4.1+cs/305-libmudflap-susv3-legacy.patch | 47 - .../gcc/patches/4.4.1+cs/600-ubicom_support.patch | 9368 --- .../4.4.1+cs/810-arm-softfloat-libgcc.patch | 25 - .../gcc/patches/4.4.1+cs/820-libgcc_pic.patch | 36 - .../gcc/patches/4.4.1+cs/910-mbsd_multi.patch | 172 - .../993-arm_insn-opinit-RTX_CODE-fixup.patch | 14 - toolchain/gcc/patches/4.4.1+cs/999-coldfire.patch | 10 - 45 files changed, 1 insertion(+), 120789 deletions(-) delete mode 100644 toolchain/gcc/patches/4.3.3+cs/000-codesourcery_2009q1_203.patch delete mode 100644 toolchain/gcc/patches/4.3.3+cs/105-libtool.patch delete mode 100644 toolchain/gcc/patches/4.3.3+cs/106-fix_linker_error.patch delete mode 100644 toolchain/gcc/patches/4.3.3+cs/301-missing-execinfo_h.patch delete mode 100644 toolchain/gcc/patches/4.3.3+cs/302-c99-snprintf.patch delete mode 100644 toolchain/gcc/patches/4.3.3+cs/305-libmudflap-susv3-legacy.patch delete mode 100644 toolchain/gcc/patches/4.3.3+cs/410-fix_pr37436.patch delete mode 100644 toolchain/gcc/patches/4.3.3+cs/420-fix_pr26515.patch delete mode 100644 toolchain/gcc/patches/4.3.3+cs/810-arm-softfloat-libgcc.patch delete mode 100644 toolchain/gcc/patches/4.3.3+cs/820-libgcc_pic.patch delete mode 100644 toolchain/gcc/patches/4.3.3+cs/910-mbsd_multi.patch delete mode 100644 toolchain/gcc/patches/4.3.3+cs/993-arm_insn-opinit-RTX_CODE-fixup.patch delete mode 100644 toolchain/gcc/patches/4.3.3+cs/998-gcc-4.3.0-fix-header.00.patch delete mode 100644 toolchain/gcc/patches/4.3.3+cs/999-coldfire.patch delete mode 100644 toolchain/gcc/patches/4.3.5/100-uclibc-conf.patch delete mode 100644 toolchain/gcc/patches/4.3.5/104-gnuhurd-uclibc-conf.patch delete mode 100644 toolchain/gcc/patches/4.3.5/105-libtool.patch delete mode 100644 toolchain/gcc/patches/4.3.5/106-fix_linker_error.patch delete mode 100644 toolchain/gcc/patches/4.3.5/301-missing-execinfo_h.patch delete mode 100644 toolchain/gcc/patches/4.3.5/302-c99-snprintf.patch delete mode 100644 toolchain/gcc/patches/4.3.5/305-libmudflap-susv3-legacy.patch delete mode 100644 toolchain/gcc/patches/4.3.5/410-fix_pr37436.patch delete mode 100644 toolchain/gcc/patches/4.3.5/810-arm-softfloat-libgcc.patch delete mode 100644 toolchain/gcc/patches/4.3.5/820-libgcc_pic.patch delete mode 100644 toolchain/gcc/patches/4.3.5/910-mbsd_multi.patch delete mode 100644 toolchain/gcc/patches/4.3.5/930-avr32_support.patch delete mode 100644 toolchain/gcc/patches/4.3.5/993-arm_insn-opinit-RTX_CODE-fixup.patch delete mode 100644 toolchain/gcc/patches/4.3.5/995-short-enums.diff delete mode 100644 toolchain/gcc/patches/4.3.5/998-gcc-4.3.0-fix-header.00.patch delete mode 100644 toolchain/gcc/patches/4.3.5/999-coldfire.patch delete mode 100644 toolchain/gcc/patches/4.4.1+cs/000-codesourcery_2010_71.patch delete mode 100644 toolchain/gcc/patches/4.4.1+cs/100-uclibc-conf.patch delete mode 100644 toolchain/gcc/patches/4.4.1+cs/106-fix_linker_error.patch delete mode 100644 toolchain/gcc/patches/4.4.1+cs/301-missing-execinfo_h.patch delete mode 100644 toolchain/gcc/patches/4.4.1+cs/302-c99-snprintf.patch delete mode 100644 toolchain/gcc/patches/4.4.1+cs/305-libmudflap-susv3-legacy.patch delete mode 100644 toolchain/gcc/patches/4.4.1+cs/600-ubicom_support.patch delete mode 100644 toolchain/gcc/patches/4.4.1+cs/810-arm-softfloat-libgcc.patch delete mode 100644 toolchain/gcc/patches/4.4.1+cs/820-libgcc_pic.patch delete mode 100644 toolchain/gcc/patches/4.4.1+cs/910-mbsd_multi.patch delete mode 100644 toolchain/gcc/patches/4.4.1+cs/993-arm_insn-opinit-RTX_CODE-fixup.patch delete mode 100644 toolchain/gcc/patches/4.4.1+cs/999-coldfire.patch (limited to 'toolchain') diff --git a/toolchain/gcc/Config.in b/toolchain/gcc/Config.in index 7f8a0fc317..556a56955f 100644 --- a/toolchain/gcc/Config.in +++ b/toolchain/gcc/Config.in @@ -2,16 +2,11 @@ choice prompt "GCC compiler Version" if TOOLCHAINOPTS - default GCC_VERSION_4_3_3_CS if GCC_DEFAULT_VERSION_4_3_3_CS - default GCC_VERSION_4_3_5 if GCC_DEFAULT_VERSION_4_3_5 default GCC_VERSION_4_4_6 if GCC_DEFAULT_VERSION_4_4_6 default GCC_VERSION_LINARO help Select the version of gcc you wish to use. - config GCC_VERSION_4_3_5 - bool "gcc 4.3.5" - config GCC_VERSION_4_4_6 bool "gcc 4.4.6" @@ -25,12 +20,6 @@ choice bool "llvm-gcc 4.2" depends BROKEN - config GCC_VERSION_4_3_3_CS - bool "gcc 4.3.3 with CodeSourcery enhancements" - - config GCC_VERSION_4_4_1_CS - bool "gcc 4.4.1 with CodeSourcery enhancements" - endchoice config GCC_USE_GRAPHITE diff --git a/toolchain/gcc/Config.version b/toolchain/gcc/Config.version index 81d4374e4b..46da90070d 100644 --- a/toolchain/gcc/Config.version +++ b/toolchain/gcc/Config.version @@ -1,14 +1,6 @@ config GCC_DEFAULT_VERSION bool -config GCC_DEFAULT_VERSION_4_3_3_CS - select GCC_DEFAULT_VERSION - bool - -config GCC_DEFAULT_VERSION_4_3_5 - select GCC_DEFAULT_VERSION - bool - config GCC_DEFAULT_VERSION_4_4_6 select GCC_DEFAULT_VERSION default y if (avr32 || ubicom32) @@ -21,23 +13,14 @@ config GCC_DEFAULT_VERSION_LINARO config GCC_VERSION string - default "4.3.3+cs" if GCC_VERSION_4_3_3_CS - default "4.3.5" if GCC_VERSION_4_3_5 - default "4.4.1+cs" if GCC_VERSION_4_4_1_CS default "4.4.6" if GCC_VERSION_4_4_6 default "4.6.1" if GCC_VERSION_4_6_1 default "linaro" if GCC_VERSION_LINARO default "llvm" if GCC_VERSION_LLVM default "linaro" -config GCC_VERSION_4_3 - bool - default y if GCC_VERSION_4_3_3_CS - default y if GCC_VERSION_4_3_5 - config GCC_VERSION_4_4 bool - default y if GCC_VERSION_4_4_1_CS default y if GCC_VERSION_4_4_6 config GCC_VERSION_4_5 @@ -50,14 +33,6 @@ config GCC_VERSION_4_6 if !TOOLCHAINOPTS - config GCC_VERSION_4_3_3_CS - default y if GCC_DEFAULT_VERSION_4_3_3_CS - bool - - config GCC_VERSION_4_3_5 - default y if GCC_DEFAULT_VERSION_4_3_5 - bool - config GCC_VERSION_4_4_6 default y if GCC_DEFAULT_VERSION_4_4_6 bool @@ -66,5 +41,4 @@ if !TOOLCHAINOPTS default y if GCC_DEFAULT_VERSION_LINARO bool - endif diff --git a/toolchain/gcc/common.mk b/toolchain/gcc/common.mk index d0c62940a2..2762f6ad09 100644 --- a/toolchain/gcc/common.mk +++ b/toolchain/gcc/common.mk @@ -48,20 +48,11 @@ else PKG_SOURCE_URL:=@GNU/gcc/gcc-$(PKG_VERSION) PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 - ifeq ($(PKG_VERSION),4.3.3) - PKG_MD5SUM:=cc3c5565fdb9ab87a05ddb106ba0bd1f - 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.6) PKG_MD5SUM:=ab525d429ee4425050a554bc9247d6c4 endif ifeq ($(PKG_VERSION),4.6.1) - PKG_MD5SUM:=c57a9170c677bf795bdc04ed796ca491 + PKG_MD5SUM:=c57a9170c677bf795bdc04ed796ca491 endif endif endif @@ -112,7 +103,6 @@ GCC_CONFIGURE:= \ $(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),--enable-poison-system-directories) ifneq ($(CONFIG_GCC_VERSION_4_4)$(CONFIG_GCC_VERSION_4_5)$(CONFIG_GCC_VERSION_4_6),) ifneq ($(CONFIG_mips)$(CONFIG_mipsel),) diff --git a/toolchain/gcc/patches/4.3.3+cs/000-codesourcery_2009q1_203.patch b/toolchain/gcc/patches/4.3.3+cs/000-codesourcery_2009q1_203.patch deleted file mode 100644 index 4e93370341..0000000000 --- a/toolchain/gcc/patches/4.3.3+cs/000-codesourcery_2009q1_203.patch +++ /dev/null @@ -1,57486 +0,0 @@ ---- /dev/null -+++ b/ChangeLog.csl -@@ -0,0 +1,7077 @@ -+2009-05-21 Paul Brook -+ -+ Issue #5545 -+ gcc/ -+ * config/arm/arm.md (ifcompare_neg_move): Disable when -+ TARGET_NO_SINGLE_COND_EXEC. -+ -+2009-05-20 Joseph Myers -+ -+ Issue #5399 -+ -+ gcc/ -+ * config/mips/mips.md (sqrt2): Condition on -+ . -+ -+2009-05-20 Maciej W. Rozycki -+ -+ Issue #5448 -+ gcc/ -+ * config/mips/predicates.md (const_call_insn_operand): Correct the -+ condition used for -call_nonpic support. -+ -+ * release-notes-csl.xml (Compiler performance bug fix): New. -+ -+2009-05-12 Maxim Kuvyrkov -+ -+ * ChangeLog.csl: Add changelog for the previous commit. -+ gcc/ -+ * configure: Regenerate with proper autoconf version. -+ -+2009-05-12 Maxim Kuvyrkov -+ -+ gcc/ -+ * common.opt (feglibc): New dummy option. -+ * opts.c (common_handle_option): Handle it. -+ * config.gcc: Handle 'eglibc' vendor. -+ * config/t-eglibc: Define multilibs for testing EGLIBC features. -+ * configure.ac (--with-eglibc-configs, EGLICB_CONFIGS): New option and -+ variable. -+ * configure: Regenerate. -+ * Makefile.in (EGLIBC_CONFIGS): Handle -+ -+2009-05-08 Nathan Sidwell -+ -+ Issue 5335 -+ gcc/ -+ * class.c (resolve_address_of_overloaded_function): Use -+ OVL_CURRENT for error. -+ (instantiate_type): Allow FUNCTION_DECL when ms_extensions are -+ active. Don't copy the rhs node. Delete COMPOUND_EXPR code. -+ * typeck.c (build_compound_expr): Check RHS has known type. -+ -+ gcc/testsuite/ -+ * g++.dg/ext/ms-1.C: New. -+ * g++.old-deja/g++.other/overload11.C: Adjust. -+ -+ * release-notes-csl.xml: Add two notes. -+ -+2009-04-22 Maxim Kuvyrkov -+ -+ gcc/testsuite/ -+ * gcc.dg/tls/alias-1.c: Fix check for TLS. -+ -+2009-04-22 Maxim Kuvyrkov -+ -+ Issue #5106 -+ Issue #4768 -+ -+ gcc/testsuite/ -+ * gcc.dg/falign-labels-1.c (dg-options): Don't set for m68k and fido. -+ -+2009-04-21 Andrew Jenner -+ -+ gcc/testsuite/ -+ * gcc.dg/pr34856.c: Handle powerpc*-*-elf. -+ -+2009-04-21 Andrew Jenner -+ -+ gcc/testsuite/ -+ * lib/target-supports.exp: Handle powerpc-*-elf. -+ -+2009-04-21 Maxim Kuvyrkov -+ -+ gcc/testsuite/ -+ * gcc.target/m68k/tls-ld.c, gcc.target/m68k/tls-le.c, -+ * gcc.target/m68k/tls-ld-xgot-xtls.c, gcc.target/m68k/tls-gd-xgot.c, -+ * gcc.target/m68k/tls-ie-xgot.c, gcc.target/m68k/tls-ld-xgot.c, -+ * gcc.target/m68k/tls-ld-xtls.c, gcc.target/m68k/tls-le-xtls.c, -+ * gcc.target/m68k/tls-gd.c, gcc.target/m68k/tls-ie.c: Remove -mcpu=5475 -+ setting, run only for *-linux-* target. -+ -+2009-04-15 Daniel Jacobowitz -+ -+ Revert (moved to scripts): -+ -+ 2009-04-10 Maxim Kuvyrkov -+ -+ Issue #693 -+ -+ gcc/ -+ * config/arm/linux-eabi.h (TARGET_UNWIND_TABLES_DEFAULT): Define -+ to true. -+ -+2009-04-13 Kazu Hirata -+ -+ gcc/testsuite/ -+ * gcc.dg/promote-short-3.c: XFAIL on fido. -+ -+2009-04-10 Daniel Jacobowitz -+ -+ gcc/testsuite/ -+ * gcc.dg/promote-short-3.c: Correct XFAIL syntax. -+ -+2009-04-10 Maxim Kuvyrkov -+ -+ Issue #693 -+ -+ gcc/ -+ * config/arm/linux-eabi.h (TARGET_UNWIND_TABLES_DEFAULT): Define -+ to true. -+ -+2009-04-09 Sandra Loosemore -+ -+ Issue #5174 -+ Backport from mainline: -+ -+ gcc/ -+ * doc/invoke.texi (Optimize Options): Add cross-reference to -+ -Q --help=optimizers examples. -+ -+2009-04-09 Nathan Froyd -+ -+ gcc/testsuite/ -+ * gcc.dg/promote-short-3.c: XFAIL test for x86, m68k, sh, and mips. -+ -+2009-04-09 Nathan Froyd -+ -+ Issue #5186 -+ -+ gcc/ -+ * tree-ssa-loop-promote.c (rebuild_with_promotion_1): Load a memory -+ reference prior to promoting it. -+ -+ gcc/testsuite/ -+ * gcc.dg/promote-short-9.c: New test. -+ -+2009-04-08 Nathan Froyd -+ -+ Issue #5171 -+ -+ gcc/ -+ * tree-ssa-loop-promote.c (collection_promotion_candidates): -+ Delay allocation and initialization of new promote_info until we -+ know we have a candidate loop index. -+ -+2009-04-06 Daniel Jacobowitz -+ -+ Backport from upstream: -+ -+ gcc/ -+ 2008-04-24 Uros Bizjak -+ -+ PR rtl-optimization/36006 -+ * expmed.c (store_fixed_bit_field): Copy op0 rtx before moving -+ temp to op0 in order to avoid invalid rtx sharing. -+ -+ gcc/testsuite/ -+ 2008-04-24 Francois-Xavier Coudert -+ -+ PR rtl-optimization/36006 -+ * gfortran.dg/pr36006-1.f90: New test. -+ * gfortran.dg/pr36006-2.f90: Ditto. -+ -+2009-04-06 Paul Brook -+ -+ Issue #5117 -+ Partial backport from FSF. -+ -+ gcc/ -+ * tree-ssa-pre.c (create_expression_by_pieces): Convert to sizetype -+ for POINTER_PLUS_EXPR. -+ -+2009-04-04 Daniel Jacobowitz -+ -+ gcc/ -+ * gcc.c (do_self_spec): Handle switches with arguments. -+ -+2009-04-04 Daniel Jacobowitz -+ -+ gcc/ -+ * testsuite/gcc.dg/pr34263.c: Add -fno-unroll-loops. -+ -+2009-04-04 Daniel Jacobowitz -+ -+ gcc/ -+ * config/arm/arm.md (insv): Do not share operands[0]. -+ -+2009-04-04 Sandra Loosemore -+ -+ Issue #5104 -+ PR tree-optimization/39604 -+ -+ * release-notes-csl.xml (Corruption of block-scope variables): -+ New note. -+ -+ gcc/testsuite -+ * g++.dg/tree-ssa/sink-1.C: New. -+ -+ gcc/ -+ * tree_ssa-sink.c (sink_code_in_bb): Do not sink statements out -+ of a lexical block containing variable definitions. -+ -+2009-03-31 Andrew Jenner -+ -+ gcc/testsuite/ -+ * gcc.dg/arm-g2.c: Add dg-skip-if for MontaVista. -+ * gcc.dg/arm-scd42-2.c: Ditto. -+ -+2009-03-31 Daniel Jacobowitz -+ -+ gcc/ -+ * common.opt (fpromote-loop-indices): Add Optimization keyword. -+ -+2009-03-31 Kazu Hirata -+ -+ Issue #5105 -+ gcc/testsuite/ -+ * gcc.target/m68k/pr36134.c: Use dg-skip-if to skip the testcase -+ if there is a conflict with -mcpu=. Use -mcpu=5208. -+ -+2009-03-30 Andrew Jenner -+ -+ gcc/ -+ * config.gcc: Accept montavista*-, not just montavista-. -+ * config/mips/t-montavista-linux: Add Octeon multilibs. -+ -+2009-03-25 Andrew Stubbs -+ -+ gcc/testsuite/ -+ * gcc.dg/pragma-isr-trapa2.c: Skip test for FPU-less architectures. -+ -+2009-03-24 Andrew Stubbs -+ -+ Backport from upstream: -+ gcc/testsuite/ -+ 2008-02-25 Kaz Kojima -+ * gcc.dg/tree-ssa/ssa-pre-10.c: Use -fno-finite-math-only on -+ sh* targets. -+ -+2009-03-22 Mark Mitchell -+ -+ Backport: -+ -+ libstdc++-v3/ -+ * testsuite/25_algorithms/search_n/iterator.cc: Condition -+ iterations for simulators. -+ * testsuite/25_algorithms/heap/moveable.cc: Likewise. -+ * testsuite/21_strings/basic_string/inserters_extractors/char/28277.cc -+ Condition stream width for simulators. -+ * testsuite/27_io/basic_ostream/inserters_character/char/28277-3.cc: -+ Likewise. -+ * testsuite/27_io/basic_ostream/inserters_character/char/28277-4.cc: -+ Likewise. -+ * testsuite/ext/vstring/inserters_extractors/char/28277.cc: Likewise. -+ -+2009-03-20 Mark Mitchell -+ -+ Issue #4403 -+ -+ * release-notes-csl.xsml: Document compile-time performance -+ improvement. -+ -+2009-03-19 Joseph Myers -+ -+ Issue #2062 -+ Issue #4730 -+ -+ gcc/ -+ * config/arm/t-cs-linux: Add MULTILIB_MATCHES for ARMv4T -mcpu -+ options and for -mfpu=neon-fp16. Add armv7-a-hard multilib. -+ -+2009-03-19 Daniel Gutson -+ -+ Issue #4459 -+ -+ gcc/ -+ * config/arm/t-cs-linux: Replaced armv7 by armv7-a in MULTILIB_OPTIONS -+ and added mfpu=neon, plus the required MULTILIB_ALIASES. -+ -+ * release-notes.xml: Document. -+ -+2009-03-19 Andrew Stubbs -+ -+ gcc/ -+ * config.gcc (sh-*-*): Add support for --enable-extra-sgxx-multilibs. -+ -+2009-03-18 Daniel Gutson -+ -+ Issue #4753 -+ -+ gcc/ -+ * doc/invoke.texi: Added entries for cpus ARM Cortex-M0 and Cortex-M1. -+ -+2009-03-18 Sandra Loosemore -+ -+ Issue #4882 -+ -+ * release-notes-csl.xml (Better code for accessing global variables): -+ Copy-edit. Reference updated GCC manual discussion. -+ -+ Applied simultaneously to mainline: -+ gcc/ -+ * doc/invoke.texi (Code Gen Options): Expand discussion of -+ -fno-common. -+ -+2009-03-18 Kazu Hirata -+ -+ gcc/ -+ * config/sparc/sparc.c (sparc_emit_float_lib_cmp): Pass a libcall -+ SYMBOL_REF to hard_libcall_value. -+ -+2009-03-17 Sandra Loosemore -+ -+ Issue #4755 -+ -+ gcc/ -+ * config/arm/arm.c (arm_emit_fp16_const): New function. -+ * config/arm/arm-protos.h (arm_emit_fp16_const): Declare it. -+ * config/arm/arm.md (consttable_2): Replace logic for HFmode values -+ with assertion that they can't appear here. -+ (consttable_4): Add HFmode case and use the new function for it. -+ -+2009-03-17 Sandra Loosemore -+ -+ Issue #4755 -+ -+ Revert: -+ -+ 2009-01-23 Sandra Loosemore -+ -+ gcc/ -+ * config/arm/arm.c (dump_minipool): Use size of mode, not padded size, -+ in switch that controls whether to emit padding. -+ -+ 2009-02-05 Sandra Loosemore -+ -+ gcc/ -+ * config/arm/arm.c (struct minipool_fixup): Split mode field into -+ value_mode and ref_mode. -+ (add_minipool_forward_ref): Use value_mode of fixup. -+ (add_minipool_backward_ref): Likewise. -+ (push_minipool_fix): Pass both value_mode and ref_mode as parameters, -+ and store them in the fixup. -+ (note_invalid_constants): Adjust arguments to push_minipool_fix. -+ (arm_reorg): Use ref_mode of fixup. -+ -+2009-03-17 Daniel Gutson -+ -+ Issue #4753 -+ -+ gcc/ -+ * config/arm/t-cs-eabi (MULTILIB_MATCHES): Added cortex-m0 as a synonym of march=armv6-m. -+ * config/arm/arm-cores.def: Added core cortex-m0. -+ * config/arm/arm-tune.md ("tune"): Aded cortexm0. -+ * config/arm/t-arm-elf (MULTILIB_MATCHES): Added cortex-m0 as a synonym of march=armv6-m. -+ * config/arm/t-uclinux-eabi (MULTILIB_MATCHES): Added cortex-m0 as a synonym of march=armv6-m. -+ -+ * release-notes.csl: Document. -+ -+2009-03-16 Daniel Jacobowitz -+ -+ gcc/ -+ * config/arm/neon-testgen.ml: Use dg-add-options arm_neon. -+ -+ gcc/testsuite/ -+ * gcc/target/arm/neon/: Regenerated test cases. -+ -+ * gcc.target/arm/neon-dse-1.c, gcc.target/arm/neon/polytypes.c, -+ gcc.target/arm/neon-vmla-1.c, gcc.target/arm/neon-vmls-1.c, -+ gcc.target/arm/neon-cond-1.c, gcc.dg/torture/arm-fp16-ops-8.c, -+ gcc.dg/torture/arm-fp16-ops-7.c, g++.dg/ext/arm-fp16/arm-fp16-ops-7.C, -+ g++.dg/ext/arm-fp16/arm-fp16-ops-8.C, g++.dg/abi/mangle-neon.C: Use -+ dg-add-options arm_neon. -+ -+ * gcc.target/arm/fp16-compile-vcvt.c, gcc.dg/torture/arm-fp16-ops-5.c, -+ gcc.dg/torture/arm-fp16-ops-6.c, g++.dg/ext/arm-fp16/arm-fp16-ops-5.C, -+ g++.dg/ext/arm-fp16/arm-fp16-ops-6.C: Use dg-add-options arm_neon_fp16 -+ and arm_neon_fp16_ok. -+ -+ * gcc.dg/vect/vect.exp, g++.dg/vect/vect.exp, -+ gfortran.dg/vect/vect.exp: Use add_options_for_arm_neon. -+ -+ * lib/target-supports.exp (add_options_for_arm_neon): New. -+ (check_effective_target_arm_neon_ok_nocache): New, from -+ check_effective_target_arm_neon_ok. Check multiple possibilities. -+ (check_effective_target_arm_neon_ok): Use -+ check_effective_target_arm_neon_ok_nocache. -+ (add_options_for_arm_neon_fp16) -+ (check_effective_target_arm_neon_fp16_ok) -+ check_effective_target_arm_neon_fp16_ok_nocache): New. -+ (check_effective_target_arm_neon_hw): Use add_options_for_arm_neon. -+ -+2009-03-16 Daniel Jacobowitz -+ -+ gcc/testsuite/ -+ * lib/target-supports.exp (check_effective_target_arm_neon_ok): -+ Correct arm_neon.h typo. -+ -+2009-03-16 Sandra Loosemore -+ -+ Issue #4878 -+ -+ * release-notes-csl.xml (VFP ABI support): New note. -+ -+2008-03-15 Catherine Moore -+ -+ Merge from Sourcery G++ 4.2: -+ -+ gcc/ -+ 2008-02-11 David Ung -+ -+ * config/mips/mips.c (mips_output_division): When -+ GENERATE_DIVIDE_TRAPS, generate the trap instrutions -+ against zero before the actual divide. This is friendlier -+ to out-of-order cpus like the 74k. -+ -+2009-03-13 Joseph Myers -+ -+ Issue #2062 -+ -+ gcc/ -+ * config/arm/t-linux-eabi: Add MULTILIB_MATCHES for ARMv4T -mcpu -+ options. -+ -+2009-03-13 Mark Mitchell -+ -+ Issue #3999 -+ -+ * release-notes-csl.xml: Document. -+ gcc/ -+ * config/arm/neon.md (*mul3add_neon): New pattern. -+ (*mul3negadd_neon): Likewise. -+ gcc/testsuite -+ * gcc.dg/target/arm/neon-vmla-1.c: New. -+ * gcc.dg/target/arm/neon-vmls-1.c: Likewise. -+ -+2009-03-13 Catherine Moore -+ -+ gcc/ -+ * config/i386/x-mingw32 (host-mingw32.o): Replace -+ diagnostic.h with $(DIAGNOSTIC_H). -+ -+2009-03-12 Joseph Myers -+ -+ Issue #4730 -+ -+ gcc/ -+ * config/arm/t-cs-eabi: Add MULTILIB_MATCHES for -mhard-float. -+ -+2009-03-12 Joseph Myers -+ -+ Issue #4730 -+ Issue #4850 -+ -+ gcc/ -+ * config/arm/t-cs-eabi: Add VFP ABI multilib. Add -+ MULTILIB_MATCHES for -march=armv5t and -mfpu=neon-fp16. -+ -+2009-03-12 Daniel Gutson -+ -+ Issue #4459 -+ -+ gcc/ -+ * config/arm/t-cs-eabi: Replaced Thumb2 VFP multilibs by ARM VFP3 NEON. -+ * release-notes-csl.xml: Document. -+ -+2009-03-11 Nathan Froyd -+ -+ Backport from mainline: -+ -+ gcc/ -+ 2009-03-10 Richard Guenther -+ Nathan Froyd -+ -+ PR middle-end/37850 -+ * libgcc2.c (__mulMODE3): Use explicit assignments to form the -+ result. -+ (__divMODE3): Likewise. -+ -+2009-03-11 Nathan Froyd -+ -+ Backport from mainline: -+ -+ gcc/testsuite/ -+ 2009-03-11 Nathan Froyd -+ -+ * gcc.dg/vect/vect-82.c: Combine dg-do and -+ dg-require-effective-target into dg-skip-if. -+ * gcc.dg/vect/vect-83.c: Likewise. -+ -+2009-03-10 Nathan Froyd -+ -+ Issue #4569 -+ -+ * release-notes-csl.xml (Loop optimization improvements): New note. -+ -+2009-03-09 Nathan Froyd -+ -+ Issue #4569 -+ -+ gcc/ -+ * tree-ssa-loop-promote.c: New file. -+ * common.opt (fpromote-loop-indices): New option. -+ * timevar.def (TV_TREE_LOOP_PROMOTE): New timevar. -+ * Makefile.in (tree-ssa-loop-promote.o): New rule. -+ (OBJS-comon): Include it. -+ * tree-pass.h (pass_promote_short_indices): Declare. -+ * passes.c (init_optimization_passes): Add it. -+ * pointer-set.h (pointer_set_n_elements, pointer_set_clear, -+ pointer_map_n_elements, pointer_map_clear): Declare. -+ * pointer-set.c (pointer_set_n_elements, pointer_set_clear, -+ pointer_map_n_elements, pointer_map_clear): Define. -+ -+ gcc/doc/ -+ * invoke.texi (-fpromote-loop-indices): New entry. -+ -+ gcc/testsuite/ -+ * gcc.dg/promote-short-1.c: New file. -+ * gcc.dg/promote-short-2.c: New file. -+ * gcc.dg/promote-short-3.c: New file. -+ * gcc.dg/promote-short-4.c: New file. -+ * gcc.dg/promote-short-5.c: New file. -+ * gcc.dg/promote-short-6.c: New file. -+ * gcc.dg/promote-short-7.c: New file. -+ * gcc.dg/promote-short-8.c: New file. -+ -+2009-03-07 Mark Mitchell -+ -+ * release-notes-csl.xml: Mention use of -fno-common by default on -+ bare--metal targets. -+ -+2009-03-07 Joseph Myers -+ -+ Issue #4730 -+ -+ Merge from ARM/hard_vfp_4_4_branch: -+ -+ gcc/testsuite/ -+ 2009-03-06 Richard Earnshaw -+ * lib/target-supports.exp (check_effective_target_hard_vfp_ok): Make -+ this a linkage test. -+ * gcc.target/arm/aapcs/aapcs.exp: New framework for testing AAPCS -+ argument marshalling. -+ * abitest.h: New file. -+ * vfp1.c, vfp2.c, vfp3.c, vfp4.c, vfp5.c, vfp6.c, vfp7.c: New tests. -+ * vfp8.c, vfp9.c, vfp10.c, vfp11.c, vfp12.c, vfp13.c, vfp14.c: New. -+ -+2009-03-06 Joseph Myers -+ -+ Issue #4730 -+ -+ gcc/ -+ * doc/invoke.texi (-mfloat-abi=@var{name}): Remove statement about -+ -mfloat-abi=hard not being supported for VFP. -+ -+2009-03-06 Mark Mitchell -+ -+ gcc/ -+ * configure.ac (--with-specs): New option. -+ * configure: Regenerated. -+ * gcc.c (driver_self_specs): Include CONFIGURE_SPECS. -+ * Makefile.in (DRIVER_DEFINES): Add -DCONFIGURE_SPECS. -+ -+2009-03-05 Mark Mitchell -+ -+ Backport: -+ -+ gcc/testsuite/ -+ 2009-01-07 Janis Johnson -+ * g++.dg/torture/pr38586.C: Ignore a possible warning. -+ -+2009-03-05 Joseph Myers -+ -+ Issue #4730 -+ -+ gcc/ -+ * config/arm/arm.c (arm_handle_pcs_attribute): New. -+ (arm_get_pcs_model): Pass attribute arguments to -+ arm_pcs_from_attribute. -+ (arm_init_cumulative_args): Use base AAPCS for conversions from -+ floating-point types to DImode. -+ (arm_attribute_table): Add pcs attribute. -+ (arm_handle_pcs_attribute): New. -+ * config/arm/bpabi.h (DECLARE_LIBRARY_RENAMES): When renaming -+ conversions from floating-point types to DImode, also declare them -+ to use base AAPCS and declare functions they call to use base -+ AAPCS and their RTABI names. -+ -+ gcc/testsuite/ -+ * gcc.target/arm/eabi1.c: Do not skip for non-base ABI variants. -+ (PCS): Define macro to use base AAPCS. -+ (decl_float, __aeabi_d2f, __aeabi_f2d): Use PCS macro. -+ -+2009-03-05 Mark Mitchell -+ -+ Backport: -+ -+ gcc/testsuite/ -+ 2008-11-24 DJ Delorie -+ * gcc.c-torture/execute/pr36321.c: Don't rely on argv[0] being set. -+ -+2009-03-05 Joseph Myers -+ -+ Issue #4730 -+ -+ gcc/ -+ * config/arm/arm.c (aapcs_vfp_sub_candidate): Use V2SImode and -+ V4SImode as representatives of all 64-bit and 128-bit vector -+ types. Allow vector types without vector modes. -+ (aapcs_vfp_is_call_or_return_candidate): Handle vector types -+ without vector modes like BLKmode. -+ (aapcs_vfp_allocate): Handle TImode for non-TARGET_NEON like -+ BLKmode. Avoid unsupported vector modes or TImode moves for -+ non-TARGET_NEON. -+ (aapcs_vfp_allocate_return_reg): Likewise. -+ (arm_vector_mode_supported_p): Only support V2SImode, V4HImode and -+ V8QImode if TARGET_NEON || TARGET_IWMMXT. -+ -+2009-03-04 Daniel Gutson -+ -+ Issue #4462 -+ -+ gcc/ -+ * config/arm/t-cs-linux: Removed marvell-f multilibs. -+ -+ * release-notes-csl.xml: Document. -+ -+2009-03-04 Joseph Myers -+ -+ Issue #4730 -+ -+ gcc/ -+ * config/arm/arm.c (arm_return_in_memory): Handle returning -+ vectors of suitable size in registers also for AAPCS case. -+ -+2009-03-04 Joseph Myers -+ -+ Issue #3681 -+ -+ Backport: -+ -+ gcc/ -+ 2009-03-03 Joseph Myers -+ * emit-rtl.c (adjust_address_1): Reduce offset to a signed value -+ that fits within Pmode. -+ -+ gcc/testsuite/ -+ 2009-03-03 Joseph Myers -+ * gcc.c-torture/compile/20090303-1.c, -+ gcc.c-torture/compile/20090303-2.c: New tests. -+ -+2009-03-03 Andrew Stubbs -+ -+ gcc/ -+ * config/sh/t-sgxxlite-linux (MULTILIB_EXCEPTIONS): Allow big endian -+ SH4A multilib. -+ -+2009-03-01 Mark Mitchell -+ -+ Issue #4768 -+ -+ * release-notes-csl.xml: Document. -+ gcc/ -+ * final.c (shorten_branches): Do not align labels for jump tables. -+ (final_scan_insn): Use JUMP_TABLE_DATA_P. -+ -+2009-03-02 Daniel Gutson -+ -+ Issue #4462 -+ -+ gcc/ -+ * config/arm/t-cs-eabi: Replaced marvell-f with armv5t multilibs. -+ -+ * release-notes-csl.xml: Document. -+ -+2009-03-02 Nathan Froyd -+ -+ Issue #4344 -+ -+ gcc/ -+ * tree.h (struct tree_type): Enlarge precision field. Rearrange -+ fields to position things within bytes. Move packed_flag to... -+ (struct tree_base): ...here. Decrease spare field accordingly. -+ (TYPE_PACKED): Adjust to reflect new packed_flag location. -+ * config/arm/arm-modes.def (XI): Define it as a real INT_MODE. -+ -+ gcc/testsuite/ -+ * gcc.target/arm/neon-dse-2.c: New test. -+ -+2009-02-27 Daniel Gutson -+ -+ Issue #4459 -+ -+ gcc/ -+ * config/arm/linux-eabi.h (LINK_SPEC): BE8_LINK_SPEC added. -+ * config/arm/arm-cores.def: Comment added. -+ * config/arm/bpapi.h (BE8_LINK_SPEC): New define. -+ (LINK_SPEC): BE_LINK_SPEC added. -+ -+ * release-notes-csl.xml: Add note. -+ -+2009-02-27 Joseph Myers -+ -+ Issue #4730 -+ -+ gcc/ -+ * config/arm/arm.c (aapcs_layout_arg): Handle coprocessor argument -+ candidates after a previous argument failed to be allocated to -+ coprocessor registers the same way as the first failing argument. -+ -+2009-02-26 Joseph Myers -+ -+ Issue #4730 -+ -+ gcc/ -+ * config/arm/arm.c (arm_libcall_value, arm_init_cumulative_args): -+ Use base ABI for conversion libfuncs between HFmode and SFmode. -+ -+2009-02-26 Nathan Froyd -+ -+ Issue #4344 -+ -+ gcc/testsuite/ -+ * gcc.target/arm/neon-dse-1.c: New test. -+ -+2009-02-25 Nathan Froyd -+ -+ Issue #4344 -+ -+ * release-notes-csl.xml (Internal compiler error with large -+ NEON types): New note. -+ -+ gcc/ -+ * dse.c (struct store_info): Change positions_needed to an -+ unsigned HOST_WIDEST_INT. -+ -+ Backport portions of: -+ 2008-12-23 Jakub Jelinek -+ -+ gcc/ -+ * dse.c (struct store_info): Change begin and end fields to -+ HOST_WIDE_INT. -+ (set_position_unneeded, set_all_positions_unneeded, -+ any_positions_needed_p, all_positions_needed_p): New static inline -+ functions. -+ (set_usage_bits): Don't look at stores where -+ offset + width >= MAX_OFFSET. -+ (check_mem_read_rtx): Use all_positions_needed_p function. -+ -+ Backport from mainline: -+ gcc/ -+ 2008-04-11 H.J. Lu -+ -+ * dse.c (lowpart_bitmask): New. -+ -+2009-02-26 Joseph Myers -+ -+ Issue #4730 -+ -+ Merge from ARM/hard_vfp_4_4_branch: -+ -+ gcc/ -+ 2009-01-13 Richard Earnshaw -+ -+ * doc/tm.texi (TARGET_LIBCALL_VALUE): Add missing end statement. -+ -+ 2008-12-09 Richard Earnshaw -+ -+ ARM Hard-VFP calling convention -+ * target-def.h (TARGET_LIBCALL_VALUE): New hook. -+ * target.h (gcc_target): Add libcall_value to table of call hooks. -+ * targhooks.h (default_libcall_value): Default implementation. -+ * targhooks.c (default_libcall_value): Likewise. -+ * doc/tm.texi (TARGET_LIBCALL_VALUE): Document it. -+ * optabs.c (expand_unop): Use it. -+ * expr.h (hard_libcall_value): Pass the function RTX through. -+ * calls.c (emit_library_call_value_1): Update call to -+ hard_libcall_value. -+ * explow.c (hard_libcall_value): Use new target hook. -+ * testsuite/lib/target-supports.exp -+ (check_effective_target_arm_hard_vfp_ok): New hook. -+ (check_effective_target_arm_neon_ok): Improve test for neon -+ availability. -+ * testsuite/gcc.target/arm/eabi1.c: Only run test in base variant. -+ * config/arm/arm.c: Include cgraph.h -+ (TARGET_FUNCTION_VALUE): Override default hook. -+ (arm_pcs_default): New variable. -+ (arm_override_options): Don't fault hard calling convention with VFP. -+ Add support for AAPCS variants. -+ (arm_function_value): Make static. Handle AAPCS variants. -+ (arm_libcall_value): New function. -+ (arm_apply_result_size): Handle VFP registers in results. -+ (arm_return_in_memory): Rework all AAPCS variants; handle hard-vfp -+ conventions. -+ (pcs_attribute_args): New variable. -+ (arm_pcs_from_attribute): New function. -+ (arm_get_pcs_model): New function. -+ (aapcs_vfp_cum_init): New function. -+ (aapcs_vfp_sub_candidate): New function. -+ (aapcs_vfp_is_return_candidate): New function. -+ (aapcs_vfp_is_call_candidate): New function. -+ (aapcs_vfp_allocate): New function. -+ (aapcs_vfp_allocate_return_reg): New function. -+ (aapcs_vfp_advance): New function. -+ (aapcs_cp_arg_layout): New variable. -+ (aapcs_select_call_coproc): New function. -+ (aapcs_select_return_coproc): New function. -+ (aapcs_allocate_return_reg): New function. -+ (aapcs_libcall_value): New function. -+ (aapcs_layout_arg): New function. -+ (arm_init_cumulative_args): Initialize AAPCS args data. -+ (arm_function_arg): Handle AAPCS variants using new interface. -+ (arm_arg_parital_bytes): Likewise. -+ (arm_function_arg_advance): New function. -+ (arm_function_ok_for_sibcall): Ensure that sibling calls agree on -+ calling conventions. -+ (arm_setup_incoming_varargs): Handle new AAPCS args data. -+ * arm.h (NUM_VFP_ARG_REGS): Define. -+ (LIBCALL_VALUE): Update. -+ (FUNCTION_VALUE): Delete. -+ (FUNCTION_VALUE_REGNO_P): Add VFP regs. -+ (arm_pcs): New enum. -+ (CUMULATIVE_ARGS): New data to support AAPCS argument marshalling. -+ (FUNCTION_ARG_ADVANCE): Call arm_function_arg_advance. -+ (FUNCTION_ARG_REGNO_P): Add VFP regs. -+ * arm-protos.h (arm_function_arg_advance): Add. -+ (aapcs_libcall_value): Add. -+ (arm_function_value): Delete. -+ -+2009-02-25 Joseph Myers -+ -+ Backport from FSF: -+ -+ gcc/ -+ 2008-05-08 Kai Tietz -+ * config/arm/arm.c (arm_return_in_memory): Add fntype argumen. -+ * config/arm/arm.h (RETURN_IN_MEMORY): Replace RETURN_IN_MEMORY -+ by TARGET_RETURN_IN_MEMORY. -+ * config/arm/arm-protos.h (arm_return_in_memory): Add fntype argument. -+ -+ 2008-05-15 Diego Novillo -+ * config/arm/arm.c (arm_return_in_memory): Fix return type. -+ * config/arm/arm-protos.h (arm_return_in_memory): Likewise. -+ -+ 2008-06-19 Chung-Lin Tang -+ * arm-protos.h (arm_return_in_memory): Remove public -+ arm_return_in_memory() prototype. -+ * arm.c (arm_return_in_memory): Add static prototype, add target -+ hook macro, change definition and comments. -+ * arm.h (TARGET_RETURN_IN_MEMORY): Remove. -+ -+2009-02-24 Sandra Loosemore -+ -+ Issue #2369 -+ Committed upstream at the same time. -+ -+ gcc/ -+ * doc/invoke.texi (Link Options): Document an easier way to pass -+ options that take arguments to the GNU linker using -Xlinker and -+ -Wl. -+ -+2009-02-24 Andrew Stubbs -+ -+ gcc/ -+ * config/sh/lib1funcs.asm (ic_invalidate): icbi is not valid in a -+ delay slot. -+ -+2009-02-24 Andrew Stubbs -+ -+ gcc/testsuite/ -+ * gcc.target/sh/sh4a-memmovua.c: Include string.h instead of stdlib.h. -+ -+2009-02-24 Andrew Stubbs -+ -+ gcc/testsuite/ -+ * gcc.target/sh/sh4a-bitmovua.c (y0): Rename to y_0 to avoid a clash -+ with the built-in y0, and the subsequent warning. -+ (y1): Likewise, rename to y_1. -+ -+2009-02-21 Mark Mitchell -+ -+ Issue #4694 -+ Backport: -+ libiberty/ -+ 2008-07-31 Jakub Jelinek -+ * mkstemps.c (mkstemps): Keep looping even for EISDIR. -+ 2008-07-31 Denys Vlasenko -+ * mkstemps.c (mkstemps): If open failed with errno other than -+ EEXIST, return immediately. -+ * make-temp-file.c: Include errno.h. -+ (make_temp_file): If mkstemps failed, print an error message -+ before aborting. -+ -+2009-02-19 Kazu Hirata -+ -+ Issue #4152 -+ * release-notes-csl.xml: Mention the bug fix below. -+ -+ Backport: -+ 2008-07-30 Andrew Jenner -+ -+ * config/arm/arm.c (arm_compute_static_chain_stack_bytes): New -+ function. -+ (arm_compute_initial_elimination_offset): Use it. -+ (arm_compute_save_reg_mask): Include static chain save slot when -+ calculating alignment. -+ (arm_get_frame_offsets): Ditto. -+ (thumb1_compute_save_reg_mask): Ensure we have a low register saved -+ that we can use to decrement the stack when the stack decrement -+ could be too big for an immediate value in a single insn. -+ (thumb1_expand_prologue): Avoid using r12 for stack decrement. -+ -+2009-02-19 Catherine Moore -+ -+ Issue #2953 -+ -+ gcc/ -+ * debug.h (set_name): Declare. -+ * dwarf2out.c (dwarf2out_set_name): Declare. -+ (dwarf2_debug_hooks): Add set_name. -+ (find_AT_string): New. -+ (add_AT_string): Call find_AT_string. -+ (dwarf2out_set_name): New. -+ * cp/decl.c (grokdeclarator): Call set_name. -+ * vmsdbgout.c (vmsdbg_debug_hooks): Add set_name_debug_nothing. -+ * debug.c (do_nothing_debug_hooks): Likewise. -+ * dbxout.c (dbx_debug_hooks): Likewise. -+ * sdbout.c (sdb_debug_hooks): Likewise. -+ -+ * release-notes-csl.xml: Add note. -+ -+2009-02-19 Kazu Hirata -+ -+ Issue #4613 -+ gcc/ -+ * config/arm/arm.c (arm_rtx_costs_1): Teach that the cost of MLS -+ is the same as its underlying multiplication. -+ * config/arm/arm.md (two splitters): New. -+ * config/arm/predicates.md (binary_operator): New. -+ -+ * release-notes-csl.xml: Add a release note fragment for this -+ optimization. -+ -+2009-02-17 Andrew Jenner -+ Maciej Rozycki -+ -+ gcc/ -+ * unwind.inc (_Unwind_RaiseException): Use return value of -+ uw_init_context. -+ * unwind-dw2.c (uw_init_context): Make macro an expression instead of -+ a statement. -+ (uw_init_context_1): Add return value. -+ * unwind-sjlj.c (uw_init_context): Add return value. -+ -+2009-02-17 Kazu Hirata -+ -+ gcc/ -+ * config/arm/arm.c (arm_rtx_costs_1): Treat a minus with a shift -+ the same as a minus without a shift. -+ -+2009-02-16 Joseph Myers -+ -+ Issue #4622 -+ -+ gcc/ -+ * tree-predcom.c (ref_at_iteration): Return NULL_TREE if loop -+ header is an empty block. -+ -+ gcc/testsuite/ -+ * g++.dg/torture/predcom-1.C: New test. -+ -+2009-02-16 Julian Brown -+ -+ Issue #3747 -+ gcc/ -+ * config/arm/t-linux-eabi (LIB2FUNCS_STATIC_EXTRA): Add -+ config/arm/linux-atomic.c. -+ * config/arm/linux-atomic.c: New. -+ -+2009-02-12 Nathan Sidwell -+ -+ Issue #4620 -+ gcc/ -+ * config/rs6000/rs6000.c (rs6000_init_builtins): Set TYPE_NAME of -+ our distinct integral and vector types. -+ gcc/testsuite/ -+ * g++.dg/ext/altivec-17.C: New. -+ -+ * release-notes-csl.xml: Add note. -+ -+2009-02-10 Mark Mitchell -+ -+ libjava/classpath/ -+ * m4/acinclude.m4 (CLASSPATH_TOOLEXECLIBDIR): Match libjava. -+ * configure.ac (--enable-version-specific-runtime-libs): Support. -+ * Makefile.in, */Makefile.in: Regenerated. -+ -+ libjava/ -+ * Makefile.am (pkgconfigdir): Use toolexeclibdir, not $(libdir). -+ * configure.ac (dbexecdir): Likewise. -+ * configure: Regenerated. -+ -+ libjava/ -+ * Makefile.am (jardir): Set to a target-specific location. -+ gcc/java/ -+ * Make-lang.in: Adjust to match. -+ -+2009-02-09 Mark Mitchell -+ -+ Backport: -+ libffi/ -+ 2008-05-09 Julian Brown -+ * Makefile.am (LTLDFLAGS): New. -+ (libffi_la_LDFLAGS): Use above. -+ * Makefile.in: Regenerate. -+ boehm-gc/ -+ 2009-02-09 Mark Mitchell -+ * Makefile.am (LTLDFLAGS): New variable. -+ (LINK): Use it. -+ * Makefile.in: Regenerated. -+ libjava/ -+ 2009-02-09 Mark Mitchell -+ * Makefile.am (LTLDFLAGS): Define. -+ (GCJLINK): Use it. -+ (LIBLINK): Likewise. -+ * Makefile.in: Regenerated. -+ 2009-02-09 Mark Mitchell -+ * configure.ac: Define enable_sjlj_exceptions -+ appropriately under the ARM EH ABI. -+ * configure: Regenerated. -+ PR other/5303 -+ * addr2name.awk: Remove. -+ * Makefile.am (bin_SCRIPTS): Remove addr2name.awk. -+ * Makefile.in: Regenerated. -+ -+2009-02-05 Sandra Loosemore -+ -+ gcc/ -+ * config/arm/arm.c (struct minipool_fixup): Split mode field into -+ value_mode and ref_mode. -+ (add_minipool_forward_ref): Use value_mode of fixup. -+ (add_minipool_backward_ref): Likewise. -+ (push_minipool_fix): Pass both value_mode and ref_mode as parameters, -+ and store them in the fixup. -+ (note_invalid_constants): Adjust arguments to push_minipool_fix. -+ (arm_reorg): Use ref_mode of fixup. -+ -+2009-02-04 Andrew Jenner -+ -+ gcc/ -+ * config.gcc: Handle arm-montavista-linux-gnueabi, -+ mips-montavista-linux-gnu, mips64octeon*-montavista-elf* and -+ powerpc-montavista-linux-gnu. -+ * config/rs6000/t-montavista-linux: New file. -+ * config/rs6000/montavista-linux.h: New file. -+ * config/arm/t-montavista-linux: New file. -+ * config/arm/montavista-linux.h: New file. -+ * config/mips/t-montavista-linux: New file. -+ * config/mips/t-montavista-elf: New file. -+ * config/mips/montavista-linux.h: New file. -+ -+ libgcc/ -+ * config.host: Handle mips64octeon-montavista-elf*. -+ -+2009-02-04 Catherine Moore -+ -+ Backport: -+ -+ 2009-02-02 Catherine Moore -+ -+ * sde.h (SUBTARGET_ARM_SPEC): Don;t assemble -fpic code as -+ -mabicalls. -+ -+2009-02-03 Kazu Hirata -+ -+ * release-notes-csl.xml: Add a release note for improved -+ multiplication.c -+ -+2009-02-03 Kazu Hirata -+ -+ gcc/ -+ * expmed.c (synth_mult): When trying out a shift, pass the result -+ of a signed shift. -+ -+2009-02-03 Andrew Stubbs -+ -+ gcc/ -+ * config.gcc (sh-*): Add --enable-extra-sgxxlite-multilibs option to -+ enable uclibc multilibs. -+ * config/sh/cs-sgxxlite-linux.h: New file. -+ * config/sh/t-sgxxlite-linux: New file. -+ -+2009-02-03 Andrew Stubbs -+ -+ gcc/ -+ * config/sh/linux-unwind.h: Disable when inhibit_libc is defined. -+ -+2009-02-03 Andrew Stubbs -+ -+ gcc/ -+ * config.gcc (sh-*-*): Add sysroot-suffix.h to tm_file. -+ Add t-sysroot-suffix to tmake_file. -+ -+2009-02-03 Kazu Hirata -+ -+ config/ -+ * mh-mingw: Add a comment. -+ -+ libiberty/ -+ * cygpath.c (msvcrt_dll): Change the return type to HMODULE. -+ (msvcrt_fopen): Use HMODULE for the return value from msvcrt_dll. -+ -+2009-02-03 Andrew Stubbs -+ -+ gcc/ -+ * configure.ac: Add new AC_SUBST for TM_ENDIAN_CONFIG, -+ TM_MULTILIB_CONFIG and TM_MULTILIB_EXCEPTIONS_CONFIG. -+ * configure: Regenerate. -+ * Makefile.in: Add variables TM_ENDIAN_CONFIG, TM_MULTILIB_CONFIG -+ and TM_MULTILIB_EXCEPTIONS_CONFIG. -+ * config.gcc (sh-*-*): Switch to using TM_ENDIAN_CONFIG, -+ TM_MULTILIB_CONFIG, and TM_MULTILIB_EXCEPTIONS_CONFIG. -+ Don't add default cpu to multilib list unnecessarily, but do enable -+ the relevant compiler option.. -+ Add support for --with-multilib-list=none, and -+ --with-multilib-list=! to supress unwanted multilibs. -+ Remove use_fixproto=yes. -+ * config/sh/t-sh (DEFAULT_ENDIAN, OTHER_ENDIAN): New variables. -+ (MULTILIB_ENDIAN, MULTILIB_CPUS): Delete variables. -+ (MULTILIB_OPTIONS): Redefine using OTHER_ENDIAN and -+ TM_MULTILIB_CONFIG. -+ (MULTILIB_EXCEPTIONS): Add TM_MULTILIB_EXCEPTIONS_CONFIG. -+ (MULTILIB_OSDIRNAMES): New variable. -+ * config/sh/t-1e: Delete file. -+ * config/sh/t-mlib-sh1: Delete file. -+ * config/sh/t-mlib-sh2: Delete file. -+ * config/sh/t-mlib-sh2a: Delete file. -+ * config/sh/t-mlib-sh2a-nofpu: Delete file. -+ * config/sh/t-mlib-sh2a-single: Delete file. -+ * config/sh/t-mlib-sh2a-single-only: Delete file. -+ * config/sh/t-mlib-sh2e: Delete file. -+ * config/sh/t-mlib-sh3e: Delete file. -+ * config/sh/t-mlib-sh4: Delete file. -+ * config/sh/t-mlib-sh4-nofpu: Delete file. -+ * config/sh/t-mlib-sh4-single: Delete file. -+ * config/sh/t-mlib-sh4-single-only: Delete file. -+ * config/sh/t-mlib-sh4a: Delete file. -+ * config/sh/t-mlib-sh4a-nofpu: Delete file. -+ * config/sh/t-mlib-sh4a-single: Delete file. -+ * config/sh/t-mlib-sh4a-single-only: Delete file. -+ * config/sh/t-mlib-sh4al: Delete file. -+ * config/sh/t-mlib-sh5-32media: Delete file. -+ * config/sh/t-mlib-sh5-32media-nofpu: Delete file. -+ * config/sh/t-mlib-sh5-64media: Delete file. -+ * config/sh/t-mlib-sh5-64media-nofpu: Delete file. -+ * config/sh/t-mlib-sh5-compact: Delete file. -+ * config/sh/t-mlib-sh5-compact-nofpu: Delete file. -+ * config/sh/t-linux: Don't override MULTILIB_EXCEPTIONS. -+ -+2009-02-03 Andrew Stubbs -+ -+ gcc/ -+ * config/print-sysroot-suffix.sh: Add support for MULTILIB_ALIASES. -+ * config/t-sysroot-suffix: Pass MULTILIB_ALIASES. -+ -+2009-02-03 Andrew Stubbs -+ -+ gcc/ -+ * config/arm/print-sysroot-suffix.sh: Move to ... -+ * config/print-sysroot-suffix.sh: ... here. -+ Remove all MULTILIB_ALIASES to make it suitable for upstream -+ submission. -+ * config/arm/t-sysroot-suffix: Move to ... -+ * config/t-sysroot-suffix: ... here. -+ Modify path to print-sysroot-suffix.sh. -+ Remove all MULTILIB_ALIASES. -+ * config.gcc: Modify paths to print-sysroot-suffix.sh. -+ -+2009-01-30 Andrew Stubbs -+ -+ gcc/libstdc++-v3/ -+ * config/cpu/sh/atomicity.h: Put the SH4A specific functions in the -+ __gnu_cxx namespace. Remove "static inline". -+ -+2009-01-29 Kazu Hirata -+ -+ * expmed.c (shiftsub_cost): Rename to shiftsub0_cost. -+ (shiftsub1_cost): New. -+ (init_expmed): Compute shiftsub1_cost. -+ (synth_mult): Optimize multiplications by constants of the form -+ -(2^^m-1) for some constant positive integer m. -+ -+2009-01-27 Nathan Sidwell -+ -+ Issue #4428 -+ gcc/ -+ * config/mips/mips.md (jump): Deal with $gp restoration in delay -+ slot for o32 and o64 ABIs. -+ -+ gcc/testsuite/ -+ * gcc.target/mips/branch-2.c: New. -+ -+ * release-notes-csl.xml: Add note. -+ -+2009-01-26 Kazu Hirata -+ -+ * release-notes-csl.xml: Mention performance improvements for ARM. -+ -+ Backport from mainline: -+ 2009-01-13 Richard Earnshaw -+ -+ * arm.c (struct processors): Pass for speed down into cost helper -+ functions. -+ (const_ok_for_op): Handle COMPARE and inequality nodes. -+ (arm_rtx_costs_1): Rewrite. -+ (arm_size_rtx_costs): Update prototype. -+ (arm_rtx_costs): Pass speed down to helper functions. -+ (arm_slowmul_rtx_costs): Rework cost calculations. -+ (arm_fastmul_rtx_costs, arm_xscale_rtx_costs): Likewise. -+ (arm_9e_rtx_costs): Likewise. -+ -+2009-01-26 Julian Brown -+ -+ Issue #4515 -+ -+ gcc/ -+ * config/arm/ieee754-df.S (cmpdf2): Avoid writing below SP. -+ * config/arm/ieee754-sf.S (cmpsf2): Likewise. -+ -+2009-01-23 Sandra Loosemore -+ -+ Issue #3989 -+ -+ * release-notes-csl.xml (Thumb half-precision floating point bug fix): -+ New note. -+ -+ gcc/ -+ * config/arm/arm.c (dump_minipool): Use size of mode, not padded size, -+ in switch that controls whether to emit padding. -+ -+2009-01-20 Sandra Loosemore -+ -+ Issue #4289 -+ -+ fixincludes/ -+ * server.c (run_shell): Quote directory name passed to cd. -+ -+2009-01-14 Nathan Froyd -+ -+ * release-notes-csl.xml: Add note. Correct TARGET line for -+ previous note. -+ -+ gcc/ -+ * tree-ssa-remove-local-statics.c (maybe_discover_new_declaration): -+ Avoid variables with aggregate and vector types. -+ (maybe_create_new_variable): Create the var_ann prior to marking -+ the symbol for renaming. -+ -+ gcc/testsuite/ -+ * gcc.dg/remove-local-statics-15.c: New test. -+ * gcc.dg/remove-local-statics-16.c: New test. -+ -+2009-01-14 Joseph Myers -+ -+ gcc/ -+ * config/sparc/sol2-bi.h (LINK_ARCH64_SPEC_BASE): Use %R with -+ absolute library paths. -+ -+2009-01-12 Joseph Myers -+ -+ gcc/ -+ * config/sol2.h (LINK_ARCH32_SPEC_BASE): Use %R with absolute -+ library paths. -+ -+2009-01-06 Andrew Stubbs -+ Nathan Sidwell -+ -+ Issue #4436 -+ -+ gcc/ -+ * config/rs6000/rs6000.c (rs6000_override_options): Don't override -+ an explicit -mno-isel. -+ -+2009-01-02 Nathan Sidwell -+ -+ Issue 4361 -+ gcc/ -+ * config/m68k/m68k-devices.def: Add 51jm. -+ -+ * release-notes-csl.xml: Document 51jm addition. -+ -+2008-12-21 Mark Mitchell -+ -+ * release-notes-csl.xml: Adjust wording of last note. -+ -+2008-12-18 Mark Mitchell -+ -+ Issue #4399 -+ * release-notes-csl.xml: Document. -+ gcc/ -+ * tree-ssa-pre.c (compute_antic): Correct loop bounds. -+ -+2008-12-19 Joseph Myers -+ -+ gcc/testsuite/ -+ * gcc.target/powerpc/20081204-1.c: Require powerpc_spe_ok. -+ -+2008-12-19 Joseph Myers -+ -+ Backport from FSF: -+ -+ gcc/testsuite/ -+ 2008-03-13 Uros Bizjak -+ * gcc.dg/vect/vect-align-2.c: Remove dg-do run directive. -+ (main): Call check_vect. -+ -+2008-12-18 Joseph Myers -+ -+ Backport from FSF: -+ -+ gcc/ -+ 2008-12-18 Joseph Myers -+ * config/rs6000/rs6000.c (rs6000_generate_compare): Condition -+ choice of e500 comparison instructions on flag_finite_math_only && -+ !flag_trapping_math, not flag_unsafe_math_optimizations. -+ * config/rs6000/rs6000.md (abstf2): Condition choice of e500 -+ instructions on flag_finite_math_only && !flag_trapping_math, not -+ flag_unsafe_math_optimizations. -+ (bltgt, sltgt): Disable for TARGET_HARD_FLOAT && !TARGET_FPRS. -+ * config/rs6000/spe.md (cmpsfeq_gpr, tstsfeq_gpr, cmpsfgt_gpr, -+ tstsfgt_gpr, cmpsflt_gpr, tstsflt_gpr, cmpdfeq_gpr, tstdfeq_gpr, -+ cmpdfgt_gpr, tstdfgt_gpr, cmpdflt_gpr, tstdflt_gpr, cmptfeq_gpr, -+ tsttfeq_gpr, cmptfgt_gpr, tsttfgt_gpr, cmptflt_gpr, tsttflt_gpr): -+ Condition choice of comparison instructions on -+ flag_finite_math_only && !flag_trapping_math, not -+ flag_unsafe_math_optimizations. -+ -+2008-12-18 Catherine Moore -+ -+ Issue #4439 -+ -+ * release-notes-csl.xml: Document -march= bug fix. -+ -+2008-12-18 Catherine Moore -+ -+ Issue #4334 -+ -+ Backport: -+ -+ gcc/ -+ 2008-11-23 Richard Sandiford -+ -+ * config/mips/mips.c (mips_legitimize_address): Handle -+ illegitimate CONST_INT addresses. -+ -+ -+ 2008-06-01 Richard Sandiford -+ -+ * config/mips/mips.c (mips_valid_offset_p): New function. -+ -+2008-12-18 Catherine Moore -+ -+ Issue #4439 -+ -+ gcc/ -+ * config/mips/mips.h (MIPS_ISA_LEVEL_SPEC): Remove extraneous -+ colon. -+ -+2008-12-16 Joseph Myers -+ -+ gcc/ -+ * config/i386/cs-linux.opt (mrh73, mrhel3): New options. -+ * config/i386/cs-linux.h (SYSROOT_SUFFIX_SPEC): Handle new -+ options. -+ * config/i386/t-cs-linux (MULTILIB_OPTIONS, MULTILIB_DIRNAMES, -+ MULTILIB_OSDIRNAMES): Update for new options. -+ (MULTILIB_EXCEPTIONS): Define. -+ -+2008-12-05 Catherine Moore -+ -+ gcc/testsuite/ -+ * gcc-target/mips/mips-nonpic/mips-nonpic.h: New. -+ * gcc-target/mips/mips-nonpic/nonpic-[0-9]*.c: Rename to -+ main-[0-9]*.c. -+ * gcc-target/mips/mips-nonpic/mips-nonpic.exp: Run -+ main-*.c tests. -+ * gcc-target/mips/mips-nonpic/pic-*.c: Include mips-nonpic.h. -+ * gcc-target/mips/mips-nonpic/nonpic-*.c: Likewise. -+ -+2008-12-05 Catherine Moore -+ -+ * gcc/config/mips/MIPS-TOOLCHAIN.pdf: Remove. -+ -+2008-12-04 Joseph Myers -+ -+ gcc/ -+ * config/rs6000/rs6000.md (move_from_CR_gt_bit): Enable for -+ TARGET_HARD_FLOAT && !TARGET_FPRS, not TARGET_E500. -+ * config/rs6000/spe.md (e500_cr_ior_compare): Likewise. -+ -+ gcc/testsuite/ -+ * gcc.target/powerpc/20081204-1.c: New test. -+ -+2008-12-03 Daniel Jacobowitz -+ -+ gcc/testsuite/ -+ * gcc.dg/vect/vect-shift-2.c, gcc.dg/vect/vect-shift-3.c: New. -+ * lib/target-supports.exp (check_effective_target_vect_shift): New -+ function. -+ -+2008-12-02 Daniel Jacobowitz -+ -+ Issue #4343 -+ * release-notes-csl.xml: Document right shift fix. -+ -+ Backport from trunk: -+ -+ gcc/ -+ 2008-09-25 Dorit Nuzman -+ -+ * tree-vectorizer.c (vect_is_simple_use): Fix indentation. -+ * tree-vect-transform.c (vect_get_constant_vectors): Use vectype -+ instead of vector_type for constants. Take computation out of loop. -+ (vect_get_vec_def_for_operand): Use only vectype for constant case, -+ and use only vector_type for invariant case. -+ (get_initial_def_for_reduction): Use vectype instead of vector_type. -+ -+ gcc/testsuite/ -+ 2008-09-25 Dorit Nuzman -+ -+ * gcc.dg/vect/ggc-pr37574.c: New test. -+ * gcc.dg/vect/vect.exp: Compile some tests with ggc flags. -+ -+2008-12-02 Maxim Kuvyrkov -+ -+ gcc/testsuite/ -+ * gcc.target/m68k/tls-1.c: Rename to tls-ie.c; fix. -+ * gcc.target/m68k/tls-2.c: Rename to tls-le.c; fix. -+ * gcc.target/m68k/tls-1-pic.c: Rename to tls-gd.c; fix. -+ * gcc.target/m68k/tls-2-pic.c: Rename to tls-ld.c; fix. -+ * gcc.target/m68k/xtls-1.c: Rename to tls-ie-xgot.c; fix. -+ * gcc.target/m68k/xtls-2.c: Rename to tls-le-xtls.c; fix. -+ * gcc.target/m68k/xtls-1-pic.c: Rename to tls-gd-xgot.c; fix. -+ * gcc.target/m68k/xtls-2-pic.c: Split into tls-ld-xgot.c, -+ tls-ld-xtls.c and tls-ld-xgot-xtls.c; fix. -+ -+ gcc/ -+ * config/m68k/m68k.md (UNSPEC_XGOT, UNSPEC_TLS, UNSPEC_XTLS): Replace -+ with ... -+ (UNSPEC_RELOC, UNSPEC_RELOC32): New. -+ * config/m68k/m68k.opt: Fix documentation. -+ * config/m68k/m68k.c (m68k_unwrap_symbol): Update. -+ (m68k_decompose_address): Update comment. -+ (enum m68k_tls_reloc): Rename to m68k_reloc; add RELOC_GOT value. -+ (TLS_RELOC_P): New macro. -+ (m68k_get_tls_unspec): Rewrite, rename to m68k_wrap_symbol. -+ (m68k_move_to_reg, m68k_wrap_symbol_into_got_ref): New static -+ functions. -+ (legitimize_pic_address): Use them, update comment. -+ (m68k_call_tls_get_addr, m68k_call_read_tp): Rewrite. -+ (m68k_legitimize_tls_address): Rewrite, fix code generation for -+ initial exec model. -+ (m68k_tls_referenced_p_1, m68k_tls_mentioned_p): Update. -+ (m68k_legitimize_address): Remove excessive assert. -+ (m68k_get_tls_decoration): Rename to m68k_get_reloc_decoration, update. -+ (m68k_output_addr_const_extra): Update. -+ (sched_attr_op_type): Update comment. -+ -+2008-12-01 Catherine Moore -+ -+ * gcc/config/mips/MIPS-TOOLCHAIN.pdf: New. -+ -+2008-11-30 Maxim Kuvyrkov -+ -+ Fix bugs in TLS code generation, add -mxtls option, add tests. -+ -+ gcc/ -+ * config/m68k/predicates.md (symbolc_operand): Fix. -+ * config/m68k/m68k.md (UNSPEC_GOTOFF): Rename to UNSPEC_XGOT, update -+ all uses. -+ (UNSPEX_XTLS): New constant. -+ (addsi3_5200): Handle XTLS symbols, indent. -+ * config/m68k/m68k-protos.h (m68k_unwrap_symbol): Declare. -+ * config/m68k/m68k.opt (mxtls): New option. -+ * config/m68k/m68k.c (m68k_unwrap_symbol): New function. -+ (m68k_decompose_address): Handle TLS references. -+ (m68k_get_gp): Move to a better place. -+ (legitimize_pic_address): Update, cleanup, add REG_EQUAL note when -+ appropriate. -+ (m68k_get_tls_unspec): New function to unify generation of TLS -+ references. -+ (m68k_libcall_value_in_a0_p): New static variable. -+ (m68k_call_tls_get_addr, m68k_call_m68k_read_tp): Rewrite. -+ (m68k_legitimize_tls_address): Cleanup, use m68k_get_tls_unspec. -+ (m68k_tls_referenced_p_1, m68k_tls_mentioned_p): Handle UNSPEC_XTLS. -+ (m68k_output_addr_const_extra): Handle UNSPEC_XTLS. -+ (print_operand_address): Update. -+ (m68k_libcall_value): Support calls to TLS helpers. -+ (m68k_sched_attr_op_type): Update. -+ * config/m68k/constraints.md (Cu): New constraint. -+ -+ gcc/testsuite/ -+ * gcc.target/m68k/tls-1.c: New test. -+ * gcc.target/m68k/tls-1-pic.c: New test. -+ * gcc.target/m68k/tls-2.c: New test. -+ * gcc.target/m68k/tls-2-pic.c: New test. -+ * gcc.target/m68k/xtls-1.c: New test. -+ * gcc.target/m68k/xtls-1-pic.c: New test. -+ * gcc.target/m68k/xtls-2.c: New test. -+ * gcc.target/m68k/xtls-2-pic.c: New test. -+ -+2008-11-29 Joseph Myers -+ -+ Backport from FSF: -+ -+ gcc/testsuite/ -+ 2008-11-29 Joseph Myers -+ * g++.dg/cpp/stringop-1.C: New test. -+ -+ libcpp/ -+ 2008-11-29 Joseph Myers -+ * lex.c (cpp_token_len): Use 6 as default length. -+ -+2008-11-26 Catherine Moore -+ -+ gcc/testsuite/ -+ * gcc.target/mips/vr-mult-1.c: Require hard-float. -+ * gcc.target/mips/branch-cost-1.c: Likewise. -+ * gcc.target/mips/movcc-2.c: Likewise. -+ * gcc.target/mips/rsqrt-3.c: Likewise. -+ * gcc.target/mips/vr-mult-2.c: Likewise. -+ * gcc.target/mips/branch-cost-2.c: Likewise. -+ * gcc.target/mips/movcc-3.c: Likewise. -+ * gcc.target/mips/nmadd-1.c: Likewise. -+ * gcc.target/mips/nmadd-2.c: Likewise. -+ * gcc.target/mips/movcc-1.c: Likewise. -+ * gcc.target/mips/nmadd-3.c: Likewise. -+ -+2008-11-24 Catherine Moore -+ -+ gcc/testsuite/ -+ * gcc.target/mips/mips-nonpic/mips-nonpic.exp: Don't run for mips16. -+ -+2008-11-24 Nathan Froyd -+ -+ gcc/ -+ * config/rs6000/rs6000.c (rs6000_savres_strategy): Always use -+ inline saves and restores when compiling position-independent code. -+ -+2008-11-24 Nathan Froyd -+ -+ gcc/ -+ * config.gcc (powerpc-*-elf*): Only include e500mc-specific files -+ if --enable-powerpc-e500mc-elf was specified. -+ -+2008-11-20 Maxim Kuvyrkov -+ -+ PR35018 -+ -+ gcc/ -+ * config/m68k/m68k.md (addsi_lshrsi_31): Rename to -+ addsi_lshrsi_31_m68k, don't use it for ColdFire. -+ Add (define_expand "addsi_lshrsi_31"). -+ (addsi_lshrsi_31_cf): New, almost identical copy of extendsidi2_m68k. -+ -+ gcc/testsuite/ -+ * gcc.target/m68k/pr35018.c: New. -+ -+2008-11-20 Joseph Myers -+ -+ gcc/ -+ * config/arm/thumb2.md (thumb2_casesi_internal, -+ thumb2_casesi_internal_pic): Use earlyclobber for scratch operand -+ 4. -+ -+2008-11-19 Andrew Stubbs -+ -+ Issue #3283 -+ -+ gcc/ -+ PR target/36133 -+ * config/m68k/m68k.h (CC_OVERFLOW_UNUSABLE, CC_NO_CARRY): New defines. -+ * config/m68k/m68k.c (notice_update_cc): Set cc_status properly for -+ shift instructions. -+ * config/m68k/m68k.md: Adjust all conditional branches that use the -+ carry and overflow flags so they understand CC_OVERFLOW_UNUSABLE. -+ -+ gcc/testsuite/ -+ PR target/36133 -+ * gcc.target/m68k/pr36133.c: New test. -+ -+2008-11-17 Nathan Froyd -+ -+ gcc/ -+ * config/rs6000/rs6000.c (rs6000_emit_epilogue): Adjust -+ computation of restore_lr. Duplicate restoration of LR and -+ execute the appropriate one depending on whether GPRs are being -+ restored inline. -+ -+2008-11-17 Catherine Moore -+ -+ * config/mt-sde: Revert last patch. -+ -+2008-11-17 Paul Brook -+ -+ gcc/ -+ * config/arm/t-symbian (MULTILIB_EXCEPTIONS, MULTILIB_MATCHES, -+ MULTILIB_ALIASES): Define. -+ -+2008-11-17 Nathan Froyd -+ -+ gcc/ -+ * config/rs6000/rs6000.c (rs6000_savres_routine_sym): Fix -+ computation for cache selector. Mark the generated symbol as a -+ function. -+ (rs6000_emit_prologue): Correct condition. -+ * config/rs6000/rs6000.md (*save_gpregs_): Use explicit -+ match for register 11. -+ (*save_fpregs_): Likewise. -+ (*restore_gpregs_): Likewise. -+ (*return_and_restore_gpregs_): Likewise. -+ (*return_and_restore_fpregs_): Likewise. -+ * config/rs6000/spe.md (*save_gpregs_spe): Use explicit match for -+ register 11. -+ (*restore_gpregs_spe): Likewise. -+ (*return_and_restore_gpregs_spe): Likewise. -+ -+2008-11-14 Catherine Moore -+ -+ * config/mt-sde (CFLAGS_FOR_TARGET): Add -mexplicit-relocs. -+ (CXXFLAGS_FOR_TARGET): Likewise. -+ -+2008-11-14 Maxim Kuvyrkov -+ Andrew Stubbs -+ Gunnar Von Boehn -+ -+ Issue #3284 -+ -+ gcc/ -+ PR target/36134 -+ * config/m68k/m68k.md (addsi3_5200): Add a new alternative preferring -+ the shorter LEA insn over ADD.L where possible. -+ -+ gcc/testsuite/ -+ PR target/36134 -+ * gcc.target/m68k/pr36134.c: New test. -+ -+2008-11-13 Joseph Myers -+ -+ gcc/ -+ * config/mips/sicortex.h, config/mips/t-sicortex: New. -+ * config.gcc (mips64el-sicortex-linux-gnu): Use these config -+ files. -+ -+2008-11-13 Nathan Froyd -+ -+ gcc/ -+ * config.gcc (powerpc*-elf*): Configure for e500mc. -+ * config/rs6000/t-ppc-e500mc: New. -+ * config/rs6000/e500mc.h: New. -+ -+2008-11-12 Nathan Sidwell -+ -+ Issue 4221/1 -+ * release-notes-csl.xml: Document removal of default -mfix-ice9a. -+ -+2008-11-11 Joseph Myers -+ -+ gcc/ -+ * function.c (alignment_for_aligned_arrays): Use floor_log2 -+ instead of CLZ_HWI. -+ -+2008-11-10 Nathan Froyd -+ -+ Issue #4082 -+ -+ gcc/ -+ * config/rs6000/rs6000.c (rs6000_legitimize_address): Check for -+ non-word-aligned REG+CONST addressing. -+ -+ gcc/testsuite/ -+ * gcc.target/powerpc/20081104-1.c: New test. -+ -+2008-11-07 Julian Brown -+ -+ Issue #4085 -+ -+ gcc/ -+ * combine.c (find_split_point): Disable patch from PR27971. -+ -+2008-11-06 Kazu Hirata -+ -+ Issue 4029 -+ gcc/ -+ Backport: -+ 2008-11-06 Kazu Hirata -+ PR target/35574 -+ * config/sparc/predicates.md (const_double_or_vector_operand): -+ New. -+ * config/sparc/sparc.c (sparc_extra_constraint_check): Handle the -+ 'D' constraint. -+ * config/sparc/sparc.h: Document the 'D' constraint. -+ * config/sparc/sparc.md (*movdf_insn_sp32_v9, *movdf_insn_sp64): -+ Use the 'D' constraint in addition to 'F' in some alternatives. -+ (DF splitter): Generalize for V64mode. -+ * doc/md.texi (SPARC): Document the 'D' constraint. -+ -+ * release-notes-csl.xml: Add a release note for the fix above. -+ -+2008-11-06 Andrew Stubbs -+ -+ Issue #3120 -+ -+ gcc/ -+ * release-notes-csl.xml: -pg support for ARM EABI. -+ -+2008-10-29 Andrew Stubbs -+ -+ Issue 3120 -+ -+ gcc/ -+ * config/arm/linux-eabi.h (ARM_FUNCTION_PROFILER): Delete. -+ (SUBTARGET_FRAME_POINTER_REQUIRED): Delete. -+ * config/arm/bpabi.h (PROFILE_HOOK): New undef. -+ -+ Back-port from mainline: -+ 2008-10-08 Paul Brook -+ gcc/ -+ * config/arm/bpabi.h (ARM_FUNCTION_PROFILER): Define new EABI -+ compatible profiler (__gnu_mcount_nc). -+ (SUBTARGET_FRAME_POINTER_REQUIRED): Define. -+ -+2008-10-27 Catherine Moore -+ -+ Issue #4105 -+ -+ Backport: -+ -+ gcc/ -+ 2008-10-22 Chao-ying Fu -+ -+ * config/mips/mips.opt (msmartmips): Accept -mno-smartmips. -+ -+2008-10-24 Maxim Kuvyrkov -+ -+ gcc/ -+ * config/m68k/m68k.c (m68k_output_dwarf_dtprel): Use .long instead of -+ .word for TLS debug information. -+ -+2008-10-24 Nathan Froyd -+ -+ gcc/ -+ * config/rs6000/rs6000.c (no_global_regs_above): Fix precedence -+ problem. -+ -+2008-10-23 Kazu Hirata -+ -+ Issue 3852 -+ gcc/ -+ * config/arm/t-asa (MULTILIB_EXTRA_OPTS): New. -+ -+2008-10-22 Paul Brook -+ -+ gcc/ -+ * config/arm/t-uclinux-eabi (MULTILIB_EXCEPTIONS): Exclude bogus ARM -+ multilib. -+ -+2008-10-21 Paul Brook -+ -+ gcc/ -+ * doc/invoke.texi: Document -mfix-cortex-m3-ldrd. -+ * config/arm/arm.c (arm_override_options): Set fix_cm3_ldrd -+ if Cortex-M3 cpu is selected. -+ (output_move_double): Avoid overlapping base register and first -+ destination register when fix_cm3_ldrd. -+ * config/arm/arm.opt: Add -mfix-cortex-m3-ldrd. -+ * config/arm/t-cs-eabi: Add -mfix-cortex-m3-ldrd to Thumb-2 multilib. -+ * config/arm/t-arm-elf: Ditto. -+ * config/arm/t-uclinux-eabi: Ditto. -+ -+2008-10-21 Paul Brook -+ -+ gcc/ -+ * config/arm/arm.md (consttable_4): Handle (high ...). -+ -+2008-10-16 Nathan Froyd -+ -+ gcc/ -+ * config.gcc (powerpc-*-eabi*): Add rs6000/t-cs-eabi when -+ --enable-extra-sgxx-multilibs is passed to configure. -+ * config/rs6000/t-ppcgas (MULTILIB_OPTIONS): Remove te500mc. -+ (MULTILIB_DIRNAMES): Likewise. -+ (MULTILIB_EXCEPTIONS): Likewise. -+ * config/rs6000/t-cs-eabi: New file. -+ -+2008-10-16 Julian Brown -+ -+ Issue #4039 -+ -+ gcc/ -+ * config/arm/neon.md (movmisalign): Use expander/unnamed insn -+ for both D & Q variants. Don't permit both operands to be mems. -+ * release-notes-csl.xml (Misaligned NEON memory accesses): Add note. -+ -+2008-10-15 Catherine Moore -+ -+ gcc/testsuite/ -+ * gcc-target/mips/octeon-1.c (dg-mips-options): Use -mno-abicalls. -+ * gcc-target/mips/octeon-5.c (dg-mips-options): Likewise. -+ * gcc-target/mips/octeon-6.c (dg-mips-options): Likewise. -+ * gcc-target/mips/octeon-18.c (dg-mips-options): Likewise. -+ * gcc-target/mips/octeon-19.c (dg-mips-options): Likewise. -+ * gcc-target/mips/octeon-23.c (dg-mips-options): Likewise. -+ * gcc-target/mips/octeon-28.c (dg-mips-options): Likewise. -+ * gcc-target/mips/octeon-34.c (dg-mips-options): Likewise. -+ * gcc-target/mips/octeon-37.c (dg-mips-options): Likewise. -+ * gcc-target/mips/octeon-43.c (dg-mips-options): Likewise. -+ * gcc-target/mips/octeon-44.c (dg-mips-options): Likewise. -+ * gcc-target/mips/octeon-49.c (dg-mips-options): Likewise. -+ * gcc-target/mips/octeon-54.c (dg-mips-options): Likewise. -+ -+2008-10-14 Sandra Loosemore -+ -+ Issue #4017 -+ -+ * release-notes-csl.xml (Linker script option syntax): New note. -+ -+ gcc/ -+ * config.gcc (powerpc-*): Make t-ppcgas imply usegas.h. -+ * config/svr4.h (SVR4_ASM_SPEC): New. -+ (ASM_SPEC): Inherit from SVR4_ASM_SPEC. -+ * config/rs6000/sysv4.h (ASM_SPEC): Inherit from SVR4_ASM_SPEC. -+ -+ gcc/doc/ -+ * invoke.texi (Option Summary): Add -T to linker options. -+ (Link Options): Document -T. -+ -+2008-10-13 Nathan Froyd -+ -+ gcc/ -+ * config/rs6000/rs6000.c (rs6000_file_start): Output gnu -+ attribute for struct return convention. -+ -+2008-10-13 Paul Brook -+ -+ gcc/ -+ * config/arm/arm.h (fputype): Remove stray comma. -+ -+2008-10-13 Andrew Stubbs -+ -+ Issue #3884 -+ -+ gcc/ -+ * doc/invoke.texi (PowerPC Options): -meabi option no longer places -+ __eabi function in main. -+ -+2008-10-12 Mark Mitchell -+ -+ Issue #3224 -+ * release-notes-csl.xml: Mention OpenMP add-on. -+ -+2008-10-12 Catherine Moore -+ -+ Issue # 3903 -+ -+ Backport: -+ -+ 2008-07-28 Ilie Garbacea -+ Chao-ying Fu -+ -+ * configure.tgt: Enable futex for MIPS. -+ * config/linux/mips/futex.h: New file. -+ -+2008-10-12 Catherine Moore -+ -+ gcc/ -+ * config/mips/mips.opt (muclibc): New option entry. -+ * config/mips/mips.c (mips_override_options): Disable -+ __thread support when the -muclibc option is used. -+ -+2008-10-11 Maxim Kuvyrkov -+ -+ M68K NPTL support. -+ gcc/ -+ * configure.ac (m68k-*-*): Check if binutils support TLS. -+ * configure: Regenerate. -+ * config/m68k/predicates.md (symbolic_operand): Handle UNSPECs. -+ * config/m68k/m68k.md (UNSPEC_TLS): New constant. -+ (movsi): Handle TLS symbols. -+ * config/m68k/m68k-protos.h (m68k_legitimize_tls_address): Declare. -+ (m68k_tls_referenced_p, m68k_tls_mentioned_p): Declare. -+ (m68k_legitimize_address): Declare. -+ * config/m68k/m68k.c (ggc.h): Include. -+ (m68k_output_dwarf_dtprel): Implement hook. -+ (TARGET_HAVE_TLS, TARGET_ASM_OUTPUT_DWARF_DTPREL): Define. -+ (m68k_expand_prologue): Load GOT pointer when function needs it. -+ (m68k_illegitimate_symbolic_constant_p): Handle TLS symbols. -+ (m68k_legitimate_constant_address_p): Same. -+ (legitimize_pic_address): Same. -+ (enum m68k_tls_reloc): New. -+ (m68k_tls_get_addr, m68k_get_tls_get_addr, m68k_get_gp) -+ (m68k_call_tls_get_addr, m68k_read_tp, m68k_get_m68k_read_tp) -+ (m68k_call_m68k_read_tp): Helper variables and functions for ... -+ (m68k_legitimize_tls_address): Handle TLS references. -+ (m68k_tls_symbol_p, m68k_tls_referenced_p_1, m68k_tls_referenced_p) -+ (m68k_tls_mentioned_p): New functions. -+ (m68k_legitimize_address): Rewrite LEGITIMIZE_ADDRESS macro, handle -+ TLS symbols. -+ (m68k_get_tls_decoration): New static function. -+ (m68k_output_addr_const_extra): Handle UNSPEC_TLS. -+ (m68k_output_dwarf_dtprel): Implement hook. -+ (gt-m68k.h): Include. -+ * config/m68k/m68k.h (LEGITIMATE_PIC_OPERAND_P): Support TLS. -+ (LEGITIMATE_ADDRESS): Move logic to m68k.c:m68k_legitimize_address. -+ -+2008-10-11 Maxim Kuvyrkov -+ -+ gcc/ -+ * config/m68k/lb1sf68.asm (PICCALL, PICJUMP): Use GOT instead of -+ PC-relative addressing when compiling for uclinux PIC. -+ -+2008-10-09 Catherine Moore -+ -+ Issue #3312 -+ -+ gcc/ -+ * config/mips/mips.h ( DSP_CTRL_REG_FIRST): Define. -+ (DSP_CTRL_REG_LAST): Define. -+ * config/mips/mips.c (mips_conditional_register_usage): Handle -+ DSP registers. -+ -+2008-10-08 Maxim Kuvyrkov -+ -+ * release-notes-csl.xml: Fix typo. -+ -+2008-10-08 Nathan Sidwell -+ Maxim Kuvyrkov -+ -+ * release-notes-csl.xml (Shared Libraries bug fix): New. -+ -+ gcc/ -+ * config/m68k/lb1sf68.asm (__cmpdf_internal, __cmpsf_internal): Hide. -+ (__cmpdf, __cmpsf): Use PIC call sequence. -+ -+2008-10-07 Nathan Froyd -+ -+ Issue #3988 -+ -+ * release-notes-csl.xml (Dynamic libraries and -Os bug fix): New. -+ -+ gcc/ -+ * config/rs6000/ppc-asm.h (HIDDEN_FUNC): New macro. -+ * config/rs6000/crtresfpr.asm, config/rs6000/crtresgpr.asm, -+ config/rs6000/crtresxfpr.asm, config/rs6000/crtresxgpr.asm, -+ config/rs6000/crtsavfpr.asm, config/rs6000/crtsavgpr.asm, -+ config/rs6000/e500crtres32gpr.asm, -+ config/rs6000/e500crtres64gpr.asm, -+ config/rs6000/e500crtres64gprctr.asm, -+ config/rs6000/e500crtrest32gpr.asm, -+ config/rs6000/e500crtrest64gpr.asm, -+ config/rs6000/e500crtresx32gpr.asm, -+ config/rs6000/e500crtresx64gpr.asm, -+ config/rs6000/e500crtsav32gpr.asm, -+ config/rs6000/e500crtsav64gpr.asm, -+ config/rs6000/e500crtsav64gprctr.asm, -+ config/rs6000/e500crtsavg32gpr.asm, -+ config/rs6000/e500crtsavg64gpr.asm, -+ config/rs6000/e500crtsavg64gprctr.asm: Use it. -+ -+2008-10-07 Nathan Sidwell -+ -+ * release-notes-csl.xml: Document it. -+ -+ gcc/ -+ * doc/invoke.texi (MIPS Options): Add ice9 arch. -+ * config/mips/mips.c (mips_cpu_info_table): Add ice9 arch. -+ -+2008-10-03 Catherine Moore -+ -+ gcc/testsuite/ -+ * gcc.target/mips/fix-ice9a-1.c: Disable for soft-float -+ multilibs. -+ * gcc.target/mips/fix-ice9a-1.c: Likewise. -+ -+2008-10-03 Kazu Hirata -+ -+ Backport: -+ gcc/testsuite/ -+ 2008-09-23 Eric Botcazou -+ -+ * gcc.dg/pragma-init-fini.c: Use dg-warning in lieu of dg-error. -+ * gcc.dg/pragma-align-2.c: Likewise. -+ * gcc.dg/format/cmn-err-1.c: Likewise. -+ -+2008-10-02 Catherine Moore -+ -+ gcc/testsuite/ -+ * gcc.target/mips/lazy-binding-1.c: Compile with -fpic. -+ -+2008-10-02 Maciej W. Rozycki -+ -+ Issue #3673 -+ gcc/testsuite/ -+ * lib/target-supports.exp -+ (check_effective_target_arm_iwmmxt_ok): New procedure. -+ * gcc.dg/arm-mmx-1.c: Only run if arm_iwmmxt_ok. -+ -+2008-09-29 Joseph Myers -+ -+ Backport: -+ -+ gcc/ -+ 2008-09-29 Joseph Myers -+ * ifcvt.c (noce_emit_store_flag): If using condition from original -+ jump, reverse it if if_info->cond was reversed. -+ -+2008-09-29 Maxim Kuvyrkov -+ -+ Issue #3922 -+ * release-notes-csl.xml (Code generation bug fix): New. -+ gcc/ -+ * config/m68k/m68k.md (extendsidi2): Rename to extendsidi2_m68k, -+ don't use it for ColdFire. Add (define_expand "extendsidi2"). -+ (extendsidi2_cf): New, almost identical copy of extendsidi2_m68k. -+ gcc/testsuite/ -+ * gcc.c-torture/compile/20080929-1.c: New. -+ -+2008-09-29 Maxim Kuvyrkov -+ -+ * release-notes-csl.xml (ColdFire M54455 support): Fix target. -+ -+2008-09-25 Sandra Loosemore -+ -+ Issue #3208 -+ -+ * release-notes-csl.xml (Half-precision floating point): New note. -+ -+2008-09-25 Paul Brook -+ -+ gcc/ -+ * config/arm/fp16.c (__gnu_f2h_ieee, __gnu_h2f_ieee): Enable on -+ ARMv6-M. -+ * config/arm/t-bpabi (LIB2FUNCS_EXTRA): Remove fp16.c. -+ (LIB2FUNCS_STATIC_EXTRA): Add fp16.c. -+ * config/arm/t-symbian (LIB2FUNCS_EXTRA): Rename... -+ (LIB2FUNCS_STATIC_EXTRA): ... to this. -+ * config/arm/t-arm-softfp: Remove HFmode conversions. -+ * config/soft-fp/extendhfsf2.c: Revert HFmode suport. -+ * config/soft-fp/truncsfhf2.c: Ditto. -+ * config/soft-fp/README: Ditto. -+ * config/soft-fp/half.h: Ditto. -+ -+2008-09-25 Sandra Loosemore -+ -+ gcc/testsuite/ -+ * gcc.dg/torture/arm-fp16-ops.h: Fix bogus tests. -+ * g++.dg/ext/arm-fp16/arm-fp16-ops.h: Ditto. -+ -+2008-09-25 Julian Brown -+ -+ gcc/ -+ * config/arm/arm.c (arm_hard_regno_mode_ok): Allow 4-word quantities -+ in core registers. Update comment. -+ -+2008-09-25 Nathan Sidwell -+ -+ * release-notes-csl.xml: Document ice9a option. -+ -+2008-09-25 Julian Brown -+ -+ Issue #3800 -+ -+ gcc/testsuite/ -+ * gcc.target/arm/eabi1.c (__eabi_uread4, __eabi_uwrite4) -+ (__eabi_uread8, __eabi_uwrite8): Change spellings of declarations -+ to... -+ (__aeabi_uread4, __aeabi_uwrite4, __aeabi_uread8, __aeabi_uwrite8): -+ These. -+ -+2008-09-24 Paul Brook -+ -+ gcc/ -+ * config/arm/t-arm-softfp (softfp_extensions): Add hfsf. -+ (softfp_truncations): Add sfhf. -+ * config/arm/sfp-machine.h (_FP_NANFRAC_H, _FP_NANSIGN_H): Define. -+ * config/arm/fp16.c: New file. -+ * config/arm/t-bpabi (LIB2FUNCS_EXTRA): Add fp16.c. -+ * config/arm/t-symbian (LIB2FUNCS_EXTRA): Add fp16.c. -+ * config/soft-fp/extendhfsf2.c: New file. -+ * config/soft-fp/truncsfhf2.c: New file. -+ * config/soft-fp/half.h: New file. -+ * config/soft-fp/README: HFmode routines do not come from gcc. -+ -+2008-09-22 Daniel Gutson -+ Nathan Sidwell -+ Maciej W. Rozycki -+ -+ Issue #3634 -+ gcc/ -+ * config.gcc (all_defaults): Add fix-ice9a. -+ * config/mips/mips.c (mips_conditional_register_usage): Add $f30 -+ and $f31 as appropriate as fixed registers. -+ * config/mips/mips.h (OPTION_DEFAULT_SPECS): Add -mfix-ice9a -+ handling. -+ (ASM_SPEC): Likewise. -+ * config/mips/mips.md (ice9a_stallnops): New mode attribute. -+ (ice9a_round): Likewise. -+ (ice9a_length_stall): Likewise. -+ (ice9a_length_round): Likewise. -+ (ice9a_length_both): Likewise. -+ (*mul3): Change condition. -+ (*mul3_fix_ice9a): New. -+ (*madd): Change condition. -+ (*madd_ice9a): New. -+ (*msub): Change condition. -+ (*msub_ice9a): New. -+ (*nmadd): Change condition. -+ (*nmadd_fastmath): Likewise. -+ (*nmadd_ice9a): New. -+ (*nmadd_fastmath_ice9a): New. -+ (*nmsub): Change condition. -+ (*nmsub_fastmath): Likewise. -+ (*nmsub_ice9a): New. -+ (*nmsub_fastmath_ice9a): Likewise. -+ (*recip3): Change condition and definition. Move the SB1 -+ fix to... -+ (*recip3_fix_sb1): ... this new pattern. -+ (*recip3_fix_ice9a): New. -+ (sqrt2): Change from define_insn to define_expand. Move -+ the SB1 fix to... -+ (*sqrt2): New. -+ (*sqrt2_fix_sb1): ... this new pattern. -+ (*sqrt2_fix_ice9a): New. -+ (*rsqrta): Change condition and definition. Move the SB1 -+ fix to... -+ (*rsqrta_fix_sb1): ... this new pattern. -+ (*rsqrta_fix_ice9a): New. -+ (*rsqrtb): Likewise *rsqrta. -+ (*rsqrtb_fix_sb1): Likewise *rsqrta_fix_sb1. -+ (*rsqrtb_fix_ice9a): New. -+ * config/mips/mips.opt (mfix-ice9a): New option. -+ * doc/invoke.texi (-mno-fix-ice9a): New option. -+ (-mfix-ice9a): Likewise. -+ -+ gcc/testsuite/ -+ * gcc.target/mips/fix-ice9a.h: New file. -+ * gcc.target/mips/fix-ice9a-1.c: Likewise. -+ * gcc.target/mips/fix-ice9a-2.c: Likewise. -+ -+2008-09-23 Sandra Loosemore -+ -+ Issue #3208 -+ -+ gcc/ -+ * config/arm/arm.c (arm_init_libfuncs): Add NULL entries for -+ HFmode arithmetic functions. -+ (arm_override_options): Call sorry for fp16 and no ldrh. -+ (arm_legitimate_index_p): Treat HFmode like HImode. -+ (coproc_secondary_reload_class): Special-case HFmode. -+ * config/arm/arm.md (floatsihf2): Use emit_move_insn. -+ (floatdihf2): Likewise. -+ (truncdfhf2): Likewise. -+ (*thumb1_movhf): Fix backwards operands to strh. -+ -+2008-09-23 Sandra Loosemore -+ -+ Issue #3208 -+ -+ gcc/testsuite/ -+ * gcc.target/arm/fp16-compile-alt-10.c: Add -std=gnu99 to options. -+ * gcc.target/arm/fp16-compile-alt-11.c: Likewise. -+ * gcc.target/arm/fp16-compile-ieee-10.c: Likewise. -+ * gcc.target/arm/fp16-compile-ieee-11.c: Likewise. -+ * gcc.target/arm/fp16-compile-exprtype.c: New. -+ * gcc.target/arm/fp16-builtins-1.c: New. -+ * gcc.target/arm/fp16-unprototyped-1.c: New. -+ * gcc.target/arm/fp16-unprototyped-2.c: New. -+ * gcc.target/arm/fp16-variadic-1.c: New. -+ * gcc.target/arm/fp16-rounding-alt-1.c: New. -+ * gcc.target/arm/fp16-rounding-ieee-1.c: New. -+ * gcc.dg/torture/arm-fp16-int-convert-alt.c: New. -+ * gcc.dg/torture/arm-fp16-int-convert-ieee.c: New. -+ * gcc.dg/torture/arm-fp16-ops.h: New. -+ * gcc.dg/torture/arm-fp16-ops-1.c: New. -+ * gcc.dg/torture/arm-fp16-ops-2.c: New. -+ * gcc.dg/torture/arm-fp16-ops-3.c: New. -+ * gcc.dg/torture/arm-fp16-ops-4.c: New. -+ * gcc.dg/torture/arm-fp16-ops-5.c: New. -+ * gcc.dg/torture/arm-fp16-ops-6.c: New. -+ * gcc.dg/torture/arm-fp16-ops-7.c: New. -+ * gcc.dg/torture/arm-fp16-ops-8.c: New. -+ * g++.dg/ext/arm-fp16/arm-fp16-ops.h: New. -+ * g++.dg/ext/arm-fp16/arm-fp16-ops-1.C: New. -+ * g++.dg/ext/arm-fp16/arm-fp16-ops-2.C: New. -+ * g++.dg/ext/arm-fp16/arm-fp16-ops-3.C: New. -+ * g++.dg/ext/arm-fp16/arm-fp16-ops-4.C: New. -+ * g++.dg/ext/arm-fp16/arm-fp16-ops-5.C: New. -+ * g++.dg/ext/arm-fp16/arm-fp16-ops-6.C: New. -+ * g++.dg/ext/arm-fp16/arm-fp16-ops-7.C: New. -+ * g++.dg/ext/arm-fp16/arm-fp16-ops-8.C: New. -+ -+2008-09-23 Sandra Loosemore -+ -+ gcc/ -+ * optabs.c (prepare_float_lib_cmp): Test that the comparison, -+ swapped, and reversed optabs exist before trying to use them. -+ -+2008-09-23 Julian Brown -+ -+ gcc/ -+ * config/arm/arm.c (arm_override_options): Override alignments if -+ tuning for Cortex-A8. -+ (create_fix_barrier, arm_reorg): If aligning to jumps or loops, -+ make labels have a size. -+ * config/arm/arm.md (VUNSPEC_ALIGN16, VUNSPEC_ALIGN32): New constants. -+ (align_16, align_32): New patterns. -+ -+2008-09-23 Julian Brown -+ -+ gcc/ -+ * config/arm/vfp.md (*arm_movsi_vfp, *thumb2_movsi_vfp) -+ (*arm_movdi_vfp, *thumb2_movdi_vfp, *movsf_vfp, *thumb2_movsf_vfp) -+ (*movdf_vfp, *thumb2_movdf_vfp, *movsfcc_vfp, *thumb2_movsfcc_vfp) -+ (*movdfcc_vfp, *thumb2_movdfcc_vfp): Add neon_type. -+ * config/arm/arm.md (neon_type): Update comment. -+ -+2008-09-23 Julian Brown -+ -+ gcc/ -+ * config/arm/arm.md (movsi): Don't split symbol refs here. -+ (define_split): New. -+ -+2008-09-22 Maxim Kuvyrkov -+ Paul Brook -+ -+ gcc/ -+ * config/m68k/lb1sf68.asm: Add GNU-stack annotation to avoid -+ executable stack. -+ -+2008-09-18 Joseph Myers -+ -+ Backport: -+ -+ gcc/ -+ 2008-09-17 Joseph Myers -+ * expr.c (emit_group_store): Do not shift before moving via a -+ stack slot. -+ -+ 2008-08-13 H.J. Lu -+ PR middle-end/36701 -+ * expr.c (emit_group_store): Allocate stack temp with the -+ largest alignment when copying from register to stack. -+ -+ 2008-09-02 H.J. Lu -+ * expr.c (emit_group_store): Don't assert stack temp mode size. -+ -+2008-09-15 Joseph Myers -+ -+ gcc/ -+ * config/mips-octeon-elf.h (TARGET_OS_CPP_BUILTINS): Remove. -+ -+2008-09-11 Mark Mitchell -+ -+ Issue #3606 -+ * release-notes-csl.xml: Document dllexport fix. -+ -+ gcc/ -+ * tree.c (handle_dll_attribute): Mark dllexport'd inlines as -+ non-external. -+ gcc/cp -+ * decl2.c (decl_needed_p): Consider dllexport'd functions needed. -+ * semantics.c (expand_or_defer_fn): Similarly. -+ gcc/testsuite/ -+ * gcc.dg/dll-6.c: New test. -+ * gcc.dg/dll-6a.c: Likewise. -+ * gcc.dg/dll-7.c: Likewise. -+ * gcc.dg/dll-7a.c: Likewise. -+ * g++.dg/ext/dllexport2.C: Likewise. -+ * g++.dg/ext/dllexport2a.cc: Likewise. -+ -+2008-09-12 Nathan Froyd -+ -+ Backport from mainline: -+ -+ gcc/testsuite/ -+ 2008-08-25 Janis Johnson -+ * gcc.dg/Wstrict-aliasing-bogus-ref-all-2.c: Ignore a warning. -+ -+2008-09-11 Joseph Myers -+ -+ Backport: -+ -+ gcc/testsuite/ -+ 2008-09-11 Joseph Myers -+ * gcc.dg/builtins-8.c: Condition cbrt test on HAVE_C99_RUNTIME. -+ -+ 2008-09-11 Joseph Myers -+ * gcc.target/i386/sse5-haddX.c, gcc.target/i386/sse5-hsubX.c: -+ Avoid intN_t types. -+ -+ 2008-09-11 Joseph Myers -+ * lib/compat.exp, gcc.dg/compat/struct-layout-1.exp, -+ g++.dg/compat/struct-layout-1.exp: Use .exe extension for compat -+ test executables. -+ * gcc.dg/compat/struct-layout-1_generate.c, -+ g++.dg/compat/struct-layout-1_generate.c: Convert backslash to -+ slash in srcdir for dg-options string. -+ -+2008-09-11 Nathan Sidwell -+ -+ gcc/ -+ * config.gcc (mips*-sde-elf*): Always apply sdemtk parts. Apply -+ t-sdelib only when not building newlib. -+ * config/mips/t-sdemtk: Move sdelib specific pieces to ... -+ * config/mips/t-sdelib: ... here. New file. -+ -+2008-09-10 Daniel Jacobowitz -+ -+ Issue #3406 -+ * release-notes-csl.xml: Document -fpie fix. -+ -+ gcc/ -+ * config/mips/linux.h (SUBTARGET_ASM_SPEC): Add -fpie and -fPIE. -+ * config/mips/linux64.h (SUBTARGET_ASM_SPEC): Likewise. -+ -+2008-09-09 Sandra Loosemore -+ -+ Issue #3208 -+ -+ gcc/testsuite/ -+ * gcc.target/arm/fp16-compile-alt-1.c: New. -+ * gcc.target/arm/fp16-compile-alt-2.c: New. -+ * gcc.target/arm/fp16-compile-alt-3.c: New. -+ * gcc.target/arm/fp16-compile-alt-4.c: New. -+ * gcc.target/arm/fp16-compile-alt-5.c: New. -+ * gcc.target/arm/fp16-compile-alt-6.c: New. -+ * gcc.target/arm/fp16-compile-alt-7.c: New. -+ * gcc.target/arm/fp16-compile-alt-8.c: New. -+ * gcc.target/arm/fp16-compile-alt-9.c: New. -+ * gcc.target/arm/fp16-compile-alt-10.c: New. -+ * gcc.target/arm/fp16-compile-alt-11.c: New. -+ * gcc.target/arm/fp16-compile-ieee-1.c: New. -+ * gcc.target/arm/fp16-compile-ieee-2.c: New. -+ * gcc.target/arm/fp16-compile-ieee-3.c: New. -+ * gcc.target/arm/fp16-compile-ieee-4.c: New. -+ * gcc.target/arm/fp16-compile-ieee-5.c: New. -+ * gcc.target/arm/fp16-compile-ieee-6.c: New. -+ * gcc.target/arm/fp16-compile-ieee-7.c: New. -+ * gcc.target/arm/fp16-compile-ieee-8.c: New. -+ * gcc.target/arm/fp16-compile-ieee-9.c: New. -+ * gcc.target/arm/fp16-compile-ieee-10.c: New. -+ * gcc.target/arm/fp16-compile-ieee-11.c: New. -+ * gcc.target/arm/fp16-compile-none-1.c: New. -+ * gcc.target/arm/fp16-param-1.c: New. -+ * gcc.target/arm/fp16-return-1.c: New. -+ * gcc.target/arm/fp16-compile-vcvt.c: New. -+ * gcc.dg/torture/arm-fp16-compile-assign.c: New. -+ * gcc.dg/torture/arm-fp16-compile-convert.c: New. -+ * g++.dg/ext/arm-fp16/fp16-overload-1.C: New. -+ * g++.dg/ext/arm-fp16/fp16-return-1.C: New. -+ * g++.dg/ext/arm-fp16/fp16-param-1.C: New. -+ * g++.dg/ext/arm-fp16/fp16-mangle-1.C: New. -+ -+2008-09-09 Sandra Loosemore -+ -+ Issue #3208 -+ -+ gcc/ -+ * doc/tm.texi (Misc): Document TARGET_INVALID_PARAMETER_TYPE, -+ TARGET_INVALID_RETURN_TYPE, TARGET_PROMOTED_TYPE, and -+ TARGET_CONVERT_TO_TYPE. -+ * doc/invoke.texi (Option Summary): List -mfp16-format. -+ (ARM Options): List neon-fp16 as -mfpu value. Document -mfp16-format. -+ * hooks.c (hook_tree_const_tree_null): Define. -+ * hooks.h (hook_tree_const_tree_null): Declare. -+ * target.h (struct gcc_target): Add invalid_parameter_type, -+ invalid_return_type, promoted_type, and convert_to_type fields. -+ * target-def.h: (TARGET_INVALID_PARAMETER_TYPE): Define. -+ (TARGET_INVALID_RETURN_TYPE): Define. -+ (TARGET_PROMOTED_TYPE): Define. -+ (TARGET_CONVERT_TO_TYPE): Define. -+ (TARGET_INITIALIZER): Update for new fields. -+ * fold-const.c (fold_convert_const_real_from_real): Check for -+ overflow. -+ * real.c (encode_ieee_half): Define. -+ (decode_ieee_half): Define. -+ (ieee_half_format): Define. -+ (arm_half_format): Define. -+ * real.h (ieee_half_format): Declare. -+ (arm_half_format): Declare. -+ * c-decl.c (grokdeclarator): Check targetm.invalid_return_type. -+ (grokparms): Check targetm.invalid_parameter_type. -+ * c-typeck.c (default_conversion): Check targetm.promoted_type. -+ * c-convert.c (convert): Check targetm.convert_to_type. -+ * cp/typeck.c (default_conversion): Check targetm.promoted_type. -+ * cp/decl.c (grokdeclarator): Check targetm.invalid_return_type. -+ (grokparms): Check targetm.invalid_parameter_type. -+ * cp/cvt.c (ocp_convert): Check targetm.convert_to_type. -+ (build_expr_type_conversion): Check targetm.promoted_type. -+ * config/arm/arm.c: Include intl.h. -+ (TARGET_INVALID_PARAMETER_TYPE): Redefine. -+ (TARGET_INVALID_RETURN_TYPE): Redefine. -+ (TARGET_PROMOTED_TYPE): Redefine. -+ (TARGET_CONVERT_TO_TYPE): Redefine. -+ (arm_fp16_format): Define. -+ (all_fpus): Add entry for neon-fp16. -+ (fp_model_for_fpu): Likewise. -+ (struct fp16_format): Declare. -+ (all_fp16_formats): Define. -+ (arm_init_libfuncs): Add entries for HFmode conversions. -+ (arm_override_options): Set arm_fp16_format. -+ (thumb1_legitimate_address_p): Make it recognize HFmode constants. -+ (arm_print_operand): Add 'z' specifier for vld1.16/vst1.16. -+ (arm_hard_regno_mode_ok): Allow HFmode values in VFP registers. -+ (arm_init_fp16_builtins): New. -+ (arm_init_builtins): Call it. -+ (arm_invalid_parameter_type): New. -+ (arm_invalid_return_type): New. -+ (arm_promoted_type): New. -+ (arm_convert_to_type). -+ (arm_file_start): Deal with neon-fp16 as fpu_name. Emit tag for fp16 -+ format. -+ (arm_mangle_type): Mangle __fp16 as "Dh". -+ * config/arm/arm.h (TARGET_VFPD32): Make it know about -+ FPUTYPE_NEON_FP16. -+ (TARGET_NEON_FP16): New. -+ (TARGET_NEON): Make it know about FPUTYPE_NEON_FP16. -+ (enum fputype): Add FPUTYPE_NEON_FP16. -+ (enum arm_fp16_format_type): Declare. -+ (arm_fp16_format): Declare. -+ (LARGEST_EXPONENT_IS_NORMAL): Define. -+ * config/arm/arm-modes.def (HFmode): Define. -+ * config/arm/vfp.md: (*movhf_vfp): New. -+ (extendhfsf2): New. -+ (truncsfhf2): New. -+ * config/arm/arm.opt (mfp16-format=): New. -+ * config/arm/arm.md: (fpu): Add neon_fp16. -+ (floatsihf2, floatdihf2): New. -+ (fix_trunchfsi2, fix_trunchfdi2): New. -+ (truncdfhf2): New. -+ (extendhfdf2): New. -+ (movhf): New. -+ (*arm32_movhf): New. -+ (*thumb1_movhf): New. -+ (consttable_2): Handle HFmode constants. -+ -+ libiberty/ -+ * cp-demangle.c (cplus_demangle_builtin_Dh_type): Declare. -+ (cplus_demangle_type): Make it handle "Dh". -+ -+2008-09-09 Sandra Loosemore -+ -+ Issue #3732 -+ -+ gcc/ -+ * doc/invoke.texi (ARM Options): Correct errors in discussion -+ of -mfloat-abi, -mhard-float, and -msoft-float. -+ -+2008-09-09 Kazu Hirata -+ -+ gcc/ -+ * config.gcc (mips-sgi-irix[56]*, mips*-*-netbsd*, -+ mips*-*-openbsd*, mips*-sde-elf*, mips64octeon*-wrs-elf*, -+ mipsisa64-*-elf*, mipsisa64el-*-elf*, mipsisa64sr71k-*-elf*, -+ mipsisa64sb1-*-elf*, mipsisa64sb1el-*-elf*, mips-*-elf*, -+ mipsel-*-elf*, mips64-*-elf*, mips64el-*-elf*, mips64vr-*-elf*, -+ mips64vrel-*-elf*, mips64orion-*-elf*, mips64orionel-*-elf*, -+ mips*-*-rtems*, mips-wrs-vxworks, mips-wrs-windiss, -+ mipstx39-*-elf*, mipstx39el-*-elf*): Don't add t-crtfm to -+ tmake_file. -+ -+ libgcc/ -+ * config.host (mips-sgi-irix[56]*, mips*-*-netbsd*, -+ mips*-*-openbsd*, mipsisa32-*-elf*, mipsisa32el-*-elf*, -+ mipsisa32r2-*-elf*, mipsisa32r2el-*-elf*, mipsisa64-*-elf*, -+ mipsisa64el-*-elf*, mipsisa64sr71k-*-elf*, mipsisa64sb1-*-elf*, -+ mipsisa64sb1el-*-elf*, mips-*-elf*, mipsel-*-elf*, mips64-*-elf*, -+ mips64el-*-elf*, mips64vr-*-elf*, mips64vrel-*-elf*, -+ mips64orion-*-elf*, mips64orionel-*-elf*, mips64octeon-wrs-elf*, -+ mips64octeonel-wrs-elf*, mips*-*-rtems*, mips-wrs-vxworks, -+ mips-wrs-windiss, mipstx39-*-elf*, mipstx39el-*-elf*): Remove -+ extra_parts and tmake_file. -+ -+2008-09-08 Daniel Jacobowitz -+ -+ * release-notes-csl.xml: Document exception handler fix. -+ -+ gcc/ -+ * config/arm/unwind-arm.c (__gnu_unwind_pr_common): Correct test -+ for barrier handlers. -+ -+2008-09-08 Daniel Jacobowitz -+ Mark Mitchell -+ -+ gcc/testsuite/ -+ * g++.dg/compat/eh/filter2_x.C: Declare abort. -+ * g++.dg/compat/eh/new1_x.C, g++.dg/compat/eh/new1_y.C: Include -+ cstddef and use std::size_t. -+ -+ * gcc.dg/compat/compat-common.h: Define SKIP_COMPLEX_INT if -+ SKIP_COMPLEX. Honor SKIP_COMPLEX. -+ * gcc.dg/compat/scalar-by-value-3_x.c, -+ gcc.dg/compat/scalar-by-value-3_y.c, -+ gcc.dg/compat/scalar-by-value-4_x.c, -+ gcc.dg/compat/scalar-by-value-4_y.c, -+ gcc.dg/compat/scalar-by-value-5.c, -+ gcc.dg/compat/scalar-by-value-5_main.c, -+ gcc.dg/compat/scalar-by-value-6.c, -+ gcc.dg/compat/scalar-by-value-6_main.c, -+ gcc.dg/compat/scalar-by-value-6_x.c, -+ gcc.dg/compat/scalar-by-value-6_y.c, -+ gcc.dg/compat/struct-by-value-16_x.c, -+ gcc.dg/compat/struct-by-value-16_y.c, -+ gcc.dg/compat/struct-by-value-17_x.c, -+ gcc.dg/compat/struct-by-value-17_y.c, -+ gcc.dg/compat/struct-by-value-18_x.c, -+ gcc.dg/compat/struct-by-value-18_y.c, -+ gcc.dg/compat/struct-layout-1.h, -+ gcc.dg/compat/scalar-return-3_x.c, -+ gcc.dg/compat/scalar-return-3_y.c, -+ gcc.dg/compat/scalar-return-4_x.c, -+ gcc.dg/compat/scalar-return-4_y.c: Honor SKIP_COMPLEX. -+ -+ * gcc.dg/compat/scalar-by-value-y.h: Use stdarg.h for non-GCC -+ compilers. -+ -+ * gcc.dg/compat/struct-by-value-22_y.c, -+ gcc.dg/compat/struct-by-value-22_main.c, -+ gcc.dg/compat/struct-by-value-22_x.c: Honor SKIP_VLA_IN_STRUCT. -+ -+ * lib/c-compat.exp (compat_setup_dfp): Check the compiler under test -+ first. -+ * lib/compat.exp: Document COMPLEX and VLA_IN_STRUCT skips. -+ -+2008-09-08 Paul Brook -+ -+ gcc/ -+ * config/arm/arm.md (arm_addsi3): Add r/r/k alternative. -+ -+2008-09-08 Kazu Hirata -+ -+ gcc/ -+ * config.gcc (mips-sgi-irix[56]*, mips*-*-netbsd*, mips*-*-linux*, -+ mips*-sde-elf*, mips64octeon*-wrs-elf*, mipsisa32r2*, -+ mipsisa64sr71k-*-elf*, mipsisa64sb1*, mips64vr*, mips64orion*, -+ mips*-*-rtems*, mips-wrs-vxworks, mips-wrs-windiss, mipstx39): Add -+ mips/t-crtfm to tmake_file. -+ -+ libgcc/ -+ * config.host (mips*): Add mips/t-crtfm to tmake_file. Add -+ crtfastmath.o to extra_parts. -+ * config/mips/t-crtfm: New. -+ -+2008-09-07 Maxim Kuvyrkov -+ -+ gcc/testsuite/ -+ * gcc.gd/struct/wo_prof_global_var.c: Use uninitialized integer -+ values instead of uninitialized FP values to avoid NaNs. -+ * gcc.dg/struct/wo_prof_local_var.c: Same. -+ -+2008-09-07 Maxim Kuvyrkov -+ -+ gcc/ -+ * config/m68k/m68k.c (sched_attr_op_type): Handle all CONSTs. -+ -+ gcc/testsuite/ -+ * gcc.target/m68k/xgot-1.c (dg-options): Add -O2. -+ -+2008-09-06 Joseph Myers -+ -+ gcc/ -+ * combine.c (simplify_set): Avoid calling LOAD_EXTEND_OP on -+ non-integer modes. -+ -+2008-09-05 Joseph Myers -+ -+ Backport: -+ -+ gcc/ -+ 2008-09-05 Joseph Myers -+ * config/mips/mips.h (enum reg_class): Add FRAME_REGS. -+ (REG_CLASS_NAMES): Update. -+ (REG_CLASS_CONTENTS): Update. -+ * config/mips/mips.c (mips_regno_to_class): Use FRAME_REGS instead -+ of ALL_REGS for regs 77 and 78. -+ * function.c (instantiate_virtual_regs_in_insn): Assert that -+ return value of simplify_gen_subreg is not NULL. -+ -+ gcc/testsuite/ -+ 2008-09-05 Joseph Myers -+ * gcc.c-torture/compile/20080903-1.c: New test. -+ -+2008-09-04 Nathan Sidwell -+ -+ Issue 3304 -+ gcc/ -+ * config/arm/arm.c (arm_print_operand): Deal with HIGH. -+ * config/arm/constraints.md (j): New constraint for movw operands. -+ (N): Remove thumb2 meaning. -+ * config/arm/arm.md (*arm_movw): Delete. -+ (*arm_movsi_insn): Use j constraint for movw instead of N constraint. -+ * config/arm/vfp.md (*arm_movsi_vfp, *thumb2_movsi_vfp): Likewise. -+ * config/arm/thumb2.md (*thumb2_movsi_insn): Likewise. -+ -+2008-09-04 Julian Brown -+ -+ gcc/ -+ * Makefile.in (CSL_LICENSELIB): Remove space after -L to appease -+ Darwin ld. -+ -+2008-09-04 Nathan Sidwell -+ -+ gcc/ -+ * config/arm/bpabi.h (LINK_SPEC): Add --fix-janus-2cc if needed. -+ -+ * release-notes-csl.xml: Adjust janus-2cc note. -+ -+2008-09-03 Nathan Froyd -+ -+ libgomp/ -+ * libgomp.texi (Library Index): Renamed from "Index" to prevent -+ conflict with index.html on case-insensitive file systems. -+ -+2008-09-03 Julian Brown -+ -+ * release-notes-csl.xml (NEON improvements): Add release note. -+ -+2008-09-02 Joseph Myers -+ -+ gcc/testsuite/ -+ * g++.dg/abi/arm_va_list.C: Correct order of dg-do and -+ dg-require-effective-target directives. -+ -+2008-09-02 Mark Mitchell -+ -+ gcc/testsuite/ -+ * gcc.target/arm/long-calls-1.c: Tolerate the lack of sibling -+ calls and/or PLT markers. -+ * gcc.target/arm/long-calls-2.c: Tolerate the lack of sibling -+ calls and/or PLT markers. -+ * gcc.target/arm/long-calls-3.c: Tolerate the lack of sibling -+ calls and/or PLT markers. -+ * gcc.target/arm/long-calls-4.c: Tolerate the lack of sibling -+ calls and/or PLT markers. -+ -+2008-09-01 Mark Mitchell -+ -+ Backport: -+ 2008-09-01 Mark Mitchell -+ * include/std/type_traits (__make_unsigned_selector<>): Consider -+ enums of size smaller than short. -+ (__make_signed_selector<>): Likewise. -+ * testsuite/20_util/make_signed/requirements/typedefs_neg.cc: -+ Adjust line numbers. -+ * testsuite/20_util/make_usigned/requirements/typedefs_neg.cc: -+ Adjust line numbers. -+ * testsuite/20_util/make_signed/requirements/typedefs-2.cc: -+ Ensure test_enum is the same size as short. -+ * testsuite/20_util/make_unsigned/requirements/typedefs-2.cc: -+ Ensure test_enum is the same size as short. -+ -+2008-09-01 Joseph Myers -+ -+ * release-notes-csl.xml: Avoid line containing only whitespace. -+ -+2008-08-27 Daniel Gutson -+ -+ Janus 2CC ARM shift fix: -+ gcc/ -+ * config/arm/arm.md (*addsi3_carryin_shift): Added "length" clause -+ to handle the extra NOP. -+ (andsi_not_shiftsi_si): Likewise. -+ (*thumb1_ashlsi3): Likewise. -+ (*thumb1_ashrsi3): Likewise. -+ (*thumb1_lshrsi3): Likewise. -+ (*thumb1_rotrsi3): Likewise. -+ (*arm_shiftsi3): Likewise. -+ (*shiftsi3_compare0): Likewise. -+ (*shiftsi3_compare0_scratch): Likewise. -+ (*arm_notsi_shiftsi): Likewise. -+ (*arm_notsi_shiftsi_compare0): Likewise. -+ (*arm_not_shiftsi_compare0_scratch): Likewise. -+ (*arm_cmpsi_shiftsi): Likewise. -+ (*arm_cmpsi_shiftsi_swp): Likewise. -+ (*arm_cmpsi_negshiftsi_si): Likewise. -+ (*arith_shiftsi): Likewise. -+ (*arith_shiftsi_compare0): Likewise. -+ (*arith_shiftsi_compare0_scratch): Likewise. -+ (*sub_shiftsi): Likewise. -+ (*sub_shiftsi_compare0): Likewise. -+ (*sub_shiftsi_compare0_scratch): Likewise. -+ (*if_shift_move): Likewise. -+ (*if_move_shift): Likewise. -+ (*if_shift_shift): Likewise. -+ (*thumb1_ashlsi3_janus2): New. Duplicated pattern to handle the -+ extra NOP. -+ (*thumb1_ashrsi3_janus2): Likewise. -+ (*thumb1_lshrsi3_janus2): Likewise. -+ (*thumb1_rotrsi3_janus2): Likewise. -+ * config/arm/arm.c (arm_print_operand): Added the nop after the %S -+ pattern. -+ (arm_override_options): Added handling of the -mfix-janus-2cc flag. -+ * config/arm/arm.h (janus2_code): Declare. -+ * config/arm/arm.opt (-mfix-janus-2cc): New. -+ -+ gcc/testsuite/ -+ * lib/target-supports.exp (check_effective_target_arm_no_thumb): -+ New function. -+ * gcc.target/arm/janus-2cc-shift-1.c: New. -+ * gcc.target/arm/janus-2cc-shift-2.c: New. -+ -+ * release-notes-csl.xml: Document. -+ -+2008-08-31 Mark Mitchell -+ -+ gcc/ -+ * gcc.target/arm/va_list.c: Return zero on success. -+ -+ * release-notes-csl.xml: Update note for va_list change. -+ -+2008-08-30 Mark Mitchell -+ -+ libstdc++-v3/ -+ * testsuite/25_algorithms/nth_element/2.cc: Constrain iterations -+ when testing on a simultor. -+ -+2008-08-29 Mark Mitchell -+ -+ * release-notes-csl.xml: Update note for NEON mangling. -+ -+ Issue #3579 -+ gcc/ -+ * config/arm/arm.c (arm_build_builtin_va_list): New function. -+ (arm_extract_valist_ptr): Likewise. -+ (arm_expand_builtin_va_start): Likewise. -+ (arm_gimplify_va_arg_expr): Likewise. -+ (TARGET_BUILD_BUILTIN_VA_LIST): Define. -+ (TARGET_EXPAND_BUILTIN_VA_START): Likewise. -+ (TARGET_GIMPLIFY_VA_VARG_EXPR): Likewise. -+ (arm_mangle_type): Handle __va_list specially. -+ gcc/testsuite/ -+ * lib/target-supports.exp (check_effective_target_arm_eabi): New -+ function. -+ * gcc.target/arm/va_list.c: New test. -+ * g++.dg/abi/arm_va_list.C: Likewise. -+ -+2008-08-29 Mark Mitchell -+ -+ gcc/cp/ -+ * mangle.c (write_type): Add target-specific manglings for -+ non-fundamental types to the substitution table. -+ gcc/testsuite/ -+ * g++.dg/abi/mangle-neon.C: Add substitution test. -+ -+ * release-notes-csl.xml: Document change. -+ -+2008-08-29 Joseph Myers -+ -+ Backport: -+ -+ gcc/testsuite/ -+ 2008-04-09 Andy Hutchinson -+ PR testsuite/34894 -+ PR testsuite/33782 -+ * lib/target-supports.dg: Add check_effective_target_trampolines. -+ Disable profiling for avr-*-*. -+ * gcc.c-torture/compile/pr27889.c: dg-requires trampolines. -+ * gcc.c-torture/compile/nested-1.c: Ditto. -+ * gcc.c-torture/compile/20050122-2.c: Ditto. -+ * gcc.c-torture/compile/20010226-1.c: Ditto. -+ * gcc.c-torture/compile/20010327-1.c: Skip for avr-*-*. -+ * gcc.c-torture/compile/980506-1.c: Ditto. -+ * gcc.c-torture/compile/20020604-1.c: Ditto. -+ * gcc.c-torture/compile/limits-stringlit.c: Ditto -+ * gcc.c-torture/compile/20001226-1.c: Ditto -+ -+ 2008-05-12 Andy Hutchinson -+ * gcc.dg/pr34457-1.c: Skip for target without trampolines. -+ * gcc.dg/20050607-1.c: Ditto. -+ * gcc.dg/trampoline-1.c: Ditto. -+ * gcc.dg/debug/debug-3.c: Ditto. -+ * gcc.dg/debug/debug-5.c: Ditto. -+ -+2008-08-29 Mark Mitchell -+ -+ gcc/testsuite/ -+ * gcc.dg/vect/vect-105.c: Prevent compiler from hoisting abort out -+ of loop. -+ -+2008-08-28 Mark Mitchell -+ -+ gcc/testsuite/ -+ * gcc.dg/struct/wo_prof_single_str_global.c: Mask return value. -+ * gcc.dg/struct/wo_prof_single_str_local.c: Mask return value. -+ * gcc.dg/struct/wo_prof_single_str_pointer.c: Mask return value. -+ -+ Backport: -+ -+ gcc/testsuite/ -+ 2008-04-22 Steve Ellcey -+ * gcc.dg/struct/wo_prof_global_var.c: Initialize array. -+ * gcc.dg/struct/wo_prof_malloc_size_var.c: Ditto. -+ * gcc.dg/struct/w_prof_local_var.c: Ditto. -+ * gcc.dg/struct/w_prof_global_var.c: Ditto. -+ * gcc.dg/struct/wo_prof_local_var.c: Ditto. -+ -+2008-08-28 Mark Mitchell -+ -+ gcc/cp -+ * decl.c (maybe_deduce_size_from_array_init): Use relayout_decl. -+ gcc/testsuite/ -+ * g++.dg/cpp/_Pragma1.C: Skip on arm*-*-eabi*. -+ * g++.dg/ext/visibility/arm1.C: Require DLL targets. -+ * g++.dg/init/ref15.C: Require unwrapped targets. -+ -+2008-08-28 Paul Brook -+ -+ Merge from Sourcery G++ 4.2: -+ gcc/ -+ * config/arm/neon.md (neon_type): Move to arm.md. -+ (neon_mov): Add neon_type attribute. -+ (movmisalign): Ditto. -+ * config/arm/arm.md (neon_type): Move to here. -+ (conds): Add "unconditioal" and use as default for NEON insns. -+ -+ gcc/testsuite/ -+ * gcc.target/arm/neon-cond-1.c: New test. -+ -+2008-08-27 Nathan Froyd -+ -+ libgomp/ -+ * Makefile.am: Use install-data-local for install-html and -+ install-pdf. -+ * Makefile.in: Regenerate. -+ -+2008-08-26 Maxim Kuvyrkov -+ -+ Port not-reviewed patch from gcc-patches@. -+ -+ gcc/ -+ 200x-xx-xx Roman Zippel -+ PR middle-end/29474 -+ * gcc/recog.c (validate_replace_rtx_1): Prevent swap of -+ commutative operands during reload -+ -+ -+2008-08-26 Maxim Kuvyrkov -+ -+ gcc/ -+ * config/m68k/m68k.md (cmpdi): Use (scratch) instead of pseudo. -+ -+2008-08-25 Nathan Froyd -+ -+ Issue #3604 -+ -+ * release-notes-csl.xml (-msim build fix): New. -+ -+ gcc/ -+ * config/rs6000/sysv4.h (LIB_SIM_SPEC): Use LIB_DEFAULT_SPEC. -+ (STARTFILE_SIM_SPEC): Remove sim-crt0.o%s. -+ (ENDFILE_SIM_SPEC): Add -Tsim-hosted.ld. -+ (LINK_OS_SIM_SPEC): Define to empty. -+ -+2008-08-23 Nathan Froyd -+ -+ * release-notes-csl.xml (OpenMP support): New. -+ -+2008-08-21 Nathan Sidwell -+ -+ gcc/ -+ * config/m68k/m68k-devices.def (52274, 52277): New devices. -+ -+ * release-notes-csl.xml: Document addition of DragonFire0. -+ -+2008-08-21 Joseph Myers -+ -+ Backport: -+ -+ gcc/testsuite/ -+ 2008-08-21 Joseph Myers -+ * g++.dg/opt/anchor1.C (foo): Return the return value of -+ ycf->ascent. -+ -+2008-08-21 Nathan Froyd -+ -+ Backport from mainline: -+ -+ libgomp/ -+ 2008-08-21 Nathan Froyd -+ * testsuite/libgomp.exp (libgomp_init): Only set things that -+ depend on blddir if blddir exists. -+ (libgomp_target_compile): Likewise. -+ * testsuite/libgomp.c++/c++.exp: Likewise. -+ * testsuite/libgomp.fortran/fortran.exp: Likewise. -+ -+2008-08-20 Joseph Myers -+ -+ Backport: -+ -+ gcc/ -+ 2008-08-20 Joseph Myers -+ PR target/31070 -+ * config/sparc/sparc.c (function_arg_slotno): Handle structure -+ with MODE_VECTOR_INT mode. -+ -+2008-08-19 Joseph Myers -+ -+ * release-notes-csl.xml (Target architecture defaults to i686): -+ Add new release note. -+ -+2008-08-19 Joseph Myers -+ -+ * release-notes-csl.xml: Update release note for upgrade to refer -+ to version 4.3.2. -+ -+2008-08-19 Kazu Hirata -+ -+ Issue 3422 -+ gcc/ -+ * config.gcc (mips64*-*-linux*, mips-*-elf*, mipsel-*-elf*, -+ mips64-*-elf*, mips64el-*-elf*): Add mips/t-crtfm. -+ * config/mips/crtfastmath.c: New. -+ * config/mips/linux.h (ENDFILE_SPEC): New. -+ * config/mips/linux64.h (ENDFILE_SPEC): New. -+ * config/mips/t-crtfm: New. -+ -+ * release-notes-csl.xml: Add a release note for the new FPU -+ defaults on mips64el-sicortex-linux-gnu -+ -+2008-08-18 Nathan Froyd -+ -+ gcc/testuite/ -+ * gcc.dg/pr34856.c: Fix thinko -+ -+2008-08-18 Nathan Froyd -+ -+ libgomp/ -+ * Makefile.am (datarootdir, docdir, htmldir, pdfdir): Define. -+ (HTMLS_INSTALL, HTMLS_BUILD): Define. -+ ($(HTMLS_BUILD)): New rule. -+ (html__strip_dir): Define. -+ (install-data-am): Add install-html and install-pdf prerequsites. -+ (install-html): Add actions. -+ (TEXI2HTML): Define. -+ * Makefile.in: Regenerate. -+ * configure.ac (datarootdir, docdir, htmldir, pdfdir): Add -+ appropriate --with options and AC_SUBSTs. -+ * configure: Regenerate. -+ -+2008-08-18 Nathan Froyd -+ -+ libgomp/ -+ * Makefile.am (LTLDFLAGS): Define. -+ (LINK): Define. -+ * Makefile.in: Regenerate. -+ -+2008-08-18 Nathan Froyd -+ -+ gcc/testuite/ -+ * gcc.dg/pr34856.c: Add powerpc*-eabi* exception. -+ -+2008-08-15 Joseph Myers -+ -+ Backport: -+ -+ gcc/ -+ 2008-06-28 Andrew Jenner -+ * regrename.c (build_def_use): Don't copy RTX. -+ -+2008-08-13 Joseph Myers -+ -+ Backport: -+ -+ gcc/ -+ 2008-08-13 Joseph Myers -+ * config/sparc/sparc.c (emit_soft_tfmode_cvt): Explicitly sign or -+ zero extend SImode values being converted to TFmode before passing -+ to libcalls. -+ -+2008-08-12 Nathan Froyd -+ -+ Backport from mainline: -+ -+ gcc/ -+ 2008-08-12 Nathan Froyd -+ -+ PR libgomp/26165 -+ * gcc.c (include_spec_function): Tweak call to find_a_file. -+ -+2008-08-10 Catherine Moore -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2008-02-28 Julian Brown -+ -+ Merge from MIPS: -+ -+ gcc/ -+ * Makefile.in (stmp-int-hdrs): Don't depend on -+ fixinc_list. Only -+ process fixincludes if fixinc_list is -+ present. -+ (install-mkheaders): Likewise. -+ -+ 2008-02-11 Julian Brown -+ -+ Merge from MIPS: -+ -+ 2004-06-29 Nigel Stephens -+ -+ * Makefile.in (libgcc.mk): Make this depend on -+ $(tmake_file), in -+ case new multilib options have been defined. -+ (s-mlib): Similarly. -+ -+2008-08-07 Joseph Myers -+ -+ Backport: -+ -+ gcc/ -+ * config/arm/neon.md neon_vget_lane): Adjust element indices -+ for big-endian. -+ -+2008-08-07 Joseph Myers -+ -+ Backport: -+ -+ gcc/ -+ 2008-08-07 Joseph Myers -+ * config/arm/iwmmxt.md (movv8qi_internal, movv4hi_internal, -+ movv2si_internal): Combine into mov_internal. -+ (movv2si_internal_2): Remove. -+ -+2008-08-06 Catherine Moore -+ -+ gcc/ -+ * config/mips/mips.h (MIPS_ARCH_DSP_SPEC): Add missing *. -+ -+ * release-notes-csl.xml: Fix target. -+ -+2008-08-06 Joseph Myers -+ -+ Backport: -+ -+ gcc/ -+ 2008-08-06 Joseph Myers -+ * jump.c (rtx_renumbered_equal_p): Do not call subreg_regno_offset -+ for unrepresentable subregs or treat them as equal to other regs -+ or subregs with the same register number. -+ -+2008-08-05 Catherine Moore -+ -+ Issue #3088 -+ gcc/ -+ * config/mips/sde.h (SUBTARGET_SELF_SPECS): Add -+ MIPS_ARCH_DSP_SPEC. -+ * config/mips/mips.h (MIPS_ARCH_DSP_SPEC): New. -+ -+ * release-notes-csl.xml: Document. -+ -+2008-08-04 Joseph Myers -+ -+ gcc/testsuite/ -+ * gcc.target/mips/mips-nonpic/nonpic-9.c (main): Call exit. -+ -+2008-07-30 Nathan Froyd -+ -+ Issue #2576 -+ -+ Backport: -+ -+ gcc/ -+ 2008-07-30 Nathan Froyd -+ -+ * config/arm/arm.c (arm_expand_prologue): Use 0-length rtvec -+ instead of NULL_RTVEC. -+ -+2008-07-28 Mark Mitchell -+ -+ Issue #466 -+ gcc/ -+ * config/arm/thumb2.md: Add 16-bit multiply instructions. -+ gcc/testsuite/ -+ * lib/target-supports.exp (check_effective_target_arm_thumb2_ok): -+ New function. -+ * gcc.target/arm/thumb2-mul-space.c: New file. -+ * gcc.target/arm/thumb2-mul-space-2.c: New file. -+ * gcc.target/arm/thumb2-mul-space-3.c: New file. -+ * gcc.target/arm/thumb2-mul-speed.c: New file. -+ -+ * release-notes-csl.xml: Document. -+ -+2008-07-29 Catherine Moore -+ Daniel Jacobowitz -+ -+ gcc/ -+ * config/mips/mips.h (ISA_HAS_BBIT): Enable for TARGET_OCTEON. -+ * config/mips/mips.md (branch_with_likely): New attribute. -+ (branch_without_likely): New attribute. -+ (define_delay): Check for new branch_likely attributes. -+ (branch_bit): Set branch_without_likely to "yes". -+ (branch_bit_truncdi): Likewise. -+ (branch_bit_inverted): Likewise. -+ (branch_bit_truncdi_inverted): Likewise. -+ -+2008-07-25 Mark Mitchell -+ -+ Issue #3433 -+ gcc/ -+ * gcc.c (SWITCHES_NEED_SPACES): Define to "o". -+ -+ * release-notes-csl.xml: Document. -+ -+2008-07-25 Joseph Myers -+ -+ gcc/ -+ * config/arm/iwmmxt.md (movv8qi_internal, movv4hi_internal, -+ movv2si_internal): Use "*" for pool_range and neg_pool_range for -+ mem = reg alternative. -+ -+2008-07-25 Maxim Kuvyrkov -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2008-06-03 Maxim Kuvyrkov -+ * release-notes-csl.xml: Add note. -+ gcc/ -+ * config/mips/mips.c (mips_expand_prologue): Fix thinko. -+ -+ 2008-05-27 Maxim Kuvyrkov -+ -mwarn-framesize= option for MIPS. -+ * release-notes-csl.xml: Add note. -+ gcc/ -+ * doc/invoke.texi (mwarn-framesize): Document option. -+ * config/mips/mips.opt (mwarn-framesize): Add option. -+ * config/mips/mips.c (mips_warn_framesize): New static variable. -+ (mips_handle_option): Handle mwarn-framesize. -+ (mips_expand_prologue): Emit warning if frame size exceeds specified -+ value. -+ -+2008-07-24 Joseph Myers -+ -+ * config.sub: Allow mips64octeon* targets. -+ -+ NOT ASSIGNED TO FSF -+ COPYRIGHT CAVIUM -+ gcc/ -+ * config/mips/octeon-elf-unwind.h, config/mips/octeon-elf.h, -+ config/mips/octeon.h, config/mips/t-octeon-elf: New. -+ * config.gcc: Handle mips64octeon*-wrs-elf*. -+ (mips-wrs-linux-gnu): Use mips/octeon.h. -+ * config/mips/mips-protos.h (octeon_output_shared_variable): New. -+ * config/mips/mips.c (octeon_handle_cvmx_shared_attribute, -+ octeon_select_section, octeon_unique_section, -+ octeon_output_shared_variable): New. -+ (mips_attribute_table): Add cvmx_shared. -+ (mips_in_small_data_p): Check for cvmx_shared attribute. -+ * config/mips/mips.opt (mocteon-useun): Use Mask. -+ -+ libgcc/ -+ * config.host: Handle mips64octeon*-wrs-elf*. -+ -+2008-07-24 Joseph Myers -+ -+ gcc/ -+ * config/mips/mips.c (mips_expand_ins_as_unaligned_store): Restore -+ Octeon unaligned store support. -+ -+2008-07-21 Mark Mitchell -+ -+ Issue #3245 -+ -+ Backport: -+ -+ libstdc++-v3/ -+ 2008-07-21 Mark Mitchell -+ * config/os/gnu-linux/arm-eabi-extra.ver: New file. -+ * configure.host: Use it for arm*-*-linux-*eabi. -+ -+ * release-notes-csl.xml: Document. -+ -+2008-07-21 Joseph Myers -+ -+ gcc/ -+ * config/mips/mips.md (extzv): Avoid using dext instructions for -+ certain DImode subreg extractions. From Cavium toolchain. -+ -+2008-07-21 Nathan Froyd -+ -+ gcc/ -+ * tree-ssa-remove-local-statics.c -+ (find_static_nonvolatile_declarations): Don't check for potential -+ definitions if we're looking at a statement with a CALL_EXPR. -+ (compute_definedness_for_block): Reorganize logic. -+ -+ gcc/testsuite/ -+ * gcc.dg/remove-local-statics-13.c: New test. -+ * gcc.dg/remove-local-statics-14.c: New test. -+ -+2008-07-18 Joseph Myers -+ -+ Backport: -+ -+ gcc/testsuite/ -+ 2008-07-18 Joseph Myers -+ * gcc.dg/fshort-wchar.c: Use -Wl,--no-wchar-size-warning on -+ arm*-*-*eabi. -+ -+2008-07-17 Catherine Moore -+ -+ gcc/ -+ * config/mips/sde.h (TARET_MIPS_SDE): Define to 1. -+ (SUBTARGET_SELF_SPECS): Undefine before defining. -+ -+2008-07-10 Joseph Myers -+ -+ Backport: -+ -+ gcc/testsuite/ -+ 2008-07-10 Joseph Myers -+ PR middle-end/29056 -+ * gcc.target/powerpc/ppc-negeq0-1.c: Use long instead of int. -+ Adjust shift and scan-assembler-not pattern to allow for 64-bit -+ case. -+ -+2008-07-10 Joseph Myers -+ -+ config/ -+ * mh-mingw (LDFLAGS): Append to rather than replacing previous -+ value. -+ -+2008-07-09 Joseph Myers -+ -+ gcc/ -+ * config/mips/linux64.h (SUBTARGET_ASM_SPEC): Update for non-PIC. -+ -+2008-07-09 Joseph Myers -+ -+ gcc/ -+ * config/mips/wrs-linux.h (SUBTARGET_SELF_SPECS): Add missing -+ comma. -+ -+2008-07-09 Joseph Myers -+ -+ Backport: -+ -+ libstdc++-v3/ -+ 2008-07-09 Joseph Myers -+ * libsupc++/unwind-cxx.h (__is_gxx_forced_unwind_class, -+ __GXX_INIT_FORCED_UNWIND_CLASS): Define for ARM EABI unwinder. -+ * libsupc++/eh_personality.cc (PERSONALITY_FUNCTION): Call -+ __GXX_INIT_FORCED_UNWIND_CLASS for forced unwind with ARM EABI -+ unwinder. -+ * libsupc++/eh_arm.cc (__cxa_type_match): Use -+ __is_gxx_forced_unwind_class to check for forced unwind. -+ -+2008-07-09 Joseph Myers -+ -+ gcc/ -+ * config/mips/wrs-linux.h (SUBTARGET_SELF_SPECS): Add -+ NO_SHARED_SPECS. -+ -+2008-07-09 Joseph Myers -+ -+ Backport: -+ -+ libstdc++-v3/ -+ 2008-07-09 Joseph Myers -+ * testsuite/20_util/make_signed/requirements/typedefs-2.cc, -+ testsuite/20_util/make_unsigned/requirements/typedefs-2.cc: Use -+ -Wl,--no-enum-size-warning for arm*-*-linux*eabi. -+ -+2008-07-09 Joseph Myers -+ -+ gcc/ -+ * config/mips/mips.h (ISA_HAS_BBIT): Temporarily disable. -+ -+2008-07-09 Joseph Myers -+ -+ gcc/ -+ * config/mips/linux64.h (SUBTARGET_SELF_SPECS): Undefine before -+ redefining. -+ -+2008-07-08 Catherine Moore -+ -+ gcc/config/mips -+ xlr.md (ir_xlr_alu): Add logical, signext attributes. -+ -+2008-07-08 Nathan Froyd -+ -+ gcc/ -+ * passes.c (init_optimization_passes): Move pass_remove_local_statics -+ later in the pass order. -+ * tree-ssa-remove-local-statics.c (rls_done): Conditionally free the -+ bitmaps and NULL out bb->aux. -+ (unstaticize_variable): Deal with GIMPLE_MODIFY_STMTs instead of -+ MODIFY_EXPRs. -+ (compute_definedness_for_block): Check for defines only if we haven't -+ found a CALL_EXPR. -+ -+2008-07-07 Joseph Myers -+ -+ Backport: -+ -+ gcc/ -+ 2008-07-07 Joseph Myers -+ * config/arm/aout.h (DOLLARS_IN_IDENTIFIERS): Remove. -+ -+2008-07-07 Vladimir Prus -+ -+ gcc/ -+ * gcc.c (print_sysroot): New. -+ (option_map, display_help, process_command): Handle the -+ -print-sysroot option. -+ (main): Print the sysroot if requested. -+ -+ gcc/doc/ -+ * invoke.texi (Debugging Options): Document -print-sysroot. -+ -+2008-07-03 Joseph Myers -+ -+ gcc/ -+ * config/arm/arm.c (arm_init_neon_builtins): Register built-in -+ types immediately after creating them. -+ -+2008-07-03 Joseph Myers -+ -+ gcc/ -+ * config/arm/arm.c (add_minipool_backward_ref): Check for -+ 8-byte-aligned entries in second case of forcing insertion after a -+ particular entry. Change third case to avoid inserting -+ non-8-byte-aligned entries before 8-byte-aligned ones. -+ -+2008-07-03 Joseph Myers -+ -+ gcc/ -+ * config/arm/iwmmxt.md (movv8qi_internal, movv4hi_internal, -+ movv2si_internal): Add mem = reg alternative. -+ -+2008-07-03 Nathan Froyd -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2008-07-02 Nathan Froyd -+ -+ gcc/ -+ * config/rs6000/t-ppcgas (MULTILIB_OPTIONS): Add te500mc. -+ (MULTILIB_DIRNAMES): Likewise. -+ (MULTILIB_EXCEPTIONS): Add exception for te500mc. -+ * config/rs6000/eabi.h (NAME__MAIN, INVOKE__main): Remove. -+ (CC1_EXTRA_SPEC): Add te500mc clause. -+ (ASM_DEFAULT_SPEC): Likewise. -+ * config/rs6000/t-ppccomm (LIB2FUNS_STATIC_EXTRA): Remove eabi.S. -+ (eabi.S): Remove rule. -+ -+2008-07-03 Nathan Sidwell -+ -+ gcc/ -+ * config/m68k/t-uclinux (M68K_MLIB_CPU): Check for FL_UCLINUX. -+ * config/m68k/m68k-devices.def: Add FL_UCLINUX to 68020 and 54455 -+ multilibs. -+ * config/m68k/m68k.h (FL_UCLINUX): Define. -+ -+ * release-notes-csl.xml: Document. -+ -+2008-07-02 Joseph Myers -+ -+ gcc/ -+ * c-incpath.c: Include toplev.h. -+ (merge_include_chains): Use warning instead of cpp_error for -+ system directory poisoning diagnostic. -+ * Makefile.in (c-incpath.o): Depend on toplev.h. -+ * gcc.c (LINK_COMMAND_SPEC): Pass -+ --error-poison-system-directories if -+ -Werror=poison-system-directories. -+ -+2008-07-02 Julian Brown -+ -+ Backport from mainline: -+ -+ 2008-06-27 Mark Mitchell -+ -+ libstdc++-v3/ -+ * libsupc++/vec.cc (__aeabi_vec_dtor_cookie): Handle NULL array -+ address. -+ (__aeabi_vec_delete): Likewise. -+ (__aeabi_vec_delete3): Likewise. -+ (__aeabi_vec_delete3_nodtor): Likewise. -+ -+ gcc/testsuite/ -+ * g++.dg/abi/arm_cxa_vec2.C: New test. -+ -+2008-07-01 Joseph Myers -+ -+ gcc/testsuite/ -+ * lib/target-supports.exp (check_effective_target_arm_neon): New. -+ (check_effective_target_vect_cmdline_needed): Use it. -+ -+2008-07-01 Joseph Myers -+ -+ gcc/ -+ * config/arm/neon.md (neon_vget_lane_sext_internal, -+ neon_vget_lane_zext_internal): Adjust element indices for -+ big-endian. -+ -+2008-07-01 Nathan Sidwell -+ -+ gcc/ -+ * config/mips/linux.h (SUBTARGET_SELF_SPECS): Override this, -+ rather than ... -+ (DRIVER_SELF_SPECS): ... this. -+ * config/mips/mips.md (extzv, extzv, insv, insv, -+ *insvdi): Use mips_use_ins_ext_p rather than mips_use_ext_p -+ and mips_use_ins_p. -+ * config/mips/mips-protos.h (mips_lower_sign_bit_p, -+ mips_use_ext_p): Delete. -+ (mips_expand_vector_init): Declare. -+ * config/mips/mips.c (mips_gnu_local_gp): Declare. -+ (mips_got_base): Use can_create_pseudo_p. -+ (mips16_build_function_stub): Remove unused variable. -+ (mips_lower_sign_bit_p, mips_use_ins_p, mips_use_ext_p): Delete. -+ -+ gcc/ -+ * config/mips/mips.md (type): Correct typo for accext. -+ -+2008-06-30 Joseph Myers -+ -+ config/ -+ * mh-mingw (BOOT_CFLAGS): Do not use -D__USE_MINGW_ACCESS. -+ -+2008-06-28 Sandra Loosemore -+ -+ Backport 2 patches from mainline: -+ -+ 2008-06-28 Sandra Loosemore -+ -+ gcc/ -+ * doc/extend.texi (Variable Attributes): Use @ref instead of @xref. -+ (Type Attributes): Fix nesting of @table and @subsection. Adjust -+ punctuation. Use @ref instead of @xref. -+ (Function Names): Remove stray @display/@end display. -+ (C++ Attributes): Use @ref instead of @xref. -+ (Deprecated Features): Fix punctuation around @xref. -+ (Backwards Compatibility): Likewise. -+ * doc/rtl.texi (Incdec): Remove stray @table/@end table. -+ -+ 2008-06-15 Ralf Wildenhues -+ -+ gcc/ -+ * doc/sourcebuild.texi (Config Fragments): Remove obsolete -+ FIXME note about gcc/config.guess. -+ * doc/options.texi (Option file format): Remove non-ASCII bytes. -+ * doc/cpp.texi: Expand TABs, drop indentation outside examples. -+ * doc/cppopts.texi: Likewise. -+ * doc/extend.texi: Likewise. -+ * doc/gcc.texi: Likewise. -+ * doc/gccint.texi: Likewise. -+ * doc/gcov.texi: Likewise. -+ * doc/gty.texi: Likewise. -+ * doc/hostconfig.texi: Likewise. -+ * doc/install.texi: Likewise. -+ * doc/invoke.texi: Likewise. -+ * doc/loop.texi: Likewise. -+ * doc/makefile.texi: Likewise. -+ * doc/md.texi: Likewise. -+ * doc/passes.texi: Likewise. -+ * doc/tm.texi: Likewise. -+ * doc/tree-ssa.texi: Likewise. -+ * doc/trouble.texi: Likewise. -+ -+2008-06-27 Julian Brown -+ -+ gcc/cp/ -+ * decl2.c (determine_visibility): Allow target to override -+ visibility of class data. -+ -+ gcc/ -+ * config/arm/arm.c (arm_cxx_determine_class_data_visibility): Make -+ no-op for targets which don't use DLLs. -+ -+ gcc/testsuite/ -+ * g++.dg/ext/visibility/arm3.C: Add explanatory text. Skip on -+ non-DLL targets. -+ -+2008-06-26 Nathan Froyd -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2008-02-13 Nathan Froyd -+ -+ gcc/ -+ * optabs.c (expand_binop): Force operands to registers before -+ generating libcalls. -+ -+2008-06-26 Daniel Jacobowitz -+ -+ gcc/ -+ * config/mips/mips.c (mips_call_tls_get_addr) -+ (mips_emit_loadgp): Correct merge. -+ -+2008-06-26 Joseph Myers -+ -+ * release-notes-csl.xml: Resync release note text with Sourcery -+ G++ 4.2. -+ -+2008-06-25 Catherine Moore -+ -+ Merge from SourceryG++ 4.2: -+ -+ 2008-04-01 Joseph Myers -+ -+ gcc/ -+ * config/mips/mips.h (TARGET_CPU_CPP_BUILTINS): Define -+ __mips_isa_rev=2 for Octeon. -+ -+2008-06-25 Julian Brown -+ -+ gcc/ -+ * config.gcc (arm*-*-uclinux*): Remove duplicate uclinux-elf.h. -+ -+2008-06-25 Catherine Moore -+ -+ Merge from SourceryG++ 4.2: -+ -+ 2008-02-15 Julian Brown -+ -+ Merge from MIPS: -+ -+ 2007-11-06 David Ung -+ -+ gcc/ -+ * config/mips/mips.h (AC1HI_REGNUM, AC1LO_REGNUM, AC2HI_REGNUM) -+ (AC2LO_REGNUM, AC3HI_REGNUM, AC3LO_REGNUM): Define constants. -+ -+2008-06-25 Catherine Moore -+ -+ Merge from SourceryG++ 4.2: -+ -+ 2007-07-02 Richard Sandiford -+ -+ gcc/ -+ * config/mips/mips.h (MIPS_ISA_LEVEL_SPEC): Handle -march=octeon. -+ -+2008-06-25 Catherine Moore -+ -+ Revert: -+ -+ 2008-06-25 Catherine Moore -+ -+ Merge from SourceryG++ 4.2: -+ -+ 2007-10-18 Joseph Myers -+ -+ NOT ASSIGNED TO FSF -+ COPYRIGHT RAZA -+ * config.sub (mipsisa64xlr, ipsisa64xlrel): Add new machine names. -+ -+ gcc/ -+ * config.gcc (mipsisa64xlr-*-elf*, mipsisa64xlrel-*-elf*): New -+ targets. -+ -+2008-06-25 Catherine Moore -+ -+ Merge from SourceryG++ 4.2: -+ -+ 2007-10-18 Joseph Myers -+ -+ NOT ASSIGNED TO FSF -+ COPYRIGHT RAZA -+ * config.sub (mipsisa64xlr, ipsisa64xlrel): Add new machine names. -+ -+ gcc/ -+ * config.gcc (mipsisa64xlr-*-elf*, mipsisa64xlrel-*-elf*): New -+ targets. -+ * config/mips/mips.h (PROCESSOR_XLR, TARGET_XLR): Define. -+ (MIPS_ISA_LEVEL_SPEC): Handle -march=xlr. -+ -+2008-06-24 Catherine Moore -+ -+ Merge from SourceryG++ 4.2: -+ -+ 2008-02-12 Julian Brown -+ -+ Merge from MIPS: -+ -+ 2008-01-16 David Ung -+ -+ * config/mips/sdemtk.h: Define macro TARGET_MIPS_SDEMTK. -+ * config/mips/mips.c (mips_file_start): Check against -+ TARGET_MIPS_SDEMTK which supports the TARGET_NO_FLOAT option. -+ -+ 2007-11-02 Thiemo Seufer -+ -+ * config/mips/mips.c (mips_file_start): Add support for flagging -+ 32-bit code with -mfp64 floating point. -+ -+2008-06-24 Catherine Moore -+ -+ Merge from SourceryG++ 4.2: -+ -+ 2008-03-12 Julian Brown -+ -+ Merge from MIPS: -+ -+ 2007-11-29 Thiemo Seufer -+ -+ gcc/ -+ * config/mips/mips.c (override_options): Let -fpic imply -+ -mabicalls, forward port from SDE6. -+ -+2008-06-23 Julian Brown -+ -+ gcc/ -+ * config/arm/arm.h (ASM_OUTPUT_REG_PUSH): Handle STATIC_CHAIN_REGNUM -+ specially for Thumb-1. -+ (ASM_OUTPUT_REG_POP): Likewise. -+ -+2008-06-23 Julian Brown -+ -+ gcc/ -+ * config/arm/thumb2.md (*thumb2_negscc): Remove bad negated-GT -+ code sequence. -+ -+2008-06-20 Catherine Moore -+ -+ Merge from SourceryG++ 4.2: -+ -+ 2007-10-21 Sandra Loosemore -+ -+ gcc/ -+ * config/mips/mips.c (mips_cpu_info_table): Fix damaged merge -+ of XLR entry from r185319. -+ (mips_rtx_cost_data): Likewise. -+ (mips_sched_reorder): Add ATTRIBUTE_UNUSED to cycle parameter. -+ -+2008-06-18 Catherine Moore -+ -+ Merge from SourceryG++ 4.2: -+ -+ 2007-09-06 Sandra Loosemore -+ -+ gcc/ -+ * config/mips/mips.opt (mips16e): Add as deprecated alias -+ for -mips16. -+ * doc/invoke.texi (Option Summary, MIPS Options): Document it. -+ -+2008-06-18 Catherine Moore -+ -+ Merge from SourceryG++ 4.2: -+ -+ 2008-02-12 Julian Brown -+ -+ Merge from MIPS: -+ -+ 2007-12-21 David Ung -+ -+ gcc/ -+ * config/mips/mips.h (TARGET_MIPS_SDE): Define macro as 0. -+ * config/mips/sde.h (TARGET_MIPS_SDE): Override macro definition to 1. -+ * config/mips/mips.md (abs2): Enable abs.[sd] patterns if -+ TARGET_MIPS_SDE && TARGET_HARD_FLOAT. -+ -+2008-06-18 Catherine Moore -+ -+ Merge from SourceryG++ 4.2: -+ -+ 2007-10-14 Sandra Loosemore -+ -+ * config/mt-sde: Update to make it agree with the mainline -+ version committed with the below patch. -+ -+ Backport from mainline: -+ gcc/ -+ -+ 2007-08-17 Richard Sandiford -+ Nigel Stephens -+ -+ * config/mips/sde.h (DRIVER_SELF_SPECS): Add commas. -+ Treat -mno-data-in-code and -mcode-xonly as aliases for -+ -mcode-readable=no and -mcode-readable=pcrel respectively. -+ * config/mips/t-sde (TARGET_LIBGCC2_CFLAGS): Add -mcode-xonly. -+ (MULTILIB_OPTIONS): Add -mcode-readable=no multilibs. -+ (MULTILIB_DIRNAMES): Update accordingly. -+ -+2008-06-18 Catherine Moore -+ -+ Merge from SourceryG++ 4.2: -+ -+ 2007-09-08 Sandra Loosemore -+ -+ gcc/ -+ * config/mips/t-sde (MULTILIB_MATCHES): Add mips16e as alias -+ for mips16. -+ -+2008-06-18 Joseph Myers -+ -+ gcc/ -+ * config/arm/arm.c (arm_assemble_integer): Do not handle -+ big-endian NEON vectors specially. -+ * config/arm/neon.md (vec_set_internal, vec_extract): -+ Adjust element indices for big-endian. -+ -+2008-06-18 Catherine Moore -+ -+ Merge from SourceryG++ 4.2: -+ -+ 2008-02-11 Julian Brown -+ -+ Merge from MIPS: -+ -+ gcc/ -+ * config/mips/t-sde (MULTILIB_OPTIONS): Substitute mno-data-in-code for -+ mcode-readable=no option. -+ -+2008-06-17 Catherine Moore -+ -+ Merge from SourceryG++ 4.2: -+ -+ 2008-03-28 Nathan Sidwell -+ -+ * config/mips/t-sdemtk (MULTILIB_OPTIONS, MULTILIB_DIRNAMES, -+ MULTILIB_EXCLUSIONS): Likewise. -+ -+2008-06-17 Catherine Moore -+ -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2008-03-17 Julian Brown -+ -+ gcc/ -+ * config.gcc (mips*-sde-elf*): Add SourceryG++ multilib support. -+ * config/mips/t-sgxx-sde: New. -+ * config/mips/sdemtk.h (MIPS_ARCH_FLOAT_SPEC): Override, adding -+ -mno-float option. -+ -+2008-06-17 Joseph Myers -+ -+ Backport: -+ -+ gcc/ -+ 2008-03-09 Ira Rosen -+ * config/rs6000/rs6000.c (builtin_description): Rename vector -+ left shift operations. -+ * config/rs6000/altivec.md (UNSPEC_VSL): Remove. -+ (altivec_vsl): Rename to ... -+ (ashl3): ... new name. -+ (mulv4sf3, mulv4si3, negv4sf2): Replace gen_altivec_vslw with -+ gen_ashlv4si3. -+ (absv4sf2): Convert to use ashift:V4SI instead of UNSPEC_VSL. -+ -+2008-06-16 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-03-30 Mark Mitchell -+ -+ gcc/testsuite/ -+ * gcc.dg/sibcall-3.c: XFAIL for Thumb. -+ * gcc.dg/sibcall-4.c: Likewise. -+ -+2008-06-16 Paul Brook -+ -+ Merge from Sourcery G++ 4.2 -+ 2007-03-30 Paul Brook -+ gcc/ -+ * calls.c (store_one_arg): Check alignment of mode used for save. -+ -+2008-06-13 Nathan Froyd -+ -+ gcc/ -+ * config.gcc (powerpc-*-linux*): Add rs6000/e500.h to tm_file -+ and rs6000/t-linux to tmake_file. -+ -+2008-06-13 Paul Brook -+ -+ Merge from Sourcery G++ 4.2 -+ Issue #1510 -+ 2007-04-27 Paul Brook -+ gcc/ -+ * cse.c (cse_process_notes): Make sure PLUS are canonical. -+ -+2008-06-13 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ libgcc/ -+ * config.host (arm*-*-linux*, arm*-*-uclinux*, arm*-*-eabi*) -+ (arm*-*-symbianelf): Add arm/t-divmod-ef to tmake_file. -+ * Makefile.in (LIB2_DIVMOD_EXCEPTION_FLAGS): Set to previous -+ default if not set by a target-specific Makefile fragment. -+ (lib2-divmod-o, lib2-divmod-s-o): Use above. -+ * config/arm/t-divmod-ef: New. -+ -+2008-06-13 Daniel Jacobowitz -+ -+ libgcc/ -+ * shared-object.mk (c_flags-$(base)$(objext)): New. -+ ($(base)$(objext)): Use above. -+ ($(base)_s$(objext)): Likewise. -+ * static-object.mk (c_flags-$(base)$(objext)): New. -+ ($(base)$(objext)): Use above. -+ -+2008-06-13 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ gcc/testsuite/ -+ * lib/target-supports.exp (check_effective_target_vect_int) -+ (check_effective_target_vect_shift) -+ (check_effective_target_vect_long) -+ (check_effective_target_vect_float) -+ (check_effective_target_vect_int_mult): Check for ARM. -+ -+2008-06-12 Catherine Moore -+ -+ Merge from Sourcery G++ 4.2: -+ -+ gcc/ -+ * config/mips/linux64.h: USE_SUBTARGET_SELF_SPECS. -+ * config/mips/sde.h: Likewise. -+ * config/mips/iris6.h: Likewise. -+ -+2008-06-12 Catherine Moore -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2008-02-15 Julian Brown -+ -+ gcc/ -+ * config/mips/t-sgxx-linux: New target fragment. -+ * config/mips/t-sgxxlite-linux: New target fragment. -+ * config/mips/cs-sgxx-linux.h: New header file. -+ * config/mips/cs-sgxxlite-linux.h: New header file. -+ * config/mips/t-none-linux: Remove. -+ * config/mips/cs-linux.h: Remove. -+ * config.gcc (mips*-*-linux*): Handle --enable-extra-sgxx-multilibs -+ and --enable-extra-sgxxlite-multilibs configure options. Use -+ sgxx-specific header files and target fragments. Remove use of -+ t-none-linux and cs-linux.h. -+ -+2008-06-12 Catherine Moore -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2008-03-25 Maxim Kuvyrkov -+ Julian Brown -+ -+ * 74k.md: (r74k_dsp_alu, r74k_dsp_alu_sat, r74k_dsp_mac, r74k_dsp_mac_sat) -+ (r74k_dsp_acc_ext, r74k_dsp_acc_mod): New insn reservations. -+ (r74k_dsp_mac, r74k_dsp_mac_sat, r74k_int_mult, r74k_int_mul3) -+ (r74k_dsp_mac, r74k_dsp_mac_sat): New bypasses. -+ -+ -+2008-06-12 Catherine Moore -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2008-03-25 Maxim Kuvyrkov -+ Julian Brown -+ -+ Merge from MIPS: -+ -+ gcc/ -+ * config/mips/mips-protos.h (dspalu_bypass_p): Add prototype. -+ * config/mips/mips.c (dspalu_bypass_table): New. -+ (dspalu_bypass_p): New. -+ * 24k.md (r24k_dsp_alu, r24k_dsp_mac, r24k_dsp_mac_sat) -+ (r24k_dsp_acc_ext, r24k_dsp_acc_mod): New insn reservations. -+ (r24k_int_mult, r24k_int_mthilo, r24k_dsp_mac, r24k_dsp_mac_sat) -+ (r24k_dsp_acc_ext, r24k_dsp_acc_mod, r24k_dsp_alu): New bypasses. -+ * config/mips/mips.md (dspmac, dspmacsat, accext, accmod, dspalu) -+ (dspalusat): Add insn types. -+ * config/mips/mips-dsp.md (add3) -+ (mips_add_s_) -+ (sub3, mips_sub_s_, mips_addsc) -+ (mips_addwc, mips_modsub, mips_raddu_w_qb, mips_absq_s_) -+ (mips_precrq_qb_ph, mips_precrq_ph_w, mips_precrq_rs_ph_w) -+ (mips_precrqu_s_qb_ph, mips_preceq_w_phl, mips_preceq_w_phr) -+ (mips_precequ_ph_qbl, mips_precequ_ph_qbr, mips_precequ_ph_qbla) -+ (mips_precequ_ph_qbra, mips_preceu_ph_qbl, mips_preceu_ph_qbr) -+ (mips_preceu_ph_qbla, mips_preceu_ph_qbra, mips_shll_) -+ (mips_shll_s_, mips_shll_s_, mips_shrl_qb) -+ (mips_shra_ph, mips_shra_r_, mips_bitrev, mips_insv) -+ (mips_repl_qb, mips_repl_ph, mips_cmp_eq_) -+ (mips_cmp_lt_) -+ (mips_cmp_le_, mips_cmpgu_eq_qb) -+ (mips_cmpgu_lt_qb, mips_cmpgu_le_qb, mips_pick_) -+ (mips_packrl_ph, mips_wrdsp, mips_rddsp): Change type to dspalu. -+ (mips_dpau_h_qbl, mips_dpau_h_qbr, mips_dpsu_h_qbl, mips_dpsu_h_qbr) -+ (mips_dpaq_s_w_ph, mips_dpsq_s_w_ph, mips_mulsaq_s_w_ph) -+ (mips_maq_s_w_phl, mips_maq_s_w_phr, mips_maq_sa_w_phr: Set type to -+ dspmac. -+ (mips_dpaq_sa_l_w, mips_dpsq_sa_l_w, mips_maq_sa_w_phl): Set type to -+ dspmacsat. -+ (mips_extr_w, mips_extr_r_w, mips_extr_rs_w, mips_extp, mips_extpdp): -+ Set type to accext. -+ (mips_shilo, mips_mthlip): Set type to accmod. -+ * config/mips/mips-dspr2.md (mips_absq_s_qb, mips_addu_s_ph) -+ (mips_adduh_r_qb): Set type to dspalusat. -+ (mips_addu_ph, mips_adduh_qb, mips_append, mips_balign) -+ (mips_cmpgdu_eq_qb, mips_cmpgdu_lt_qb, mips_cmpgdu_le_qb) -+ (mips_precr_qb_ph, mips_precr_sra_ph_w, mips_precr_sra_r_ph_w) -+ (mips_prepend, mips_shra_qb, mips_shra_r_qb, mips_shrl_ph) -+ (mips_subu_ph, mips_subuh_qb, mips_subuh_r_qb, mips_addqh_ph) -+ (mips_addqh_r_ph, mips_addqh_w, mips_addqh_r_w, mips_subqh_ph) -+ (mips_subqh_r_ph, mips_subqh_w, mips_subqh_r_w): Set type to dspalu. -+ (mips_dpa_w_ph, mips_dps_w_ph, mips_mulsa_w_ph, mips_dpax_w_ph) -+ (mips_dpsx_w_ph, mips_dpaqx_s_w_ph, mips_dpsqx_s_w_ph): Set type to -+ dspmac. -+ (mips_subu_s_ph): Set type to dspalusat. -+ (mips_dpaqx_sa_w_ph, mips_dpsqx_sa_w_ph): Set type to dspmacsat. -+ -+2008-06-12 Joseph Myers -+ -+ gcc/testsuite/ -+ * lib/target-supports.exp -+ (check_effective_target_powerpc_hard_double): New. -+ * gcc.dg/tree-ssa/loop-19.c: Use powerpc_hard_double instead of -+ powerpc*-*-*. -+ -+2008-06-12 Joseph Myers -+ -+ gcc/testsuite/ -+ * gcc.dg/dfp/convert-bfp-6.c, gcc.dg/dfp/convert-bfp-9.c: XFAIL -+ for lax_strtofp. -+ -+2008-06-12 Joseph Myers -+ -+ Backport: -+ -+ gcc/ -+ 2008-05-21 Janis Johnson -+ * doc/sourcebuild.texi (Test Directives): Add dg-xfail-run-if. -+ -+ gcc/testsuite/ -+ 2008-05-21 Janis Johnson -+ * lib/target-supports-dg.exp (dg-xfail-run-if): New. -+ -+2008-06-12 Catherine Moore -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2008-03-25 Maxim Kuvyrkov -+ Julian Brown -+ -+ Merge from MIPS: -+ -+ gcc/ -+ * config/mips/mips.c (mips_mult_madd_chain_bypass_p): New. -+ * config/mips/mips-protos.h (mips_mult_madd_chain_bypass_p): Add -+ prototype. -+ * config/mips/74k.md: Add bypasses for r74k_int_mult, r74_int_madd, -+ r74k_int_mul3. -+ -+ -+2008-06-11 Catherine Moore -+ -+ Backport: -+ -+ gcc/ -+ 2008-06-06 Sandip Matte -+ -+ * doc/invoke.texi: Document -march=xlr. -+ * config/mips/xlr.md: New file. -+ * config/mips/mips.md: Include it. -+ (cpu): Add "xlr". -+ * config/mips/mips.h (PROCESSOR_XLR): New processor_type. -+ * config/mips/mips.c (mips_cpu_info_table): Add an XLR entry. -+ (mips_rtx_cost_data): Likewise. -+ -+2008-06-10 Catherine Moore -+ -+ Merge from Sourcery G++ 4.2: -+ -+ -+ 2008-03-27 Daniel Jacobowitz -+ -+ gcc/ -+ * config/mips/mips.md (loadgp_nonpic): New pattern. -+ (builtin_longjmp): Use for all TARGET_ABICALLS. -+ (exception_receiver): Revert local changes. -+ * config/mips/mips.c (mips_gnu_local_gp, mips_got_base): New functions. -+ (struct machine_function): Update the comment for -+ mips16_gp_pseudo_rtx. -+ (mips_call_tls_get_addr, mips_legitimize_tls_address): Use -+ mips_got_base. -+ (mips_restore_gp): Revert local changes. Assert PIC. -+ (mips_load_call_address, mips_expand_call): Revert local changes. -+ (mips_conditional_register_usage): Make $gp ordinary for -+ non-PIC. -+ (mips_tls_got_ref_1, mips_tls_got_ref_p): Delete. -+ (mips_function_has_gp_insn, mips_global_pointer): Revert local changes. -+ (mips_save_reg_p): Check for fixed $gp. -+ (mips_gnu_local_gp_rtx): Renamed from mips_gnu_local_gp. -+ (mips_emit_loadgp): Use mips_gnu_local_gp. -+ (mips_dangerous_for_la25_p): Revert local change. -+ (mips16_gp_pseudo_reg): Use gen_loadgp_nonpic. -+ (mips_extra_live_on_entry): Revert local change. -+ * config/mips/mips.h (TARGET_USE_GOT): Require flag_pic. -+ (TARGET_CALL_CLOBBERED_GP): Likewise. -+ (TARGET_NONPIC_ABICALLS): Define. -+ 2008-03-19 Mark Shinwell -+ Catherine Moore -+ Daniel Jacobowitz -+ -+ gcc/ -+ * configure.ac: Add --enable-mips-nonpic. -+ * configure: Regenerated. -+ * config.gcc: Set TARGET_ABICALLS_DEFAULT instead of MASK_ABICALLS -+ for MIPS targets. Handle --enable-mips-nonpic. -+ * config/mips/linux.h (TARGET_DEFAULT): Delete. -+ (SUBTARGET_ASM_SPEC): Use -mnon-pic-abicalls. -+ * config/mips/elfoabi.h, config/mips/linux64.h, -+ config/mips/sde.h, config/mips/iris6.h, config/mips/wrs-linux.h, -+ config/mips/vr.h: Use SUBTARGET_SELF_SPECS. -+ * config/mips/mips.md (exception_receiver): Disable for -+ non-PIC. -+ * config/mips/mips.c (mips_classify_symbol): Do not use the GOT -+ for non-PIC. -+ (mips_tls_symbol_ref_1, mips_cannot_force_const_mem): Correct comments. -+ (mips_restore_gp): Skip for non-PIC. -+ (mips_load_call_address): Skip lazy binding for non-PIC. -+ (mips_expand_call): Skip GP usage for non-PIC. -+ (override_options): Remove flag_pic override. Use sorry for -+ other ABIs. -+ (mips_file_start): Emit pic0 for non-PIC. -+ (mips_tls_got_ref_1, mips_tls_got_ref_p): New. -+ (mips_function_has_gp_insn): Use mips_tls_got_ref_p. Skip jump -+ tables. -+ (mips_global_pointer, mips_current_loadgp_style): Adjust for non-PIC. -+ (mips_expand_prologue): Do not cprestore for non-PIC. -+ (mips_function_rodata_section): Skip for non-PIC. -+ (mips_dangerous_for_la25_p): Likewise. -+ (mips_extra_live_on_entry): Skip for non-PIC. -+ * config/mips/mips.h (TARGET_GPWORD): Require flag_pic. -+ (ABICALLS_SPEC, ABICALLS_SELF_SPECS, SUBTARGET_SELF_SPECS) -+ (DRIVER_SELF_SPECS): New. -+ (MIPS_CALL): Correct for non-PIC. -+ -+2008-06-09 Kazu Hirata -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2008-05-28 Kazu Hirata -+ -+ Issue 2895 -+ gcc/ -+ * config.gcc (arm*-*-linux*): Handle enable_extra_asa_multilibs. -+ enable_extra_asa_multilibs. -+ * config/arm/t-asa: New. -+ -+ 2008-05-28 Kazu Hirata -+ -+ * config/arm/t-asa (MULTILIB_EXCEPTIONS): Remove -+ march=armv4t/mfpu=neon* and march=armv4t/*mfloat-abi=softfp. Add -+ *march=armv4t*/*mfpu=neon* and *march=armv4t*/*mfloat-abi=softfp*. -+ (MULTILIB_ALIASES): Remove march?armv4t=mthumb/march?armv4t* and -+ march?armv6=mthumb/march?armv6*. Add -+ march?armv4t=mthumb/march?armv4t, march?armv6=mthumb/march?armv6, -+ and -+ march?armv6/mfloat-abi?softfp=mthumb/march?armv6/mfloat-abi?softfp. -+ -+2008-06-09 Joseph Myers -+ -+ gcc/testsuite/ -+ * gcc.target/powerpc/20030218-1.c: Separate dg-message and -+ dg-error for two diagnostics on the same line. -+ -+2008-06-09 Catherine Moore -+ -+ From 4.2 branch: -+ -+ gcc/testsuite/ -+ * gcc.target/mips/branch-1.c: Support OCTEON. -+ -+2008-06-09 Joseph Myers -+ -+ Backport: -+ -+ gcc/testsuite/ -+ 2008-05-20 Janis Johnson -+ * g++.dg/ext/vector14.C: Ignore a possible warning. -+ -+2008-06-09 Joseph Myers -+ -+ Backport: -+ -+ gcc/testsuite/ -+ 2008-06-09 Joseph Myers -+ * gcc.dg/pr34856.c: Condition use of -maltivec on -+ powerpc_altivec_ok. Use -w on other powerpc*-*-linux*. -+ -+2008-06-09 Catherine Moore -+ -+ From 4.2 branch: -+ -+ gcc/testsuite/ -+ * gcc.target/mips/mips-nonpic: New testsuite. -+ -+2008-06-09 Catherine Moore -+ -+ gcc/testsuite/ -+ * gcc.target/mips/mips32-dsp-run.c (mipsisa32-sde-elf): Add as -+ target. -+ * gcc.target/mips/mips32-dsp.c: Likewise. -+ -+2008-06-07 Joseph Myers -+ -+ Backport: -+ -+ gcc/testsuite/ -+ 2008-04-04 Janis Johnson -+ * g++.dg/other/anon5.C: Don't depend on line number for error message. -+ * gcc.dg/torture/builtin-modf-1.c: Use special options for -+ powerpc*-*-linux*. -+ * gcc.dg/var-expand3.c: Skip for powerpc-linux if not on AltiVec HW. -+ * gcc.dg/pr34856.c: Use -maltivec on powerpc linux. -+ -+2008-06-07 Joseph Myers -+ -+ gcc/testsuite/ -+ * gcc.target/powerpc/altivec-24.c, gcc.target/powerpc/pr35907.c: -+ Correct target selector syntax. -+ -+2008-06-06 Sandra Loosemore -+ -+ From 4.2 branch: -+ -+ * release-notes-csl.xml (GCC stack size limit increased): -+ Conditionalize release note for host. -+ (UNC pathname bug fix): Likewise. -+ -+2008-06-06 Joseph Myers -+ -+ gcc/ -+ * config/arm/wrs-linux.h (SUBTARGET_EXTRA_LINK_SPEC): Don't pass -+ --be8 for -r links. -+ -+2008-06-06 Joseph Myers -+ -+ Backport: -+ -+ libstdc++-v3/ -+ 2008-06-06 Joseph Myers -+ * configure.ac: Do not check for gconv.h. -+ * crossconfig.m4 (GLIBCXX_CROSSCONFIG): Do not test for gconv.h or -+ gconf.h. For glibc and uClibc systems, define -+ _GLIBCXX_USE_RANDOM_TR1 and HAVE_MMAP and use AC_LC_MESSAGES and -+ AM_ICONV. -+ * configure, config.h.in: Regenerate. -+ -+2008-06-06 Joseph Myers -+ -+ Backport: -+ -+ libstdc++-v3/ -+ 2008-06-06 Joseph Myers -+ * testsuite/17_intro/headers/all.cc, -+ testsuite/17_intro/headers/all_c++200x_compatibility.cc, -+ testsuite/17_intro/headers/all_pedantic_errors.cc, -+ testsuite/ext/headers.cc: Only include -+ and if -+ _GLIBCXX_HAVE_ICONV. -+ -+2008-06-05 Catherine Moore -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2006-12-15 Richard Sandiford -+ -+ gcc/testsuite/ -+ * gcc.target/mips/mips.exp (setup_mips_tests): Record whether -+ endianness is forced. Trest -mabicalls and -mno-abicalls as -+ ABI options. -+ (is_gp32_flag): Treat -mabi=32 as a 32-bit option. -+ (is_gp64_flag): New function. -+ (dg-mips-options): Generalize -mgp64 handling to is_gp64_flag. -+ Do not set the ABI if the arguments already specify one. -+ Skip tests if the arguments specify an incompatible ABI. -+ Use -mno-abicalls for -mabi=eabi. -+ * gcc.target/mips/octeon-1.c, gcc.target/mips/octeon-2.c: New tests. -+ * gcc.target/mips/octeon-3.c, gcc.target/mips/octeon-4.c: Likewise -+ * gcc.target/mips/octeon-5.c, gcc.target/mips/octeon-6.c: Likewise -+ * gcc.target/mips/octeon-7.c, gcc.target/mips/octeon-8.c: Likewise -+ * gcc.target/mips/octeon-9.c, gcc.target/mips/octeon-10.c: Likewise -+ * gcc.target/mips/octeon-11.c, gcc.target/mips/octeon-12.c: Likewise -+ * gcc.target/mips/octeon-13.c, gcc.target/mips/octeon-14.c: Likewise -+ * gcc.target/mips/octeon-15.c, gcc.target/mips/octeon-16.c: Likewise -+ * gcc.target/mips/octeon-17.c, gcc.target/mips/octeon-18.c: Likewise -+ * gcc.target/mips/octeon-19.c, gcc.target/mips/octeon-20.c: Likewise -+ * gcc.target/mips/octeon-21.c, gcc.target/mips/octeon-22.c: Likewise -+ * gcc.target/mips/octeon-23.c, gcc.target/mips/octeon-24.c: Likewise -+ * gcc.target/mips/octeon-25.c, gcc.target/mips/octeon-26.c: Likewise -+ * gcc.target/mips/octeon-27.c, gcc.target/mips/octeon-28.c: Likewise -+ * gcc.target/mips/octeon-29.c, gcc.target/mips/octeon-30.c: Likewise -+ * gcc.target/mips/octeon-31.c, gcc.target/mips/octeon-32.c: Likewise -+ * gcc.target/mips/octeon-33.c, gcc.target/mips/octeon-34.c: Likewise -+ * gcc.target/mips/octeon-35.c, gcc.target/mips/octeon-36.c: Likewise -+ * gcc.target/mips/octeon-37.c, gcc.target/mips/octeon-38.c: Likewise -+ * gcc.target/mips/octeon-39.c, gcc.target/mips/octeon-40.c: Likewise -+ * gcc.target/mips/octeon-41.c, gcc.target/mips/octeon-42.c: Likewise -+ * gcc.target/mips/octeon-43.c, gcc.target/mips/octeon-44.c: Likewise -+ * gcc.target/mips/octeon-45.c, gcc.target/mips/octeon-46.c: Likewise -+ * gcc.target/mips/octeon-47.c, gcc.target/mips/octeon-48.c: Likewise -+ * gcc.target/mips/octeon-49.c, gcc.target/mips/octeon-50.c: Likewise -+ * gcc.target/mips/octeon-51.c, gcc.target/mips/octeon-52.c: Likewise -+ * gcc.target/mips/octeon-53.c, gcc.target/mips/octeon-54.c: Likewise -+ * gcc.target/mips/octeon-55.c, gcc.target/mips/octeon-56.c: Likewise -+ * gcc.target/mips/scc-1.c, gcc.target/mips/scc-2.c: Likewise. -+ * gcc.target/mips/branch-1.c: Likewise. -+2008-06-05 Catherine Moore -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2006-12-15 Richard Sandiford -+ -+ Adapted from a patch by Cavium Networks. -+ -+ gcc/ -+ * config/mips/mips.opt (mocteon-useun): New option. -+ * config/mips/mips-protos.h (mask_low_and_shift_len): Declare. -+ (mips_lower_sign_bit_p, mips_use_ins_p, mips_use_ext_p): Declare. -+ (mips_adjust_register_ext_operands): Likewise. -+ * config/mips/mips.h (PROCESSOR_OCTEON): New processor_type. -+ (TARGET_OCTEON): New macro. -+ (ISA_HAS_DCLZ_DCLO): Delete. -+ (ISA_HAS_POPCOUNT): New macro. -+ (ISA_HAS_ROTR_SI, ISA_HAS_ROTR_DI): Include TARGET_OCTEON. -+ (ISA_HAS_SEB_SEH, ISA_HAS_INS_EXT): Likewise. -+ (ISA_HAS_EXTS, ISA_HAS_BBIT, ISA_HAS_SEQ_SNE, ISA_HAS_BADDU) -+ (ISA_HAS_UL_US, ISA_HAS_CINS): New macros. -+ (ASM_SPEC): Pass down -mocteon-useun and -mno-octeon-useun. -+ * config/mips/mips.c (mips_cpu_info_table): Add an octeon entry. -+ (mips_rtx_cost_data): Likewise. -+ (mask_low_and_shift_len, mips_get_seq_sne_operand): New functions. -+ (mips_emit_scc): Use mips_get_seq_sne_operand to choose between -+ seq/sne and xor/addu. -+ (mips_expand_unaligned_load): Use mov_ulw and mov_uld if -+ ISA_HAS_UL_US. -+ (mips_expand_unaligned_store): Likewise mov_usw and mov_usd. -+ (mips_lower_sign_bit_p, mips_use_ins_p, mips_use_ext_p): New functions. -+ (mips_adjust_register_ext_operands): Likewise. -+ (print_operand): Add %E, %G and %H formats. -+ (mips_issue_rate): Return 2 when scheduling for PROCESSOR_OCTEON. -+ (mips_multipass_dfa_lookahead): Likewise. -+ * config/mips/octeon.md: New file. -+ * config/mips/mips.md: Include it. -+ (UNSPEC_UNALIGNED_LOAD, UNSPEC_UNALIGNED_STORE): New constants. -+ (type): Add pop. -+ (cpu): Add octeon. -+ (SUBDI): New mode macro. -+ (topbit): New mode attribute. -+ (any_extract, any_shiftrt, equailty_op): New code macros. -+ (*baddu_si, *baddu_disi, *baddu_didi, *baddu_didi2, popcount2) -+ (*_trunc_exts, *trunc_zero_ext_): -+ New patterns. -+ (zero_extendsidi2): Turn into a define_expand. Rename old -+ define_insn_and_split to... -+ (*zero_extendsidi2): ...this and require !ISA_HAS_EXT_INS. -+ (*clear_upper32): Require !ISA_HAS_EXT_INS. -+ (*zero_extendsidi2_dext, *clear_upper32_dext): New patterns. -+ (extv): Change operand 1 from a QImode memory_operand to any -+ nonimmediate_operand. Try using extvsi and extvdi for register -+ extractions if ISA_HAS_EXTS. -+ (extv, *extv_truncdi): New patterns. -+ (extzv): Use mips_use_ext_p instead of mips_use_ins_ext_p. -+ Call mips_adjust_register_ext_operands. -+ (extzv): Use mips_use_ext_p instead of mips_use_ins_ext_p. -+ (*extzv_truncdi, *extz_truncdi_exts): New patterns. -+ (insv): Use mips_use_ins_p instead of mips_use_ins_ext_p. -+ Fix formatting. -+ (insv): Use mips_use_ins_p instead of mips_use_ins_ext_p. -+ (*insvdi, *insv__di, *insvdi_clear_upper32) -+ (*cins): New patterns. -+ (mov_l, mov_r, mov_l, mov_r): Require -+ ISA_HAS_UL_US. -+ (mov_u, mov_u): New patterns. -+ (*truncsi_storeqi, *truncsi_storehi): Likewise. -+ (*branch_bit, *branch_bit_testdi): New patterns. -+ (*branch_bit_inverted): New pattern. -+ (*branch_bit_truncdi_inverted): Likewise. -+ (*seq_, *seq__mips16, *sne_): Require -+ !ISA_HAS_SEQ_SNE. -+ (*seq_si_to_di, *seq_si_to_di_mips16, *sne_si_to_di): New patterns. -+ (*s__s, *s_si_to_di_s): Likewise. -+ * config/mips/predicates.md (mask_low_and_shift_operator): New -+ predicate. -+ -+2008-06-05 Joseph Myers -+ -+ gcc/ -+ * config.gcc (powerpc-*-linux*spe*): Use t-dfprules. -+ * config/rs6000/dfp.md (negdd2, absdd2, negtd2, abstd2): Do not -+ enable for TARGET_E500_DOUBLE. -+ (*movdd_softfloat32): Also enable for !TARGET_FPRS. -+ * config/rs6000/rs6000.c (invalid_e500_subreg): Treat decimal -+ floating-point modes like integer modes for E500 double. -+ (rs6000_legitimate_offset_address_p): Likewise. -+ (rs6000_legitimize_address): Likewise. Do not allow REG+REG -+ addressing for DDmode for E500 double. -+ (rs6000_hard_regno_nregs): Do not treat decimal floating-point -+ modes as using 64-bits of registers for E500 double. -+ (spe_build_register_parallel): Do not handle DDmode or TDmode. -+ (rs6000_spe_function_arg): Do not handle DDmode or TDmode -+ specially for E500 double. -+ (function_arg): Do not call rs6000_spe_function_arg for DDmode or -+ TDmode for E500 double. -+ (rs6000_gimplify_va_arg): Only handle SDmode in registers -+ specially if TARGET_HARD_FLOAT && TARGET_FPRS. -+ (rs6000_split_multireg_move): Do not handle TDmode specially for -+ E500 double. -+ (spe_func_has_64bit_regs_p): Do not treat DDmode or TDmode as -+ using 64-bit registers for E500 double. -+ (emit_frame_save): Do not handle DDmode specially for E500 double. -+ (gen_frame_mem_offset): Likewise. -+ (rs6000_function_value): Do not call spe_build_register_parallel -+ for DDmode or TDmode. -+ (rs6000_libcall_value): Likewise. -+ * config/rs6000/rs6000.h (LOCAL_ALIGNMENT, MEMBER_TYPE_FORCES_BLK, -+ DATA_ALIGNMENT, CLASS_MAX_NREGS): Do not handle DDmode specially -+ for E500 double. -+ -+2008-06-05 Joseph Myers -+ -+ gcc/ -+ * dfp.c (WORDS_BIGENDIAN): Define to 0 if not defined. -+ (encode_decimal64, decode_decimal64, encode_decimal128, -+ decode_decimal128): Reverse order of 32-bit parts of value if host -+ and target endianness differ. -+ -+ libdecnumber/ -+ * dconfig.h: New. -+ * decContext.c, decExcept.c, decExcept.h, decLibrary.c, -+ decNumber.c, decNumberLocal.h, decRound.c, dpd/decimal128.c, -+ dpd/decimal32.c, dpd/decimal64.c: Include dconfig.h not config.h. -+ * dpd/decimal128Local.h (decimal128SetSign, decimal128ClearSign, -+ decimal128FlipSign): Use WORDS_BIGENDIAN not -+ FLOAT_WORDS_BIG_ENDIAN. -+ * bid/host-ieee128.c: Include dconfig.h. -+ (__host_to_ieee_128, __ieee_to_host_128): Swap 64-bit halves of -+ value if WORDS_BIGENDIAN. -+ -+ libgcc/ -+ * Makefile.in (DECNUMINC): Remove -+ -I$(MULTIBUILDTOP)../../libdecnumber. -+ * gstdint.h: New. -+ -+2008-06-05 Joseph Myers -+ -+ gcc/ -+ * config/arm/arm.c (arm_init_neon_builtins): Move initialization -+ with function calls after declarations. Lay out -+ neon_float_type_node before further use. -+ -+2008-06-04 Catherine Moore -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2008-03-27 Robin Randhawa -+ -+ * libstdc++-v3/config/cpu/mips/atomicity.h : Added memory barriers -+ to enforce strict ordering on weakly ordered systems. -+ -+2008-06-04 Paul Brook -+ -+ Fix Issue #2917 -+ gcc/ -+ * config/arm/arm.c (neon_vector_mem_operand): Handle element/structure -+ loads. Allow PRE_DEC. -+ (output_move_neon): Handle PRE_DEC. -+ (arm_print_operand): Add 'A' for neon structure loads. -+ * config/arm/arm-protos.h (neon_vector_mem_operand): Update prototype. -+ * config/arm/neon.md (movmisalign): Use Um constraint and %A. -+ * config/arm/constraints.md (Un, Us): Update neon_vector_mem_operand -+ calls. -+ (Um): New constraint. -+ -+2008-06-04 Joseph Myers -+ -+ Backport: -+ -+ gcc/testsuite/ -+ 2008-06-04 Joseph Myers -+ * lib/target-supports.exp (check_effective_target_powerpc_spu): -+ Call check_effective_target_powerpc_altivec_ok. -+ * gcc.target/powerpc/dfp-dd.c, gcc.target/powerpc/dfp-td.c, -+ gcc.target/powerpc/ppc32-abi-dfp-1.c, -+ gcc.target/powerpc/ppu-intrinsics.c: Require powerpc_fprs. -+ -+2008-06-04 Kazu Hirata -+ -+ Issue 1073 -+ gcc/ -+ * config/m68k/m68k.c (m68k_tune_flags): New. -+ (override_options): Compute m68k_tune_flags. -+ (MULL_COST, MULW_COST): Update for various variants of CFV2. -+ * config/m68k/m68k.h (TUNE_MAC, TUNE_EMAC): New. -+ -+2008-06-03 Nathan Froyd -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2008-06-02 Nathan Froyd -+ -+ gcc/ -+ * config/rs6000/t-linux (MULTILIB_OPTIONS): Add te500mc. -+ (MULTILIB_DIRNAMES): Likewise. -+ (MULTILIB_EXCEPTIONS): Handle te500mc. -+ * config/rs6000/linux.h (CC1_EXTRA_SPEC): Handle te500mc. -+ (ASM_DEFAULT_SPEC): Likewise. -+ * config/rs6000/rs6000.h (OPTION_DEFAULT_SPECS): Handle te500mc. -+ -+2008-06-03 Nathan Froyd -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2008-06-02 Nathan Froyd -+ -+ NOT ASSIGNED TO FSF -+ COPYRIGHT FREESCALE -+ -+ gcc/doc: -+ * invoke.texi: Mention e500mc as a legitimate Power cpu. -+ -+ gcc/ -+ * config.gcc: Mention e500mc as a legitimate --with-cpu option. -+ * config/rs6000/rs6000.c (ppce500mc_cost): New. -+ (rs6000_override_options): Add e500mc to processor_target_table. -+ Enable isel for e500mc. Disable string instructions for e500mc. -+ Set rs6000_cost for e500mc. -+ (rs6000_issue_rate): Handle CPU_PPCE500MC. -+ * config/rs6000/rs6000.h (ASM_CPU_SPEC): Handle mcpu=e500mc. -+ (enum processor_type): Add PROCESSOR_PPCE500MC. -+ (TARGET_ISEL): Use rs6000_isel. -+ * config/rs6000/e500mc.md: New file. -+ * config/rs6000/rs6000.md: Include it. -+ (define_attr "cpu"): Add e500mc. -+ (define_attr "type"): Add insert_dword. -+ * config/rs6000/e500.h (TARGET_ISEL): Remove. -+ (CHECK_E500_OPTIONS): Remove TARGET_ISEL condition. -+ -+ 2008-06-02 Nathan Froyd -+ -+ * release-notes-csl.xml (E500mc support): New. -+ -+ gcc/ -+ * config/rs6000/e500mc.md: Eliminate duplication. -+ -+2008-06-03 Joseph Myers -+ -+ Backport: -+ -+ gcc/ -+ 2008-02-22 Nathan Froyd -+ * config/rs6000/rs6000.c (rs6000_legitimize_address): Check to -+ ensure that we can address an entire entity > 8 bytes. Don't -+ generate reg+reg addressing for such data. -+ -+ 2008-03-07 Peter Bergner -+ PR target/35373 -+ * config/rs6000/rs6000.c (rs6000_legitimize_address): Don't generate -+ reg+const addressing for Altivec modes. Don't generate reg+reg -+ addressing for TFmode or TDmode quantities. -+ -+2008-06-03 Nathan Froyd -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-03-28 Daniel Jacobowitz -+ -+ gcc/testsuite/ -+ * lib/target-supports.exp (check_effective_target_powerpc_spe_ok): New. -+ -+2008-06-03 Nathan Froyd -+ -+ gcc/ -+ * config/rs6000/predicates.md (save_world_operation): Adjust checks. -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2008-05-22 Nathan Froyd -+ -+ Issue #3062 -+ -+ * release-notes-csl.xml (E500 size optimization compiler crash): New. -+ -+ gcc/ -+ * config/rs6000/rs6000.c (rs6000_emit_prologue): Mark the -+ adjustment to r11 as frame related when generating out-of-line -+ prologues. -+ -+ 2008-03-07 Nathan Froyd -+ -+ gcc/ -+ * config/rs6000/rs6000.c (rs6000_savres_strategy): Be slightly -+ smarter about restoring with an out-of-line function. -+ (rs6000_emit_prologue): Make sure we only set r11 once. Be -+ smarter about restoring LR. -+ -+ 2008-02-29 Nathan Froyd -+ -+ gcc/ -+ * config/rs6000/rs6000.c (emit_allocate_stack): Add copy_r11 -+ parameter. Copy stack_reg to r11 where appropriate. -+ (rs6000_stack_info): Only add padding for SPE save area if we -+ are saving SPE GPRs and CR. -+ (saveres_routine_syms): New variable. -+ (FIRST_SAVRES_REGISTER, LAST_SAVRES_REGISTER, N_SAVRES_REGISTERS): -+ Define. -+ (rs6000_savres_routine_sym): New function. -+ (rs6000_emit_stack_reset, rs6000_restore_saved_cr): New functions, -+ split out of... -+ (rs6000_emit_epilogue): ...here. Use rs6000_use_multiple_p and -+ rs6000_savres_strategy. Restore GPRs out-of-line if appropriate. -+ Tweak FPR out-of-line saving. -+ (rs6000_make_savres_rtx): New function. -+ (rs6000_use_multiple_p): New function. -+ (rs6000_savres_strategy): New function. -+ (rs6000_emit_prologue): Use rs6000_savres_strategy. Save GPRs -+ out-of-line if appropriate. -+ * config/rs6000/sysv4.h (FP_SAVE_INLINE): Save FPRs out-of-line -+ if we are optimizing for size. -+ (GP_SAVE_INLINE): Define. -+ (SAVE_FP_SUFFIX, RESTORE_FP_SUFFIX): Only use _l on 64-bit targets. -+ * config/rs6000/darwin.h (GP_SAVE_INLINE): Define. -+ * config/rs6000/aix.h (GP_SAVE_INLINE): Define. -+ * config/rs6000/rs6000.md (*save_gpregs_): New insn. -+ (*save_fpregs_): Add use of r11. -+ (*restore_gpregs_): New insn. -+ (*return_and_restore_gpregs_): New insn. -+ (*return_and_restore_fpregs_): Adjust to clobber LR and -+ use r11. -+ * config/rs6000/spe.md (*save_gpregs_spe): New insn. -+ (*restore_gpregs_spe): New insn. -+ (*return_and_restore_gpregs_spe): New insn. -+ -+2008-06-02 Nathan Froyd -+ -+ gcc/ -+ * config/rs6000/rs6000.md (absv2sf2, negv2sf2, addv2sf3, subv2sf3, -+ mulv2sf3, divv2sf3): New expanders. -+ * config/rs6000/spe.md (spe_evabs, spe_evand, spe_evaddw, -+ spe_evdivws): Rename to use standard GCC names. -+ * config/rs6000/paired.md (negv2sf, absv2sf2, addv2sf3, subv2sf3, -+ mulv2sf3, divv2sf3): Rename to avoid conflict with the new expanders. -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-09-19 Nathan Froyd -+ -+ gcc/ -+ * config/rs6000/rs6000.c (bdesc_2arg, bdesc_1arg): Use new CODE_FOR_ -+ names for renamed patterns. -+ -+2008-05-30 Joseph Myers -+ -+ gcc/ -+ * config/arm/wrs-linux.h (CC1_SPEC): Allow -tcortex-a8-be8 -+ -mfloat-abi=softfp. -+ (SUBTARGET_EXTRA_ASM_SPEC): Use -meabi=5. -+ * config/arm/t-wrs-linux (MULTILIB_EXCEPTIONS): Remove -+ *cortex-a8-be8*/*mfloat-abi=softfp*. -+ (MULTILIB_ALIASES): Add -+ tcortex-a8-be8=tcortex-a8-be8/mfloat-abi?softfp. -+ -+2008-05-30 Maxim Kuvyrkov -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2006-12-12 Richard Sandiford -+ gcc/testsuite/ -+ * gcc.dg/torture/m68k-interrupt-1.c: New file. -+ 2006-06-23 Richard Sandiford -+ gcc/testsuite/ -+ * gcc.dg/tree-ssa/20040204-1.c: Don't XFAIL for m68k*-*-*. -+ -+2008-05-30 Nathan Froyd -+ -+ gcc/ -+ * config/rs6000/rs6000.c (ppc8540_cost): Fix typo. -+ (spe_synthesize_frame_save): Remove declaration. -+ -+2008-05-30 Nathan Froyd -+ -+ gcc/ -+ * tree-ssa-remove-local-statics.c -+ (find_static_nonvolatile_declarations): Use SSA_OP_VDEF. -+ (unstaticize_variable): Likewise. -+ (dump_final_bitmaps): Remove. -+ -+2008-05-30 Maxim Kuvyrkov -+ -+ Tree->const_tree fix. -+ -+ gcc/ -+ * config/m68k/m68k.c (m68k_return_in_memory): Fix arguments types. -+ -+2008-05-30 Maxim Kuvyrkov -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-02-16 Richard Sandiford -+ gcc/ -+ * config/m68k/m68k.h (INDEX_REG_CLASS): Delete in favor of... -+ (MODE_INDEX_REG_CLASS): ...this new macro. Return NO_REGS unless -+ MODE_OK_FOR_INDEX_P. -+ (MODE_OK_FOR_INDEX_P): New macro. -+ (REGNO_OK_FOR_INDEX_P): Delete in favor of... -+ (REGNO_MODE_OK_FOR_INDEX_P): ...this new macro. Return false -+ unless MODE_OK_FOR_INDEX_P. -+ (REG_OK_FOR_INDEX_P): Delete in favor of... -+ (REG_MODE_OK_FOR_INDEX_P): ...this new macro. Return false -+ unless MODE_OK_FOR_INDEX_P. -+ * m68k-protos.h (m68k_legitimate_index_reg_p): Add mode argument. -+ * m68k.c (m68k_legitimate_index_reg_p, m68k_decompose_index): -+ Add mode argument. Use it. -+ * config/m68k/m68k.md (tst_cf, cmp_cf, movsf_cf_hard) -+ (movdf_cf_hard, extendsfdf2_cf, truncdfsf2_cf, ftrunc2_cf) -+ (add3_cf, sub3_cf, fmul3_cf, div3_cf) -+ (neg2_cf, sqrt2_cf, abs2_cf): Replace "Q" -+ constraints for FP addresses with "m" constraints. -+ 2007-02-16 Nathan Sidwell -+ gcc/testsuite/ -+ * gcc.dg/m68k-fp-1.c: New. -+ -+2008-05-30 Julian Brown -+ -+ gcc/ -+ * config/arm/cortex-r4.md: Update GPLv3 notice. -+ * hwdiv.md: Likewise. -+ * marvell-f-vfp.md: Likewise. -+ * marvell-f.md: Likewise. -+ * nocrt0.h: Likewise. -+ * vfp11.md: Likewise. -+ -+2008-05-30 Maxim Kuvyrkov -+ -+ Merge from Sourcery G++ 4.2 (Add missing testcase from -+ earlier merge): -+ -+ 2008-02-01 Joseph Myers -+ gcc/testsuite/ -+ * gcc.target/m68k/xgot-1.c: New test. -+ -+2008-05-30 Maxim Kuvyrkov -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2008-01-11 Kazu Hirata -+ Issue 2396 -+ gcc/ -+ * configure.ac: Teach that fido supports .debug_line. -+ * configure: Regenerate. -+ -+2008-05-30 Maxim Kuvyrkov -+ -+ Merge from Sourcery G++ 4.2 (config.gcc part was merged earlier): -+ -+ 2007-03-26 Nathan Sidwell -+ gcc/ -+ * config.gcc (m68k-*-linux*): Add sysroot-suffix.h to tm_file. Add -+ m68k/t-floatlib, m68k/t-linux & m68k/t-mlibs to tmake_file. -+ * config/m68k/t-linux: New. -+ * doc/install.texi: Document m68k-*-linux is now multilibbed by -+ default. -+ -+2008-05-30 Maxim Kuvyrkov -+ -+ Revert: -+ -+ 2008-05-29 Maxim Kuvyrkov -+ Merge from Sourcery G++ 4.2: -+ 2007-02-16 Paul Brook -+ Richard Sandiford -+ gcc/ -+ * config/m68k/m68k.md (UNSPEC_MOVEQ_MEM): New constant. -+ (*movsi_smallconst): New pattern. -+ -+2008-05-29 Maxim Kuvyrkov -+ -+ * config/m68k/m68k.md: Fix previous commit. -+ -+2008-05-29 Maxim Kuvyrkov -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-02-16 Richard Sandiford -+ gcc/ -+ * config/m68k/m68k.md (tst_cf, cmp_cf, movsf_cf_hard) -+ (movdf_cf_hard, extendsfdf2_cf, truncdfsf2_cf, floatsi2_cf) -+ (floathi2_cf, floatqi2_cf, ftrunc2_cf) -+ (fixqi2_cf, fixhi2_cf, fixsi2_cf) -+ (add3_cf, sub3_cf, fmul3_cf, div3_cf) -+ (divmodsi4_cf, udivmodsi4_cf) -+ (neg2_cf, sqrt2_cf, abs2_cf): Replace "Q" -+ constraints for FP addresses with "m" constraints. -+ -+2008-05-29 Maxim Kuvyrkov -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-02-16 Paul Brook -+ Richard Sandiford -+ gcc/ -+ * config/m68k/m68k.md (UNSPEC_MOVEQ_MEM): New constant. -+ (*movsi_smallconst): New pattern. -+ -+2008-05-29 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2008-05-19 Kazu Hirata -+ -+ gcc/ -+ * config.gcc (arm-timesys-linux-gnueabi): Add ./sysroot-suffix.h -+ ./sysroot-suffix.h to tm_file while removing arm/timesys-linux.h -+ from tm_file. Add tmake_file. -+ * config/arm/t-timesys (MULTILIB_OSDIRNAMES): Populate. -+ * config/arm/timesys-liunx.h: Remove. -+ -+2008-05-29 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2008-05-07 Paul Brook -+ -+ * config/arm/arm.c (arm_no_early_mul_dep): Correct the logic to -+ look into a MAC instruction. -+ -+2008-05-29 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2008-04-04 Paul Brook -+ -+ gcc/ -+ * config/arm/linux-eabi.h (ARM_FUNCTION_PROFILER): Define. -+ (SUBTARGET_FRAME_POINTER_REQUIRED): Define. -+ -+2008-05-29 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2008-03-08 Paul Brook -+ -+ gcc/ -+ * config/arm/t-linux-eabi (MULTILIB_OSDIRNAMES): Override old value. -+ -+2008-05-29 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2008-02-29 Paul Brook -+ -+ gcc/ -+ * config/arm/lib1funcs.asm (THUMB_LDIV0): Fix bogus ARCH_7 ifdefs. -+ Use cbz. -+ -+2008-05-29 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2008-02-25 Sandra Loosemore -+ -+ gcc/ -+ * testsuite/gcc.dg/arm-mmx-1.c: Skip if conflicting -mcpu or -mabi -+ argument specified. -+ -+2008-05-29 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2008-02-18 Julian Brown -+ -+ gcc/ -+ * config/arm/bpabi.S (test_div_by_zero): New macro. -+ (aeabi_ldivmod): Use above macro to tailcall long long div-by-zero -+ handler. -+ (aeabi_uldivmod): Likewise. -+ * config/arm/bpabi-v6m.S (test_div_by_zero): New macro. -+ (aeabi_ldivmod, aeabi_uldivmod): Use above macro. -+ * config/arm/lib1funcs.asm (ARM_LDIV0): Tailcall int div-by-zero -+ handler. Add signed/unsigned argument, pass correct value to that -+ handler. -+ (THUMB_LDIV0): Same, for Thumb. -+ (DIV_FUNC_END): Add signed argument. -+ (WEAK): New macro. -+ (__udivsi3, __umodsi3): Add unsigned argument to DIV_FUNC_END. -+ (__divsi3, modsi3): Add signed argument to DIV_FUNC_END. -+ (__aeabi_uidivmod, __aeabi_idivmod): Check division by zero. -+ (__div0): Rename to __aeabi_idiv0, __aeabi_ldiv0 for EABI, and declare -+ those names weak. -+ * config/arm/t-bpabi (LIB1ASMFUNCS): Add _aeabi_idiv0, _aeabi_ldiv0. -+ -+2008-05-29 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2008-02-17 Paul Brook -+ -+ gcc/ -+ * doc/invoke.texi: Document -mword-relocations. -+ * config/arm/uclinux-elf.h: Define TARGET_DEFAULT_WORD_RELOCATIONS. -+ * config/arm/symbian.h: Define TARGET_DEFAULT_WORD_RELOCATIONS. -+ * config/arm/vxworks.h: Define TARGET_DEFAULT_WORD_RELOCATIONS. -+ * config/arm/arm.h: Define TARGET_DEFAULT_WORD_RELOCATIONS. -+ * config/arm/arm.md (movsi): Don't use movt if only word relocations -+ are permitted. -+ * config/arm/arm.opt: Add -mword-relocations. -+ -+2008-05-29 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2008-02-16 Paul Brook -+ -+ gcc/ -+ * config.gcc (arm*): Handle --enable-extra-sgxx-multilibs. -+ Use arm/t-sysroot-suffix and ./sysroot-suffix.h. -+ * config/arm/uclinux-eabi.h (SYSROOT_SUFFIX_SPEC): Remove. -+ * config/arm/linux-eabi.h (SYSROOT_SUFFIX_SPEC): Remove. -+ * config/arm/t-linux-eabi: Remove marvell-f multilib. -+ Match Cortex-A9 and Cortex-R4F. -+ * config/arm/t-arm-elf: Remove marvell-f multilib. -+ Match Cortex-A9 and Cortex-R4F. -+ * config/arm/t-uclinux-eabi: Match Cortex-A9 and Cortex-R4F. -+ * config/arm/print-sysroot-suffix.sh: New file. -+ * config/arm/t-sysroot-suffix: New file. -+ * config/arm/t-cs-eabi: New file. -+ * config/arm/t-cs-linux: New file. -+ -+2008-05-29 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2008-02-05 Paul Brook -+ -+ gcc/ -+ * genmultilib: Fix sed patterns. -+ Verify that aliases are valid. -+ * config/arm/t-timesys (MULTILIB_ALIASES): Set. -+ -+2008-05-29 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2008-02-05 Paul Brook -+ -+ gcc/doc/ -+ * fragments.texi: Document MULTILIB_ALIASES. -+ -+ gcc/ -+ * genmultilib: Add aliases. -+ * Makefile.in (s-mlib): Pass MULTILIB_ALIASES. -+ * config/arm/t-linux-eabi: Use MULTILIB_ALIASES. -+ * config/arm/t-arm-elf: Ditto. -+ * config/arm/t-uclinux-eabi: Ditto. -+ -+2008-05-29 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2008-01-28 Paul Brook -+ -+ gcc/ -+ * config/arm/arm.c (arm_override_options): Set arm_abi earlier. -+ Allow Interworking on ARMv4 EABI based targets. -+ * config/arm/bpabi.h (TARGET_FIX_V4BX_SPEC): Define. -+ (SUBTARGET_EXTRA_ASM_SPEC, LINK_SPEC): Add TARGET_FIX_V4BX_SPEC. -+ -+2008-05-29 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2008-01-25 Paul Brook -+ -+ gcc/ -+ * config/arm/ieee754-df.S (muldf3): Use RET macros. -+ -+2008-05-29 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2008-01-23 Paul Brook -+ -+ gcc/ -+ * config/arm/arm.c (arm_tune_cortex_a9): New variable. -+ (arm_override_options): Set arm_tune_cortex_a9. -+ (arm_split_constant): Use arm_emit_movpair. -+ (arm_rtx_costs_1): Increase cost of register shifts on cortex-A9. -+ Add costs for HIGH and LO_SUM. -+ (arm_size_rtx_costs): Add costs for HIGH and LO_SUM. -+ (arm_emit_movpair): New function. -+ (arm_print_operand): Handle symbols with %c. -+ (arm_final_prescan_insn): Use TARGET_NO_SINGLE_COND_EXEC. -+ (arm_issue_rate): Add cortexa9. -+ * config/arm/arm.h (TARGET_NO_SINGLE_COND_EXEC): Define. -+ (TARGET_USE_MOVT): Define. -+ (arm_tune_cortex_a9): Add prototype. -+ * config/arm/arm-cores.def: Add cortex-a9. -+ * config/arm/arm-tune.md: Regenerate. -+ * config/arm/arm-protos.h (arm_emit_movpair): Add prototype. -+ * config/arm/arm.md: Include cortex-a9.md. -+ Add TARGET_NO_SINGLE_COND_EXEC conditions. -+ (generic_sched, generic_vfp): Add cortex-a9. -+ (movsi): Use arm_emit_movpair. -+ (arm_movt, arm_movw): New patterns. -+ * config/arm/cortex-a9.md: New file. -+ -+2008-05-29 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2008-01-09 Julian Brown -+ -+ gcc/ -+ * config/arm/neon.md (UNSPEC_MISALIGNED_ACCESS): New constant. -+ (movmisalign): Define for D and Q width registers. -+ -+ gcc/testsuite/ -+ * lib/target-supports.exp -+ (check_effective_target_arm_vect_no_misalign): New function. -+ (check_effective_target_vect_no_align): Use above to determine -+ whether misaligned accesses are expected for ARM. -+ -+2008-05-29 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2008-01-04 Paul Brook -+ -+ gcc/ -+ * config/arm/arm.c (arm_output_epilogue): Avoid clobbering tail call -+ arguments. -+ -+2008-05-29 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2008-01-03 Paul Brook -+ -+ gcc/ -+ * config/arm/arm.c (arm_rtx_costs_1): Add costs for ARMv6 value -+ extension instructions. -+ -+2008-05-29 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-12-20 Paul Brook -+ -+ gcc/ -+ * config/arm/cortex-r4f.md: New file. -+ * config/arm/arm.c (arm_no_early_mul_dep): Also match -+ multiply-subtract. -+ (arm_issue_rate): Return 2 for cortex-a8 and cortex-r4. -+ * config/arm/cortex-r4.md: Replace (eq_attr "tune" "cortexr4") -+ with (eq_attr "tune_cortexr4" "yes"). -+ * config/arm/vfp.md: Split ffarith and ffarith into fcpys, ffariths, -+ ffarithd, fadds, faddd, fconsts, fconstd, fcmps and fcmpd. -+ * config/arm/arm.md: Inlcude cortex-r4f.md. -+ (define_attr fpu): Add new VFP variants. -+ (define_attr type): Add new types. -+ (tune_cortexr4): New attr. -+ (generic_sched, generic_vfp): Use tune_cortexr4 and new FPU types. -+ * config/arm/cortex-a8-neon.md: Split farith and ffarith insn types. -+ * config/arm/marvell-f-vfp.md: Ditto. -+ * config/arm/arm1020e.md: Ditto. -+ * config/arm/vfp11.md: Ditto. -+ * config/arm/arm-tune.md: Regenerate. -+ -+2008-05-29 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-12-14 Paul Brook -+ -+ gcc/ -+ * doc/invoke.texi: Document new ARM -mfpu= and -mcpu= options. -+ * config/arm/arm.c (all_fpus): Add vfpv3 and vfpv3-d16. -+ (fp_model_for_fpu): Add entry for FPUTYPE_VFP3D16. -+ (arm_file_start): Add FPUTYPE_VFP3D16. Rename vfp3 to vfpv3. -+ * config/arm/arm.h (TARGET_VFPD32): Define. -+ (TARGET_VFP3): Use TARGET_VFPD32. -+ (fputype): Add FPUTYPE_VFP3D16. -+ (LAST_VFP_REGNUM): Use TARGET_VFPD32. -+ * config/arm/constraints.md ("w"): Use TARGET_VFPD32. -+ * config/arm/arm-cores.def: Add cortex-r4f. -+ -+2008-05-29 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-12-11 Paul Brook -+ -+ gcc/ -+ * config/arm/thumb2.md: Extend peephole to cover 3-arg subs. -+ (thumb2_alusi3_short): Exclude MINUS. -+ (thumb2_subsi_short): New pattern. -+ -+2008-05-29 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-09-27 Paul Brook -+ -+ gcc/ -+ * config/arm/arm.c (arm_optimization_options): Revert flag_see -+ change. -+ -+2008-05-29 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-09-19 Paul Brook -+ -+ gcc/ -+ * config/arm/arm.c (FL_COMPAT): Define. -+ (arm_override_options): Mask out FL_COMPAT when checking cpu vs. arch. -+ -+2008-05-29 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-09-19 Vladimir Prus -+ -+ gcc/ -+ * config/arm/arm.c (arm_optimization_options): -+ Enable -fsee and disable -fmove-loop-invariants. -+ Use very restrictive inlining heuristics. -+ -+ gcc/testsuite/ -+ * gcc.c-torture/execute/bcp-1.x: New. Don't -+ run bcp-1.c test on arm, with -Os. -+ * gcc.c-torture/execute/990208-1.x: New. Likewise. -+ -+2008-05-29 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-08-20 Paul Brook -+ -+ gcc/ -+ * config/arm/arm.md (insv): Use gen_insv_t2 and gen_insv_zero. -+ (extzv): Use gen_extzv_t2. -+ (insv_t2, insv_zero, extv, extzv_t2): New patterns. -+ -+2008-05-29 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-08-20 Paul Brook -+ -+ gcc/ -+ * config/arm/thumb2.md (thumb2_one_cmplsi2_short, -+ thumb2_negsi2_short): New patterns and peepholes. -+ -+2008-05-29 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-08-20 Paul Brook -+ -+ gcc/ -+ * config/arm/arm.c (arm_size_rtx_costs): Use ARM costs for Thumb-2. -+ -+2008-05-29 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-08-13 Paul Brook -+ -+ * config/arm/arm.c (arm_output_epilogue): Adjust stack pointer by -+ popping call-clobbered registers. -+ (arm_expand_prologue): Adjust stack pointer by pushing extra -+ registers. -+ -+2008-05-29 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-08-12 Mark Shinwell -+ -+ gcc/ -+ * config/arm/arm.c (TARGET_ADJUST_REG_ALLOC_ORDER): Define. -+ (thumb_core_reg_alloc_order): New. -+ (arm_adjust_reg_alloc_order): New. -+ * config/arm/arm.h (REG_ALLOC_ORDER): Adjust comment. -+ * config/arm/arm-protos.h (arm_adjust_reg_alloc_order): New -+ prototype. -+ -+2008-05-29 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-08-12 Mark Shinwell -+ -+ gcc/ -+ * config/arm/arm.h (CLASS_LIKELY_SPILLED_P): Update comment. -+ -+2008-05-29 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-08-12 Mark Shinwell -+ -+ gcc/ -+ * config/arm/arm.h (CLASS_LIKELY_SPILLED_P): Check against -+ LO_REGS only for Thumb-1. -+ (MODE_BASE_REG_CLASS): Restrict base registers to low -+ registers for Thumb-2. -+ -+2008-05-29 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-08-10 Paul Brook -+ -+ * config/arm/arm.md (arm_addsi3): Add r/k/n alternative. -+ -+2008-05-29 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-08-07 Kazu Hirata -+ -+ gcc/testsuite/ -+ * gcc.dg/arm-g2.c, gcc.dg/arm-mmx-1.c, gcc.dg/arm-scd42-2.c: -+ Skip if the multilib testing specifies -march that does not -+ agree with the one specified in the testcase. -+ -+2008-05-29 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-07-25 Nathan Sidwell -+ -+ gcc/ -+ * config.gcc (arm*-*-linux*): Add timesys specific files. -+ * config/arm/timesys-linux.h: New. -+ * config/arm/t-timesys: New. -+ -+2008-05-29 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-07-16 Paul Brook -+ -+ gcc/ -+ * config/arm/arm.c (use_return_insn): Use offsets->saved_regs_mask -+ instead of {arm,thumb}_compute_save_reg_mask. -+ (output_return_instruction): Ditto. -+ (arm_output_epilogue): Ditto. -+ (arm_expand_prologue): Ditto. -+ (thumb_unexpanded_epilogue): Ditto. -+ (thumb1_expand_prologue): Ditto. -+ (thumb1_output_function_prologue): Ditto. -+ (arm_set_return_address): Ditto. -+ (thumb_set_return_address): Ditto. -+ (arm_get_frame_offsets): Set offsets->saved_regs_mask. Push extra -+ regs to achieve stack alignment. -+ (thumb1_compute_save_reg_mask): Fix compiler warning. -+ * gcc/config/arm.h (arm_stack_offsets): Add saved_regs_mask. -+ -+2008-05-29 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-07-05 Mark Shinwell -+ -+ gcc/ -+ * config/arm/arm.h (BRANCH_COST): Set to 1 when optimizing -+ for size on Thumb-2. -+ -+2008-05-29 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-07-05 Richard Sandiford -+ -+ gcc/ -+ * config/arm/neon-gen.ml: Include vxWorks.h rather than stdint.h -+ for VxWorks kernels. -+ * config/arm/arm_neon.h: Regenerate. -+ -+2008-05-29 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-07-05 Mark Shinwell -+ -+ gcc/ -+ * config/arm/thumb2.md (thumb2_movsi_insn): Split ldr and -+ str alternatives according to use of high and low regs. -+ * config/arm/vfp.md (thumb2_movsi_vfp): Likewise. -+ * config/arm/arm.h (CONDITIONAL_REGISTER_USAGE): Use high -+ regs when optimizing for size on Thumb-2. -+ -+2008-05-29 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-07-02 Paul Brook -+ -+ gcc/ -+ * config/arm/thumb2.md (thumb2_alusi3_short): Exclude PLUS. -+ (thumb2_addsi_shortim): Rename ... -+ (thumb2_addsi_short): ... to this. Allow register operands. -+ -+2008-05-29 Julian Brown -+ -+ Backport from mainline: -+ -+ 2008-02-26 Paul Brook -+ -+ * config/arm/arm.c (thumb_set_frame_pointer): Ensure SP is first -+ operand for Thumb-2. -+ * config/arm/arm.h (reg_class): Add CORE_REGS. -+ (REG_CLASS_NAMES, REG_CLASS_CONTENTS): Ditto. -+ (BASE_REG_CLASS): Use CORE_REGS. -+ (PREFERRED_RELOAD_CLASS): Add STACK_REG. -+ (REGNO_MODE_OK_FOR_REG_BASE_P): Use REGNO_MODE_OK_FOR_BASE_P. -+ (REGNO_OK_FOR_INDEX_P): Exclude SP. -+ (ARM_REG_OK_FOR_INDEX_P): Always define. Use -+ ARM_REGNO_OK_FOR_INDEX_P. -+ (ARM_PRINT_OPERAND_ADDRESS): Swap operands for [reg, sp]. -+ * config/arm/arm.md (arm_addsi3, thumb1_addsi3, arm_subsi3_insn, -+ arm_movsi_insn, thumb1_movsi_insni, stack_tie): Add "k" alternatives. -+ (ldm/stm peepholes): Ditto. -+ * config/arm/thumb2.md (thumb2_movdi): Add "k" alternatives. -+ * config/arm/vfp.md (arm_movsi_vfp, thumb2_movsi_vfp): Ditto. -+ * config/arm/iwmmxt.md (iwmmxt_movsi_insn): Ditto. -+ * config/arm/constraints.md: Enable "k" constraint on ARM. -+ -+2008-05-29 Maxim Kuvyrkov -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2008-02-01 Joseph Myers -+ * release-notes-csl.xml: Add -mxgot release note. -+ gcc/ -+ * config/m68k/m68k.opt (mxgot): New option. -+ * config/m68k/m68k.c (legitimize_pic_address): Handle -mxgot. -+ (m68k_output_addr_const_extra): New. -+ * config/m68k/m68k.h (OUTPUT_ADDR_CONST_EXTRA): New. -+ * config/m68k/m68k-protos.h (m68k_output_addr_const_extra): Declare. -+ * config/m68k/m68k.md (UNSPEC_GOTOFF): Define. -+ * doc/invoke.texi (M680x0 Options): Document -mxgot. -+ gcc/testsuite/ -+ * gcc.target/m68k/xgot-1.c: New test. -+ -+2008-05-29 Maxim Kuvyrkov -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2008-03-12 Nathan Sidwell -+ gcc/ -+ * config/m68k/t-cf (MULTILIB_EXTRA_OPTS): Add no-mac. -+ * config/m68k/m68k-devices.def: Remove multilibs that only differ -+ by MAC/EMAC. -+ -+2008-05-29 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-06-13 Joseph Myers -+ -+ gcc/ -+ * config/arm/crti.asm, config/arm/crtn.asm: Remove .file -+ directives. -+ -+2008-05-29 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-06-06 Joseph Myers -+ -+ gcc/ -+ * config/arm/arm.h (VALID_IWMMXT_REG_MODE): Allow SImode. -+ (ARM_LEGITIMIZE_RELOAD_ADDRESS): Reduce range allowed for SImode -+ offsets with iWMMXt. -+ * config/arm/arm.c (arm_hard_regno_mode_ok): Update for change to -+ VALID_IWMMXT_REG_MODE. -+ -+2008-05-29 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-05-17 Paul Brook -+ -+ gcc/ -+ * config/arm/arm.c (output_move_double): Prefer LDRD to LDM. -+ -+2008-05-29 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-05-15 Paul Brook -+ -+ gcc/ -+ * config/arm/nocrt0.h (LIB_SPEC): Remove default -T. -+ -+2008-05-29 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-05-04 Mark Shinwell -+ -+ gcc/ -+ * config/arm/bpabi.h (SUBTARGET_EXTRA_ASM_SPEC): Bump EABI -+ version number to five. -+ -+2008-05-29 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-05-02 Paul Brook -+ -+ gcc/ -+ * config/arm/arm.c (arm_unwind_emit): Suppress unused unwinding -+ annotations. -+ (arm_output_fn_unwind): Mark functions that can not be unwound. -+ -+2008-05-29 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-04-26 Vladimir Prus -+ -+ gcc/ -+ * config/arm/arm.c (vfp_output_fldmd): When low_irq_latency -+ is non zero, pop each register separately. -+ (vfp_emit_fstmd): When low_irq_latency is non zero, -+ save each register separately. -+ (arm_get_vfp_saved_size): Adjust saved register -+ size calculation for the above changes. -+ -+2008-05-29 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-04-25 Paul Brook -+ -+ gcc/ -+ * config/arm/bpabi-v6m.S (aeabi_lcmp): Use unsigned comparison for -+ low word. -+ -+2008-05-29 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-04-22 Mark Shinwell -+ -+ gcc/ -+ * config/arm/lib1funcs.asm (div0): Use correct punctuation. -+ * config/arm/ieee754-sf.S (mulsf3): Likewise. -+ -+2008-05-29 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-04-18 Vladimir Prus -+ -+ gcc/ -+ * config/arm/arm.h (TARGET_CPU_CPP_BUILTINS): Set -+ __low_irq_latency__. -+ * config/arm/lib1funcs.asm: Define do_pop and -+ do_push as variadic macros. When __low_irq_latency__ -+ is defined, push and pop registers individually. -+ * config/arm/ieee754-df.S: Adjust syntax of using -+ do_push. -+ * config/arm/ieee754-sf.S: Likewise. -+ * config/arm/bpapi.S: Likewise. -+ -+2008-05-29 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-04-17 Paul Brook -+ -+ gcc/ -+ * config/arm/arm.c (TARGET_DWARF_REGISTER_SPAN): Define. -+ (arm_dwarf_register_span): New function. -+ (arm_dbx_register_number): Add VFPv3 dwarf numbering. -+ -+2008-05-29 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-04-16 Paul Brook -+ -+ gcc/ -+ * config/arm/arm.c (print_pop_reg_by_ldr): Fix warning about ambiguous -+ else. -+ -+2008-05-29 Julian Brown -+ -+ Backport from mainline: -+ -+ 2008-05-06 Mark Shinwell -+ Daniel Jacobowitz -+ Andrew Jenner -+ -+ * g++.old-deja/g++.jason/enum6.C, g++.old-deja/g++.law/enum9.C, -+ g++.old-deja/g++.other/enum4.C, gfortran/enum_9.f90, -+ gfortran.dg/enum_10.f90: Broaden dg-options pattern. -+ -+2008-05-29 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-04-01 Paul Brook -+ -+ gcc/ -+ * config/arm/uclinux-eabi.h (SUBTARGET_EXTRA_LINK_SPEC): Add -+ --target2=abs. -+ * config/arm/unwind-arm.h (_Unwind_decode_target2): Handle uClinux. -+ -+2008-05-29 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-03-31 Paul Brook -+ -+ * config/arm/arm.c (output_move_double): Only apply limited range -+ check in ARM mode. -+ -+2008-05-29 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-03-30 Sandra Loosemore -+ -+ gcc/ -+ * config/arm/arm.c (use_return_insn): Test for TARGET_APCS_FRAME -+ if we need to adjust the stack. -+ -+2008-05-29 Maxim Kuvyrkov -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-09-07 Mark Shinwell -+ gcc/ -+ * config/m68k/lb1sf68.asm: Add PIC macros for Linux targets. -+ -+2008-05-29 Maxim Kuvyrkov -+ -+ Merge from Sourcery G++ 4.2: -+ -+ gcc/ -+ * config.gcc (m68k-*-linux*): Add with_arch, adjust tm_file, -+ add tmake_file. -+ -+2008-05-28 Paul Brook -+ -+ Avoid Issue #2945 -+ gcc/ -+ * config/arm/arm.md (abssi2): Add TARGET_NO_SINGLE_COND_EXEC expander. -+ (arm_abssi2, arm_neg_abssi2): Enable for Thumb-2. Always split. -+ (arm_nocond_abssi2, arm_nocond_neg_abssi2): New patterns. -+ Add splitters for abssi patterns. -+ * config/arm/thumb2.md (thumb2_abssi2, thumb2_neg_abssi2): Remove. -+ -+2008-05-26 Carlos O'Donell -+ -+ Backport from mainline: -+ -+ gcc/ -+ 2008-05-23 Paul Brook -+ Carlos O'Donell -+ -+ * doc/extend.texi: Clarify use of __attribute__((naked)). -+ * doc/tm.texi: Document TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS. -+ * target.h (gcc_target): Add allocate_stack_slots_for_args. -+ * function.c (use_register_for_decl): Use -+ targetm.calls.allocate_stack_slots_for_args. -+ * target-def.h (TARGET_CALLS): Add -+ TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS. -+ * config/arm/arm.c (arm_allocate_stack_slots_for_args): -+ New function. -+ (TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS): Define. -+ -+ gcc/testsuite/ -+ 2008-05-23 Paul Brook -+ Carlos O'Donell -+ -+ * gcc.target/arm/naked-1.c: New test. -+ * gcc.target/arm/naked-2.c: New test. -+ -+2008-05-26 Nathan Froyd -+ -+ Backport from mainline: -+ -+ gcc/ -+ 2008-04-30 Nathan Froyd -+ -+ * config/rs6000/crtresgpr.asm, config/rs6000/crtresxgpr.asm, -+ config/rs6000/crtsavgpr.asm, config/rs6000/crtresfpr.asm, -+ config/rs6000/crtresxfpr.asm, config/rs6000/crtsavfpr.asm: Break out -+ from... -+ * config/rs6000/crtsavres.asm: ...here. Remove unneeded file. -+ * config/rs6000/e500crtres32gpr.asm, config/rs6000/e500crtres64gpr.asm, -+ config/rs6000/e500crtres64gprctr.asm, -+ config/rs6000/e500crtrest32gpr.asm, config/rs6000/e500crtrest64gpr.asm, -+ config/rs6000/e500crtresx32gpr.asm, config/rs6000/e500crtresx64gpr.asm, -+ config/rs6000/e500crtsav32gpr.asm, config/rs6000/e500crtsav64gpr.asm, -+ config/rs6000/e500crtsav64gprctr.asm, -+ config/rs6000/e500crtsavg32gpr.asm, config/rs6000/e500crtsavg64gpr.asm, -+ config/rs6000/e500crtsavg64gprctr.asm: New files. -+ * config/rs6000/t-ppccomm: Add build rules for new files. -+ (LIB2FUNCS_STATIC_EXTRA): Add new files. -+ * config/rs6000/t-netbsd: Add build rules for new files. -+ (LIB2FUNCS_STATIC_EXTRA): New variable. -+ * config/rs6000/sysv4.h (ENDFILE_SPEC): Don't include crtsavres.o -+ (CRTSAVRES_DEFAULT_SPEC): Likewise. -+ * config/rs6000/netbsd.h (ENDFILE_SPEC): Likewise. -+ -+ libgcc/ -+ 2008-04-30 Nathan Froyd -+ -+ * config/rs6000/t-ppccomm: Add build rules for new files. -+ (LIB2ADD_ST): New variable. -+ -+2008-05-26 Nathan Froyd -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2008-02-25 Nathan Froyd -+ -+ gcc/ -+ * tree-ssa-remove-local-statics. (initialize_statement_dataflow): -+ Continue hash table traversal. -+ (compute_definedness_for_block): Delete useless return statement. -+ Adjust comment accordingly. -+ -+ 2007-03-05 Nathan Froyd -+ -+ gcc/ -+ * tree-pass.h (pass_remove_local_statics): Declare. -+ * passes.c (init_optimization_passes): Add -+ pass_remove_local_statics to the optimization passes. -+ * Makefile.in (OBJS-common): Add tree-ssa-remove-local-statics.c. -+ (tree-ssa-remove-local-statics.o): New rule. -+ * tree-ssa-remove-local-statics.c: New file. -+ * c.opt (fremove-local-statics): New option. -+ * timevar.def (TV_RLS): New timevar. -+ * toplev.h (flag_remove_local_statics): Declare. -+ * cgraph.h (struct cgraph_node): Add 'ever_was_nested'. -+ * cgraph.c (cgraph_node): Set ever_was_nested in the node and -+ its parent when creating a new node. -+ gcc/doc/ -+ * invoke.texi: Document -fremove-local-statics. -+ gcc/testsuite/ -+ * gcc.dg/remove-local-statics-1.c: New file. -+ * gcc.dg/remove-local-statics-2.c: New file. -+ * gcc.dg/remove-local-statics-3.c: New file. -+ * gcc.dg/remove-local-statics-4.c: New file. -+ * gcc.dg/remove-local-statics-5.c: New file. -+ * gcc.dg/remove-local-statics-6.c: New file. -+ * gcc.dg/remove-local-statics-7.c: New file. -+ * gcc.dg/remove-local-statics-8.c: New file. -+ * gcc.dg/remove-local-statics-9.c: New file. -+ * gcc.dg/remove-local-statics-10.c: New file. -+ * gcc.dg/remove-local-statics-11.c: New file. -+ * gcc.dg/remove-local-statics-12.c: New file. -+ -+ -+2008-05-26 Nathan Froyd -+ -+ Backport from mainline: -+ -+ 2008-04-24 Nathan Froyd -+ Nathan Sidwell -+ -+ * config/rs6000/rs6000.opt (mspe): Remove Var property. -+ (misel): Likewise. -+ * config/rs6000/rs6000.h (rs6000_spe): Declare. -+ (rs6000_isel): Likewise. -+ * config/rs6000/rs6000.c (rs6000_spe): New variable. -+ (rs6000_isel): New variable. -+ (rs6000_handle_option): Handle OPT_mspe and OPT_misel. -+ -+2008-05-26 Nathan Froyd -+ -+ gcc/testsuite/ -+ * gcc.target/powerpc/altivec-24.c, gcc.target/powerpc/pr35907.c: -+ Run if vmx_hw, compile otherwise. Do not check for AltiVec at -+ runtime. -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-03-22 Daniel Jacobowitz -+ -+ gcc/testsuite/ -+ * gcc.target/powerpc/altivec-vec-merge.c, -+ gcc.target/powerpc/altivec-10.c, gcc.target/powerpc/altivec-12.c, -+ gcc.target/powerpc/altivec-1.c, gcc.target/powerpc/altivec-3.c, -+ g++.dg/ext/altivec-2.C, g++.dg/ext/altivec-3.C: Run if vmx_hw, compile -+ otherwise. Do not check for AltiVec at runtime. -+ * gcc.target/powerpc/altivec_check.h: Delete. -+ * g++.dg/eh/simd-2.C: Only use -maltivec if vmx_hw. -+ * g++.dg/ext/altivec_check.h: Delete. -+ * g++.dg/eh/check-vect.h (sig_ill_handler): Remove AltiVec runtime -+ check. -+ -+ * gcc.target/powerpc/20030505.c: Compile for all EABI targets. -+ Explicitly enable SPE. -+ * gcc.target/powerpc/ppc-spe.c: Likewise. -+ -+ * gcc.target/powerpc/darwin-longlong.c: Explicitly require 64-bit -+ instruction support. Do not check for it at runtime. -+ -+ * gcc.target/powerpc/20030218-1.c: Pass -mfloat-gprs=single. Expect -+ -flax-vector-conversions message. -+ * gcc.target/powerpc/spe1.c: Pass -mfloat-gprs=single. Make Foo -+ extern. -+ * g++.dg/other/opaque-2.C: Pass -mfloat-gprs=single. -+ * g++.dg/other/opaque-3.C, g++.dg/ext/spe1.C: Likewise. -+ -+ * gcc.dg/cpp/assert4.c: Recognize __PPC__. -+ -+ * g++.dg/other/opaque-1.C: Run on targets with SPE. -+ * g++.dg/other/profile1.C: Use dg-require-profiling. -+ -+ * g++.dg/conversion/simd1.C: Expect warning on all PowerPC -+ non-AltiVec targets. -+ * g++.dg/ext/attribute-test-1.C, g++.dg/ext/attribute-test-2.C, -+ g++.dg/ext/attribute-test-3.C, g++.dg/ext/attribute-test-4.C: Likewise. -+ -+ * lib/target-supports.exp (check_effective_target_ppc64): New. -+ -+2008-05-26 Maxim Kuvyrkov -+ -+ * release-notes-csl.xml: Add missing release note. -+ -+2008-05-23 Joseph Myers -+ -+ gcc/ -+ * config/arm/t-wrs-linux (MULTILIB_OPTIONS, MULTILIB_DIRNAMES, -+ MULTILIB_EXCEPTIONS): Add -tcortex-a8-be8 multilib. -+ * config/arm/wrs-linux.h (CC1_SPEC, SUBTARGET_EXTRA_ASM_SPEC, -+ SUBTARGET_EXTRA_LINK_SPEC, SYSROOT_SUFFIX_SPEC): Update for new -+ multilib. -+ -+2008-05-23 Nathan Froyd -+ -+ Backport from mainline: -+ -+ gcc/ -+ 2008-02-23 David Edelsohn -+ -+ * config/rs6000/rs6000.h (CONSTANT_ALIGNMENT): Use STRICT_ALIGNMENT -+ instead of TARGET_STRICT_ALIGN. -+ -+ gcc/ -+ 2008-02-22 Nathan Froyd -+ -+ * config/rs6000/rs6000.h (CONSTANT_ALIGNMENT): Don't overalign -+ strings when optimizing for size, unless the target cares about -+ alignment. -+ -+2008-05-23 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-03-28 Paul Brook -+ -+ Merge ARMv6-M support. -+ gcc/ -+ * config/arm/t-linux-eabi: Remove explicit marm (default) multilib. -+ Add entries for all multilibs to MULTILIB_OSDIRNAMES. -+ * config/arm/t-arm-elf: Ditto. Add armv6-m multilib. -+ (LIB1ASMFUNCS): Prefix sf/df routines with arm_. -+ * config/arm/t-uclinux-eabi: New file. -+ * config/arm/t-linux-eabi: Add Thumb-2 multilib. -+ * config/arm/uclinux-eabi.h (SYSROOT_SUFFIX_SPEC): Define. -+ * config/arm/linux-eabi.h (SYSROOT_SUFFIX_SPEC): Add thumb-2 sysroot. -+ * config.gcc: Add t-softfp and t-arm-softfp to ARM ELF based targets. -+ Add armv6-m. -+ * config/arm/t-arm-softfp: New file. -+ * config/arm/elf.h: Prevent libgcc float conversion routines being -+ built when we have assembly implementations. -+ * config/arm/ieee754-sf.S: Rename L_* L_arm_* -+ * config/arm/ieee754-df.S: Ditto. -+ * config/arm/arm.c (FL_FOR_ARCH6M): Define. -+ (all_architectures): Add armv6-m. -+ (arm_output_mi_thunk): Add TARGET_THUNMB1_ONLY code. -+ * config/arm/arm.h (TARGET_THUMB1_ONLY): Define. -+ (ARM_DECLARE_FUNCTION_NAME): Handle v6m thunks. -+ * config/arm/lib1funcs.asm: Add __ARM_ARCH_6M__. Omit ARM mode -+ code and macros when it is defined. Include bpabi-v6m.S. -+ (gnu_Unwind_Restore_VFP_D, gnu_Unwind_Save_VFP_D, -+ gnu_Unwind_Restore_VFP_D_16_to_31, gnu_Unwind_Save_VFP_D_16_to_31, -+ gnu_Unwind_Restore_WMMXD, gnu_Unwind_Save_WMMXD, -+ gnu_Unwind_Restore_WMMXC, gnu_Unwind_Save_WMMXC): Stubs for ARMv6-M. -+ * config/arm/sfp-machine.h: New file. -+ * config/arm/arm-cores.def: Add cortex-m1. -+ * config/arm/arm-tune.md: Regenerate. -+ * config/arm/libunwind.S: Add ARMv6-M implementation. -+ * config/arm/bpabi.h: Add renames for unsigned conversion routines. -+ * config/arm/bpabi-v6m.S: New file. -+ -+2008-05-23 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-03-26 Joseph Myers -+ -+ Merge from Sourcery G++ 4.1 branch: -+ -+ 2006-03-01 Paul Brook -+ gcc/testsuite/ -+ * g++.dg/other/armv7m-1.C: New test. -+ -+ 2006-10-27 Joseph Myers -+ Richard Sandiford -+ gcc/testsuite/ -+ * gcc.dg/arm-vfp1.c, gcc.target/arm/vfp-ldmdbd.c, -+ gcc.target/arm/vfp-ldmdbs.c, gcc.target/arm/vfp-ldmiad.c, -+ gcc.target/arm/vfp-ldmias.c, gcc.target/arm/vfp-stmdbd.c, -+ gcc.target/arm/vfp-stmdbs.c, gcc.target/arm/vfp-stmiad.c, -+ gcc.target/arm/vfp-stmias.c: Use arm_vfp_ok. -+ -+ 2006-08-19 Joseph Myers -+ gcc/testsuite/ -+ * gcc.target/arm/vfp-ldmdbd.c, gcc.target/arm/vfp-ldmdbs.c, -+ gcc.target/arm/vfp-ldmiad.c, gcc.target/arm/vfp-ldmias.c, -+ gcc.target/arm/vfp-stmdbd.c, gcc.target/arm/vfp-stmdbs.c, -+ gcc.target/arm/vfp-stmiad.c, gcc.target/arm/vfp-stmias.c: Skip for -+ iWMMXt. -+ -+ 2006-04-21 Kazu Hirata -+ gcc/testsuite/ -+ * gcc.target/arm/vfp-ldmdbd.c, gcc.target/arm/vfp-ldmdbs.c, -+ gcc.target/arm/vfp-ldmiad.c, gcc.target/arm/vfp-ldmias.c, -+ gcc.target/arm/vfp-stmdbd.c, gcc.target/arm/vfp-stmdbs.c, -+ gcc.target/arm/vfp-stmiad.c, gcc.target/arm/vfp-stmias.c: New. -+ -+2008-05-23 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-03-25 Vladimir Prus -+ -+ gcc/ -+ * config/arm/arm.c (load_multiple_sequence): Return -+ 0 if low irq latency is requested. -+ (store_multiple_sequence): Likewise. -+ (arm_gen_load_multiple): Load registers one-by-one -+ if low irq latency is requested. -+ (arm_gen_store_multiple): Likewise. -+ * config/arm/predicates.md (load_multiple_operation): -+ Return false is low irq latency is requested. -+ (store_multiple_operation): Likewise. -+ * config/arm/arm.h (low_irq_latency): Define. -+ * config/arm/arm.md (movmemqi): Don't use -+ it if low irq latency is requsted. -+ -+2008-05-23 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-03-24 Vladimir Prus -+ -+ gcc/ -+ * config/arm/arm.c (arm_override_options): Warn if -+ mlow-irq-latency is specified in thumb mode. -+ (print_pop_reg_by_ldr): New. -+ (arm_output_epilogue): Use print_pop_reg_by_ldr -+ when low irq latency is requested. -+ (emit_multi_reg_push): Push registers separately -+ if low irq latency is requested. -+ * config/arm/arm.opt (mlow-irq-latency): New option. -+ -+2008-05-23 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-03-23 Paul Brook -+ -+ gcc/ -+ * config/arm/uclinux-eabi.h (SUBTARGET_EXTRA_LINK_SPEC): Add -elf2flt -+ and --pic-veneer. -+ * config/arm/bpabi.h (SUBTARGET_EXTRA_LINK_SPEC): Provide empty -+ default definition. -+ (LINK_SPEC): Include SUBTARGET_EXTRA_LINK_SPEC. -+ -+2008-05-23 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-03-22 Paul Brook -+ -+ gcc/ -+ * config.gcc: Loosen checks for arm uclinux eabi targets. -+ -+2008-05-23 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-03-22 Sandra Loosemore -+ -+ gcc/ -+ * config/arm/lib1funcs.asm (ARM_DIV_BODY): Conditionalize for -+ __ARM_TUNE_MARVELL_F__. -+ * config/arm/arm.h (TARGET_CPU_CPP_BUILTINS): Add code to define -+ __ARM_TUNE_MARVELL_F__. -+ * config/arm/linux-eabi.h (SYSROOT_SUFFIX_SPEC): Add support for -+ marvell-f multilibs. -+ * config/arm/t-linux-eabi (MULTILIB_OPTIONS, MULTILIB_DIRNAMES, -+ MULTILIB_EXCEPTIONS, MULTILIB_MATCHES): Likewise. -+ * config/arm/t-arm-elf (MULTILIB_OPTIONS, MULTILIB_DIRNAMES, -+ MULTILIB_EXCEPTIONS, MULTILIB_MATCHES): Likewise. -+ -+2008-05-23 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-03-22 Mark Shinwell -+ -+ gcc/ -+ * config/arm/cortex-r4.md: New. -+ * config/arm/hwdiv.md (divsi3, udivsi3): Annotate with -+ insn attributes. -+ * config/arm/arm.md: Include cortex-r4.md. -+ (insn): Add sdiv and udiv values. -+ (generic_sched): Don't use generic scheduling for Cortex-R4. -+ -+2008-05-23 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-03-22 Vladimir Prus -+ -+ * config/arm/arm.c -+ (arm_compute_save_reg0_reg12_mask): Always -+ check if register 11 must be saved. Additionally -+ force save of it if frame_pointer_needeed. -+ (arm_compute_save_reg_mask): Save IP and PC -+ only with apcs frames. -+ (arm_output_epilogue): Adjust Thumb2 codepath to -+ be also invoked and work for ARM non-apcs frames. -+ (arm_expand_prologue): Don't bother saving IP -+ for non-apcs frame, since it's not clobbered by -+ prologue code. Implement non-apcs frame -+ layout. -+ -+2008-05-23 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-03-20 Mark Shinwell -+ -+ gcc/ -+ * config/arm/arm.c (arm_arch_marvell_f): Delete. -+ (all_architectures): Delete marvell-f entry. -+ (arm_override_options): Improve diagnostic. Ignore -+ FL_MARVELL_F when checking CPU feature flags against -+ architecture feature flags. Don't set arm_arch_marvell_f. -+ Check insn_flags instead of TARGET_MARVELL_F. -+ * config/arm/arm.h (arm_arch_marvell_f): Delete. -+ (TARGET_MARVELL_F): Delete. -+ * doc/invoke.texi: Remove marvell-f entry from -march= -+ documentation. -+ -+2008-05-23 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-03-20 Carlos O'Donell -+ -+ Issue #1314 -+ gcc/ -+ * target.h (calls): Add use_reg_for_func. -+ * function.c (use_register_for_decl): Return true if -+ target hook use_ref_for_func returns true. -+ * target-def.h (TARGET_USE_REG_FOR_FUNC): Define. -+ (TARGET_CALLS): Add TARGET_USE_REG_FOR_FUNC. -+ * config/arm/arm.c (arm_use_reg_for_func): New function. -+ (TARGET_USE_REG_FOR_FUNC): Define as arm_use_reg_for_func. -+ * doc/extend.texi (naked): Naked functions must only have -+ asms without operands. -+ * release-notes-csl.xml: Document #1314 fix. -+ -+2008-05-23 Nathan Froyd -+ -+ Backport from mainline: -+ -+ gcc/ -+ 2008-05-23 Steven Munroe -+ -+ * config/rs6000/darwin-ldouble.c (fmsub): Eliminate the full -+ PACK/UNPACK between FP_SUB_Q and FD_TRUNC so that the result -+ is only rounded once. -+ -+2008-05-23 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-03-18 Mark Shinwell -+ -+ gcc/ -+ * doc/invoke.texi: Document -mmarvell-div. -+ * config/arm/arm.c (arm_override_options): Take setting of -+ -mmarvell-div and TARGET_THUMB2 into account when setting -+ arm_arch_hwdiv. Cause error if -mmarvell-div is used when -+ not targeting a Marvell core. -+ * config/arm/arm.opt: Add entry for -mmarvell-div option. -+ * config/arm/hwdiv.md: Use only arm_arch_hwdiv to check -+ applicability of instruction patterns. -+ -+2008-05-23 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-03-18 Mark Shinwell -+ -+ gcc/ -+ * config/arm/vfp.md: When targeting a Marvell core, only -+ enable patterns involving multiply-accumulate type -+ instructions when optimizing for size. -+ -+2008-05-23 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-03-12 Sandra Loosemore -+ -+ gcc/ -+ * config/arm/arm.c (arm_final_prescan_insn): Skip this processing -+ if TARGET_NO_COND_EXEC is true. -+ * config/arm/arm.h (TARGET_NO_COND_EXEC): Define. -+ * config/arm/arm.md (smaxsi3, *arm_smax_insn): Disable if -+ TARGET_NO_COND_EXEC is set. -+ (sminsi3, *arm_smin_insn): Likewise. -+ (umaxsi3, *arm_umaxsi3): Likewise. -+ (uminsi3, *arm_uminsi3): Likewise. -+ (*store_minmaxsi): Likewise. -+ (seq, sne, sgt, sle, sge, slt): Likewise. -+ (sgtu, sleu, sgeu, sltu): Likewise. -+ (sunordered, sordered): Likewise. -+ (sungt, sunge, sunlt, sunle): Likewise. -+ (movsicc, movsfcc, movdfcc): Likewise. -+ (*cond_return, *cond_return_inverted): Likewise. -+ (*compare_scc): Likewise. -+ (*cond_arith): Likewise. -+ (movcond): Likewise. -+ (anonymous define_split patterns): Likewise. -+ (define_cond_exec): Likewise. -+ -+2008-05-23 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-02-02 Mark Shinwell -+ Richard Earnshaw -+ -+ gcc/ -+ * config/arm/arm.c (TARGET_MAX_ANCHOR_OFFSET): New. -+ (TARGET_MIN_ANCHOR_OFFSET): New. -+ (arm_override_options): Set correct anchor ranges for Thumb-1 -+ and Thumb-2 if required. -+ (legitimize_pic_address): Handle case involving a TLS symbol -+ reference with an addend. -+ (arm_optimization_options): Enable section anchors at -O1 and -+ above. -+ * config/arm/arm.h (OPTIMIZATION_OPTIONS): New. -+ * config/arm/arm-protos.h (arm_optimization_options): New. -+ -+2008-05-23 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-02-02 Mark Shinwell -+ -+ gcc/ -+ * config/arm/arm.md (UNSPEC_STACK_ALIGN): Use a number that -+ does not clash with other unspecs. -+ -+2008-05-23 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-02-02 Mark Shinwell -+ -+ gcc/ -+ * config/arm/thumb2.md: Update copyright notice and FSF address. -+ Include hwdiv.md and move instruction patterns for sdiv and udiv -+ to that file. -+ * config/arm/arm.c (arm_arch_marvell_f): New. -+ (all_architectures): Add marvell-f entry. -+ (ARM_ARCH_NAME_SIZE): Define. -+ (arm_arch_name): Allocate ARM_ARCH_NAME_SIZE bytes of space. -+ (arm_override_options): Be more careful writing to arm_arch_name. -+ Set arm_arch_hwdiv if arm_tune_marvell_f is set. -+ * config/arm/arm.h (arm_arch_marvell_f): New. -+ * config/arm/arm_cores.def: Add FL_MARVELL_F for the marvell-f -+ entry. -+ * config/arm/hwdiv.md: New. -+ * config/arm/t-arm (MD_INCLUDES): Add hwdiv.md. -+ * config.gcc: Recognize marvell-f as a supported ARM architecture. -+ * doc/invoke.texi (ARM Options): Document -mcpu=marvell-f and -+ -march=marvell-f. -+ -+2008-05-23 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-01-10 Mark Shinwell -+ -+ gcc/ -+ * config/arm/marvell-f.md: Fix FSF address and comment -+ capitalization. -+ * config/arm/marvell-f-vfp.md: New. -+ * config/arm/arm-cores.def: Add FL_VFPV2 for marvell-f. -+ * config/arm/arm.md: Include marvell-f-vfp.md. -+ (generic_vfp): Don't set attribute to "yes" for marvell_f tuning. -+ -+2008-05-23 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-01-07 Mark Shinwell -+ -+ gcc/ -+ * config/arm/vfp.md: Document fmul{s,d} and fmac{s,d} types. -+ Remove documentation entry for fmul type. -+ Use fmuls to annotate single-precision multiplication patterns, -+ fmuld to annotate double-precision multiplication patterns, -+ fmacs to annotate single-precision multiply-accumulate patterns -+ and fmacd to annotate double-precision multiply-accumulate patterns. -+ * config/arm/vfp11.md: Update reservations accordingly. -+ * config/arm/arm.md: Note that certain values of the "type" -+ attribute are documented in vfp.md. Add fmul{s,d} and fmac{s,d} -+ values for that attribute. -+ -+2008-05-23 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-01-04 Mark Shinwell -+ -+ gcc/ -+ * config/arm/vfp.md: Move pipeline description for VFP11 to... -+ * config/arm/vfp11.md: ...here. New. -+ * config/arm/arm.md: Include vfp11.md. -+ -+2008-05-23 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-01-03 Mark Shinwell -+ -+ NOT ASSIGNED TO FSF -+ Port from Marvell compiler: -+ gcc/ -+ * config/arm/arm.c (arm_issue_rate): New. -+ (arm_multipass_dfa_lookahead): New. -+ (TARGET_SCHED_ISSUE_RATE): Define. -+ (TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD): Define. -+ (FL_MARVELL_F): New. -+ (arm_tune_marvell_f): New. -+ (arm_override_options): Set arm_tune_marvell_f as appropriate. -+ * config/arm/arm.h (arm_tune_marvell_f): Declare. -+ * config/arm/arm-cores.def: Add marvell-f entry. -+ * config/arm/arm-tune.md: Regenerate. -+ * config/arm/t-arm (MD_INCLUDES): Add marvell-f.md. -+ * config/arm/arm.md: Don't use generic scheduler for marvell-f. -+ Include marvell-f.md. Extend "insn" attribute with mov/mvn/ -+ and/orr/eor cases and annotate instruction patterns accordingly. -+ * config/arm/vfp.md: Annotate likewise. -+ * config/arm/marvell-f.md: New. -+ -+2008-05-23 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2006-11-09 Paul Brook -+ -+ Merge from branches/csl/sourcerygxx-4_1. -+ gcc/ -+ * config/arm/arm.c (all_architectures): Add iWMMXt2 entry. -+ * config/arm/arm-cores.def: New ARM_CORE entry for iWMMXt2. -+ * config/arm/arm-tune.md: Regenerate. -+ -+2008-05-23 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2006-11-09 Paul Brook -+ -+ Merge from branches/csl/sourcerygxx-4_1. -+ 2006-09-10 Paul Brook -+ gcc/ -+ * config/arm/linux-eabi.h (SYSROOT_SUFFIX_SPEC): Define. -+ * config/arm/t-linux-eabi (MULTILIB_OPTIONS, MULTILIB_DIRNAMES): -+ Add armv4t multilib. -+ -+2008-05-23 Julian Brown -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2006-11-02 Paul Brook -+ -+ gcc/ -+ * config.gcc (arm*-*-eabi*): Add arm/nocrt0.h to tm_file. -+ * config/arm/nocrt0.h: New file. -+ -+2008-05-23 Nathan Froyd -+ -+ gcc/ -+ * config/rs6000/e300c2c3.md: Correctly use FSF upstream version, -+ not Sourcery G++ 4.2 version. -+ -+2008-05-23 Nathan Froyd -+ -+ Backport from mainline: -+ -+ gcc/ -+ 2008-02-26 Edmar Wienskoski -+ -+ * config/rs6000/rs6000.c (processor_costs): Update e300 cache -+ line sizes. -+ * doc/invoke.texi: Add e300c2 and e300c3 to list of cpus. -+ -+ gcc/ -+ 2008-02-24 Edmar Wienskoski -+ -+ * config.gcc (powerpc*-*-*): Add new cores e300c2 and e300c3. -+ * config/rs6000/e300c2c3.md: New file. -+ * config/rs6000/rs6000.c (processor_costs): Add new costs for -+ e300c2 and e300c3. -+ (rs6000_override_options): Add e300c2 and e300c3 cases to -+ processor_target_table. Do not allow usage of Altivec or Spe -+ with e300 cores. Initialize rs6000_cost for e300c2 and e300c3. -+ (rs6000_issue_rate): Set issue rate for e300c2 and e300c3. -+ * config/rs6000/rs6000.h (processor_type): Add -+ PROCESSOR_PPCE300C2 and PROCESSOR_PPCE300C3. -+ (ASM_CPU_SPEC): Add e300c2 and e300c3. -+ * config/rs6000/rs6000.md (define_attr "cpu"): Add ppce300c2 -+ and ppce300c3. Include e300c2c3.md. -+ -+2008-05-23 Nathan Froyd -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-12-31 Joseph Myers -+ -+ gcc/ -+ * config/rs6000/eabi-cn.asm, config/rs6000/sol-ci.asm, -+ config/rs6000/sol-cn.asm: Remove .file directives. -+ -+2008-05-23 Nathan Froyd -+ -+ Backport from mainline: -+ -+ 2008-03-06 Nathan Froyd -+ -+ * dwarf2out.c (dwarf2out_frame_debug_expr): Consult the -+ dwarf_register_span hook when emitting unwind information for -+ register-to-memory saves. -+ * config/rs6000/rs6000.c (spe_synthesize_frame): Delete. -+ (rs6000_frame_related): Remove call to spe_synthesize_frame. -+ -+2008-05-23 Nathan Froyd -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2008-03-04 Nathan Froyd -+ -+ gcc/ -+ * config/rs6000/eabi.asm (__eabi): Don't run __init. -+ (__eabi_convert, __eabi_uconvert): Define only if _RELOCATABLE. -+ -+2008-05-23 Nathan Froyd -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-03-22 Daniel Jacobowitz -+ -+ gcc/ -+ * config/rs6000/eabi.asm (.Lfini): New. -+ -+2008-05-23 Nathan Froyd -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2008-02-12 Nathan Sidwell -+ Daniel Jacobowitz -+ -+ gcc/ -+ * config/rs6000/eabi-ci.asm (__init): Add _init func start. -+ (__fini): Also declare _fini for newlib. -+ -+2008-05-22 Daniel Jacobowitz -+ -+ gcc/ -+ * function.c (assign_parm_remove_parallels): New. -+ (assign_parm_setup_block_p): Do not return true for non-BLKmode -+ PARALLELs. -+ (assign_parm_setup_block): Do not handle them. -+ (assign_parm_setup_reg, assign_parm_setup_stack): Call -+ assign_parm_remove_parallels. -+ -+2008-05-22 Daniel Jacobowitz -+ -+ gcc/ -+ * c-typeck.c (convert_for_assignment): Use -+ vector_targets_convertible_p. -+ * c-common.c (vector_targets_convertible_p): New. -+ * c-common.h (vector_targets_convertible_p): New prototype. -+ * config/rs6000/rs6000.c (rs6000_is_opaque_type): Do not check -+ opaque_p_V2SI_type_node. -+ -+ gcc/cp/ -+ * typeck.c (comp_ptr_ttypes_real): Use vector_targets_convertible_p. -+ (comp_ptr_ttypes_const): Likewise. -+ -+ gcc/testsuite/ -+ * g++.dg/other/opaque-1.C, g++.dg/other/opaque-2.C, -+ g++.dg/other/opaque-3.C: Also run on powerpc*-*-linux*spe*. -+ -+2008-05-22 Sandra Loosemore -+ -+ Revert (as already fixed in a different way): -+ -+ 2008-05-21 Sandra Loosemore -+ -+ libgcc/ -+ * config/t-vxworks: New file. -+ * config.host (Common parts for widely ported systems): Use it. -+ -+2008-05-22 Nathan Sidwell -+ -+ gcc/testsuite/ -+ Backport 2008-05-22 Nathan Sidwell -+ * lib/dg-pch.exp (dg-pch): Fix if bracing. -+ -+2008-05-21 Sandra Loosemore -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-04-13 Joseph Myers -+ -+ Merge from Sourcery G++ 4.1 branch: -+ -+ 2007-03-27 Mark Mitchell -+ gcc/testsuite/ -+ * gcc.target/i386/sse-10.c: Pass -mno-omit-leaf-frame-pointer. -+ -+2008-05-21 Sandra Loosemore -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-08-26 Mark Mitchell -+ -+ gcc/testsuite/ -+ * lib/prune.exp (prune_warnings): Extend the default -+ implementation to prune linker warnings about libm on Solaris. -+ libstdc++-v3/ -+ * testsuite/lib/prune.exp (prune_g++_output): Prune linker -+ warnings about libm on Solaris. -+ -+2008-05-21 Sandra Loosemore -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-08-26 Mark Mitchell -+ -+ fixincludes/ -+ * inclhack.def (solaris_mutex_init_2): Remove precise machine -+ checks; look at to determine whether fix is -+ required. -+ (solaris_rwlock_init_1): Likewise. -+ (solaris_once_init_2): Likewise. -+ * tests/base/sys/types.h: Add output generated by -+ solaris_mutex_init_2. -+ * fixincl.x: Regenerated. -+ -+2008-05-21 Sandra Loosemore -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-03-05 Mark Mitchell -+ -+ * configure.in (*-*-vxworks*): Remove target-libstdc++-v3 from -+ noconfigdirs. -+ * configure: Regenerated. -+ -+2008-05-21 Sandra Loosemore -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-03-12 Richard Sandiford -+ -+ gcc/ -+ * config/vx-common.h (TARGET_FLEXLM): Define. -+ -+2008-05-21 Sandra Loosemore -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-03-22 Daniel Jacobowitz -+ -+ gcc/testsuite/ -+ * g++.dg/other/profile1.C: Use dg-require-profiling. -+ -+2008-05-21 Sandra Loosemore -+ -+ libgcc/ -+ * config/t-vxworks: New file. -+ * config.host (Common parts for widely ported systems): Use it. -+ -+2008-05-21 Sandra Loosemore -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-04-25 Paul Brook -+ -+ Merge from sourcerygxx-4_1 -+ 2005-03-10 Julian Brown -+ libstdc++-v3/ -+ * configure.ac (LIBSUPCXX_PRONLY): New AM_CONDITIONAL: yes -+ if we are compiling for SymbianOS on ARM. -+ * include/Makefile.am: Don't install C++ headers if -+ LIBSUPCXX_PRONLY is true. -+ * libsupc++/Makefile.am: Include only eh_personality.cc -+ in libsupc++ if LIBSUPCXX_PRONLY is true. -+ * Makefile.in: Regenerate. -+ * configure: Regenerate. -+ * include/Makefile.in: Regenerate. -+ * libmath/Makefile.in: Regenerate. -+ * libsupc++/Makefile.in: Regenerate. -+ * po/Makefile.in: Regenerate. -+ * src/Makefile.in: Regenerate. -+ * testsuite/Makefile.in: Regenerate. -+ -+2008-05-21 Maxim Kuvyrkov -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2008-05-02 Maxim Kuvyrkov -+ gcc/ -+ Backport from mainline. -+ 2008-02-19 Christian Bruel -+ Zdenek Dvorak -+ * tree-ssa-loop-ivopts.c (may_be_unaligned_p): Check step alignment. -+ -+2008-05-21 Maxim Kuvyrkov -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-12-05 Maxim Kuvyrkov -+ Make scheduler better process end of the blocks. -+ -+ gcc/ -+ * haifa-sched.c (insn_finishes_cycle_p): New static function. -+ (max_issue): Use it. Fix handling of number of instruction to try. -+ * sched-int.h (struct sched_info: insn_finished_block_p): New -+ scheduler hook. -+ * sched-rgn.c (rgn_insn_finishes_block_p): Implement it. -+ (region_sched_info): Update. -+ * sched-ebb.c (ebb_sched_info): Update. -+ * modulo-sched.c (sms_sched_info): Update. -+ -+2008-05-20 Sandra Loosemore -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-03-22 Daniel Jacobowitz -+ -+ libstdc++-v3/ -+ * testsuite/27_io/basic_filebuf/sputbackc/char/9425.cc: Use -+ dg-require-fileio. -+ * testsuite/27_io/basic_filebuf/sputbackc/char/1-out.cc: Likewise. -+ * testsuite/27_io/basic_filebuf/sputbackc/char/2-out.cc: Likewise. -+ -+2008-05-20 Sandra Loosemore -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2008-02-12 Julian Brown -+ -+ Merge from MIPS: -+ -+ 2007-12-05 Thiemo Seufer -+ -+ libcpp/ -+ * Makefile.in ($(srcdir)/config.in): Fix dependency. -+ -+2008-05-20 Sandra Loosemore -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2006-03-29 Richard Sandiford -+ gcc/ -+ * config.gcc (tm_file): Update commentary. -+ -+2008-05-20 Nathan Sidwell -+ -+ Merge from Sourcery G++ 4.2: -+ -+ * gcc.c-torture/execute/builtins/memops-asm.c: Set inside_main. -+ -+ * lib/gcc-dg.exp (cleanup-saved-temps): Add optional list of -+ suffixes not to delete. -+ * gcc.dg/pch/save-temps-1.c: Don't delete ".s" temp. -+ * g++.dg/pch/pch.C: Likewise. -+ -+ * g++.old-deja/g++.pt/static11.C: Replace xfail by target requirement. -+ -+ * lib/dg-pch.exp (dg-pch): Don't expect .s files if there are -+ dg-errors expected. -+ -+2008-05-20 Nathan Sidwell -+ -+ Merge from Sourcery G++ 4.2: -+ -+ * c-incpath.c (INO_T_EQ): Do not define on non-inode systems. -+ (DIRS_EQ): New. -+ (remove_duplicates): Do not set inode on non-inode systems. Use -+ DIRS_EQ. -+ -+2008-05-19 Sandra Loosemore -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-08-12 Mark Shinwell -+ -+ gcc/ -+ * target.h (gcc_target): Add adjust_reg_alloc_order member. -+ * target-def.h (TARGET_ADJUST_REG_ALLOC_ORDER): New. -+ (TARGET_INITIALIZER): Add TARGET_ADJUST_REG_ALLOC_ORDER. -+ * regclass.c (init_reg_sets): Don't initialize -+ inv_reg_alloc_order. -+ (init_reg_sets_1): Call adjust_reg_alloc_order hook and -+ then initialize inv_reg_alloc_order. -+ * hooks.c (hook_intp_void): New. -+ * hooks.h (hook_intp_void): New. -+ * doc/tm.texi: Document TARGET_ADJUST_REG_ALLOC_ORDER. -+ -+2008-05-19 Sandra Loosemore -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-02-02 Mark Shinwell -+ Richard Earnshaw -+ -+ gcc/ -+ * varasm.c (use_object_blocks_p): Prevent use of object blocks -+ if -fno-toplevel-reorder is specified. -+ -+2008-05-19 Sandra Loosemore -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-02-16 Richard Sandiford -+ -+ gcc/ -+ * Makefile.in (postreload.o): Depend on addresses.h. -+ * addresses.h (index_reg_class, ok_for_index_p_1): New functions. -+ (regno_ok_for_index_p): New function. -+ * postreload.c: Include addresses.h. -+ (reload_combine): Use index_reg_class instead of INDEX_REG_CLASS. -+ * regclass.c (ok_for_index_p_nonstrict): Add a mode argument. -+ Use ok_for_index_p_1 instead of REGNO_OK_FOR_INDEX_P. -+ (record_address_regs): Use index_reg_class instead of INDEX_REG_CLASS. -+ Update calls to ok_for_index_p_nonstrict. -+ * regrename.c (scan_rtx_address): Use regno_ok_for_index_p instead of -+ REGNO_OK_FOR_INDEX_P and index_reg_class instead of INDEX_REG_CLASS. -+ (replace_oldest_value_addr): Likewise. -+ * reload.c (find_reloads_address): Use index_reg_class instead -+ of INDEX_REG_CLASS. Do not push an index register reload if -+ index_reg_class returns NO_REGS. -+ (find_reloads_address_1): Use index_reg_class instead -+ of INDEX_REG_CLASS and regno_ok_for_index_p instead of -+ REGNO_OK_FOR_INDEX_P. -+ * doc/tm.texi (MODE_INDEX_REG_CLASS): Document new macro. -+ (REGNO_MODE_OK_FOR_INDEX_P): Likewise. -+ -+2008-05-19 Sandra Loosemore -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-06-05 Mark Shinwell -+ -+ * release-notes-csl.xml (Register allocation bug fix): New. -+ -+ gcc/ -+ * reload1.c (emit_reload_insns): Upon discovery of an input -+ reload whose reload register is not a spill register, -+ invalidate any existing reloads involving that register. -+ -+2008-05-19 Sandra Loosemore -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2006-10-24 Mark Shinwell -+ gcc/ -+ * final.c (asm_insn_count): Return zero for an empty asm body. -+ -+2008-05-19 Sandra Loosemore -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2006-12-15 Richard Sandiford -+ gcc/testsuite/ -+ * gcc.c-torture/compile/20061214-1.c: New test. -+ -+2008-05-19 Sandra Loosemore -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-05-02 Mark Shinwell -+ -+ * release-notes-csl.xml (Forced alignment of array variables): -+ New. -+ -+ gcc/ -+ * doc/tm.texi: Document that LOCAL_ALIGNMENT and -+ DATA_ALIGNMENT should not be used directly. -+ * doc/invoke.texi (-falign-arrays): Document. -+ * function.c (DATA_ALIGNMENT): Define to a default if -+ undefined. -+ (alignment_for_aligned_arrays): New. -+ (calculate_local_alignment): New. -+ (calculate_global_alignment): New. -+ * function.h (calculate_local_alignment): New. -+ (calculate_global_alignment): New. -+ * cfgexpand.c (LOCAL_ALIGNMENT): Don't define to a default. -+ (get_decl_align_unit): Use calculate_local_alignment. -+ * common.opt (-falign-arrays): New. -+ * varasm.c (assemble_variable): Use calculate_data_alignment, -+ and use it irrespective of whether DATA_ALIGNMENT is defined. -+ -+2008-05-16 Nathan Froyd -+ Kazu Hirata -+ Daniel Jacobowitz -+ Nathan Sidwell -+ -+ Merge from Sourcery G++ 4.2: -+ -+ gcc/ -+ * config/rs6000/linux.h (CC1_EXTRA_SPEC, ASM_DEFAULT_SPEC, -+ SYSROOT_SUFFIX_SPEC): Define. -+ * config/rs6000/eabi.h (CC1_EXTRA_SPEC, ASM_DEFAULT_SPEC): Define. -+ * config/rs6000/t-linux: New file. -+ * config/rs6000/t-ppcgas (MULTILIB_OPTIONS): Add te500v1/te500v2/te600. -+ (MULTILIB_DIRNAMES): Add te500v1 te500v2 te600. -+ (MULTILIB_EXCEPTIONS): New. -+ (MULTILIB_EXTRA_OPTS): Remove mrelocatable-lib. -+ -+2008-05-16 Nathan Froyd -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-09-07 Daniel Jacobowitz -+ gcc/ -+ * config/rs6000/rs6000.c (rs6000_dwarf_register_span): Fix -+ debug output for other floating point modes. -+ -+2008-05-16 Nathan Froyd -+ -+ Merge from Sourcery G++ 4.2: -+ -+ 2007-08-16 Daniel Jacobowitz -+ gcc/ -+ * config/rs6000/rs6000.c (rs6000_conditional_register_usage): Mark -+ call-saved AltiVec registers call-used if ! TARGET_ALTIVEC_ABI. -+ * config/rs6000/rs6000.h (CALL_USED_REGISTERS): Mark the first 20 -+ AltiVec registers call-used. -+ (CALL_REALLY_USED_REGISTERS): Likewise. -+ -+ gcc/testsuite/ -+ * gcc.target/powerpc/altivec-consts.c: Remove -mabi=altivec. -+ * gcc.target/powerpc/altivec-varargs-1.c: Likewise. -+ * gcc.dg/vmx/vmx.exp: Likewise. -+ -+2008-05-16 Nathan Froyd -+ -+ Merge from Sourcery G++ 4.2: -+ -+ gcc/ -+ * config.gcc (powerpc-timesys-linux-gnu): Handle new target. -+ * config/rs6000/timesys-linux.h: New file. -+ * config/rs6000/t-timesys: New file. -+ -+2008-05-14 Joseph Myers -+ -+ Backport: -+ -+ fixincludes/ -+ 2008-05-14 Joseph Myers -+ * inclhack.def (AAB_fd_zero_asm_posix_types_h): Bypass on -+ posix_types_64. -+ * fixincl.x: Regenerate. -+ -+2008-05-09 Maxim Kuvyrkov -+ -+ Backport from mainline. -+ -+ gcc/ -+ 2008-05-09 Maxim Kuvyrkov -+ -+ * rtl-factoring.c (collect_pattern_seqs): Fix typo. -+ -+2008-05-09 Maxim Kuvyrkov -+ -+ Backport from mainline. -+ -+ gcc/ -+ 2008-05-07 Maxim Kuvyrkov -+ -+ Cleanup ColdFire scheduling support and add V4 pipeline model. -+ -+ * config/m68k/m68k.md (UNSPEC_TIE): New constant. -+ (define_attr cpu): Add cfv4 value. -+ (define_attr type, define_attr type1): Merge into a single 'type' -+ attribute. Update all uses. -+ (define_attr opx_type, define_attr opy_type, define_attr opx_access): -+ Rearrange and update. Rename value 'reg' to 'Rn', add value 'FPn'. -+ Update all uses. -+ (define_attr opx_mem, define_attr opy_mem): Remove. -+ (define_attr op_mem): Clean up, update comment. -+ (define_attr size): Use specific values instead of general int. -+ (define_attr guess, define_attr split): Remove. Update all uses. -+ (movdf_internal, tstsi_internal, tsthi_internal, tstqi_internal, -+ tst_68881, pushexthisi_const, movsi_const0_68000_10, -+ movsi_const0_68040_60, movsi_const0, movsi_cf, movstrictqi_cf, -+ zero_extendhisi2_cf, zero_extendqisi2_cfv4, cfv4_extendhisi2, -+ 68k_extendhisi2, extendqihi2, cfv4_extendqisi2, 68k_extendqisi2, -+ floatsi2_68881, ftrunc2_68881, ftrunc2_cf, -+ fixqi2_68881, fixhi2_68881, fixsi2_68881, -+ adddi_dishl32, addsi3_5200, add3_floatsi_68881, -+ add3_floathi_68881, add3_floatqi_68881, -+ add3_68881, add3_cf, subdi_dishl32, subsi3, -+ sub3_floatsi_68881, sub3_floathi_68881, -+ sub3_floatqi_68881, sub3_68881, sub3_cf, -+ mulhi3, mulhisi3, mulhisisi3_s, mulsi3_68020, mulsi3_cf, -+ umulhisi3, mulhisisi3_z, mul3_floatsi_68881, -+ mul3_floathi_68881, mul3_floatqi_68881, fmul3_cf, -+ div3_cf, sqrt2_cf, abs2_cf, clzsi2, -+ one_cmplsi2_5200, subreghi1ashrdi_const32, ashrsi3, lshrsi3, -+ bsetmemqi, bsetmemqi_ext, bclrmemqi, bclrmemqi_ext, -+ beq, bne, bgt, blt, bordered, bunordered, buneq, bunge, bungt, bunle, -+ bunlt, bltgt, tablejump_internal, call, non_symbolic_call_value, -+ symbolic_call_value_jsr, symbolic_call_value_bsr, link): -+ Update or set attributes. -+ (stack_tie): New fake instruction. -+ -+ * config/m68k/m68k.h (TUNE_CFV4): New macro. -+ (m68k_sched_attr_size): Update declaration. -+ (m68k_sched_attr_type2): Remove. -+ (m68k_sched_address_bypass_p, m68k_sched_indexed_address_bypass_p): -+ Declare new bypass predicates. -+ -+ * config/m68k/m68k.c (m68k_sched_issue_rate, -+ m68k_sched_first_cycle_multipass_dfa_lookahead): Declare hook -+ implementations. -+ (TARGET_SCHED_ISSUE_RATE, -+ TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD): Override hooks. -+ (override_options): Handle scheduling for ColdFire V4 core. -+ (m68k_expand_prologue): Emit stack_tie. -+ (enum attr_op_type): Split value 'OP_TYPE_REG' to 'OP_TYPE_RN' and -+ 'OP_TYPE_FPN'. Update all uses. -+ (sched_guess_p): Remove. -+ (sched_address_type): Handle symbolic addresses. -+ (sched_get_operand): New static function. -+ (sched_operand_type): Merge into sched_attr_op_type. -+ (sched_attr_op_type): Handle FP registers, handle quick constants, -+ update. -+ (m68k_sched_attr_opx_type, m68k_sched_attr_opy_type): Update. -+ (m68k_sched_attr_size): Update. Move logic to ... -+ (sched_get_attr_size_int): New static function. -+ (sched_get_opxy_mem_type): New static function. -+ (m68k_sched_attr_op_mem): Update. -+ (m68k_sched_attr_type2): Remove. -+ (sched_cfv4_bypass_data): New static variable. -+ (m68k_sched_adjust_cost): Handle ColdFire V4 bypass. -+ (m68k_sched_issue_rate): Implement scheduler hook. -+ (struct _sched_ib: enabled_p): New field. -+ (m68k_sched_variable_issue): Update. Handle V4. -+ (SCHED_DUMP_TODO, SCHED_DUMP_DONE, SCHED_DUMP_NOTHING, -+ sched_dump_class_func_t, sched_dump_split_class, -+ sched_dump_dfa_guess_unit_code, sched_dump_dfa_state, -+ sched_dump_dfa_class, m68k_sched_dump): Remove. -+ (m68k_sched_first_cycle_multipass_dfa_lookahead): Implement scheduler -+ hook. -+ (m68k_sched_init_global): Remove statisctics dumping, introduce -+ sanity check that all instructions have pipeline reservations. Handle -+ ColdFire V4 core. -+ (m68k_sched_dfa_pre_advance_cycle, m68k_sched_dfa_post_advance_cycle): -+ Handle ColdFire V4 core. -+ (sched_mem_operand_p, sched_get_reg_operand, sched_get_mem_operand): -+ New static functions. -+ (m68k_sched_address_bypass_p): New bypass predicate. -+ (sched_get_indexed_address_scale): New static function. -+ (m68k_sched_indexed_address_bypass_p): New bypass predicate. -+ -+ * cf.md: Update comments. -+ (define_attr type2): Remove. Use 'type' attribute instead. -+ Update all uses. -+ (cf_ib): Rename to cfv123_ib. Update all uses. -+ (cf_oep): Rename to cfv123_oep. Update all uses. -+ (cf_chr): Rename to cfv123_chr. Update all uses. -+ (cf_mem): Rename to cfv123_mem. Update all uses. -+ (cf_mac): Move to more appropriate place. -+ (cfv123_guess): New automaton and cpu_unit. -+ (cfv123_*, cfv12_*, cfv1_*, cfv2_*, cfv3_*): Use type attribute. -+ Update uses of 'size' attribute. Handle before reload scheduling. -+ (cfv123_guess): New dummy reservation for unhandled instructions. -+ (cfv4_*): Pipeline description of ColdFire V4 core. -+ (ignore): New reservation to handle 'ignore' type. -+ -+2008-05-09 Maxim Kuvyrkov -+ -+ Backport from mainline. -+ -+ gcc/ -+ -+ 2008-04-22 Maxim Kuvyrkov -+ -+ Support scheduling for ColdFire V1 and V3 microarchitecture. -+ Improve scheduling of multiplication instructions. -+ -+ * config/m68k/m68k.md (cpu): Add cfv1 and cfv3. Rename cf_v2 to cfv1. -+ (mac): New instruction attribute. -+ * config/m68k/m68k.c (override_options): Handle cfv1, cfv3 and mac. -+ (m68k_sched_mac): New variable. -+ (m68k_sched_attr_type2, m68k_sched_md_init_global): Update. -+ Handle cfv1 and cfv3. -+ (max_insn_size): New static variable. -+ (struct _sched_ib): New type. -+ (sched_ib): New static variable. -+ (sched_ib_size, sched_ib_filled, sched_ib_insn): Convert variables -+ to fields of 'struct _sched_ib sched_ib'. Update all uses. -+ (m68k_sched_variable_issue): Add modeling of cfv3 instruction buffer. -+ Update. -+ (m68k_sched_md_init_global, m68k_sched_md_finish_global, -+ m68k_sched_md_init, m68k_sched_md_finish): Handle cfv1 and cfv3. Init -+ new variables. Update. -+ (m68k_sched_dfa_pre_advance_cycle, m68k_sched_dfa_post_advance_cycle): -+ Add modeling of cfv3 instruction buffer. Update. -+ * config/m68k/m68k-protos.h (m68k_sched_mac): Declare. -+ * config/m68k/m68k.h (TUNE_CFV3): New macro. -+ * config/m68k/cf.md: Change substrings 'cf_v2' to 'cfv12' or 'cfv123'. -+ (cf_* reservations): Rename to cfv12 or cfv123 to indicate cores -+ a particular reservation applies to. -+ (type2): Reorganize attribute values. Rename alu to alu_reg, -+ alu_l to alu, move_l to omove. Join move to alu. Split mul -+ to mul_l and mul_w. -+ (cf_ib_*): Simplify description of instruction buffer. -+ (cf_ib_w0, cf_ib_w4, cf_ib_w5, cf_ib_w6): Remove. -+ (cf_mem): Split into cf_mem1 and cf_mem2. -+ (cf_v2_move_??): Rename to cfv12_alu_??. -+ (cf_v2_move_l_??): Rename to cfv12_omove_??. -+ (cf_v2_mul_??): Remove reservations. -+ (cfv12_mul_l_??, cfv12_mul_w_??, cfv12_mac_w_??, cfv12_mac_l_??, -+ cfv12_emac_??, cfv12_emac_w_i0): New reservations. -+ (cfv12_rts, cfv12_call, cfv12_bcc, cfv12_bra, cfv12_jmp): Move to -+ appropriate place. -+ (cfv3_alu_10, cfv3_omove_10, cfv3_alu_i0, cfv3_omove_i0, cfv3_alu_01, -+ cfv3_alu_0i, cfv3_alu_11, cfv3_omove_11, cfv3_alu_i1, cfv3_omove_i1, -+ cfv3_alu_1i, cfv3_omove_1i, cfv3_pea_11, cfv3_pea_i1, cfv3_mul_w_10, -+ cfv3_mul_l_10, cfv3_mul_w_i0, cfv3_mac_w_10, cfv3_mac_l_10, -+ cfv3_mac_w_i0, cfv3_emac_10, cfv3_emac_w_i0, cfv3_rts, cfv3_call, -+ cfv3_bcc, cfv3_bra, cfv3_jmp): New reservations. -+ (cfv3_*_1, cfv3_*_2, cfv3_*_3): New instruction reservations that are -+ expansions of the above reservations for instructions of sizes -+ 1, 2 and 3 words. -+ -+2008-05-09 Maxim Kuvyrkov -+ -+ Backport from mainline. -+ -+ gcc/ -+ 2008-04-22 Maxim Kuvyrkov -+ * rtl-factoring.c (collect_patterns_seqs): Handle CC0 targets. -+ -+2008-05-05 Mark Mitchell -+ Joseph Myers -+ Mark Shinwell -+ Vladimir Prus -+ Paul Brook -+ -+ Merge from Sourcery G++ 4.2: -+ -+ gcc/ -+ * config.gcc (arm-wrs-linux-gnueabi, i586-wrs-linux-gnu, -+ mips-wrs-linux-gnu, powerpc-wrs-linux-gnu, sparc-wrs-linux-gnu): -+ Handle new targets. -+ * config/arm/t-wrs-linux, config/arm/wrs-linux.h, -+ config/mips/t-wrs-linux, config/mips/wrs-linux.h, -+ config/rs6000/t-wrs-linux, config/rs6000/wrs-linux.h: New. -+ * config/sparc/linux64.h (TARGET_DEFAULT): Define differently for -+ BIARCH_32BIT_DEFAULT. -+ -+ libcpp/ -+ * configure.ac (sparc-wrs-linux-gnu): Add to need_64bit_hwint=yes -+ targets. -+ * configure: Regenerate. -+ -+2008-05-05 Joseph Myers -+ -+ Merge from Sourcery G++ 4.2: -+ -+ gcc/ -+ * config/sparc/linux64.h (LINK_ARCH32_SPEC, LINK_ARCH64_SPEC, -+ LINK_SPEC): Use %R in -Y P argument. -+ -+2008-05-05 Joseph Myers -+ Daniel Jacobowitz -+ -+ Merge from Sourcery G++ 4.2: -+ -+ gcc/ -+ * config/rs6000/rs6000.h (OPTION_DEFAULT_SPECS): Handle -te500v1, -+ -te500v2 and -te600. -+ -+2008-05-05 Joseph Myers -+ -+ Merge from Sourcery G++ 4.2: -+ -+ gcc/ -+ * config/rs6000/sysv4.h (CC1_EXTRA_SPEC): Define and use. -+ -+2008-05-05 Joseph Myers -+ -+ Merge from Sourcery G++ 4.2: -+ -+ gcc/testsuite/ -+ * g++.dg/compat/struct-layout-1.exp: Compile generator on build -+ system. -+ * gcc.dg/compat/struct-layout-1.exp: Likewise. -+ -+2008-05-05 Joseph Myers -+ -+ Merge from Sourcery G++ 4.2: -+ -+ gcc/testsuite/ -+ * lib/gcc-dg.exp (remove-build-file): Remove files on remote host -+ as well as on build. -+ -+2008-05-05 Joseph Myers -+ -+ Backport: -+ -+ gcc/ -+ 2008-03-04 Joseph Myers -+ * config/i386/i386.c (override_options): Force -+ -maccumulate-outgoing-args on if TARGET_STACK_PROBE. -+ -+ gcc/testsuite/ -+ 2008-03-04 Joseph Myers -+ * gcc.target/i386/sse-10.c: Don't use -+ -mno-accumulate-outgoing-args on *-*-mingw* *-*-cygwin*. -+ -+2008-05-05 Joseph Myers -+ -+ Merge from Sourcery G++ 4.2: -+ -+ config/ -+ * config/mh-mingw (LDFLAGS): Define. -+ -+ gcc/ -+ * configure.ac: Use empty LDFLAGS when running configure for the -+ build system. -+ * configure: Regenerate. -+ * Makefile.in (BUILD_LDFLAGS): Do not define to $(LDFLAGS) unless -+ host == build. -+ -+2008-05-05 Joseph Myers -+ -+ Merge from Sourcery G++ 4.2: -+ -+ gcc/ -+ * libgcc2.c (__do_global_dtors): Do not call -+ __deregister_frame_info on MinGW. -+ (__do_global_ctors): Call atexit before calling constructors. Do -+ not call __register_frame_info on MinGW. -+ * config/i386/mingw32.h (LIBGCC_SPEC): Start with -lgcc. -+ -+2008-05-05 Joseph Myers -+ -+ Merge from Sourcery G++ 4.2: -+ -+ gcc/ -+ 2007-06-13 Joseph Myers -+ * common.opt (--Wno-poison-system-directories): New. -+ * doc/invoke.texi (-Wno-poison-system-directories): Document. -+ * c-incpath.c: Include flags.h. -+ (merge_include_chains): Check flag_poison_system_directories. -+ * gcc.c (LINK_COMMAND_SPEC): Pass --no-poison-system-directories -+ to linker if -Wno-poison-system-directories. -+ * Makefile.in (c-incpath.o): Depend on $(FLAGS_H). -+ -+ 2007-03-20 Daniel Jacobowitz -+ Joseph Myers -+ * configure.ac (--enable-poison-system-directories): New option. -+ * configure, config.in: Regenerate. -+ * c-incpath.c (merge_include_chains): If -+ ENABLE_POISON_SYSTEM_DIRECTORIES defined, warn for use of -+ /usr/include, /usr/local/include or /usr/X11R6/include. -+ -+2008-05-02 Joseph Myers -+ -+ Backport: -+ -+ gcc/ -+ 2008-02-23 Joseph Myers -+ * explow.c (memory_address): Assert that the generated address is -+ valid. -+ -+2008-05-02 Joseph Myers -+ -+ Backport: -+ -+ libstdc++-v3/ -+ 2008-03-04 Joseph Myers -+ * crossconfig.m4 (*-mingw32*): Define HAVE_STRTOF and -+ HAVE_STRTOLD. -+ * configure: Regenerate. -+ -+2008-05-02 Joseph Myers -+ -+ Merge from Sourcery G++ 4.2: -+ -+ gcc/ -+ * collect2.c (find_a_file): Use IS_ABSOLUTE_PATH. -+ -+2008-05-02 Joseph Myers -+ -+ gcc/ -+ * config.gcc (i[34567]86-*-* | x86_64-*-*): Support arch32 arch64. -+ * config/i386/i386.h (OPT_ARCH32, OPT_ARCH64): Define. -+ (OPTION_DEFAULT_SPECS): Add arch32 and arch64. -+ -+2008-05-02 Joseph Myers -+ -+ Merge from Sourcery G++ 4.2: -+ -+ gcc/ -+ * config.gcc (mips*-*-*): Support arch32 arch64 tune32 tune64. -+ (powerpc*-*-* | rs6000-*-*): Support cpu32 cpu64. -+ (all_defaults): Add arch32 arch64 cpu32 cpu64 tune32 tune64. -+ * config/mips/mips.h (OPTION_DEFAULT_SPECS): Add support for -+ arch32 arch64 tune32 tune64. -+ * gcc/config/rs6000/rs6000.h (OPTION_DEFAULT_SPECS): Add cpu32 and -+ cpu64. -+ -+2008-05-02 Joseph Myers -+ -+ Merge from Sourcery G++ 4.2: -+ -+ gcc/ -+ * config.gcc (i[34567]86-*-linux*): Use extra config files if -+ --enable-extra-sgxx-multilibs. -+ * config/i386/cs-linux.h, config/i386/cs-linux.opt, -+ config/i386/t-cs-linux: New. -+ -+2008-05-01 Mark Mitchell -+ Vladimir Prus -+ Joseph Myers -+ Carlos O'Donell -+ Daniel Jacobowitz -+ Kazu Hirata -+ -+ libiberty/ -+ * configure.ac: Add cygpath for mingw hosts. -+ * configure: Regenerate. -+ * Makefile.in: Add cygpath. -+ * cygpath.c: New. -+ * pex-win32.c (pex_win32_open_read, pex_win32_open_write): Use -+ open not _open. -+ -+ include/ -+ * libiberty.h (cygpath): Declare. -+ -+2008-05-01 Carlos O'Donell -+ -+ Merge from Sourcery G++ 4.2: -+ -+ * Makefile.tpl (install): Call install-html and install-pdf. -+ * Makefile.in: Regenerate. -+ -+ gcc/ -+ * Makefile.in (install): Depend on install-html and install-pdf. -+ -+2008-05-01 Joseph Myers -+ -+ Merge from Sourcery G++ 4.2: -+ -+ gcc/ -+ 2007-10-16 Joseph Myers -+ * gcc.c (license_me_flag): Define to 1 if not TARGET_FLEXLM. -+ -+ 2007-08-10 Nathan Froyd -+ * gcc.c (main): Consult license_me_flag to see if failure to -+ acquire a license implies bailing out entirely. -+ -+ 2007-08-24 Nathan Froyd -+ Issue #1892 -+ * gcc.c (main): Check license_me_flag before declaring failure. -+ -+ 2007-08-30 Nathan Sidwell -+ Issue #1892 -+ * gcc.c (main): Don't complain if license fails without -flicense-me -+ -+ 2007-04-12 Richard Sandiford -+ * gcc.c (main): If find_a_file fails, pass the original subproc -+ to csl_subproc_license_new. -+ -+ 2006-12-27 Mark Mitchell -+ NOT ASSIGNED TO FSF -+ COPYRIGHT CODESOURCERY -+ * gcc.c (main): If the license check fails, remove the generated -+ file. -+ -+ 2006-12-22 Mark Mitchell -+ NOT ASSIGNED TO FSF -+ COPYRIGHT CODESOURCERY -+ * aclocal.m4: Move licensing options ... -+ * acinclude.m4: ... here. -+ -+ 2006-12-13 Mark Mitchell -+ NOT ASSIGNED TO FSF -+ COPYRIGHT CODESOURCERY -+ * gcc.c (csl/license.h): Include, if required. -+ (license_checked): New variable. -+ (no_license): Remove. -+ (process_command): Set license_checked, not no_license. -+ (main): Use CodeSourcery license library. Remove most -+ TARGET_FLEXLM code. -+ * aclocal.m4 (--with-license): New option. -+ (--with-csl-license-feature): Likewise. -+ (--with-csl-license-version): Likewise. -+ * Makefile.in (CSL_LICENSEINC): Define it. -+ (CSL_LICENSELIB): Likewise. -+ (CSL_LICENSE_PROG): Likewise. -+ (LIBS): Depend on CSL_LICENSELIB. -+ (GCC_PASSES): Depend on CSL_LICENSE_PROG. -+ (INCLUDES): Add CSL_LICENSEINC. -+ * configure.ac (CSL_AC_LICENSE_VERSION): Use it. -+ (CSL_AC_LICENSE): Likewise. -+ (CSL_AC_LICENSE_FEATURE): Likewise. -+ * config.in: Regenerated. -+ * configure: Regenerated. -+ -+ 2006-10-29 Richard Sandiford -+ Joseph Myers -+ * gcc.c (license_me_flag): New variable. -+ (feature_proxy_flag): New variable. -+ (no_license): New variable. -+ (process_command): Handle -flicense-me, -ffeature-proxy and -+ -fno-feature-proxy. Initialize no_license. -+ (main): Check licenses. -+ -+2008-05-01 Joseph Myers -+ -+ * release-notes-csl.xml: New. -+ -+ -+Local Variables: -+mode: change-log -+change-log-default-name: "ChangeLog.csl" -+End: ---- a/boehm-gc/Makefile.am -+++ b/boehm-gc/Makefile.am -@@ -66,7 +66,8 @@ TESTS = gctest - ## CFLAGS, not those passed in from the top level make. - LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CFLAGS) $(MY_CFLAGS) $(GC_CFLAGS) --LINK = $(LIBTOOL) --mode=link $(CC) $(AM_CFLAGS) $(MY_CFLAGS) $(LDFLAGS) -o $@ -+LTLDFLAGS = $(shell $(top_srcdir)/../libtool-ldflags $(LDFLAGS)) -+LINK = $(LIBTOOL) --mode=link $(CC) $(AM_CFLAGS) $(MY_CFLAGS) $(LTLDFLAGS) -o $@ - - # Work around what appears to be a GNU make bug handling MAKEFLAGS - # values defined in terms of make variables, as is the case for CC and ---- a/boehm-gc/Makefile.in -+++ b/boehm-gc/Makefile.in -@@ -303,7 +303,8 @@ TESTS = gctest - LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CFLAGS) $(MY_CFLAGS) $(GC_CFLAGS) - --LINK = $(LIBTOOL) --mode=link $(CC) $(AM_CFLAGS) $(MY_CFLAGS) $(LDFLAGS) -o $@ -+LTLDFLAGS = $(shell $(top_srcdir)/../libtool-ldflags $(LDFLAGS)) -+LINK = $(LIBTOOL) --mode=link $(CC) $(AM_CFLAGS) $(MY_CFLAGS) $(LTLDFLAGS) -o $@ - - # Work around what appears to be a GNU make bug handling MAKEFLAGS - # values defined in terms of make variables, as is the case for CC and ---- a/config.sub -+++ b/config.sub -@@ -254,6 +254,7 @@ case $basic_machine in - | mips | mipsbe | mipseb | mipsel | mipsle \ - | mips16 \ - | mips64 | mips64el \ -+ | mips64octeon | mips64octeonel \ - | mips64vr | mips64vrel \ - | mips64orion | mips64orionel \ - | mips64vr4100 | mips64vr4100el \ -@@ -335,6 +336,7 @@ case $basic_machine in - | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ - | mips16-* \ - | mips64-* | mips64el-* \ -+ | mips64octeon-* | mips64octeonel-* \ - | mips64vr-* | mips64vrel-* \ - | mips64orion-* | mips64orionel-* \ - | mips64vr4100-* | mips64vr4100el-* \ ---- a/config/mh-mingw -+++ b/config/mh-mingw -@@ -1,3 +1,7 @@ - # 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 -+# Because we wrap access in libiberty/cygpath.c, we do not want to use -+# the MinGW wrappers for access. -+# BOOT_CFLAGS += -D__USE_MINGW_ACCESS -+# Increase stack limit to same as Linux default. -+LDFLAGS += -Wl,--stack,8388608 ---- a/config/mt-sde -+++ b/config/mt-sde -@@ -6,5 +6,5 @@ - # has two purposes: it allows libraries to be used in situations where - # $gp != our _gp, and it allows them to be built with -G8 while - # retaining link compability with -G0 and -G4. --CFLAGS_FOR_TARGET += -Os -minterlink-mips16 -mcode-xonly -mno-gpopt -+CFLAGS_FOR_TARGET += -Os -minterlink-mips16 -mcode-xonly -mno-gpopt - CXXFLAGS_FOR_TARGET += -Os -minterlink-mips16 -mcode-xonly -mno-gpopt ---- a/configure -+++ b/configure -@@ -2195,7 +2195,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 -@@ -472,7 +472,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.x -+++ b/fixincludes/fixincl.x -@@ -2,11 +2,11 @@ - * - * DO NOT EDIT THIS FILE (fixincl.x) - * -- * It has been AutoGen-ed Monday January 5, 2009 at 04:00:24 PM PST -+ * It has been AutoGen-ed Tuesday February 17, 2009 at 01:49:33 PM PST - * From the definitions inclhack.def - * and the template file fixincl - */ --/* DO NOT SVN-MERGE THIS FILE, EITHER Mon Jan 5 16:00:24 PST 2009 -+/* DO NOT SVN-MERGE THIS FILE, EITHER Tue Feb 17 13:49:33 PST 2009 - * - * You must regenerate it. Use the ./genfixes script. - * -@@ -214,11 +214,14 @@ tSCC zAab_Fd_Zero_Asm_Posix_Types_HBypas - "} while"; - tSCC zAab_Fd_Zero_Asm_Posix_Types_HBypass1[] = - "x86_64"; -+tSCC zAab_Fd_Zero_Asm_Posix_Types_HBypass2[] = -+ "posix_types_64"; - --#define AAB_FD_ZERO_ASM_POSIX_TYPES_H_TEST_CT 2 -+#define AAB_FD_ZERO_ASM_POSIX_TYPES_H_TEST_CT 3 - static tTestDesc aAab_Fd_Zero_Asm_Posix_Types_HTests[] = { - { TT_NEGREP, zAab_Fd_Zero_Asm_Posix_Types_HBypass0, (regex_t*)NULL }, -- { TT_NEGREP, zAab_Fd_Zero_Asm_Posix_Types_HBypass1, (regex_t*)NULL }, }; -+ { TT_NEGREP, zAab_Fd_Zero_Asm_Posix_Types_HBypass1, (regex_t*)NULL }, -+ { TT_NEGREP, zAab_Fd_Zero_Asm_Posix_Types_HBypass2, (regex_t*)NULL }, }; - - /* - * Fix Command Arguments for Aab_Fd_Zero_Asm_Posix_Types_H -@@ -5974,8 +5977,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 }; - - /* -@@ -5984,8 +5986,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 }, }; - - /* -@@ -6027,8 +6036,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 }, }; - - /* -@@ -6098,8 +6114,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 }; - - /* -@@ -6108,8 +6123,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 }, }; - - /* -@@ -8606,7 +8628,7 @@ static const char* apzX11_SprintfPatch[] - * - * List of all fixes - */ --#define REGEX_COUNT 255 -+#define REGEX_COUNT 256 - #define MACH_LIST_SIZE_LIMIT 261 - #define FIX_COUNT 212 - ---- a/fixincludes/inclhack.def -+++ b/fixincludes/inclhack.def -@@ -141,6 +141,7 @@ fix = { - mach = 'i[34567]86-*-linux*'; - bypass = '} while'; - bypass = 'x86_64'; -+ bypass = 'posix_types_64'; - - /* - * Define _POSIX_TYPES_H_WRAPPER at the end of the wrapper, not -@@ -3274,24 +3275,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" -@@ -3302,6 +3311,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" -@@ -3313,17 +3323,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" -@@ -3359,24 +3366,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/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 -@@ -321,6 +321,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) $(X_CFLAGS) $(T_CFLAGS) $(LOOSE_WARN) -Wold-style-definition $($@-warn) -isystem ./include $(TCFLAGS) - -+EGLIBC_CONFIGS = @EGLIBC_CONFIGS@ -+ - # --------------------------------------------------- - # Programs which produce files for the target machine - # --------------------------------------------------- -@@ -402,6 +404,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@ -@@ -688,7 +693,11 @@ CC_FOR_BUILD = @CC_FOR_BUILD@ - BUILD_CFLAGS= @BUILD_CFLAGS@ -DGENERATOR_FILE - - # Native linker and preprocessor flags. For x-fragment overrides. -+ifeq ($(host),$(build)) - BUILD_LDFLAGS=$(LDFLAGS) -+else -+BUILD_LDFLAGS= -+endif - BUILD_CPPFLAGS=$(ALL_CPPFLAGS) - - # Actual name to use when installing a native compiler. -@@ -1205,6 +1214,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 \ -@@ -1213,6 +1223,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 \ -@@ -1605,7 +1616,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 -@@ -1656,7 +1667,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 \ -@@ -1667,10 +1678,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 -@@ -1744,7 +1756,7 @@ gcc.srcextra: gengtype-lex.c - - c-incpath.o: c-incpath.c 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 \ -@@ -1874,7 +1886,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) \ -@@ -2091,6 +2104,9 @@ tree-ssa-pre.o : tree-ssa-pre.c $(TREE_F - $(TM_H) coretypes.h $(TREE_DUMP_H) tree-pass.h $(FLAGS_H) $(CFGLOOP_H) \ - alloc-pool.h $(BASIC_BLOCK_H) bitmap.h $(HASHTAB_H) $(TREE_GIMPLE_H) \ - $(TREE_INLINE_H) tree-iterator.h tree-ssa-sccvn.h $(PARAMS_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) - tree-ssa-sccvn.o : tree-ssa-sccvn.c $(TREE_FLOW_H) $(CONFIG_H) \ - $(SYSTEM_H) $(TREE_H) $(GGC_H) $(DIAGNOSTIC_H) $(TIMEVAR_H) \ - $(TM_H) coretypes.h $(TREE_DUMP_H) tree-pass.h $(FLAGS_H) $(CFGLOOP_H) \ -@@ -2190,6 +2206,9 @@ 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) $(BASIC_BLOCK_H) $(CFGLOOP_H) $(TIMEVAR_H) \ -+ $(TREE_DUMP_H) tree.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 \ -@@ -2759,7 +2778,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) -+ $(OBSTACK_H) $(TIMEVAR_H) tree-pass.h addresses.h $(DF_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 \ -@@ -3406,7 +3425,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. -@@ -3425,21 +3444,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 -@@ -4164,16 +4185,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 -@@ -1173,6 +1173,20 @@ check_main_parameter_types (tree decl) - pedwarn ("%q+D takes only zero or two arguments", decl); - } - -+/* True if pointers to distinct types T1 and T2 can be converted to -+ each other without an explicit cast. Only returns true for opaque -+ vector types. */ -+bool -+vector_targets_convertible_p (const_tree t1, const_tree t2) -+{ -+ if (TREE_CODE (t1) == VECTOR_TYPE && TREE_CODE (t2) == VECTOR_TYPE -+ && (targetm.vector_opaque_p (t1) || targetm.vector_opaque_p (t2)) -+ && tree_int_cst_equal (TYPE_SIZE (t1), TYPE_SIZE (t2))) -+ return true; -+ -+ return false; -+} -+ - /* True if vector types T1 and T2 can be converted to each other - without an explicit cast. If EMIT_LAX_NOTE is true, and T1 and T2 - can only be converted with -flax-vector-conversions yet that is not ---- a/gcc/c-common.h -+++ b/gcc/c-common.h -@@ -829,6 +829,7 @@ extern tree finish_label_address_expr (t - extern tree lookup_label (tree); - extern tree lookup_name (tree); - -+extern bool vector_targets_convertible_p (const_tree t1, const_tree t2); - extern bool vector_types_convertible_p (const_tree t1, const_tree t2, bool emit_lax_note); - - extern rtx c_expand_expr (tree, rtx, enum machine_mode, int, rtx *); ---- 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 e1; - - if (type == error_mark_node - || expr == error_mark_node -@@ -85,7 +86,8 @@ convert (tree type, tree expr) - - if (type == TREE_TYPE (expr)) - return expr; -- -+ if (e1 = targetm.convert_to_type (type, expr)) -+ return e1; - if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (expr))) - return fold_convert (type, expr); - if (TREE_CODE (TREE_TYPE (expr)) == ERROR_MARK) ---- a/gcc/c-decl.c -+++ b/gcc/c-decl.c -@@ -3995,6 +3995,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; -@@ -4513,6 +4514,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. */ -@@ -5039,6 +5046,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 -@@ -5082,6 +5090,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); - } ---- a/gcc/c-incpath.c -+++ b/gcc/c-incpath.c -@@ -30,6 +30,8 @@ - #include "intl.h" - #include "c-incpath.h" - #include "cppdefault.h" -+#include "flags.h" -+#include "toplev.h" - - /* Windows does not natively support inodes, and neither does MSDOS. - Cygwin's emulation can generate non-unique inodes, so don't use it. -@@ -37,15 +39,18 @@ - #ifdef VMS - # define INO_T_EQ(A, B) (!memcmp (&(A), &(B), sizeof (A))) - # define INO_T_COPY(DEST, SRC) memcpy(&(DEST), &(SRC), sizeof (SRC)) --#else --# if (defined _WIN32 && !defined (_UWIN)) || defined __MSDOS__ --# define INO_T_EQ(A, B) 0 --# else --# define INO_T_EQ(A, B) ((A) == (B)) --# endif -+#elif !((defined _WIN32 && !defined (_UWIN)) || defined __MSDOS__) -+# define INO_T_EQ(A, B) ((A) == (B)) - # define INO_T_COPY(DEST, SRC) (DEST) = (SRC) - #endif - -+#if defined INO_T_EQ -+#define DIRS_EQ(A, B) ((A)->dev == (B)->dev \ -+ && INO_T_EQ((A)->ino, (B)->ino)) -+#else -+#define DIRS_EQ(A, B) (!strcasecmp ((A)->name, (B)->name)) -+#endif -+ - static const char dir_separator_str[] = { DIR_SEPARATOR, 0 }; - - static void add_env_var_paths (const char *, int); -@@ -241,14 +246,15 @@ remove_duplicates (cpp_reader *pfile, st - "%s: not a directory", cur->name); - else - { -+#if defined (INO_T_COPY) - INO_T_COPY (cur->ino, st.st_ino); - cur->dev = st.st_dev; -+#endif - - /* Remove this one if it is in the system chain. */ - reason = REASON_DUP_SYS; - for (tmp = system; tmp; tmp = tmp->next) -- if (INO_T_EQ (tmp->ino, cur->ino) && tmp->dev == cur->dev -- && cur->construct == tmp->construct) -+ if (DIRS_EQ (tmp, cur) && cur->construct == tmp->construct) - break; - - if (!tmp) -@@ -256,16 +262,14 @@ remove_duplicates (cpp_reader *pfile, st - /* Duplicate of something earlier in the same chain? */ - reason = REASON_DUP; - for (tmp = head; tmp != cur; tmp = tmp->next) -- if (INO_T_EQ (cur->ino, tmp->ino) && cur->dev == tmp->dev -- && cur->construct == tmp->construct) -+ if (DIRS_EQ (cur, tmp) && cur->construct == tmp->construct) - break; - - if (tmp == cur - /* Last in the chain and duplicate of JOIN? */ - && !(cur->next == NULL && join -- && INO_T_EQ (cur->ino, join->ino) -- && cur->dev == join->dev -- && cur->construct == join->construct)) -+ && DIRS_EQ (cur, join) -+ && cur->construct == join->construct)) - { - /* Unique, so keep this directory. */ - pcur = &cur->next; -@@ -297,8 +301,8 @@ add_sysroot_to_chain (const char *sysroo - } - - /* Merge the four include chains together in the order quote, bracket, -- system, after. Remove duplicate dirs (as determined by -- INO_T_EQ()). -+ system, after. Remove duplicate dirs (determined in -+ system-specific manner). - - We can't just merge the lists and then uniquify them because then - we may lose directories from the <> search path that should be -@@ -352,6 +356,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/c-typeck.c -+++ b/gcc/c-typeck.c -@@ -1754,6 +1754,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); -@@ -1790,6 +1791,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); - -@@ -4196,10 +4201,7 @@ convert_for_assignment (tree type, tree - if (TREE_CODE (mvr) != ARRAY_TYPE) - mvr = TYPE_MAIN_VARIANT (mvr); - /* Opaque pointers are treated like void pointers. */ -- is_opaque_pointer = (targetm.vector_opaque_p (type) -- || targetm.vector_opaque_p (rhstype)) -- && TREE_CODE (ttl) == VECTOR_TYPE -- && TREE_CODE (ttr) == VECTOR_TYPE; -+ is_opaque_pointer = vector_targets_convertible_p (ttl, ttr); - - /* C++ does not allow the implicit conversion void* -> T*. However, - for the purpose of reducing the number of false positives, we ---- a/gcc/c.opt -+++ b/gcc/c.opt -@@ -697,6 +697,10 @@ fpreprocessed - C ObjC C++ ObjC++ - Treat the input file as already preprocessed - -+fremove-local-statics -+C Var(flag_remove_local_statics) -+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 -@@ -3834,7 +3834,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 -@@ -4133,8 +4133,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 -@@ -86,10 +86,6 @@ failed: - } - - --#ifndef LOCAL_ALIGNMENT --#define LOCAL_ALIGNMENT(TYPE, ALIGNMENT) ALIGNMENT --#endif -- - #ifndef STACK_ALIGNMENT_NEEDED - #define STACK_ALIGNMENT_NEEDED 1 - #endif -@@ -160,7 +156,7 @@ get_decl_align_unit (tree decl) - unsigned int align; - - align = DECL_ALIGN (decl); -- align = LOCAL_ALIGNMENT (TREE_TYPE (decl), align); -+ align = calculate_local_alignment (TREE_TYPE (decl), align); - if (align > PREFERRED_STACK_BOUNDARY) - align = PREFERRED_STACK_BOUNDARY; - if (cfun->stack_alignment_needed < align) ---- a/gcc/cgraph.c -+++ b/gcc/cgraph.c -@@ -205,9 +205,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; - } - return node; - } ---- a/gcc/cgraph.h -+++ b/gcc/cgraph.h -@@ -178,6 +178,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/collect2.c -+++ b/gcc/collect2.c -@@ -605,11 +605,7 @@ find_a_file (struct path_prefix *pprefix - - /* Determine the filename to execute (special case for absolute paths). */ - -- if (*name == '/' --#ifdef HAVE_DOS_BASED_FILE_SYSTEM -- || (*name && name[1] == ':') --#endif -- ) -+ if (IS_ABSOLUTE_PATH (name)) - { - if (access (name, X_OK) == 0) - { ---- a/gcc/combine.c -+++ b/gcc/combine.c -@@ -3989,14 +3989,18 @@ find_split_point (rtx *loc, rtx insn) - return &XEXP (XEXP (x, 0), 0); - } - -+#if 0 - /* If we have a PLUS whose first operand is complex, try computing it -- separately by making a split there. */ -+ separately by making a split there. -+ This causes non-canonical RTL to be created, at least on ARM. -+ See CSL issue #4085. */ - if (GET_CODE (XEXP (x, 0)) == PLUS - && ! memory_address_p (GET_MODE (x), XEXP (x, 0)) - && ! OBJECT_P (XEXP (XEXP (x, 0), 0)) - && ! (GET_CODE (XEXP (XEXP (x, 0), 0)) == SUBREG - && OBJECT_P (SUBREG_REG (XEXP (XEXP (x, 0), 0))))) - return &XEXP (XEXP (x, 0), 0); -+#endif - break; - - case SET: -@@ -5876,6 +5880,7 @@ simplify_set (rtx x) - zero_extend to avoid the reload that would otherwise be required. */ - - if (GET_CODE (src) == SUBREG && subreg_lowpart_p (src) -+ && GET_MODE_CLASS (GET_MODE (SUBREG_REG (src))) == MODE_INT - && LOAD_EXTEND_OP (GET_MODE (SUBREG_REG (src))) != UNKNOWN - && SUBREG_BYTE (src) == 0 - && (GET_MODE_SIZE (GET_MODE (src)) ---- a/gcc/common.opt -+++ b/gcc/common.opt -@@ -142,6 +142,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 -@@ -259,6 +263,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) - Align the start of functions -@@ -444,6 +454,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 -@@ -805,6 +819,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 - ---- a/gcc/config.gcc -+++ b/gcc/config.gcc -@@ -70,6 +70,10 @@ - # This helps to keep OS specific stuff out of the CPU - # defining header ${cpu_type}/${cpu_type.h}. - # -+# It is possible to include automatically-generated -+# build-directory files by prefixing them with "./". -+# All other files should relative to $srcdir/config. -+# - # tm_p_file Location of file with declarations for functions - # in $out_file. - # -@@ -751,32 +755,62 @@ arm*-*-linux*) # ARM GNU/Linux with EL - need_64bit_hwint=yes - # The EABI requires the use of __cxa_atexit. - default_use_cxa_atexit=yes -+ case ${target} in -+ arm-timesys-linux-gnueabi) -+ tmake_file="${tmake_file} arm/t-timesys" -+ tm_file="$tm_file ./sysroot-suffix.h" -+ tmake_file="$tmake_file t-sysroot-suffix" -+ ;; -+ arm-wrs-linux-gnueabi) -+ tm_file="$tm_file arm/wrs-linux.h" -+ tmake_file="$tmake_file arm/t-wrs-linux" -+ tm_defines="$tm_defines TARGET_FLEXLM" -+ ;; -+ arm-montavista*-linux-gnueabi) -+ tm_file="$tm_file arm/montavista-linux.h" -+ tmake_file="$tmake_file arm/t-montavista-linux" -+ ;; -+ *) -+ if test x$enable_extra_asa_multilibs = xyes; then -+ tmake_file="${tmake_file} arm/t-asa" -+ elif test x$enable_extra_sgxx_multilibs = xyes; then -+ tmake_file="${tmake_file} arm/t-cs-linux" -+ fi -+ tm_file="$tm_file ./sysroot-suffix.h" -+ tmake_file="$tmake_file t-sysroot-suffix" -+ ;; -+ esac - ;; - *) - tmake_file="$tmake_file arm/t-linux" - ;; - esac - tm_file="$tm_file arm/aout.h arm/arm.h" -+ tmake_file="${tmake_file} arm/t-arm-softfp soft-fp/t-softfp" - ;; - arm*-*-uclinux*) # ARM ucLinux -- tm_file="dbxelf.h elfos.h arm/unknown-elf.h arm/elf.h arm/linux-gas.h arm/uclinux-elf.h arm/uclinux-elf.h" -+ tm_file="dbxelf.h elfos.h arm/unknown-elf.h arm/elf.h arm/linux-gas.h arm/uclinux-elf.h" - tmake_file="arm/t-arm arm/t-arm-elf" - case ${target} in -- arm*-*-uclinux-*eabi) -+ arm*-*-uclinux*eabi) - tm_file="$tm_file arm/bpabi.h arm/uclinux-eabi.h" -- tmake_file="$tmake_file arm/t-bpabi" -+ tmake_file="$tmake_file arm/t-bpabi arm/t-uclinux-eabi" - # The BPABI long long divmod functions return a 128-bit value in - # registers r0-r3. Correctly modeling that requires the use of - # TImode. - need_64bit_hwint=yes - # The EABI requires the use of __cxa_atexit. - default_use_cxa_atexit=yes -+ tm_file="$tm_file ./sysroot-suffix.h" -+ tmake_file="$tmake_file t-sysroot-suffix" - esac -+ tmake_file="${tmake_file} arm/t-arm-softfp soft-fp/t-softfp" - tm_file="$tm_file arm/aout.h arm/arm.h" - ;; - arm*-*-ecos-elf) - tm_file="dbxelf.h elfos.h arm/unknown-elf.h arm/elf.h arm/aout.h arm/arm.h arm/ecos-elf.h" - tmake_file="arm/t-arm arm/t-arm-elf" -+ tmake_file="${tmake_file} arm/t-arm-softfp soft-fp/t-softfp" - ;; - arm*-*-eabi* | arm*-*-symbianelf* ) - # The BPABI long long divmod functions return a 128-bit value in -@@ -788,7 +822,11 @@ arm*-*-eabi* | arm*-*-symbianelf* ) - tmake_file="arm/t-arm arm/t-arm-elf" - case ${target} in - arm*-*-eabi*) -+ tm_file="${tm_file} arm/nocrt0.h" - tmake_file="${tmake_file} arm/t-bpabi" -+ if test x$enable_extra_sgxx_multilibs = xyes; then -+ tmake_file="${tmake_file} arm/t-cs-eabi" -+ fi - ;; - arm*-*-symbianelf*) - tm_file="${tm_file} arm/symbian.h" -@@ -798,14 +836,17 @@ arm*-*-eabi* | arm*-*-symbianelf* ) - ;; - esac - tm_file="${tm_file} arm/aout.h arm/arm.h" -+ tmake_file="${tmake_file} arm/t-arm-softfp soft-fp/t-softfp" - ;; - arm*-*-rtems*) - tm_file="dbxelf.h elfos.h arm/unknown-elf.h arm/elf.h arm/aout.h arm/arm.h arm/rtems-elf.h rtems.h" - tmake_file="arm/t-arm arm/t-arm-elf t-rtems arm/t-rtems" -+ tmake_file="${tmake_file} arm/t-arm-softfp soft-fp/t-softfp" - ;; - arm*-*-elf | ep9312-*-elf) - tm_file="dbxelf.h elfos.h arm/unknown-elf.h arm/elf.h arm/aout.h arm/arm.h" - tmake_file="arm/t-arm arm/t-arm-elf" -+ tmake_file="${tmake_file} arm/t-arm-softfp soft-fp/t-softfp" - ;; - arm*-wince-pe*) - tm_file="arm/semi.h arm/aout.h arm/arm.h arm/coff.h dbxcoff.h arm/pe.h arm/wince-pe.h" -@@ -822,6 +863,7 @@ arm-*-pe*) - arm*-*-kaos*) - tm_file="dbxelf.h elfos.h arm/unknown-elf.h arm/elf.h arm/aout.h arm/arm.h kaos.h arm/kaos-arm.h" - tmake_file="arm/t-arm arm/t-arm-elf" -+ tmake_file="${tmake_file} arm/t-arm-softfp soft-fp/t-softfp" - ;; - avr-*-rtems*) - tm_file="avr/avr.h dbxelf.h avr/rtems.h rtems.h" -@@ -1179,6 +1221,16 @@ i[34567]86-*-linux* | i[34567]86-*-kfree - else - tm_file="${tm_file} i386/linux.h" - fi -+ case ${target} in -+ *-wrs-linux*) -+ tm_defines="${tm_defines} TARGET_FLEXLM" -+ ;; -+ esac -+ if test x$enable_extra_sgxx_multilibs = xyes; then -+ tm_file="${tm_file} i386/cs-linux.h" -+ tmake_file="${tmake_file} i386/t-cs-linux" -+ extra_options="${extra_options} i386/cs-linux.opt" -+ fi - ;; - i[34567]86-*-knetbsd*-gnu) tm_file="${tm_file} i386/linux.h knetbsd-gnu.h i386/knetbsd-gnu.h" ;; - i[34567]86-*-kfreebsd*-gnu) tm_file="${tm_file} i386/linux.h kfreebsd-gnu.h i386/kfreebsd-gnu.h" ;; -@@ -1616,9 +1668,11 @@ m68k-*-linux*) # Motorola m68k's runnin - # aka the GNU/Linux C library 6. - default_m68k_cpu=68020 - default_cf_cpu=5475 -- tm_file="${tm_file} dbxelf.h elfos.h svr4.h linux.h m68k/linux.h" -+ with_arch=${with_arch:-m68k} -+ tm_file="${tm_file} dbxelf.h elfos.h svr4.h linux.h m68k/linux.h ./sysroot-suffix.h" - extra_options="${extra_options} m68k/ieee.opt" - tm_defines="${tm_defines} MOTOROLA=1" -+ tmake_file="${tmake_file} m68k/t-floatlib m68k/t-linux m68k/t-mlibs" - # if not configured with --enable-sjlj-exceptions, bump the - # libgcc version number - if test x$sjlj != x1; then -@@ -1646,7 +1700,7 @@ mcore-*-pe*) - mips-sgi-irix[56]*) - tm_file="elfos.h ${tm_file} mips/iris.h" - tmake_file="mips/t-iris mips/t-slibgcc-irix" -- target_cpu_default="MASK_ABICALLS" -+ tm_defines="${tm_defines} TARGET_ABICALLS_DEFAULT=1" - case ${target} in - *-*-irix5*) - tm_file="${tm_file} mips/iris5.h" -@@ -1672,31 +1726,77 @@ mips-sgi-irix[56]*) - use_fixproto=yes - ;; - mips*-*-netbsd*) # NetBSD/mips, either endian. -- target_cpu_default="MASK_ABICALLS" -+ tm_defines="${tm_defines} TARGET_ABICALLS_DEFAULT=1" - tm_file="elfos.h ${tm_file} mips/elf.h netbsd.h netbsd-elf.h mips/netbsd.h" - ;; - mips64*-*-linux*) - tm_file="dbxelf.h elfos.h svr4.h linux.h ${tm_file} mips/linux.h mips/linux64.h" -+ tm_defines="${tm_defines} TARGET_ABICALLS_DEFAULT=1" - tmake_file="${tmake_file} mips/t-linux64" -- tm_defines="${tm_defines} MIPS_ABI_DEFAULT=ABI_N32" -+ if test x${enable_mips_nonpic}; then -+ tm_defines="${tm_defines} TARGET_ABICALLS_NONPIC=1" -+ fi -+ case "$with_abi" in -+ "" | "n32" ) -+ tm_defines="${tm_defines} MIPS_ABI_DEFAULT=ABI_N32" -+ ;; -+ 64 ) -+ tm_defines="${tm_defines} MIPS_ABI_DEFAULT=ABI_64" -+ ;; -+ *) -+ echo "Unknown ABI used in --with-abi=$with_abi" -+ exit 1 -+ ;; -+ esac -+ case ${target} in -+ mips64el-sicortex-linux-gnu) -+ tm_file="${tm_file} mips/sicortex.h" -+ tmake_file="${tmake_file} mips/t-sicortex" -+ ;; -+ esac -+ tmake_file="$tmake_file mips/t-crtfm" - gnu_ld=yes - gas=yes - test x$with_llsc != x || with_llsc=yes - ;; - mips*-*-linux*) # Linux MIPS, either endian. - tm_file="dbxelf.h elfos.h svr4.h linux.h ${tm_file} mips/linux.h" -+ tm_defines="${tm_defines} TARGET_ABICALLS_DEFAULT=1" -+ if test x${enable_mips_nonpic}; then -+ tm_defines="${tm_defines} TARGET_ABICALLS_NONPIC=1" -+ fi - case ${target} in - mipsisa32r2*) - tm_defines="${tm_defines} MIPS_ISA_DEFAULT=33" - ;; - mipsisa32*) - tm_defines="${tm_defines} MIPS_ISA_DEFAULT=32" -+ ;; -+ mips-wrs-linux-gnu) -+ tmake_file="$tmake_file mips/t-linux64 mips/t-wrs-linux" -+ tm_file="$tm_file mips/linux64.h mips/octeon.h mips/wrs-linux.h" -+ tm_defines="$tm_defines TARGET_FLEXLM" -+ ;; -+ mips-montavista*-linux-gnu) -+ tmake_file="$tmake_file mips/t-linux64 mips/t-montavista-linux" -+ tm_file="$tm_file mips/linux64.h mips/octeon.h mips/montavista-linux.h" -+ ;; -+ *) -+ if test x$enable_extra_sgxx_multilibs = xyes; then -+ tmake_file="$tmake_file mips/t-sgxx-linux" -+ tm_file="$tm_file mips/cs-sgxx-linux.h" -+ elif test x$enable_extra_sgxxlite_multilibs = xyes; then -+ tmake_file="$tmake_file mips/t-sgxxlite-linux" -+ tm_file="$tm_file mips/cs-sgxxlite-linux.h" -+ fi -+ ;; - esac - test x$with_llsc != x || with_llsc=yes -+ tmake_file="$tmake_file mips/t-crtfm" - ;; - mips*-*-openbsd*) - tm_defines="${tm_defines} OBSD_HAS_DECLARE_FUNCTION_NAME OBSD_HAS_DECLARE_OBJECT OBSD_HAS_CORRECT_SPECS" -- target_cpu_default="MASK_ABICALLS" -+ tm_defines="${tm_defines} TARGET_ABICALLS_DEFAULT=1" - tm_file="mips/mips.h openbsd.h mips/openbsd.h mips/sdb.h" - case ${target} in - mips*el-*-openbsd*) -@@ -1707,15 +1807,15 @@ mips*-*-openbsd*) - mips*-sde-elf*) - tm_file="elfos.h ${tm_file} mips/elf.h mips/sde.h" - tmake_file="mips/t-sde mips/t-libgcc-mips16" -+ tm_file="$tm_file mips/sdemtk.h" -+ extra_options="$extra_options mips/sdemtk.opt" - case "${with_newlib}" in - yes) -- # newlib / libgloss. -+ # newlib -+ # FIXME: threading? - ;; - *) -- # MIPS toolkit libraries. -- tm_file="$tm_file mips/sdemtk.h" -- tmake_file="$tmake_file mips/t-sdemtk" -- extra_options="$extra_options mips/sdemtk.opt" -+ tmake_file="$tmake_file mips/t-sdelib" - case ${enable_threads} in - "" | yes | mipssde) - thread_file='mipssde' -@@ -1734,6 +1834,23 @@ mips*-sde-elf*) - tm_defines="MIPS_ISA_DEFAULT=64 MIPS_ABI_DEFAULT=ABI_N32" - ;; - esac -+ if [ "$enable_sgxx_sde_multilibs" = "yes" ]; then -+ tmake_file="$tmake_file mips/t-sgxx-sde" -+ # SourceryG++ is configured --with-arch=mips32r2. -+ tm_defines="MIPS_ISA_DEFAULT=33 MIPS_ABI_DEFAULT=ABI_32" -+ fi -+ ;; -+mips64octeon*-wrs-elf*) -+ tm_file="elfos.h ${tm_file} mips/elf.h mips/octeon.h mips/octeon-elf.h" -+ tmake_file=mips/t-octeon-elf -+ tm_defines="MIPS_ABI_DEFAULT=ABI_EABI MIPS_CPU_STRING_DEFAULT=\\\"octeon\\\" TARGET_FLEXLM" -+ default_use_cxa_atexit=no -+ ;; -+mips64octeon*-montavista-elf*) -+ tm_file="elfos.h ${tm_file} mips/elf.h mips/octeon.h mips/octeon-elf.h" -+ tmake_file="mips/t-octeon-elf mips/t-montavista-elf" -+ tm_defines="MIPS_ABI_DEFAULT=ABI_EABI MIPS_CPU_STRING_DEFAULT=\\\"octeon\\\"" -+ default_use_cxa_atexit=no - ;; - mipsisa32-*-elf* | mipsisa32el-*-elf* | \ - mipsisa32r2-*-elf* | mipsisa32r2el-*-elf* | \ -@@ -1767,10 +1884,11 @@ mipsisa64-*-elf* | mipsisa64el-*-elf*) - ;; - mipsisa64sr71k-*-elf*) - tm_file="elfos.h ${tm_file} mips/elf.h" -- tmake_file=mips/t-sr71k -+ tmake_file="mips/t-sr71k" - target_cpu_default="MASK_64BIT|MASK_FLOAT64" - tm_defines="${tm_defines} MIPS_ISA_DEFAULT=64 MIPS_CPU_STRING_DEFAULT=\\\"sr71000\\\" MIPS_ABI_DEFAULT=ABI_EABI" - use_fixproto=yes -+ tmake_file="$tmake_file" - ;; - mipsisa64sb1-*-elf* | mipsisa64sb1el-*-elf*) - tm_file="elfos.h ${tm_file} mips/elf.h" -@@ -1793,7 +1911,7 @@ mips64-*-elf* | mips64el-*-elf*) - ;; - mips64vr-*-elf* | mips64vrel-*-elf*) - tm_file="mips/vr.h elfos.h ${tm_file} mips/elf.h" -- tmake_file=mips/t-vr -+ tmake_file="mips/t-vr" - use_fixproto=yes - ;; - mips64orion-*-elf* | mips64orionel-*-elf*) -@@ -1926,15 +2044,18 @@ powerpc-*-eabisimaltivec*) - tmake_file="rs6000/t-fprules rs6000/t-fprules-fpbit rs6000/t-ppcendian rs6000/t-ppccomm" - ;; - powerpc-*-eabisim*) -- tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/eabi.h rs6000/e500.h rs6000/eabisim.h" -+ tm_file="${tm_file} dbxelf.h elfos.h usegas.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/eabi.h rs6000/e500.h rs6000/eabisim.h" - extra_options="${extra_options} rs6000/sysv4.opt" - tmake_file="rs6000/t-fprules rs6000/t-fprules-fpbit rs6000/t-ppcgas rs6000/t-ppccomm" - ;; - powerpc-*-elf*) -- tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h" -+ 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" -- use_fixproto=yes -+ 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" -@@ -1942,9 +2063,12 @@ powerpc-*-eabialtivec*) - tmake_file="rs6000/t-fprules rs6000/t-fprules-fpbit rs6000/t-ppcendian rs6000/t-ppccomm" - ;; - powerpc-*-eabi*) -- tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/eabi.h rs6000/e500.h" -+ tm_file="${tm_file} dbxelf.h elfos.h usegas.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/eabi.h rs6000/e500.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_extra_sgxx_multilibs = xyes; then -+ tmake_file="${tmake_file} rs6000/t-cs-eabi" -+ fi - ;; - powerpc-*-rtems*) - tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/eabi.h rs6000/e500.h rs6000/rtems.h rtems.h" -@@ -1959,7 +2083,7 @@ powerpc-*-linux*altivec*) - powerpc-*-linux*spe*) - tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/linux.h rs6000/linuxspe.h rs6000/e500.h" - extra_options="${extra_options} rs6000/sysv4.opt" -- tmake_file="rs6000/t-fprules rs6000/t-fprules-softfp soft-fp/t-softfp rs6000/t-ppcos ${tmake_file} rs6000/t-ppccomm" -+ tmake_file="t-dfprules rs6000/t-fprules rs6000/t-fprules-softfp soft-fp/t-softfp rs6000/t-ppcos ${tmake_file} rs6000/t-ppccomm" - ;; - powerpc-*-linux*paired*) - tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/linux.h rs6000/750cl.h" -@@ -1980,12 +2104,28 @@ powerpc-*-linux*) - extra_options="${extra_options} rs6000/linux64.opt" - ;; - *) -- tm_file="${tm_file} rs6000/linux.h" -+ tm_file="${tm_file} rs6000/linux.h rs6000/e500.h" -+ tmake_file="$tmake_file rs6000/t-linux" - ;; - esac - if test x${enable_secureplt} = xyes; then - tm_file="rs6000/secureplt.h ${tm_file}" - fi -+ case ${target} in -+ powerpc-wrs-linux-gnu) -+ tm_file="$tm_file rs6000/wrs-linux.h rs6000/e500.h" -+ tmake_file="$tmake_file rs6000/t-wrs-linux" -+ tm_defines="$tm_defines TARGET_FLEXLM" -+ ;; -+ powerpc-montavista*-linux-gnu) -+ tm_file="$tm_file rs6000/montavista-linux.h" -+ tmake_file="$tmake_file rs6000/t-montavista-linux" -+ ;; -+ powerpc-timesys-linux-gnu*) -+ tmake_file="${tmake_file} rs6000/t-timesys" -+ tm_file="${tm_file} rs6000/timesys-linux.h" -+ ;; -+ esac - ;; - powerpc-*-gnu-gnualtivec*) - tm_file="${cpu_type}/${cpu_type}.h elfos.h svr4.h freebsd-spec.h gnu.h rs6000/sysv4.h rs6000/linux.h rs6000/linuxaltivec.h rs6000/gnu.h" -@@ -2019,7 +2159,7 @@ powerpc-wrs-vxworks|powerpc-wrs-vxworksa - esac - ;; - powerpc-wrs-windiss*) # Instruction-level simulator for VxWorks. -- tm_file="${tm_file} elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/windiss.h" -+ tm_file="${tm_file} elfos.h usegas.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/windiss.h" - tmake_file="rs6000/t-fprules rs6000/t-fprules-fpbit rs6000/t-ppcgas rs6000/t-ppccomm" - extra_options="${extra_options} rs6000/sysv4.opt" - thread_file="" -@@ -2043,28 +2183,28 @@ powerpcle-*-sysv*) - use_fixproto=yes - ;; - powerpcle-*-elf*) -- tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/sysv4le.h" -+ tm_file="${tm_file} dbxelf.h elfos.h usegas.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/sysv4le.h" - tmake_file="rs6000/t-fprules rs6000/t-fprules-fpbit rs6000/t-ppcgas rs6000/t-ppccomm" - extra_options="${extra_options} rs6000/sysv4.opt" - use_fixproto=yes - ;; - powerpcle-*-eabisim*) -- tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/sysv4le.h rs6000/eabi.h rs6000/e500.h rs6000/eabisim.h" -+ tm_file="${tm_file} dbxelf.h elfos.h usegas.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/sysv4le.h rs6000/eabi.h rs6000/e500.h rs6000/eabisim.h" - tmake_file="rs6000/t-fprules rs6000/t-fprules-fpbit rs6000/t-ppcgas rs6000/t-ppccomm" - extra_options="${extra_options} rs6000/sysv4.opt" - ;; - powerpcle-*-eabi*) -- tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/sysv4le.h rs6000/eabi.h rs6000/e500.h" -+ tm_file="${tm_file} dbxelf.h elfos.h usegas.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/sysv4le.h rs6000/eabi.h rs6000/e500.h" - tmake_file="rs6000/t-fprules rs6000/t-fprules-fpbit rs6000/t-ppcgas rs6000/t-ppccomm" - extra_options="${extra_options} rs6000/sysv4.opt" - ;; - powerpc-*-kaos*) -- tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h kaos.h rs6000/kaos-ppc.h" -+ tm_file="${tm_file} dbxelf.h elfos.h usegas.h svr4.h freebsd-spec.h rs6000/sysv4.h kaos.h rs6000/kaos-ppc.h" - tmake_file="rs6000/t-fprules rs6000/t-fprules-fpbit rs6000/t-ppcgas rs6000/t-ppccomm" - extra_options="${extra_options} rs6000/sysv4.opt" - ;; - powerpcle-*-kaos*) -- tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/sysv4le.h kaos.h rs6000/kaos-ppc.h" -+ tm_file="${tm_file} dbxelf.h elfos.h usegas.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/sysv4le.h kaos.h rs6000/kaos-ppc.h" - tmake_file="rs6000/t-fprules rs6000/t-fprules-fpbit rs6000/t-ppcgas rs6000/t-ppccomm" - extra_options="${extra_options} rs6000/sysv4.opt" - ;; -@@ -2162,8 +2302,10 @@ sh-*-symbianelf* | sh[12346l]*-*-symbian - esac - fi - 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 -@@ -2288,29 +2430,40 @@ 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="${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="${TM_MULTILIB_EXCEPTIONS_CONFIG} ${sh_multilib#!}" ;; -+ none) ;; - *) - echo "with_multilib_list=${sh_multilib} not supported." - exit 1 - ;; - esac - done -+ TM_MULTILIB_CONFIG=${TM_MULTILIB_CONFIG#/} - 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 -+ if test x$enable_extra_sgxxlite_multilibs = xyes \ -+ || test x$enable_extra_sgxx_multilibs = xyes; then -+ # SG++ and Lite do not differ, as yet, so use the Lite files for both -+ tm_file="$tm_file sh/cs-sgxxlite-linux.h" -+ tmake_file="$tmake_file sh/t-sgxxlite-linux" -+ fi -+ tm_file="$tm_file ./sysroot-suffix.h" -+ tmake_file="$tmake_file t-sysroot-suffix" - ;; - sh-*-rtems*) - tmake_file="sh/t-sh sh/t-elf t-rtems sh/t-rtems" -@@ -2340,6 +2493,13 @@ sparc-*-elf*) - extra_parts="crti.o crtn.o crtbegin.o crtend.o" - use_fixproto=yes - ;; -+sparc-wrs-linux*) -+ tm_file="sparc/biarch64.h ${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sparc/linux64.h" -+ extra_options="${extra_options} sparc/long-double-switch.opt" -+ tmake_file="${tmake_file} sparc/t-linux sparc/t-linux64 sparc/t-crtfm" -+ tm_defines="${tm_defines} BIARCH_32BIT_DEFAULT TARGET_FLEXLM" -+ need_64bit_hwint=yes -+ ;; - sparc-*-linux*) # SPARC's running GNU/Linux, libc6 - tm_file="${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sparc/linux.h" - extra_options="${extra_options} sparc/long-double-switch.opt" -@@ -2882,7 +3042,8 @@ case "${target}" in - "" \ - | armv[23456] | armv2a | armv3m | armv4t | armv5t \ - | armv5te | armv6j |armv6k | armv6z | armv6zk \ -- | iwmmxt | ep9312) -+ | armv6-m | armv7-a | armv7-r | armv7-m \ -+ | iwmmxt | ep9312 | marvell-f ) - # OK - ;; - *) -@@ -3017,8 +3178,8 @@ case "${target}" in - ;; - - i[34567]86-*-* | x86_64-*-*) -- supported_defaults="arch cpu tune" -- for which in arch cpu tune; do -+ supported_defaults="arch arch32 arch64 cpu tune" -+ for which in arch arch32 arch64 cpu tune; do - eval "val=\$with_$which" - case ${val} in - i386 | i486 \ -@@ -3029,8 +3190,10 @@ case "${target}" in - | prescott | pentium-m | pentium4m | pentium3m) - case "${target}" in - x86_64-*-*) -- echo "CPU given in --with-$which=$val doesn't support 64bit mode." 1>&2 -- exit 1 -+ if [ "x$which" != "xarch32" ]; then -+ echo "CPU given in --with-$which=$val doesn't support 64bit mode." 1>&2 -+ exit 1 -+ fi - ;; - esac - # OK -@@ -3047,7 +3210,7 @@ case "${target}" in - ;; - - mips*-*-*) -- supported_defaults="abi arch float tune divide llsc" -+ supported_defaults="abi arch arch32 arch64 float tune tune32 tune64 divide llsc" - - case ${with_float} in - "" | soft | hard) -@@ -3079,6 +3242,21 @@ case "${target}" in - ;; - esac - -+ for fix in ice9a; do -+ supported_defaults="$supported_defaults fix-$fix" -+ eval "val=\$with_fix_$fix" -+ case $val in -+ "" | off) -+ eval "\$with_fix_$fix=" -+ ;; -+ on) -+ ;; -+ *) -+ echo "Unknown argument to --with-fix-$fix: $val" -+ ;; -+ esac -+ done -+ - case ${with_llsc} in - yes) - with_llsc=llsc -@@ -3116,9 +3294,9 @@ case "${target}" in - ;; - - powerpc*-*-* | rs6000-*-*) -- supported_defaults="cpu float tune" -+ supported_defaults="cpu cpu32 cpu64 float tune" - -- for which in cpu tune; do -+ for which in cpu cpu32 cpu64 tune; do - eval "val=\$with_$which" - case ${val} in - default32 | default64) -@@ -3134,8 +3312,8 @@ case "${target}" in - | rios | rios1 | rios2 | rsc | rsc1 | rs64a \ - | 401 | 403 | 405 | 405fp | 440 | 440fp | 505 \ - | 601 | 602 | 603 | 603e | ec603e | 604 \ -- | 604e | 620 | 630 | 740 | 750 | 7400 | 7450 \ -- | 854[08] | 801 | 821 | 823 | 860 | 970 | G3 | G4 | G5 | cell) -+ | 604e | 620 | 630 | 740 | 750 | 7400 | 7450 |e300c[23] \ -+ | 854[08] | e500mc | 801 | 821 | 823 | 860 | 970 | G3 | G4 | G5 | cell) - # OK - ;; - *) -@@ -3356,11 +3534,28 @@ case ${target} in - ;; - esac - -+case ${target} in -+ *-eglibc-*-*) -+ tmake_file="${tmake_file} t-eglibc" -+ -+ case ${target} in -+ arm-*) -+ # ARM already includes below. -+ ;; -+ *) -+ tmake_file="${tmake_file} t-sysroot-suffix" -+ tm_file="${tm_file} ./sysroot-suffix.h" -+ ;; -+ esac -+ ;; -+esac -+ - t= --all_defaults="abi cpu arch tune schedule float mode fpu divide llsc" -+all_defaults="abi cpu cpu32 cpu64 arch arch32 arch64 tune tune32 tune64 schedule float mode fpu divide fix-ice9a llsc" - for option in $all_defaults - do -- eval "val=\$with_$option" -+ underscoreoption=`echo $option | sed -e s/-/_/g` -+ eval "val=\$with_$underscoreoption" - if test -n "$val"; then - case " $supported_defaults " in - *" $option "*) ---- a/gcc/config.in -+++ b/gcc/config.in -@@ -100,6 +100,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. */ -@@ -1369,37 +1375,37 @@ - #endif - - --/* The size of `int', as computed by sizeof. */ -+/* The size of a `int', as computed by sizeof. */ - #ifndef USED_FOR_TARGET - #undef SIZEOF_INT - #endif - - --/* The size of `long', as computed by sizeof. */ -+/* The size of a `long', as computed by sizeof. */ - #ifndef USED_FOR_TARGET - #undef SIZEOF_LONG - #endif - - --/* The size of `long long', as computed by sizeof. */ -+/* The size of a `long long', as computed by sizeof. */ - #ifndef USED_FOR_TARGET - #undef SIZEOF_LONG_LONG - #endif - - --/* The size of `short', as computed by sizeof. */ -+/* The size of a `short', as computed by sizeof. */ - #ifndef USED_FOR_TARGET - #undef SIZEOF_SHORT - #endif - - --/* The size of `void *', as computed by sizeof. */ -+/* The size of a `void *', as computed by sizeof. */ - #ifndef USED_FOR_TARGET - #undef SIZEOF_VOID_P - #endif - - --/* The size of `__int64', as computed by sizeof. */ -+/* The size of a `__int64', as computed by sizeof. */ - #ifndef USED_FOR_TARGET - #undef SIZEOF___INT64 - #endif ---- a/gcc/config/arm/aout.h -+++ b/gcc/config/arm/aout.h -@@ -191,9 +191,6 @@ - } - #endif - --/* Arm Assembler barfs on dollars. */ --#define DOLLARS_IN_IDENTIFIERS 0 -- - #ifndef NO_DOLLAR_IN_LABEL - #define NO_DOLLAR_IN_LABEL 1 - #endif ---- a/gcc/config/arm/arm-cores.def -+++ b/gcc/config/arm/arm-cores.def -@@ -102,6 +102,8 @@ ARM_CORE("arm1020e", arm1020e, 5TE, - ARM_CORE("arm1022e", arm1022e, 5TE, FL_LDSCHED, fastmul) - 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_MARVELL_F | FL_VFPV2, 9e) - - /* V5TEJ Architecture Processors */ - ARM_CORE("arm926ej-s", arm926ejs, 5TEJ, FL_LDSCHED, 9e) -@@ -115,6 +117,12 @@ 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-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 -@@ -24,6 +24,7 @@ - #define GCC_ARM_PROTOS_H - - extern void arm_override_options (void); -+extern void arm_optimization_options (int, int); - extern int use_return_insn (int, rtx); - extern int arm_regno_class (int); - extern void arm_load_pic_register (unsigned long); -@@ -42,9 +43,6 @@ extern unsigned int arm_dbx_register_num - 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); -@@ -90,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); -@@ -125,6 +123,7 @@ extern const char *fp_immediate_constant - extern void arm_emit_call_insn (rtx, rtx); - extern const char *output_call (rtx *); - extern const char *output_call_mem (rtx *); -+void arm_emit_movpair (rtx, rtx); - extern const char *output_mov_long_double_fpa_from_arm (rtx *); - extern const char *output_mov_long_double_arm_from_fpa (rtx *); - extern const char *output_mov_long_double_arm_from_arm (rtx *); -@@ -145,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); -@@ -155,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 */ - -@@ -208,6 +210,7 @@ extern void arm_pr_no_long_calls (struct - extern void arm_pr_long_calls_off (struct cpp_reader *); - - extern void arm_lang_object_attributes_init(void); -+extern void arm_adjust_reg_alloc_order (int *); - - extern const char *arm_mangle_type (const_tree); - ---- 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,arm926ejs,arm1026ejs,arm1136js,arm1136jfs,arm1176jzs,arm1176jzfs,mpcorenovfp,mpcore,arm1156t2s,cortexa8,cortexr4,cortexm3" -+ "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,cortexa8,cortexa9,cortexr4,cortexr4f,cortexm3,cortexm1,cortexm0" - (const (symbol_ref "arm_tune"))) ---- a/gcc/config/arm/arm.c -+++ b/gcc/config/arm/arm.c -@@ -1,6 +1,6 @@ - /* Output routines for GCC for ARM. - Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, -- 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. -+ 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. - Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl) - and Martin Simmons (@harleqn.co.uk). - More major hacks by Richard Earnshaw (rearnsha@arm.com). -@@ -42,6 +42,7 @@ - #include "optabs.h" - #include "toplev.h" - #include "recog.h" -+#include "cgraph.h" - #include "ggc.h" - #include "except.h" - #include "c-pragma.h" -@@ -52,6 +53,7 @@ - #include "debug.h" - #include "langhooks.h" - #include "df.h" -+#include "intl.h" - - /* Forward definitions of types. */ - typedef struct minipool_node Mnode; -@@ -62,6 +64,7 @@ const struct attribute_spec arm_attribut - void (*arm_lang_output_object_attributes_hook)(void); - - /* Forward function declarations. */ -+static int arm_compute_static_chain_stack_bytes (void); - static arm_stack_offsets *arm_get_frame_offsets (void); - static void arm_add_gc_roots (void); - static int arm_gen_constant (enum rtx_code, enum machine_mode, rtx, -@@ -74,7 +77,6 @@ static int thumb1_base_register_rtx_p (r - inline static int thumb1_index_register_rtx_p (rtx, int); - static int thumb_far_jump_used_p (void); - static bool thumb_force_lr_save (void); --static unsigned long thumb1_compute_save_reg_mask (void); - static int const_ok_for_op (HOST_WIDE_INT, enum rtx_code); - static rtx emit_sfm (int, int); - static unsigned arm_size_return_regs (void); -@@ -109,6 +111,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 *); -@@ -122,15 +125,20 @@ 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); --static int arm_rtx_costs_1 (rtx, enum rtx_code, enum rtx_code); -+static bool arm_rtx_costs_1 (rtx, enum rtx_code, int*); - static bool arm_size_rtx_costs (rtx, int, int, int *); --static bool arm_slowmul_rtx_costs (rtx, int, int, int *); --static bool arm_fastmul_rtx_costs (rtx, int, int, int *); --static bool arm_xscale_rtx_costs (rtx, int, int, int *); --static bool arm_9e_rtx_costs (rtx, int, int, int *); -+static bool arm_slowmul_rtx_costs (rtx, enum rtx_code, enum rtx_code, int *); -+static bool arm_fastmul_rtx_costs (rtx, enum rtx_code, enum rtx_code, int *); -+static bool arm_xscale_rtx_costs (rtx, enum rtx_code, enum rtx_code, int *); -+static bool arm_9e_rtx_costs (rtx, enum rtx_code, enum rtx_code, int *); -+static bool arm_rtx_costs (rtx, int, int, int *); - static int arm_address_cost (rtx); - static bool arm_memory_load_p (rtx); - static bool arm_cirrus_insn_p (rtx); -@@ -146,6 +154,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; -@@ -167,11 +178,13 @@ static bool arm_default_short_enums (voi - static bool arm_align_anon_bitfield (void); - static bool arm_return_in_msb (const_tree); - static bool arm_must_pass_in_stack (enum machine_mode, const_tree); -+static bool arm_return_in_memory (const_tree, const_tree); - #ifdef TARGET_UNWIND_INFO - 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); -@@ -183,12 +196,22 @@ static void arm_cxx_determine_class_data - static bool arm_cxx_class_data_always_comdat (void); - static bool arm_cxx_use_aeabi_atexit (void); - static void arm_init_libfuncs (void); -+static tree arm_build_builtin_va_list (void); -+static void arm_expand_builtin_va_start (tree, rtx); -+static tree arm_gimplify_va_arg_expr (tree, tree, tree *, tree *); - static bool arm_handle_option (size_t, const char *, int); - static void arm_target_help (void); - static unsigned HOST_WIDE_INT arm_shift_truncation_mask (enum machine_mode); - static bool arm_cannot_copy_insn_p (rtx); - static bool arm_tls_symbol_p (rtx x); - static void arm_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED; -+static bool arm_allocate_stack_slots_for_args (void); -+static int arm_issue_rate (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); - - - /* Initialize the GCC target structure. */ -@@ -248,14 +271,19 @@ static void arm_output_dwarf_dtprel (FIL - #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 - #define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall - --/* This will be overridden in arm_override_options. */ - #undef TARGET_RTX_COSTS --#define TARGET_RTX_COSTS arm_slowmul_rtx_costs -+#define TARGET_RTX_COSTS arm_rtx_costs - #undef TARGET_ADDRESS_COST - #define TARGET_ADDRESS_COST arm_address_cost - -@@ -289,6 +317,9 @@ static void arm_output_dwarf_dtprel (FIL - #undef TARGET_SETUP_INCOMING_VARARGS - #define TARGET_SETUP_INCOMING_VARARGS arm_setup_incoming_varargs - -+#undef TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS -+#define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS arm_allocate_stack_slots_for_args -+ - #undef TARGET_DEFAULT_SHORT_ENUMS - #define TARGET_DEFAULT_SHORT_ENUMS arm_default_short_enums - -@@ -329,6 +360,9 @@ static void arm_output_dwarf_dtprel (FIL - #undef TARGET_RETURN_IN_MSB - #define TARGET_RETURN_IN_MSB arm_return_in_msb - -+#undef TARGET_RETURN_IN_MEMORY -+#define TARGET_RETURN_IN_MEMORY arm_return_in_memory -+ - #undef TARGET_MUST_PASS_IN_STACK - #define TARGET_MUST_PASS_IN_STACK arm_must_pass_in_stack - -@@ -347,6 +381,9 @@ static void arm_output_dwarf_dtprel (FIL - #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 - -@@ -355,17 +392,54 @@ static void arm_output_dwarf_dtprel (FIL - #define TARGET_HAVE_TLS true - #endif - -+#undef TARGET_ADJUST_REG_ALLOC_ORDER -+#define TARGET_ADJUST_REG_ALLOC_ORDER arm_adjust_reg_alloc_order -+ - #undef TARGET_CANNOT_FORCE_CONST_MEM - #define TARGET_CANNOT_FORCE_CONST_MEM arm_cannot_force_const_mem - - #undef TARGET_MANGLE_TYPE - #define TARGET_MANGLE_TYPE arm_mangle_type - -+#undef TARGET_BUILD_BUILTIN_VA_LIST -+#define TARGET_BUILD_BUILTIN_VA_LIST arm_build_builtin_va_list -+#undef TARGET_EXPAND_BUILTIN_VA_START -+#define TARGET_EXPAND_BUILTIN_VA_START arm_expand_builtin_va_start -+#undef TARGET_GIMPLIFY_VA_ARG_EXPR -+#define TARGET_GIMPLIFY_VA_ARG_EXPR arm_gimplify_va_arg_expr -+ - #ifdef HAVE_AS_TLS - #undef TARGET_ASM_OUTPUT_DWARF_DTPREL - #define TARGET_ASM_OUTPUT_DWARF_DTPREL arm_output_dwarf_dtprel - #endif - -+#undef TARGET_MAX_ANCHOR_OFFSET -+#define TARGET_MAX_ANCHOR_OFFSET 4095 -+ -+/* The minimum is set such that the total size of the block -+ for a particular anchor is -4088 + 1 + 4095 bytes, which is -+ divisible by eight, ensuring natural spacing of anchors. */ -+#undef TARGET_MIN_ANCHOR_OFFSET -+#define TARGET_MIN_ANCHOR_OFFSET -4088 -+ -+#undef TARGET_SCHED_ISSUE_RATE -+#define TARGET_SCHED_ISSUE_RATE arm_issue_rate -+ -+#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 -+ - struct gcc_target targetm = TARGET_INITIALIZER; - - /* Obstack for minipool constant handling. */ -@@ -403,6 +477,9 @@ enum fputype arm_fpu_tune; - /* 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; - -@@ -441,9 +518,18 @@ 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_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) -@@ -460,6 +546,7 @@ static int thumb_call_reg_needed; - #define FL_FOR_ARCH6Z FL_FOR_ARCH6 - #define FL_FOR_ARCH6ZK FL_FOR_ARCH6K - #define FL_FOR_ARCH6T2 (FL_FOR_ARCH6 | FL_THUMB2) -+#define FL_FOR_ARCH6M (FL_FOR_ARCH6 & ~FL_NOTM) - #define FL_FOR_ARCH7 (FL_FOR_ARCH6T2 &~ FL_NOTM) - #define FL_FOR_ARCH7A (FL_FOR_ARCH7 | FL_NOTM) - #define FL_FOR_ARCH7R (FL_FOR_ARCH7A | FL_DIV) -@@ -518,13 +605,22 @@ 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; - -+/* Nonzero if tuning for Cortex-A9. */ -+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 -@@ -557,6 +653,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. */ -@@ -593,7 +691,7 @@ struct processors - enum processor_type core; - const char *arch; - const unsigned long flags; -- bool (* rtx_costs) (rtx, int, int, int *); -+ bool (* rtx_costs) (rtx, enum rtx_code, enum rtx_code, int *); - }; - - /* Not all of these give usefully different compilation alternatives, -@@ -632,12 +730,14 @@ static const struct processors all_archi - {"armv6z", arm1176jzs, "6Z", FL_CO_PROC | FL_FOR_ARCH6Z, NULL}, - {"armv6zk", arm1176jzs, "6ZK", FL_CO_PROC | FL_FOR_ARCH6ZK, NULL}, - {"armv6t2", arm1156t2s, "6T2", FL_CO_PROC | FL_FOR_ARCH6T2, NULL}, -+ {"armv6-m", cortexm1, "6M", FL_FOR_ARCH6M, NULL}, - {"armv7", cortexa8, "7", FL_CO_PROC | FL_FOR_ARCH7, NULL}, - {"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}, - {"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}, - {NULL, arm_none, NULL, 0 , NULL} - }; - -@@ -667,7 +767,8 @@ 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__"; -+#define ARM_ARCH_NAME_SIZE 25 -+char arm_arch_name[ARM_ARCH_NAME_SIZE] = "__ARM_ARCH_0UNK__"; - - struct fpu_desc - { -@@ -680,13 +781,16 @@ struct fpu_desc - - static const struct fpu_desc all_fpus[] = - { -- {"fpa", FPUTYPE_FPA}, -- {"fpe2", FPUTYPE_FPA_EMU2}, -- {"fpe3", FPUTYPE_FPA_EMU2}, -- {"maverick", FPUTYPE_MAVERICK}, -- {"vfp", FPUTYPE_VFP}, -- {"vfp3", FPUTYPE_VFP3}, -- {"neon", FPUTYPE_NEON} -+ {"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}, -+ {"neon-fp16", FPUTYPE_NEON_FP16} - }; - - -@@ -702,8 +806,10 @@ static const enum fputype fp_model_for_f - 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 */ -+ ARM_FP_MODEL_VFP, /* FPUTYPE_NEON */ -+ ARM_FP_MODEL_VFP /* FPUTYPE_NEON_FP16 */ - }; - - -@@ -724,6 +830,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; -@@ -881,6 +1004,131 @@ arm_init_libfuncs (void) - set_optab_libfunc (umod_optab, DImode, NULL); - 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; -+ } -+} -+ -+/* On AAPCS systems, this is the "struct __va_list". */ -+static GTY(()) tree va_list_type; -+ -+/* Return the type to use as __builtin_va_list. */ -+static tree -+arm_build_builtin_va_list (void) -+{ -+ tree va_list_name; -+ tree ap_field; -+ -+ if (!TARGET_AAPCS_BASED) -+ return std_build_builtin_va_list (); -+ -+ /* AAPCS \S 7.1.4 requires that va_list be a typedef for a type -+ defined as: -+ -+ struct __va_list -+ { -+ void *__ap; -+ }; -+ -+ The C Library ABI further reinforces this definition in \S -+ 4.1. -+ -+ We must follow this definition exactly. The structure tag -+ name is visible in C++ mangled names, and thus forms a part -+ of the ABI. The field name may be used by people who -+ #include . */ -+ /* Create the type. */ -+ va_list_type = lang_hooks.types.make_type (RECORD_TYPE); -+ /* Give it the required name. */ -+ va_list_name = build_decl (TYPE_DECL, -+ get_identifier ("__va_list"), -+ va_list_type); -+ DECL_ARTIFICIAL (va_list_name) = 1; -+ TYPE_NAME (va_list_type) = va_list_name; -+ /* Create the __ap field. */ -+ ap_field = build_decl (FIELD_DECL, -+ get_identifier ("__ap"), -+ ptr_type_node); -+ DECL_ARTIFICIAL (ap_field) = 1; -+ DECL_FIELD_CONTEXT (ap_field) = va_list_type; -+ TYPE_FIELDS (va_list_type) = ap_field; -+ /* Compute its layout. */ -+ layout_type (va_list_type); -+ -+ return va_list_type; -+} -+ -+/* Return an expression of type "void *" pointing to the next -+ available argument in a variable-argument list. VALIST is the -+ user-level va_list object, of type __builtin_va_list. */ -+static tree -+arm_extract_valist_ptr (tree valist) -+{ -+ if (TREE_TYPE (valist) == error_mark_node) -+ return error_mark_node; -+ -+ /* On an AAPCS target, the pointer is stored within "struct -+ va_list". */ -+ if (TARGET_AAPCS_BASED) -+ { -+ tree ap_field = TYPE_FIELDS (TREE_TYPE (valist)); -+ valist = build3 (COMPONENT_REF, TREE_TYPE (ap_field), -+ valist, ap_field, NULL_TREE); -+ } -+ -+ return valist; -+} -+ -+/* Implement TARGET_EXPAND_BUILTIN_VA_START. */ -+static void -+arm_expand_builtin_va_start (tree valist, rtx nextarg) -+{ -+ valist = arm_extract_valist_ptr (valist); -+ std_expand_builtin_va_start (valist, nextarg); -+} -+ -+/* Implement TARGET_GIMPLIFY_VA_ARG_EXPR. */ -+static tree -+arm_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, -+ tree *post_p) -+{ -+ valist = arm_extract_valist_ptr (valist); -+ return std_gimplify_va_arg_expr (valist, type, pre_p, post_p); - } - - /* Implement TARGET_HANDLE_OPTION. */ -@@ -1007,7 +1255,9 @@ void - arm_override_options (void) - { - unsigned i; -+ int len; - enum processor_type target_arch_cpu = arm_none; -+ enum processor_type selected_cpu = arm_none; - - /* Set up the flags based on the cpu/architecture selected by the user. */ - for (i = ARRAY_SIZE (arm_select); i--;) -@@ -1023,7 +1273,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. */ -@@ -1040,14 +1294,17 @@ arm_override_options (void) - if (i == ARM_OPT_SET_ARCH) - target_arch_cpu = sel->core; - -+ if (i == ARM_OPT_SET_CPU) -+ selected_cpu = (enum processor_type) (sel - ptr->processors); -+ - if (i != ARM_OPT_SET_TUNE) - { - /* If we have been given an architecture and a processor - 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; -@@ -1070,21 +1327,20 @@ arm_override_options (void) - { - const struct processors * sel; - unsigned int sought; -- enum processor_type cpu; - -- cpu = TARGET_CPU_DEFAULT; -- if (cpu == arm_none) -+ selected_cpu = TARGET_CPU_DEFAULT; -+ if (selected_cpu == arm_none) - { - #ifdef SUBTARGET_CPU_DEFAULT - /* Use the subtarget default CPU if none was specified by - configure. */ -- cpu = SUBTARGET_CPU_DEFAULT; -+ selected_cpu = SUBTARGET_CPU_DEFAULT; - #endif - /* Default to ARM6. */ -- if (cpu == arm_none) -- cpu = arm6; -+ if (selected_cpu == arm_none) -+ selected_cpu = arm6; - } -- sel = &all_cores[cpu]; -+ sel = &all_cores[selected_cpu]; - - insn_flags = sel->flags; - -@@ -1148,7 +1404,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; -@@ -1158,18 +1418,59 @@ 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 (optimize_size) -- targetm.rtx_costs = arm_size_rtx_costs; -+ -+ 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++) -+ { -+ if (streq (arm_all_abis[i].name, target_abi_name)) -+ { -+ arm_abi = arm_all_abis[i].abi_type; -+ break; -+ } -+ } -+ if (i == ARRAY_SIZE (arm_all_abis)) -+ error ("invalid ABI option: -mabi=%s", target_abi_name); -+ } - else -- targetm.rtx_costs = all_cores[(int)arm_tune].rtx_costs; -+ arm_abi = ARM_DEFAULT_ABI; - - /* Make sure that the processor choice does not conflict with any of the - other command line choices. */ - if (TARGET_ARM && !(insn_flags & FL_NOTM)) - error ("target CPU does not support ARM mode"); - -- if (TARGET_INTERWORK && !(insn_flags & FL_THUMB)) -+ /* BPABI targets use linker tricks to allow interworking on cores -+ without thumb support. */ -+ if (TARGET_INTERWORK && !((insn_flags & FL_THUMB) || TARGET_BPABI)) - { - warning (0, "target CPU does not support interworking" ); - target_flags &= ~MASK_INTERWORK; -@@ -1245,10 +1546,45 @@ 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_tune_cortex_a9 = (arm_tune == cortexa9) != 0; - arm_arch_iwmmxt = (insn_flags & FL_IWMMXT) != 0; -- arm_arch_hwdiv = (insn_flags & FL_DIV) != 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) -+ { -+ /* Thumb-1 LDR instructions cannot have negative offsets. -+ Permissible positive offset ranges are 5-bit (for byte loads), -+ 6-bit (for halfword loads), or 7-bit (for word loads). -+ Empirical results suggest a 7-bit anchor range gives the best -+ overall code size. */ -+ targetm.min_anchor_offset = 0; -+ targetm.max_anchor_offset = 127; -+ } -+ else if (TARGET_THUMB2) -+ { -+ /* The minimum is set such that the total size of the block -+ for a particular anchor is 248 + 1 + 4095 bytes, which is -+ divisible by eight, ensuring natural spacing of anchors. */ -+ targetm.min_anchor_offset = -248; -+ targetm.max_anchor_offset = 4095; -+ } - - /* V5 code we generate is completely interworking capable, so we turn off - TARGET_INTERWORK here to avoid many tests later on. */ -@@ -1261,22 +1597,6 @@ arm_override_options (void) - if (arm_arch5) - target_flags &= ~MASK_INTERWORK; - -- if (target_abi_name) -- { -- for (i = 0; i < ARRAY_SIZE (arm_all_abis); i++) -- { -- if (streq (arm_all_abis[i].name, target_abi_name)) -- { -- arm_abi = arm_all_abis[i].abi_type; -- break; -- } -- } -- if (i == ARRAY_SIZE (arm_all_abis)) -- error ("invalid ABI option: -mabi=%s", target_abi_name); -- } -- else -- arm_abi = ARM_DEFAULT_ABI; -- - if (TARGET_IWMMXT && !ARM_DOUBLEWORD_ALIGN) - error ("iwmmxt requires an AAPCS compatible ABI for proper operation"); - -@@ -1354,9 +1674,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. */ -@@ -1367,10 +1684,36 @@ 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; - -+ 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 -@@ -1456,6 +1799,15 @@ arm_override_options (void) - arm_pic_register = pic_register; - } - -+ /* Enable -mfix-cortex-m3-ldrd by default for Cortex-M3 cores. */ -+ if (fix_cm3_ldrd == 2) -+ { -+ if (selected_cpu == cortexm3) -+ fix_cm3_ldrd = 1; -+ else -+ fix_cm3_ldrd = 0; -+ } -+ - /* ??? We might want scheduling for thumb2. */ - if (TARGET_THUMB && flag_schedule_insns) - { -@@ -1493,6 +1845,13 @@ 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; -+ } - } - - static void -@@ -1614,6 +1973,14 @@ arm_current_func_type (void) - - return cfun->machine->func_type; - } -+ -+bool -+arm_allocate_stack_slots_for_args (void) -+{ -+ /* Naked functions should not allocate stack slots for arguments. */ -+ return !IS_NAKED (arm_current_func_type ()); -+} -+ - - /* 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 -@@ -1656,10 +2023,11 @@ use_return_insn (int iscond, rtx sibling - || current_function_calls_alloca - /* Or if there is a stack adjustment. However, if the stack pointer - is saved on the stack, we can use a pre-incrementing stack load. */ -- || !(stack_adjust == 0 || (frame_pointer_needed && stack_adjust == 4))) -+ || !(stack_adjust == 0 || (TARGET_APCS_FRAME && frame_pointer_needed -+ && stack_adjust == 4))) - return 0; - -- saved_int_regs = arm_compute_save_reg_mask (); -+ saved_int_regs = offsets->saved_regs_mask; - - /* Unfortunately, the insn - -@@ -1812,6 +2180,24 @@ const_ok_for_op (HOST_WIDE_INT i, enum r - switch (code) - { - case PLUS: -+ case COMPARE: -+ case EQ: -+ case NE: -+ case GT: -+ case LE: -+ case LT: -+ case GE: -+ case GEU: -+ case LTU: -+ case GTU: -+ case LEU: -+ case UNORDERED: -+ case ORDERED: -+ case UNEQ: -+ case UNGE: -+ case UNLT: -+ case UNGT: -+ case UNLE: - return const_ok_for_arm (ARM_SIGN_EXTEND (-i)); - - case MINUS: /* Should only occur with (MINUS I reg) => rsb */ -@@ -1872,14 +2258,22 @@ arm_split_constant (enum rtx_code code, - { - /* Currently SET is the only monadic value for CODE, all - the rest are diadic. */ -- emit_set_insn (target, GEN_INT (val)); -+ if (TARGET_USE_MOVT) -+ arm_emit_movpair (target, GEN_INT (val)); -+ else -+ emit_set_insn (target, GEN_INT (val)); -+ - return 1; - } - else - { - rtx temp = subtargets ? gen_reg_rtx (mode) : target; - -- emit_set_insn (temp, GEN_INT (val)); -+ if (TARGET_USE_MOVT) -+ arm_emit_movpair (temp, GEN_INT (val)); -+ else -+ emit_set_insn (temp, GEN_INT (val)); -+ - /* For MINUS, the value is subtracted from, since we never - have subtraction of a constant. */ - if (code == MINUS) -@@ -2678,14 +3072,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); -@@ -2702,7 +3101,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 -@@ -2712,10 +3140,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) -@@ -2728,27 +3158,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 by the macro -- RETURN_IN_MEMORY. */ --int --arm_return_in_memory (const_tree type) -+/* 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) - { - 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) - { -@@ -2765,7 +3224,7 @@ arm_return_in_memory (const_tree type) - 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) - { -@@ -2785,18 +3244,18 @@ arm_return_in_memory (const_tree type) - 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 (RETURN_IN_MEMORY (TREE_TYPE (field))) -- return 1; -+ if (arm_return_in_memory (TREE_TYPE (field), NULL_TREE)) -+ return true; - - /* Now check the remaining fields, if any. Only bitfields are allowed, - since they are not addressable. */ -@@ -2808,10 +3267,10 @@ arm_return_in_memory (const_tree type) - continue; - - if (!DECL_BIT_FIELD_TYPE (field)) -- return 1; -+ return true; - } - -- return 0; -+ return false; - } - - if (TREE_CODE (type) == UNION_TYPE) -@@ -2828,18 +3287,18 @@ arm_return_in_memory (const_tree type) - continue; - - if (FLOAT_TYPE_P (TREE_TYPE (field))) -- return 1; -+ return true; - -- if (RETURN_IN_MEMORY (TREE_TYPE (field))) -- return 1; -+ if (arm_return_in_memory (TREE_TYPE (field), NULL_TREE)) -+ 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. */ -@@ -2864,60 +3323,811 @@ arm_float_words_big_endian (void) - return 1; - } - --/* 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, -- tree fndecl ATTRIBUTE_UNUSED) -+const struct pcs_attribute_arg - { -- /* On the ARM, the offset starts at 0. */ -- pcum->nregs = 0; -- pcum->iwmmxt_nregs = 0; -- pcum->can_split = true; -- -- /* Varargs vectors are treated the same as long long. -- named_count avoids having to change the way arm handles 'named' */ -- pcum->named_count = 0; -- pcum->nargs = 0; -+ 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} -+ }; - -- if (TARGET_REALLY_IWMMXT && fntype) -- { -- tree fn_arg; -+static enum arm_pcs -+arm_pcs_from_attribute (tree attr) -+{ -+ const struct pcs_attribute_arg *ptr; -+ const char *arg; - -- for (fn_arg = TYPE_ARG_TYPES (fntype); -- fn_arg; -- fn_arg = TREE_CHAIN (fn_arg)) -- pcum->named_count += 1; -+ /* Get the value of the argument. */ -+ if (TREE_VALUE (attr) == NULL_TREE -+ || TREE_CODE (TREE_VALUE (attr)) != STRING_CST) -+ return ARM_PCS_UNKNOWN; - -- if (! pcum->named_count) -- pcum->named_count = INT_MAX; -- } --} -+ 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; - --/* Return true if mode/type need doubleword alignment. */ --bool --arm_needs_doubleword_align (enum machine_mode mode, tree type) --{ -- return (GET_MODE_ALIGNMENT (mode) > PARM_BOUNDARY -- || (type && TYPE_ALIGN (type) > PARM_BOUNDARY)); -+ /* 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; - --/* Determine where to put an argument to a function. -- Value is zero to push the argument on the stack, -- or a hard register in which to store the argument. -+ gcc_assert (type); - -- MODE is the argument's machine mode. -- TYPE is the data type of the argument (as a tree). -- This is null for libcalls where that information may -- not be available. -- CUM is a variable of type CUMULATIVE_ARGS which gives info about -- the preceding args and about the function being called. -- NAMED is nonzero if this argument is a named parameter -- (otherwise it is an extra parameter matching an ellipsis). */ -+ 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; -+} -+ -+static bool -+aapcs_vfp_is_call_or_return_candidate (enum machine_mode mode, const_tree type, -+ int *base_mode, -+ int *count) -+{ -+ if (GET_MODE_CLASS (mode) == MODE_FLOAT -+ || GET_MODE_CLASS (mode) == MODE_VECTOR_INT -+ || GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT) -+ { -+ *count = 1; -+ *base_mode = mode; -+ return true; -+ } -+ else if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT) -+ { -+ *count = 2; -+ *base_mode = (mode == DCmode ? DFmode : SFmode); -+ return true; -+ } -+ else if (type && (mode == BLKmode || TREE_CODE (type) == VECTOR_TYPE)) -+ { -+ enum machine_mode aggregate_mode = VOIDmode; -+ int ag_count = aapcs_vfp_sub_candidate (type, &aggregate_mode); -+ -+ if (ag_count > 0 && ag_count <= 4) -+ { -+ *count = ag_count; -+ *base_mode = aggregate_mode; -+ return true; -+ } -+ } -+ return false; -+} -+ -+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 (!(pcs_variant == ARM_PCS_AAPCS_VFP -+ || (pcs_variant == ARM_PCS_AAPCS_LOCAL -+ && TARGET_32BIT && TARGET_VFP && TARGET_HARD_FLOAT))) -+ return false; -+ return aapcs_vfp_is_call_or_return_candidate (mode, type, &ag_mode, &count); -+} -+ -+static bool -+aapcs_vfp_is_call_candidate (CUMULATIVE_ARGS *pcum, enum machine_mode mode, -+ const_tree type) -+{ -+ if (!(pcum->pcs_variant == ARM_PCS_AAPCS_VFP -+ || (pcum->pcs_variant == ARM_PCS_AAPCS_LOCAL -+ && TARGET_32BIT && TARGET_VFP && TARGET_HARD_FLOAT))) -+ return false; -+ return aapcs_vfp_is_call_or_return_candidate (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 (!(pcs_variant == ARM_PCS_AAPCS_VFP -+ || (pcs_variant == ARM_PCS_AAPCS_LOCAL -+ && TARGET_32BIT && TARGET_VFP && TARGET_HARD_FLOAT))) -+ 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 (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) -+ { -+ pcum->aapcs_cprc_slot = aapcs_select_call_coproc (pcum, mode, type); -+ -+ /* 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 (pcum->aapcs_cprc_slot >= 0) -+ { -+ if (!pcum->aapcs_cprc_failed[pcum->aapcs_cprc_slot]) -+ { -+ /* C1.cp - Try to allocate the argument to co-processor -+ registers. */ -+ if (aapcs_cp_arg_layout[pcum->aapcs_cprc_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[pcum->aapcs_cprc_slot] = true; -+ pcum->can_split = false; -+ return; -+ } -+ else -+ { -+ /* Subsequent cprc candidates after one that was not -+ allocated to coprocessor registers cannot go in core -+ registers either. */ -+ 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, -+ 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; -+ pcum->can_split = true; -+ -+ /* Varargs vectors are treated the same as long long. -+ named_count avoids having to change the way arm handles 'named' */ -+ pcum->named_count = 0; -+ pcum->nargs = 0; -+ -+ if (TARGET_REALLY_IWMMXT && fntype) -+ { -+ tree fn_arg; -+ -+ for (fn_arg = TYPE_ARG_TYPES (fntype); -+ fn_arg; -+ fn_arg = TREE_CHAIN (fn_arg)) -+ pcum->named_count += 1; -+ -+ if (! pcum->named_count) -+ pcum->named_count = INT_MAX; -+ } -+} -+ -+ -+/* Return true if mode/type need doubleword alignment. */ -+bool -+arm_needs_doubleword_align (enum machine_mode mode, tree type) -+{ -+ return (GET_MODE_ALIGNMENT (mode) > PARM_BOUNDARY -+ || (type && TYPE_ALIGN (type) > PARM_BOUNDARY)); -+} -+ -+ -+/* Determine where to put an argument to a function. -+ Value is zero to push the argument on the stack, -+ or a hard register in which to store the argument. -+ -+ MODE is the argument's machine mode. -+ TYPE is the data type of the argument (as a tree). -+ This is null for libcalls where that information may -+ not be available. -+ CUM is a variable of type CUMULATIVE_ARGS which gives info about -+ the preceding args and about the function being called. -+ NAMED is nonzero if this argument is a named parameter -+ (otherwise it is an extra parameter matching an ellipsis). */ - - rtx - arm_function_arg (CUMULATIVE_ARGS *pcum, enum machine_mode mode, -@@ -2925,6 +4135,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 -@@ -2966,10 +4187,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; - -@@ -2981,6 +4208,39 @@ arm_arg_partial_bytes (CUMULATIVE_ARGS * - 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 - extension to the ARM ABI. */ - -@@ -3031,6 +4291,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 }, -@@ -3133,6 +4395,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 -@@ -3298,7 +4575,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; - -@@ -3331,6 +4608,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; -@@ -3472,10 +4764,22 @@ legitimize_pic_address (rtx orig, enum m - && XEXP (XEXP (orig, 0), 0) == cfun->machine->pic_reg) - return orig; - -+ /* Handle the case where we have: const (UNSPEC_TLS). */ - if (GET_CODE (XEXP (orig, 0)) == UNSPEC - && XINT (XEXP (orig, 0), 1) == UNSPEC_TLS) - return orig; - -+ /* Handle the case where we have: -+ const (plus (UNSPEC_TLS) (ADDEND)). The ADDEND must be a -+ CONST_INT. */ -+ if (GET_CODE (XEXP (orig, 0)) == PLUS -+ && GET_CODE (XEXP (XEXP (orig, 0), 0)) == UNSPEC -+ && XINT (XEXP (XEXP (orig, 0), 0), 1) == UNSPEC_TLS) -+ { -+ gcc_assert (GET_CODE (XEXP (XEXP (orig, 0), 1)) == CONST_INT); -+ return orig; -+ } -+ - if (reg == 0) - { - gcc_assert (can_create_pseudo_p ()); -@@ -3924,6 +5228,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) -@@ -3952,13 +5257,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 -@@ -4129,7 +5436,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 -@@ -4799,121 +6107,255 @@ thumb1_rtx_costs (rtx x, enum rtx_code c - return 99; - } - -- default: -- return 99; -- } --} -+ default: -+ return 99; -+ } -+} -+ -+static inline bool -+arm_rtx_costs_1 (rtx x, enum rtx_code outer, int* total) -+{ -+ enum machine_mode mode = GET_MODE (x); -+ enum rtx_code subcode; -+ rtx operand; -+ enum rtx_code code = GET_CODE (x); -+ int extra_cost; -+ *total = 0; -+ -+ switch (code) -+ { -+ case MEM: -+ /* Memory costs quite a lot for the first word, but subsequent words -+ load at the equivalent of a single insn each. */ -+ *total = COSTS_N_INSNS (2 + ARM_NUM_REGS (mode)); -+ return true; -+ -+ case DIV: -+ case MOD: -+ case UDIV: -+ case UMOD: -+ if (TARGET_HARD_FLOAT && mode == SFmode) -+ *total = COSTS_N_INSNS (2); -+ else if (TARGET_HARD_FLOAT && mode == DFmode) -+ *total = COSTS_N_INSNS (4); -+ else -+ *total = COSTS_N_INSNS (20); -+ return false; -+ -+ case ROTATE: -+ if (GET_CODE (XEXP (x, 1)) == REG) -+ *total = COSTS_N_INSNS (1); /* Need to subtract from 32 */ -+ else if (GET_CODE (XEXP (x, 1)) != CONST_INT) -+ *total = rtx_cost (XEXP (x, 1), code); -+ -+ /* Fall through */ -+ case ROTATERT: -+ if (mode != SImode) -+ { -+ *total += COSTS_N_INSNS (4); -+ return true; -+ } -+ -+ /* Fall through */ -+ case ASHIFT: case LSHIFTRT: case ASHIFTRT: -+ *total += rtx_cost (XEXP (x, 0), code); -+ if (mode == DImode) -+ { -+ *total += COSTS_N_INSNS (3); -+ return true; -+ } -+ -+ *total += COSTS_N_INSNS (1); -+ /* Increase the cost of complex shifts because they aren't any faster, -+ and reduce dual issue opportunities. */ -+ if (arm_tune_cortex_a9 -+ && outer != SET && GET_CODE (XEXP (x, 1)) != CONST_INT) -+ ++*total; -+ -+ 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)); -+ if (GET_CODE (XEXP (x, 0)) == CONST_INT -+ && const_ok_for_arm (INTVAL (XEXP (x, 0)))) -+ { -+ *total += rtx_cost (XEXP (x, 1), code); -+ return true; -+ } -+ -+ if (GET_CODE (XEXP (x, 1)) == CONST_INT -+ && const_ok_for_arm (INTVAL (XEXP (x, 1)))) -+ { -+ *total += rtx_cost (XEXP (x, 0), code); -+ return true; -+ } -+ -+ return false; -+ } -+ -+ if (GET_MODE_CLASS (mode) == MODE_FLOAT) -+ { -+ if (TARGET_HARD_FLOAT && (mode == SFmode || mode == DFmode)) -+ { -+ *total = COSTS_N_INSNS (1); -+ if (GET_CODE (XEXP (x, 0)) == CONST_DOUBLE -+ && arm_const_double_rtx (XEXP (x, 0))) -+ { -+ *total += rtx_cost (XEXP (x, 1), code); -+ return true; -+ } -+ -+ if (GET_CODE (XEXP (x, 1)) == CONST_DOUBLE -+ && arm_const_double_rtx (XEXP (x, 1))) -+ { -+ *total += rtx_cost (XEXP (x, 0), code); -+ return true; -+ } -+ -+ return false; -+ } -+ *total = COSTS_N_INSNS (20); -+ return false; -+ } -+ -+ *total = COSTS_N_INSNS (1); -+ if (GET_CODE (XEXP (x, 0)) == CONST_INT -+ && const_ok_for_arm (INTVAL (XEXP (x, 0)))) -+ { -+ *total += rtx_cost (XEXP (x, 1), code); -+ return true; -+ } - -+ subcode = GET_CODE (XEXP (x, 1)); -+ if (subcode == ASHIFT || subcode == ASHIFTRT -+ || subcode == LSHIFTRT -+ || subcode == ROTATE || subcode == ROTATERT) -+ { -+ *total += rtx_cost (XEXP (x, 0), code); -+ *total += rtx_cost (XEXP (XEXP (x, 1), 0), subcode); -+ return true; -+ } - --/* Worker routine for arm_rtx_costs. */ --/* ??? This needs updating for thumb2. */ --static inline int --arm_rtx_costs_1 (rtx x, enum rtx_code code, enum rtx_code outer) --{ -- enum machine_mode mode = GET_MODE (x); -- enum rtx_code subcode; -- int extra_cost; -+ /* 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); -+ *total += rtx_cost (XEXP (x, 1), code); -+ return true; -+ } - -- switch (code) -- { -- case MEM: -- /* Memory costs quite a lot for the first word, but subsequent words -- load at the equivalent of a single insn each. */ -- return (10 + 4 * ((GET_MODE_SIZE (mode) - 1) / UNITS_PER_WORD) -- + (GET_CODE (x) == SYMBOL_REF -- && CONSTANT_POOL_ADDRESS_P (x) ? 4 : 0)); -+ if (subcode == MULT -+ && GET_CODE (XEXP (XEXP (x, 1), 1)) == CONST_INT -+ && ((INTVAL (XEXP (XEXP (x, 1), 1)) & -+ (INTVAL (XEXP (XEXP (x, 1), 1)) - 1)) == 0)) -+ { -+ *total += rtx_cost (XEXP (x, 0), code); -+ *total += rtx_cost (XEXP (XEXP (x, 1), 0), subcode); -+ return true; -+ } - -- case DIV: -- case MOD: -- case UDIV: -- case UMOD: -- return optimize_size ? COSTS_N_INSNS (2) : 100; -+ if (GET_RTX_CLASS (GET_CODE (XEXP (x, 1))) == RTX_COMPARE -+ || GET_RTX_CLASS (GET_CODE (XEXP (x, 1))) == RTX_COMM_COMPARE) -+ { -+ *total = COSTS_N_INSNS (1) + rtx_cost (XEXP (x, 0), code); -+ if (GET_CODE (XEXP (XEXP (x, 1), 0)) == REG -+ && REGNO (XEXP (XEXP (x, 1), 0)) != CC_REGNUM) -+ *total += COSTS_N_INSNS (1); - -- case ROTATE: -- if (mode == SImode && GET_CODE (XEXP (x, 1)) == REG) -- return 4; -- /* Fall through */ -- case ROTATERT: -- if (mode != SImode) -- return 8; -- /* Fall through */ -- case ASHIFT: case LSHIFTRT: case ASHIFTRT: -- if (mode == DImode) -- return (8 + (GET_CODE (XEXP (x, 1)) == CONST_INT ? 0 : 8) -- + ((GET_CODE (XEXP (x, 0)) == REG -- || (GET_CODE (XEXP (x, 0)) == SUBREG -- && GET_CODE (SUBREG_REG (XEXP (x, 0))) == REG)) -- ? 0 : 8)); -- return (1 + ((GET_CODE (XEXP (x, 0)) == REG -- || (GET_CODE (XEXP (x, 0)) == SUBREG -- && GET_CODE (SUBREG_REG (XEXP (x, 0))) == REG)) -- ? 0 : 4) -- + ((GET_CODE (XEXP (x, 1)) == REG -- || (GET_CODE (XEXP (x, 1)) == SUBREG -- && GET_CODE (SUBREG_REG (XEXP (x, 1))) == REG) -- || (GET_CODE (XEXP (x, 1)) == CONST_INT)) -- ? 0 : 4)); -+ return true; -+ } - -- case MINUS: -- if (GET_CODE (XEXP (x, 1)) == MULT && mode == SImode && arm_arch_thumb2) -+ /* 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))) - { -- extra_cost = rtx_cost (XEXP (x, 1), code); -- if (!REG_OR_SUBREG_REG (XEXP (x, 0))) -- extra_cost += 4 * ARM_NUM_REGS (mode); -- return extra_cost; -+ /* The cost comes from the cost of the multiply. */ -+ return false; - } - -- if (mode == DImode) -- return (4 + (REG_OR_SUBREG_REG (XEXP (x, 1)) ? 0 : 8) -- + ((REG_OR_SUBREG_REG (XEXP (x, 0)) -- || (GET_CODE (XEXP (x, 0)) == CONST_INT -- && const_ok_for_arm (INTVAL (XEXP (x, 0))))) -- ? 0 : 8)); -- -- if (GET_MODE_CLASS (mode) == MODE_FLOAT) -- return (2 + ((REG_OR_SUBREG_REG (XEXP (x, 1)) -- || (GET_CODE (XEXP (x, 1)) == CONST_DOUBLE -- && arm_const_double_rtx (XEXP (x, 1)))) -- ? 0 : 8) -- + ((REG_OR_SUBREG_REG (XEXP (x, 0)) -- || (GET_CODE (XEXP (x, 0)) == CONST_DOUBLE -- && arm_const_double_rtx (XEXP (x, 0)))) -- ? 0 : 8)); -- -- if (((GET_CODE (XEXP (x, 0)) == CONST_INT -- && const_ok_for_arm (INTVAL (XEXP (x, 0))) -- && REG_OR_SUBREG_REG (XEXP (x, 1)))) -- || (((subcode = GET_CODE (XEXP (x, 1))) == ASHIFT -- || subcode == ASHIFTRT || subcode == LSHIFTRT -- || subcode == ROTATE || subcode == ROTATERT -- || (subcode == MULT -- && GET_CODE (XEXP (XEXP (x, 1), 1)) == CONST_INT -- && ((INTVAL (XEXP (XEXP (x, 1), 1)) & -- (INTVAL (XEXP (XEXP (x, 1), 1)) - 1)) == 0))) -- && REG_OR_SUBREG_REG (XEXP (XEXP (x, 1), 0)) -- && (REG_OR_SUBREG_REG (XEXP (XEXP (x, 1), 1)) -- || GET_CODE (XEXP (XEXP (x, 1), 1)) == CONST_INT) -- && REG_OR_SUBREG_REG (XEXP (x, 0)))) -- return 1; - /* Fall through */ - - case PLUS: -- if (GET_CODE (XEXP (x, 0)) == MULT) -+ if (code == PLUS && arm_arch6 && mode == SImode -+ && (GET_CODE (XEXP (x, 0)) == ZERO_EXTEND -+ || GET_CODE (XEXP (x, 0)) == SIGN_EXTEND)) -+ { -+ *total = COSTS_N_INSNS (1); -+ *total += rtx_cost (XEXP (XEXP (x, 0), 0), GET_CODE (XEXP (x, 0))); -+ *total += rtx_cost (XEXP (x, 1), code); -+ return true; -+ } -+ -+ /* MLA: All arguments must be registers. We filter out -+ multiplication by a power of two, so that we fall down into -+ the code below. */ -+ 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))) - { -- extra_cost = rtx_cost (XEXP (x, 0), code); -- if (!REG_OR_SUBREG_REG (XEXP (x, 1))) -- extra_cost += 4 * ARM_NUM_REGS (mode); -- return extra_cost; -+ /* The cost comes from the cost of the multiply. */ -+ return false; - } - - if (GET_MODE_CLASS (mode) == MODE_FLOAT) -- return (2 + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 8) -- + ((REG_OR_SUBREG_REG (XEXP (x, 1)) -- || (GET_CODE (XEXP (x, 1)) == CONST_DOUBLE -- && arm_const_double_rtx (XEXP (x, 1)))) -- ? 0 : 8)); -+ { -+ if (TARGET_HARD_FLOAT && (mode == SFmode || mode == DFmode)) -+ { -+ *total = COSTS_N_INSNS (1); -+ if (GET_CODE (XEXP (x, 1)) == CONST_DOUBLE -+ && arm_const_double_rtx (XEXP (x, 1))) -+ { -+ *total += rtx_cost (XEXP (x, 0), code); -+ return true; -+ } -+ -+ return false; -+ } -+ -+ *total = COSTS_N_INSNS (20); -+ return false; -+ } -+ -+ if (GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) == RTX_COMPARE -+ || GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) == RTX_COMM_COMPARE) -+ { -+ *total = COSTS_N_INSNS (1) + rtx_cost (XEXP (x, 1), code); -+ if (GET_CODE (XEXP (XEXP (x, 0), 0)) == REG -+ && REGNO (XEXP (XEXP (x, 0), 0)) != CC_REGNUM) -+ *total += COSTS_N_INSNS (1); -+ return true; -+ } - - /* Fall through */ -+ - case AND: case XOR: case IOR: - extra_cost = 0; - -@@ -4927,37 +6369,56 @@ arm_rtx_costs_1 (rtx x, enum rtx_code co - && GET_CODE (XEXP (x, 1)) != CONST_INT) - || (REG_OR_SUBREG_REG (XEXP (x, 0)) - && ARM_FRAME_RTX (REG_OR_SUBREG_RTX (XEXP (x, 0))))) -- extra_cost = 4; -+ *total = 4; - - if (mode == DImode) -- return (4 + extra_cost + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 8) -- + ((REG_OR_SUBREG_REG (XEXP (x, 1)) -- || (GET_CODE (XEXP (x, 1)) == CONST_INT -- && const_ok_for_op (INTVAL (XEXP (x, 1)), code))) -- ? 0 : 8)); -- -- if (REG_OR_SUBREG_REG (XEXP (x, 0))) -- return (1 + (GET_CODE (XEXP (x, 1)) == CONST_INT ? 0 : extra_cost) -- + ((REG_OR_SUBREG_REG (XEXP (x, 1)) -- || (GET_CODE (XEXP (x, 1)) == CONST_INT -- && const_ok_for_op (INTVAL (XEXP (x, 1)), code))) -- ? 0 : 4)); -- -- else if (REG_OR_SUBREG_REG (XEXP (x, 1))) -- return (1 + extra_cost -- + ((((subcode = GET_CODE (XEXP (x, 0))) == ASHIFT -- || subcode == LSHIFTRT || subcode == ASHIFTRT -- || subcode == ROTATE || subcode == ROTATERT -- || (subcode == MULT -- && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT -- && ((INTVAL (XEXP (XEXP (x, 0), 1)) & -- (INTVAL (XEXP (XEXP (x, 0), 1)) - 1)) == 0))) -- && (REG_OR_SUBREG_REG (XEXP (XEXP (x, 0), 0))) -- && ((REG_OR_SUBREG_REG (XEXP (XEXP (x, 0), 1))) -- || GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)) -- ? 0 : 4)); -+ { -+ *total += COSTS_N_INSNS (2); -+ if (GET_CODE (XEXP (x, 1)) == CONST_INT -+ && const_ok_for_op (INTVAL (XEXP (x, 1)), code)) -+ { -+ *total += rtx_cost (XEXP (x, 0), code); -+ return true; -+ } - -- return 8; -+ return false; -+ } -+ -+ *total += COSTS_N_INSNS (1); -+ if (GET_CODE (XEXP (x, 1)) == CONST_INT -+ && const_ok_for_op (INTVAL (XEXP (x, 1)), code)) -+ { -+ *total += rtx_cost (XEXP (x, 0), code); -+ return true; -+ } -+ subcode = GET_CODE (XEXP (x, 0)); -+ if (subcode == ASHIFT || subcode == ASHIFTRT -+ || subcode == LSHIFTRT -+ || subcode == ROTATE || subcode == ROTATERT) -+ { -+ *total += rtx_cost (XEXP (x, 1), code); -+ *total += rtx_cost (XEXP (XEXP (x, 0), 0), subcode); -+ return true; -+ } -+ -+ if (subcode == 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 (x, 1), code); -+ *total += rtx_cost (XEXP (XEXP (x, 0), 0), subcode); -+ return true; -+ } -+ -+ if (subcode == UMIN || subcode == UMAX -+ || subcode == SMIN || subcode == SMAX) -+ { -+ *total = COSTS_N_INSNS (3); -+ return true; -+ } -+ -+ return false; - - case MULT: - /* This should have been handled by the CPU specific routines. */ -@@ -4971,90 +6432,281 @@ arm_rtx_costs_1 (rtx x, enum rtx_code co - == GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 1))) - && (GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == ZERO_EXTEND - || GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == SIGN_EXTEND)) -- return 8; -- return 99; -+ { -+ *total = rtx_cost (XEXP (XEXP (x, 0), 0), LSHIFTRT); -+ return true; -+ } -+ *total = COSTS_N_INSNS (2); /* Plus the cost of the MULT */ -+ return false; - - case NEG: - if (GET_MODE_CLASS (mode) == MODE_FLOAT) -- return 4 + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 6); -+ { -+ if (TARGET_HARD_FLOAT && (mode == SFmode || mode == DFmode)) -+ { -+ *total = COSTS_N_INSNS (1); -+ return false; -+ } -+ *total = COSTS_N_INSNS (2); -+ return false; -+ } -+ - /* Fall through */ - case NOT: -- if (mode == DImode) -- return 4 + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 4); -+ *total = COSTS_N_INSNS (ARM_NUM_REGS(mode)); -+ if (mode == SImode && code == NOT) -+ { -+ subcode = GET_CODE (XEXP (x, 0)); -+ if (subcode == ASHIFT || subcode == ASHIFTRT -+ || subcode == LSHIFTRT -+ || subcode == ROTATE || subcode == ROTATERT -+ || (subcode == 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), subcode); -+ /* Register shifts cost an extra cycle. */ -+ if (GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT) -+ *total += COSTS_N_INSNS (1) + rtx_cost (XEXP (XEXP (x, 0), 1), -+ subcode); -+ return true; -+ } -+ } - -- return 1 + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 4); -+ return false; - - case IF_THEN_ELSE: - if (GET_CODE (XEXP (x, 1)) == PC || GET_CODE (XEXP (x, 2)) == PC) -- return 14; -- return 2; -+ { -+ *total = COSTS_N_INSNS (4); -+ return true; -+ } -+ -+ operand = XEXP (x, 0); -+ -+ if (!((GET_RTX_CLASS (GET_CODE (operand)) == RTX_COMPARE -+ || GET_RTX_CLASS (GET_CODE (operand)) == RTX_COMM_COMPARE) -+ && GET_CODE (XEXP (operand, 0)) == REG -+ && REGNO (XEXP (operand, 0)) == CC_REGNUM)) -+ *total += COSTS_N_INSNS (1); -+ *total += (rtx_cost (XEXP (x, 1), code) -+ + rtx_cost (XEXP (x, 2), code)); -+ return true; -+ -+ case NE: -+ if (mode == SImode && XEXP (x, 1) == const0_rtx) -+ { -+ *total = COSTS_N_INSNS (2) + rtx_cost (XEXP (x, 0), code); -+ return true; -+ } -+ goto scc_insn; -+ -+ case GE: -+ if ((GET_CODE (XEXP (x, 0)) != REG || REGNO (XEXP (x, 0)) != CC_REGNUM) -+ && mode == SImode && XEXP (x, 1) == const0_rtx) -+ { -+ *total = COSTS_N_INSNS (2) + rtx_cost (XEXP (x, 0), code); -+ return true; -+ } -+ goto scc_insn; -+ -+ case LT: -+ if ((GET_CODE (XEXP (x, 0)) != REG || REGNO (XEXP (x, 0)) != CC_REGNUM) -+ && mode == SImode && XEXP (x, 1) == const0_rtx) -+ { -+ *total = COSTS_N_INSNS (1) + rtx_cost (XEXP (x, 0), code); -+ return true; -+ } -+ goto scc_insn; -+ -+ case EQ: -+ case GT: -+ case LE: -+ case GEU: -+ case LTU: -+ case GTU: -+ case LEU: -+ case UNORDERED: -+ case ORDERED: -+ case UNEQ: -+ case UNGE: -+ case UNLT: -+ case UNGT: -+ case UNLE: -+ scc_insn: -+ /* SCC insns. In the case where the comparison has already been -+ performed, then they cost 2 instructions. Otherwise they need -+ an additional comparison before them. */ -+ *total = COSTS_N_INSNS (2); -+ if (GET_CODE (XEXP (x, 0)) == REG && REGNO (XEXP (x, 0)) == CC_REGNUM) -+ { -+ return true; -+ } - -+ /* Fall through */ - case COMPARE: -- return 1; -+ if (GET_CODE (XEXP (x, 0)) == REG && REGNO (XEXP (x, 0)) == CC_REGNUM) -+ { -+ *total = 0; -+ return true; -+ } -+ -+ *total += COSTS_N_INSNS (1); -+ if (GET_CODE (XEXP (x, 1)) == CONST_INT -+ && const_ok_for_op (INTVAL (XEXP (x, 1)), code)) -+ { -+ *total += rtx_cost (XEXP (x, 0), code); -+ return true; -+ } -+ -+ subcode = GET_CODE (XEXP (x, 0)); -+ if (subcode == ASHIFT || subcode == ASHIFTRT -+ || subcode == LSHIFTRT -+ || subcode == ROTATE || subcode == ROTATERT) -+ { -+ *total += rtx_cost (XEXP (x, 1), code); -+ *total += rtx_cost (XEXP (XEXP (x, 0), 0), subcode); -+ return true; -+ } -+ -+ if (subcode == 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 (x, 1), code); -+ *total += rtx_cost (XEXP (XEXP (x, 0), 0), subcode); -+ return true; -+ } -+ -+ return false; -+ -+ case UMIN: -+ case UMAX: -+ case SMIN: -+ case SMAX: -+ *total = COSTS_N_INSNS (2) + rtx_cost (XEXP (x, 0), code); -+ if (GET_CODE (XEXP (x, 1)) != CONST_INT -+ || !const_ok_for_arm (INTVAL (XEXP (x, 1)))) -+ *total += rtx_cost (XEXP (x, 1), code); -+ return true; - - case ABS: -- return 4 + (mode == DImode ? 4 : 0); -+ if (GET_MODE_CLASS (mode == MODE_FLOAT)) -+ { -+ if (TARGET_HARD_FLOAT && (mode == SFmode || mode == DFmode)) -+ { -+ *total = COSTS_N_INSNS (1); -+ return false; -+ } -+ *total = COSTS_N_INSNS (20); -+ return false; -+ } -+ *total = COSTS_N_INSNS (1); -+ if (mode == DImode) -+ *total += COSTS_N_INSNS (3); -+ return false; - - case SIGN_EXTEND: -- /* ??? value extensions are cheaper on armv6. */ -- if (GET_MODE (XEXP (x, 0)) == QImode) -- return (4 + (mode == DImode ? 4 : 0) -- + (GET_CODE (XEXP (x, 0)) == MEM ? 10 : 0)); -+ if (GET_MODE_CLASS (mode) == MODE_INT) -+ { -+ *total = 0; -+ if (mode == DImode) -+ *total += COSTS_N_INSNS (1); -+ -+ if (GET_MODE (XEXP (x, 0)) != SImode) -+ { -+ if (arm_arch6) -+ { -+ if (GET_CODE (XEXP (x, 0)) != MEM) -+ *total += COSTS_N_INSNS (1); -+ } -+ else if (!arm_arch4 || GET_CODE (XEXP (x, 0)) != MEM) -+ *total += COSTS_N_INSNS (2); -+ } -+ -+ return false; -+ } -+ - /* Fall through */ - case ZERO_EXTEND: -- switch (GET_MODE (XEXP (x, 0))) -+ *total = 0; -+ if (GET_MODE_CLASS (mode) == MODE_INT) - { -- case QImode: -- return (1 + (mode == DImode ? 4 : 0) -- + (GET_CODE (XEXP (x, 0)) == MEM ? 10 : 0)); -+ if (mode == DImode) -+ *total += COSTS_N_INSNS (1); - -- case HImode: -- return (4 + (mode == DImode ? 4 : 0) -- + (GET_CODE (XEXP (x, 0)) == MEM ? 10 : 0)); -+ if (GET_MODE (XEXP (x, 0)) != SImode) -+ { -+ if (arm_arch6) -+ { -+ if (GET_CODE (XEXP (x, 0)) != MEM) -+ *total += COSTS_N_INSNS (1); -+ } -+ else if (!arm_arch4 || GET_CODE (XEXP (x, 0)) != MEM) -+ *total += COSTS_N_INSNS (GET_MODE (XEXP (x, 0)) == QImode ? -+ 1 : 2); -+ } - -- case SImode: -- return (1 + (GET_CODE (XEXP (x, 0)) == MEM ? 10 : 0)); -+ return false; -+ } - -+ switch (GET_MODE (XEXP (x, 0))) -+ { - case V8QImode: - case V4HImode: - case V2SImode: - case V4QImode: - case V2HImode: -- return 1; -+ *total = COSTS_N_INSNS (1); -+ return false; - - default: - gcc_unreachable (); - } - gcc_unreachable (); - -+ case ZERO_EXTRACT: -+ case SIGN_EXTRACT: -+ *total = COSTS_N_INSNS (1) + rtx_cost (XEXP (x, 0), code); -+ return true; -+ - case CONST_INT: -- if (const_ok_for_arm (INTVAL (x))) -- return outer == SET ? 2 : -1; -- else if (outer == AND -- && const_ok_for_arm (~INTVAL (x))) -- return -1; -- else if ((outer == COMPARE -- || outer == PLUS || outer == MINUS) -- && const_ok_for_arm (-INTVAL (x))) -- return -1; -+ if (const_ok_for_arm (INTVAL (x)) -+ || const_ok_for_arm (~INTVAL (x))) -+ *total = COSTS_N_INSNS (1); - else -- return 5; -+ *total = COSTS_N_INSNS (arm_gen_constant (SET, mode, NULL_RTX, -+ INTVAL (x), NULL_RTX, -+ NULL_RTX, 0, 0)); -+ return true; - - case CONST: - case LABEL_REF: - case SYMBOL_REF: -- return 6; -+ *total = COSTS_N_INSNS (3); -+ return true; -+ -+ case HIGH: -+ *total = COSTS_N_INSNS (1); -+ return true; -+ -+ case LO_SUM: -+ *total = COSTS_N_INSNS (1); -+ *total += rtx_cost (XEXP (x, 0), code); -+ return true; - - case CONST_DOUBLE: -- if (arm_const_double_rtx (x) || vfp3_const_double_rtx (x)) -- return outer == SET ? 2 : -1; -- else if ((outer == COMPARE || outer == PLUS) -- && neg_const_double_rtx_ok_for_fpa (x)) -- return -1; -- return 7; -+ if (TARGET_HARD_FLOAT && vfp3_const_double_rtx (x)) -+ *total = COSTS_N_INSNS (1); -+ else -+ *total = COSTS_N_INSNS (4); -+ return true; - - default: -- return 99; -+ *total = COSTS_N_INSNS (4); -+ return false; - } - } - -@@ -5063,14 +6715,14 @@ static bool - arm_size_rtx_costs (rtx x, int code, int outer_code, int *total) - { - enum machine_mode mode = GET_MODE (x); -- -- if (TARGET_THUMB) -+ if (TARGET_THUMB1) - { - /* XXX TBD. For now, use the standard costs. */ - *total = thumb1_rtx_costs (x, code, outer_code); - return true; - } - -+ /* FIXME: This makes no attempt to prefer narrow Thumb-2 instructions. */ - switch (code) - { - case MEM: -@@ -5181,7 +6833,10 @@ arm_size_rtx_costs (rtx x, int code, int - - case NEG: - if (TARGET_HARD_FLOAT && GET_MODE_CLASS (mode) == MODE_FLOAT) -- *total = COSTS_N_INSNS (1); -+ { -+ *total = COSTS_N_INSNS (1); -+ return false; -+ } - /* Fall through */ - case NOT: - *total = COSTS_N_INSNS (ARM_NUM_REGS (mode)); -@@ -5270,6 +6925,13 @@ arm_size_rtx_costs (rtx x, int code, int - *total = COSTS_N_INSNS (4); - return true; - -+ case HIGH: -+ case LO_SUM: -+ /* We prefer constant pool entries to MOVW/MOVT pairs, so bump the -+ cost of these slightly. */ -+ *total = COSTS_N_INSNS (1) + 1; -+ return true; -+ - default: - if (mode != VOIDmode) - *total = COSTS_N_INSNS (ARM_NUM_REGS (mode)); -@@ -5279,11 +6941,22 @@ arm_size_rtx_costs (rtx x, int code, int - } - } - -+/* RTX costs when optimizing for size. */ -+static bool -+arm_rtx_costs (rtx x, int code, int outer_code, int *total) -+{ -+ if (optimize_size) -+ return arm_size_rtx_costs (x, code, outer_code, total); -+ else -+ return all_cores[(int)arm_tune].rtx_costs (x, code, outer_code, total); -+} -+ - /* RTX costs for cores with a slow MUL implementation. Thumb-2 is not - supported on any "slowmul" cores, so it can be ignored. */ - - static bool --arm_slowmul_rtx_costs (rtx x, int code, int outer_code, int *total) -+arm_slowmul_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer_code, -+ int *total) - { - enum machine_mode mode = GET_MODE (x); - -@@ -5299,8 +6972,8 @@ arm_slowmul_rtx_costs (rtx x, int code, - if (GET_MODE_CLASS (mode) == MODE_FLOAT - || mode == DImode) - { -- *total = 30; -- return true; -+ *total = COSTS_N_INSNS (20); -+ return false; - } - - if (GET_CODE (XEXP (x, 1)) == CONST_INT) -@@ -5316,20 +6989,19 @@ arm_slowmul_rtx_costs (rtx x, int code, - for (j = 0; i && j < 32; j += booth_unit_size) - { - i >>= booth_unit_size; -- cost += 2; -+ cost++; - } - -- *total = cost; -+ *total = COSTS_N_INSNS (cost); -+ *total += rtx_cost (XEXP (x, 0), code); - return true; - } - -- *total = 30 + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 4) -- + (REG_OR_SUBREG_REG (XEXP (x, 1)) ? 0 : 4); -- return true; -+ *total = COSTS_N_INSNS (20); -+ return false; - - default: -- *total = arm_rtx_costs_1 (x, code, outer_code); -- return true; -+ return arm_rtx_costs_1 (x, outer_code, total);; - } - } - -@@ -5337,7 +7009,8 @@ arm_slowmul_rtx_costs (rtx x, int code, - /* RTX cost for cores with a fast multiply unit (M variants). */ - - static bool --arm_fastmul_rtx_costs (rtx x, int code, int outer_code, int *total) -+arm_fastmul_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer_code, -+ int *total) - { - enum machine_mode mode = GET_MODE (x); - -@@ -5358,16 +7031,15 @@ arm_fastmul_rtx_costs (rtx x, int code, - && (GET_CODE (XEXP (x, 0)) == ZERO_EXTEND - || GET_CODE (XEXP (x, 0)) == SIGN_EXTEND)) - { -- *total = 8; -- return true; -+ *total = COSTS_N_INSNS(2); -+ return false; - } - - -- if (GET_MODE_CLASS (mode) == MODE_FLOAT -- || mode == DImode) -+ if (mode == DImode) - { -- *total = 30; -- return true; -+ *total = COSTS_N_INSNS (5); -+ return false; - } - - if (GET_CODE (XEXP (x, 1)) == CONST_INT) -@@ -5383,20 +7055,34 @@ arm_fastmul_rtx_costs (rtx x, int code, - for (j = 0; i && j < 32; j += booth_unit_size) - { - i >>= booth_unit_size; -- cost += 2; -+ cost++; - } - -- *total = cost; -- return true; -+ *total = COSTS_N_INSNS(cost); -+ return false; - } - -- *total = 8 + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 4) -- + (REG_OR_SUBREG_REG (XEXP (x, 1)) ? 0 : 4); -- return true; -+ if (mode == SImode) -+ { -+ *total = COSTS_N_INSNS (4); -+ return false; -+ } -+ -+ if (GET_MODE_CLASS (mode) == MODE_FLOAT) -+ { -+ if (TARGET_HARD_FLOAT && (mode == SFmode || mode == DFmode)) -+ { -+ *total = COSTS_N_INSNS (1); -+ return false; -+ } -+ } -+ -+ /* Requires a lib call */ -+ *total = COSTS_N_INSNS (20); -+ return false; - - default: -- *total = arm_rtx_costs_1 (x, code, outer_code); -- return true; -+ return arm_rtx_costs_1 (x, outer_code, total); - } - } - -@@ -5405,7 +7091,7 @@ arm_fastmul_rtx_costs (rtx x, int code, - so it can be ignored. */ - - static bool --arm_xscale_rtx_costs (rtx x, int code, int outer_code, int *total) -+arm_xscale_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer_code, int *total) - { - enum machine_mode mode = GET_MODE (x); - -@@ -5417,6 +7103,15 @@ arm_xscale_rtx_costs (rtx x, int code, i - - switch (code) - { -+ case COMPARE: -+ if (GET_CODE (XEXP (x, 0)) != MULT) -+ return arm_rtx_costs_1 (x, outer_code, total); -+ -+ /* A COMPARE of a MULT is slow on XScale; the muls instruction -+ will stall until the multiplication is complete. */ -+ *total = COSTS_N_INSNS (3); -+ return false; -+ - case MULT: - /* There is no point basing this on the tuning, since it is always the - fast variant if it exists at all. */ -@@ -5425,60 +7120,58 @@ arm_xscale_rtx_costs (rtx x, int code, i - && (GET_CODE (XEXP (x, 0)) == ZERO_EXTEND - || GET_CODE (XEXP (x, 0)) == SIGN_EXTEND)) - { -- *total = 8; -- return true; -+ *total = COSTS_N_INSNS (2); -+ return false; - } - - -- if (GET_MODE_CLASS (mode) == MODE_FLOAT -- || mode == DImode) -+ if (mode == DImode) - { -- *total = 30; -- return true; -+ *total = COSTS_N_INSNS (5); -+ return false; - } - - if (GET_CODE (XEXP (x, 1)) == CONST_INT) - { -- unsigned HOST_WIDE_INT i = (INTVAL (XEXP (x, 1)) -- & (unsigned HOST_WIDE_INT) 0xffffffff); -- int cost, const_ok = const_ok_for_arm (i); -+ /* If operand 1 is a constant we can more accurately -+ calculate the cost of the multiply. The multiplier can -+ retire 15 bits on the first cycle and a further 12 on the -+ second. We do, of course, have to load the constant into -+ a register first. */ -+ unsigned HOST_WIDE_INT i = INTVAL (XEXP (x, 1)); -+ /* There's a general overhead of one cycle. */ -+ int cost = 1; - unsigned HOST_WIDE_INT masked_const; - -- /* The cost will be related to two insns. -- First a load of the constant (MOV or LDR), then a multiply. */ -- cost = 2; -- if (! const_ok) -- cost += 1; /* LDR is probably more expensive because -- of longer result latency. */ -+ if (i & 0x80000000) -+ i = ~i; -+ -+ i &= (unsigned HOST_WIDE_INT) 0xffffffff; -+ - masked_const = i & 0xffff8000; -- if (masked_const != 0 && masked_const != 0xffff8000) -+ if (masked_const != 0) - { -+ cost++; - masked_const = i & 0xf8000000; -- if (masked_const == 0 || masked_const == 0xf8000000) -- cost += 1; -- else -- cost += 2; -+ if (masked_const != 0) -+ cost++; - } -- *total = cost; -- return true; -+ *total = COSTS_N_INSNS (cost); -+ return false; - } - -- *total = 8 + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 4) -- + (REG_OR_SUBREG_REG (XEXP (x, 1)) ? 0 : 4); -- return true; -+ if (mode == SImode) -+ { -+ *total = COSTS_N_INSNS (3); -+ return false; -+ } - -- case COMPARE: -- /* A COMPARE of a MULT is slow on XScale; the muls instruction -- will stall until the multiplication is complete. */ -- if (GET_CODE (XEXP (x, 0)) == MULT) -- *total = 4 + rtx_cost (XEXP (x, 0), code); -- else -- *total = arm_rtx_costs_1 (x, code, outer_code); -- return true; -+ /* Requires a lib call */ -+ *total = COSTS_N_INSNS (20); -+ return false; - - default: -- *total = arm_rtx_costs_1 (x, code, outer_code); -- return true; -+ return arm_rtx_costs_1 (x, outer_code, total); - } - } - -@@ -5486,11 +7179,9 @@ arm_xscale_rtx_costs (rtx x, int code, i - /* RTX costs for 9e (and later) cores. */ - - static bool --arm_9e_rtx_costs (rtx x, int code, int outer_code, int *total) -+arm_9e_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer_code, int *total) - { - enum machine_mode mode = GET_MODE (x); -- int nonreg_cost; -- int cost; - - if (TARGET_THUMB1) - { -@@ -5516,35 +7207,37 @@ arm_9e_rtx_costs (rtx x, int code, int o - && (GET_CODE (XEXP (x, 0)) == ZERO_EXTEND - || GET_CODE (XEXP (x, 0)) == SIGN_EXTEND)) - { -- *total = 3; -- return true; -+ *total = COSTS_N_INSNS (2); -+ return false; - } - - -- if (GET_MODE_CLASS (mode) == MODE_FLOAT) -- { -- *total = 30; -- return true; -- } - if (mode == DImode) - { -- cost = 7; -- nonreg_cost = 8; -+ *total = COSTS_N_INSNS (5); -+ return false; - } -- else -+ -+ if (mode == SImode) - { -- cost = 2; -- nonreg_cost = 4; -+ *total = COSTS_N_INSNS (2); -+ return false; - } - -+ if (GET_MODE_CLASS (mode) == MODE_FLOAT) -+ { -+ if (TARGET_HARD_FLOAT && (mode == SFmode || mode == DFmode)) -+ { -+ *total = COSTS_N_INSNS (1); -+ return false; -+ } -+ } - -- *total = cost + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : nonreg_cost) -- + (REG_OR_SUBREG_REG (XEXP (x, 1)) ? 0 : nonreg_cost); -- return true; -+ *total = COSTS_N_INSNS (20); -+ return false; - - default: -- *total = arm_rtx_costs_1 (x, code, outer_code); -- return true; -+ return arm_rtx_costs_1 (x, outer_code, total); - } - } - /* All address computations that can be done are free, but rtx cost returns -@@ -6356,10 +8049,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; - -@@ -6392,23 +8088,15 @@ 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 || 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) -@@ -6475,10 +8163,17 @@ arm_eliminable_register (rtx x) - enum reg_class - coproc_secondary_reload_class (enum machine_mode mode, rtx x, bool wb) - { -+ if (mode == HFmode) -+ { -+ 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)) -@@ -6875,6 +8570,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); -@@ -7102,6 +8800,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); -@@ -7307,7 +9008,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; - -@@ -7370,7 +9071,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; - -@@ -8739,17 +10440,20 @@ add_minipool_backward_ref (Mfix *fix) - its maximum address (which can happen if we have - re-located a forwards fix); force the new fix to come - after it. */ -- min_mp = mp; -- min_address = mp->min_address + fix->fix_size; -+ if (ARM_DOUBLEWORD_ALIGN -+ && fix->fix_size >= 8 && mp->fix_size < 8) -+ return NULL; -+ else -+ { -+ min_mp = mp; -+ min_address = mp->min_address + fix->fix_size; -+ } - } -- /* If we are inserting an 8-bytes aligned quantity and -- we have not already found an insertion point, then -- make sure that all such 8-byte aligned quantities are -- placed at the start of the pool. */ -+ /* Do not insert a non-8-byte aligned quantity before 8-byte -+ aligned quantities. */ - else if (ARM_DOUBLEWORD_ALIGN -- && min_mp == NULL -- && fix->fix_size >= 8 -- && mp->fix_size < 8) -+ && fix->fix_size < 8 -+ && mp->fix_size >= 8) - { - min_mp = mp; - min_address = mp->min_address + fix->fix_size; -@@ -8985,7 +10689,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); -@@ -9297,6 +11004,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; -@@ -9502,6 +11211,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) -@@ -9572,6 +11296,53 @@ vfp_emit_fstmd (int base_reg, int count) - rtx tmp, reg; - int i; - -+ if (low_irq_latency) -+ { -+ if (!count) -+ return 0; -+ -+ int 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. */ -+ rtx 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. */ -@@ -9729,6 +11500,14 @@ output_call_mem (rtx *operands) - } - - -+/* Emit a MOVW/MOVT pair. */ -+void arm_emit_movpair (rtx dest, rtx src) -+{ -+ emit_set_insn (dest, gen_rtx_HIGH (SImode, src)); -+ emit_set_insn (dest, gen_rtx_LO_SUM (SImode, dest, src)); -+} -+ -+ - /* Output a move from arm registers to an fpa registers. - OPERANDS[0] is an fpa register. - OPERANDS[1] is the first registers of an arm register pair. */ -@@ -9862,7 +11641,11 @@ output_move_double (rtx *operands) - switch (GET_CODE (XEXP (operands[1], 0))) - { - case REG: -- output_asm_insn ("ldm%(ia%)\t%m1, %M0", operands); -+ if (TARGET_LDRD -+ && !(fix_cm3_ldrd && reg0 == REGNO(XEXP (operands[1], 0)))) -+ output_asm_insn ("ldr%(d%)\t%0, [%m1]", operands); -+ else -+ output_asm_insn ("ldm%(ia%)\t%m1, %M0", operands); - break; - - case PRE_INC: -@@ -9878,7 +11661,10 @@ output_move_double (rtx *operands) - break; - - case POST_INC: -- output_asm_insn ("ldm%(ia%)\t%m1!, %M0", operands); -+ if (TARGET_LDRD) -+ output_asm_insn ("ldr%(d%)\t%0, [%m1], #8", operands); -+ else -+ output_asm_insn ("ldm%(ia%)\t%m1!, %M0", operands); - break; - - case POST_DEC: -@@ -9888,6 +11674,10 @@ output_move_double (rtx *operands) - - case PRE_MODIFY: - case POST_MODIFY: -+ /* Autoicrement addressing modes should never have overlapping -+ base and destination registers, and overlapping index registers -+ are already prohibited, so this doesn't need to worry about -+ fix_cm3_ldrd. */ - otherops[0] = operands[0]; - otherops[1] = XEXP (XEXP (XEXP (operands[1], 0), 1), 0); - otherops[2] = XEXP (XEXP (XEXP (operands[1], 0), 1), 1); -@@ -9902,9 +11692,9 @@ output_move_double (rtx *operands) - } - else - { -- /* IWMMXT allows offsets larger than ldrd can handle, -+ /* IWMMXT allows offsets larger than ARM ldrd can handle, - fix these up with a pair of ldr. */ -- if (GET_CODE (otherops[2]) == CONST_INT -+ if (TARGET_ARM && GET_CODE (otherops[2]) == CONST_INT - && (INTVAL(otherops[2]) <= -256 - || INTVAL(otherops[2]) >= 256)) - { -@@ -9918,9 +11708,9 @@ output_move_double (rtx *operands) - } - else - { -- /* IWMMXT allows offsets larger than ldrd can handle, -+ /* IWMMXT allows offsets larger than ARM ldrd can handle, - fix these up with a pair of ldr. */ -- if (GET_CODE (otherops[2]) == CONST_INT -+ if (TARGET_ARM && GET_CODE (otherops[2]) == CONST_INT - && (INTVAL(otherops[2]) <= -256 - || INTVAL(otherops[2]) >= 256)) - { -@@ -9937,8 +11727,15 @@ output_move_double (rtx *operands) - - case LABEL_REF: - case CONST: -- output_asm_insn ("adr%?\t%0, %1", operands); -- output_asm_insn ("ldm%(ia%)\t%0, %M0", operands); -+ /* Use the second register of the pair to avoid problematic -+ overlap. */ -+ otherops[1] = operands[1]; -+ output_asm_insn ("adr%?\t%0, %1", otherops); -+ operands[1] = otherops[0]; -+ if (TARGET_LDRD) -+ output_asm_insn ("ldr%(d%)\t%0, [%1]", operands); -+ else -+ output_asm_insn ("ldm%(ia%)\t%1, %M0", operands); - break; - - /* ??? This needs checking for thumb2. */ -@@ -9952,7 +11749,7 @@ output_move_double (rtx *operands) - - if (GET_CODE (XEXP (operands[1], 0)) == PLUS) - { -- if (GET_CODE (otherops[2]) == CONST_INT) -+ if (GET_CODE (otherops[2]) == CONST_INT && !TARGET_LDRD) - { - switch ((int) INTVAL (otherops[2])) - { -@@ -9971,30 +11768,37 @@ output_move_double (rtx *operands) - return ""; - } - } -+ otherops[0] = gen_rtx_REG(SImode, REGNO(operands[0]) + 1); -+ operands[1] = otherops[0]; - if (TARGET_LDRD - && (GET_CODE (otherops[2]) == REG - || (GET_CODE (otherops[2]) == CONST_INT - && INTVAL (otherops[2]) > -256 - && INTVAL (otherops[2]) < 256))) - { -- if (reg_overlap_mentioned_p (otherops[0], -+ if (reg_overlap_mentioned_p (operands[0], - otherops[2])) - { -+ rtx tmp; - /* Swap base and index registers over to - avoid a conflict. */ -- otherops[1] = XEXP (XEXP (operands[1], 0), 1); -- otherops[2] = XEXP (XEXP (operands[1], 0), 0); -+ tmp = otherops[1]; -+ otherops[1] = otherops[2]; -+ otherops[2] = tmp; - } - /* If both registers conflict, it will usually - have been fixed by a splitter. */ -- if (reg_overlap_mentioned_p (otherops[0], otherops[2])) -+ if (reg_overlap_mentioned_p (operands[0], otherops[2]) -+ || (fix_cm3_ldrd && reg0 == REGNO (otherops[1]))) - { -- output_asm_insn ("add%?\t%1, %1, %2", otherops); -- output_asm_insn ("ldr%(d%)\t%0, [%1]", -- otherops); -+ output_asm_insn ("add%?\t%0, %1, %2", otherops); -+ output_asm_insn ("ldr%(d%)\t%0, [%1]", operands); - } - else -- output_asm_insn ("ldr%(d%)\t%0, [%1, %2]", otherops); -+ { -+ otherops[0] = operands[0]; -+ output_asm_insn ("ldr%(d%)\t%0, [%1, %2]", otherops); -+ } - return ""; - } - -@@ -10011,7 +11815,10 @@ output_move_double (rtx *operands) - else - output_asm_insn ("sub%?\t%0, %1, %2", otherops); - -- return "ldm%(ia%)\t%0, %M0"; -+ if (TARGET_LDRD) -+ return "ldr%(d%)\t%0, [%1]"; -+ -+ return "ldm%(ia%)\t%1, %M0"; - } - else - { -@@ -10039,7 +11846,10 @@ output_move_double (rtx *operands) - switch (GET_CODE (XEXP (operands[0], 0))) - { - case REG: -- output_asm_insn ("stm%(ia%)\t%m0, %M1", operands); -+ if (TARGET_LDRD) -+ output_asm_insn ("str%(d%)\t%1, [%m0]", operands); -+ else -+ output_asm_insn ("stm%(ia%)\t%m0, %M1", operands); - break; - - case PRE_INC: -@@ -10055,7 +11865,10 @@ output_move_double (rtx *operands) - break; - - case POST_INC: -- output_asm_insn ("stm%(ia%)\t%m0!, %M1", operands); -+ if (TARGET_LDRD) -+ output_asm_insn ("str%(d%)\t%1, [%m0], #8", operands); -+ else -+ output_asm_insn ("stm%(ia%)\t%m0!, %M1", operands); - break; - - case POST_DEC: -@@ -10069,9 +11882,9 @@ output_move_double (rtx *operands) - otherops[1] = XEXP (XEXP (XEXP (operands[0], 0), 1), 0); - otherops[2] = XEXP (XEXP (XEXP (operands[0], 0), 1), 1); - -- /* IWMMXT allows offsets larger than ldrd can handle, -+ /* IWMMXT allows offsets larger than ARM ldrd can handle, - fix these up with a pair of ldr. */ -- if (GET_CODE (otherops[2]) == CONST_INT -+ if (TARGET_ARM && GET_CODE (otherops[2]) == CONST_INT - && (INTVAL(otherops[2]) <= -256 - || INTVAL(otherops[2]) >= 256)) - { -@@ -10099,7 +11912,7 @@ output_move_double (rtx *operands) - - case PLUS: - otherops[2] = XEXP (XEXP (operands[0], 0), 1); -- if (GET_CODE (otherops[2]) == CONST_INT) -+ if (GET_CODE (otherops[2]) == CONST_INT && !TARGET_LDRD) - { - switch ((int) INTVAL (XEXP (XEXP (operands[0], 0), 1))) - { -@@ -10145,7 +11958,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) -@@ -10343,6 +12156,13 @@ output_move_neon (rtx *operands) - ops[1] = reg; - break; - -+ case PRE_DEC: -+ /* FIXME: We should be using vld1/vst1 here in BE mode? */ -+ template = "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 (); -@@ -10700,25 +12520,14 @@ arm_compute_save_reg0_reg12_mask (void) - } - else - { -- /* In arm mode we handle r11 (FP) as a special case. */ -- unsigned last_reg = TARGET_ARM ? 10 : 11; -- - /* In the normal case we only need to save those registers - which are call saved and which are used by this function. */ -- for (reg = 0; reg <= last_reg; reg++) -+ for (reg = 0; reg <= 11; reg++) - if (df_regs_ever_live_p (reg) && ! call_used_regs[reg]) - save_reg_mask |= (1 << reg); - - /* Handle the frame pointer as a special case. */ -- if (! TARGET_APCS_FRAME -- && ! frame_pointer_needed -- && df_regs_ever_live_p (HARD_FRAME_POINTER_REGNUM) -- && ! call_used_regs[HARD_FRAME_POINTER_REGNUM]) -- save_reg_mask |= 1 << HARD_FRAME_POINTER_REGNUM; -- else if (! TARGET_APCS_FRAME -- && ! frame_pointer_needed -- && df_regs_ever_live_p (HARD_FRAME_POINTER_REGNUM) -- && ! call_used_regs[HARD_FRAME_POINTER_REGNUM]) -+ if (frame_pointer_needed) - save_reg_mask |= 1 << HARD_FRAME_POINTER_REGNUM; - - /* If we aren't loading the PIC register, -@@ -10753,8 +12562,27 @@ arm_compute_save_reg0_reg12_mask (void) - } - - -+/* Compute the number of bytes used to store the static chain register on the -+ stack, above the stack frame. We need to know this accurately to get the -+ alignment of the rest of the stack frame correct. */ -+ -+static int arm_compute_static_chain_stack_bytes (void) -+{ -+ unsigned long func_type = arm_current_func_type (); -+ int static_chain_stack_bytes = 0; -+ -+ if (TARGET_APCS_FRAME && frame_pointer_needed && TARGET_ARM && -+ IS_NESTED (func_type) && -+ df_regs_ever_live_p (3) && current_function_pretend_args_size == 0) -+ static_chain_stack_bytes = 4; -+ -+ return static_chain_stack_bytes; -+} -+ -+ - /* Compute a bit mask of which registers need to be -- saved on the stack for the current function. */ -+ saved on the stack for the current function. -+ This is used by arm_get_frame_offsets, which may add extra registers. */ - - static unsigned long - arm_compute_save_reg_mask (void) -@@ -10769,7 +12597,7 @@ arm_compute_save_reg_mask (void) - - /* If we are creating a stack frame, then we must save the frame pointer, - IP (which will hold the old stack pointer), LR and the PC. */ -- if (frame_pointer_needed && TARGET_ARM) -+ if (TARGET_APCS_FRAME && frame_pointer_needed && TARGET_ARM) - save_reg_mask |= - (1 << ARM_HARD_FRAME_POINTER_REGNUM) - | (1 << IP_REGNUM) -@@ -10804,7 +12632,9 @@ arm_compute_save_reg_mask (void) - - if (TARGET_REALLY_IWMMXT - && ((bit_count (save_reg_mask) -- + ARM_NUM_INTS (current_function_pretend_args_size)) % 2) != 0) -+ + ARM_NUM_INTS (current_function_pretend_args_size + -+ arm_compute_static_chain_stack_bytes()) -+ ) % 2) != 0) - { - /* The total number of registers that are going to be pushed - onto the stack is odd. We need to ensure that the stack -@@ -10882,13 +12712,33 @@ thumb1_compute_save_reg_mask (void) - reg = thumb_find_work_register (1 << LAST_LO_REGNUM); - /* Make sure the register returned by thumb_find_work_register is - not part of the return value. */ -- if (reg * UNITS_PER_WORD <= arm_size_return_regs ()) -+ if (reg * UNITS_PER_WORD <= (unsigned) arm_size_return_regs ()) - reg = LAST_LO_REGNUM; - - if (! call_used_regs[reg]) - mask |= 1 << reg; - } - -+ /* The 504 below is 8 bytes less than 512 because there are two possible -+ alignment words. We can't tell here if they will be present or not so we -+ have to play it safe and assume that they are. */ -+ if ((CALLER_INTERWORKING_SLOT_SIZE + -+ ROUND_UP_WORD (get_frame_size ()) + -+ current_function_outgoing_args_size) >= 504) -+ { -+ /* This is the same as the code in thumb1_expand_prologue() which -+ determines which register to use for stack decrement. */ -+ for (reg = LAST_ARG_REGNUM + 1; reg <= LAST_LO_REGNUM; reg++) -+ if (mask & (1 << reg)) -+ break; -+ -+ if (reg > LAST_LO_REGNUM) -+ { -+ /* Make sure we have a register available for stack decrement. */ -+ mask |= 1 << LAST_LO_REGNUM; -+ } -+ } -+ - return mask; - } - -@@ -10916,7 +12766,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; - } -@@ -10979,7 +12829,8 @@ output_return_instruction (rtx operand, - - return_used_this_function = 1; - -- live_regs_mask = arm_compute_save_reg_mask (); -+ offsets = arm_get_frame_offsets (); -+ live_regs_mask = offsets->saved_regs_mask; - - if (live_regs_mask) - { -@@ -11041,7 +12892,6 @@ output_return_instruction (rtx operand, - { - unsigned HOST_WIDE_INT stack_adjust; - -- offsets = arm_get_frame_offsets (); - stack_adjust = offsets->outgoing_args - offsets->saved_regs; - gcc_assert (stack_adjust == 0 || stack_adjust == 4); - -@@ -11245,6 +13095,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) - { -@@ -11289,7 +13174,7 @@ arm_output_epilogue (rtx sibling) - gcc_assert (!current_function_calls_eh_return || really_return); - - offsets = arm_get_frame_offsets (); -- saved_regs_mask = arm_compute_save_reg_mask (); -+ saved_regs_mask = offsets->saved_regs_mask; - - if (TARGET_IWMMXT) - lrm_count = bit_count (saved_regs_mask); -@@ -11300,7 +13185,7 @@ arm_output_epilogue (rtx sibling) - if (saved_regs_mask & (1 << reg)) - floats_offset += 4; - -- if (frame_pointer_needed && TARGET_ARM) -+ if (TARGET_APCS_FRAME && frame_pointer_needed && TARGET_ARM) - { - /* This variable is for the Virtual Frame Pointer, not VFP regs. */ - int vfp_offset = offsets->frame; -@@ -11446,32 +13331,88 @@ arm_output_epilogue (rtx sibling) - } - else - { -+ /* This branch is executed for ARM mode (non-apcs frames) and -+ Thumb-2 mode. Frame layout is essentially the same for those -+ cases, except that in ARM mode frame pointer points to the -+ first saved register, while in Thumb-2 mode the frame pointer points -+ to the last saved register. -+ -+ It is possible to make frame pointer point to last saved -+ register in both cases, and remove some conditionals below. -+ That means that fp setup in prologue would be just "mov fp, sp" -+ and sp restore in epilogue would be just "mov sp, fp", whereas -+ now we have to use add/sub in those cases. However, the value -+ of that would be marginal, as both mov and add/sub are 32-bit -+ in ARM mode, and it would require extra conditionals -+ in arm_expand_prologue to distingish ARM-apcs-frame case -+ (where frame pointer is required to point at first register) -+ and ARM-non-apcs-frame. Therefore, such change is postponed -+ until real need arise. */ - HOST_WIDE_INT amount; - int rfe; - /* Restore stack pointer if necessary. */ -- if (frame_pointer_needed) -+ if (TARGET_ARM && frame_pointer_needed) - { -- /* For Thumb-2 restore sp from the frame pointer. -- Operand restrictions mean we have to increment FP, then copy -- to SP. */ -- amount = offsets->locals_base - offsets->saved_regs; -- operands[0] = hard_frame_pointer_rtx; -+ operands[0] = stack_pointer_rtx; -+ operands[1] = hard_frame_pointer_rtx; -+ -+ operands[2] = GEN_INT (offsets->frame - offsets->saved_regs); -+ output_add_immediate (operands); - } - else - { -- operands[0] = stack_pointer_rtx; -- amount = offsets->outgoing_args - offsets->saved_regs; -- } -+ if (frame_pointer_needed) -+ { -+ /* For Thumb-2 restore sp from the frame pointer. -+ Operand restrictions mean we have to incrememnt FP, then copy -+ to SP. */ -+ amount = offsets->locals_base - offsets->saved_regs; -+ operands[0] = hard_frame_pointer_rtx; -+ } -+ else -+ { -+ unsigned long count; -+ operands[0] = stack_pointer_rtx; -+ amount = offsets->outgoing_args - offsets->saved_regs; -+ /* Pop call clobbered registers if it avoids a -+ separate stack adjustment. */ -+ count = offsets->saved_regs - offsets->saved_args; -+ if (optimize_size -+ && count != 0 -+ && !current_function_calls_eh_return -+ && bit_count (saved_regs_mask) * 4 == count -+ && !IS_INTERRUPT (func_type) -+ && !cfun->tail_call_emit) -+ { -+ unsigned long mask; -+ mask = (1 << (arm_size_return_regs () / 4)) - 1; -+ mask ^= 0xf; -+ mask &= ~saved_regs_mask; -+ reg = 0; -+ while (bit_count (mask) * 4 > amount) -+ { -+ while ((mask & (1 << reg)) == 0) -+ reg++; -+ mask &= ~(1 << reg); -+ } -+ if (bit_count (mask) * 4 == amount) -+ { -+ amount = 0; -+ saved_regs_mask |= mask; -+ } -+ } -+ } - -- if (amount) -- { -- operands[1] = operands[0]; -- operands[2] = GEN_INT (amount); -- output_add_immediate (operands); -+ if (amount) -+ { -+ operands[1] = operands[0]; -+ operands[2] = GEN_INT (amount); -+ output_add_immediate (operands); -+ } -+ if (frame_pointer_needed) -+ asm_fprintf (f, "\tmov\t%r, %r\n", -+ SP_REGNUM, HARD_FRAME_POINTER_REGNUM); - } -- if (frame_pointer_needed) -- asm_fprintf (f, "\tmov\t%r, %r\n", -- SP_REGNUM, HARD_FRAME_POINTER_REGNUM); - - if (arm_fpu_arch == FPUTYPE_FPA_EMU2) - { -@@ -11557,22 +13498,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); - } -@@ -11693,6 +13631,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)) -@@ -11930,7 +13894,8 @@ thumb_force_lr_save (void) - - - /* Calculate stack offsets. These are used to calculate register elimination -- offsets and in prologue/epilogue code. */ -+ offsets and in prologue/epilogue code. Also calculates which registers -+ should be saved. */ - - static arm_stack_offsets * - arm_get_frame_offsets (void) -@@ -11939,7 +13904,9 @@ arm_get_frame_offsets (void) - unsigned long func_type; - int leaf; - int saved; -+ int core_saved; - HOST_WIDE_INT frame_size; -+ int i; - - offsets = &cfun->machine->stack_offsets; - -@@ -11966,13 +13933,16 @@ arm_get_frame_offsets (void) - offsets->saved_args = current_function_pretend_args_size; - - /* In Thumb mode this is incorrect, but never used. */ -- offsets->frame = offsets->saved_args + (frame_pointer_needed ? 4 : 0); -+ offsets->frame = offsets->saved_args + (frame_pointer_needed ? 4 : 0) + -+ arm_compute_static_chain_stack_bytes(); - - if (TARGET_32BIT) - { - unsigned int regno; - -- saved = bit_count (arm_compute_save_reg_mask ()) * 4; -+ offsets->saved_regs_mask = arm_compute_save_reg_mask (); -+ core_saved = bit_count (offsets->saved_regs_mask) * 4; -+ saved = core_saved; - - /* We know that SP will be doubleword aligned on entry, and we must - preserve that condition at any subroutine call. We also require the -@@ -12003,13 +13973,16 @@ arm_get_frame_offsets (void) - } - else /* TARGET_THUMB1 */ - { -- saved = bit_count (thumb1_compute_save_reg_mask ()) * 4; -+ offsets->saved_regs_mask = thumb1_compute_save_reg_mask (); -+ core_saved = bit_count (offsets->saved_regs_mask) * 4; -+ saved = core_saved; - if (TARGET_BACKTRACE) - saved += 16; - } - - /* Saved registers include the stack frame. */ -- offsets->saved_regs = offsets->saved_args + saved; -+ offsets->saved_regs = offsets->saved_args + saved + -+ arm_compute_static_chain_stack_bytes(); - offsets->soft_frame = offsets->saved_regs + CALLER_INTERWORKING_SLOT_SIZE; - /* A leaf function does not need any stack alignment if it has nothing - on the stack. */ -@@ -12023,7 +13996,39 @@ arm_get_frame_offsets (void) - /* Ensure SFP has the correct alignment. */ - if (ARM_DOUBLEWORD_ALIGN - && (offsets->soft_frame & 7)) -- offsets->soft_frame += 4; -+ { -+ offsets->soft_frame += 4; -+ /* Try to align stack by pushing an extra reg. Don't bother doing this -+ when there is a stack frame as the alignment will be rolled into -+ the normal stack adjustment. */ -+ if (frame_size + current_function_outgoing_args_size == 0) -+ { -+ 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 -+ && !cfun->tail_call_emit) -+ { -+ /* Push/pop an argument register (r3) if all callee saved -+ registers are already being pushed. */ -+ reg = 3; -+ } -+ -+ if (reg != -1) -+ { -+ offsets->saved_regs += 4; -+ offsets->saved_regs_mask |= (1 << reg); -+ } -+ } -+ } - - offsets->locals_base = offsets->soft_frame + frame_size; - offsets->outgoing_args = (offsets->locals_base -@@ -12069,14 +14074,9 @@ arm_compute_initial_elimination_offset ( - return offsets->soft_frame - offsets->saved_args; - - case ARM_HARD_FRAME_POINTER_REGNUM: -- /* If there is no stack frame then the hard -- frame pointer and the arg pointer coincide. */ -- if (offsets->frame == offsets->saved_regs) -- return 0; -- /* FIXME: Not sure about this. Maybe we should always return 0 ? */ -- return (frame_pointer_needed -- && cfun->static_chain_decl != NULL -- && ! cfun->machine->uses_anonymous_args) ? 4 : 0; -+ /* This is only non-zero in the case where the static chain register -+ is stored above the frame. */ -+ return offsets->frame - offsets->saved_args - 4; - - case STACK_POINTER_REGNUM: - /* If nothing has been pushed on the stack at all -@@ -12229,9 +14229,20 @@ thumb_set_frame_pointer (arm_stack_offse - else - { - emit_insn (gen_movsi (hard_frame_pointer_rtx, GEN_INT (amount))); -- insn = emit_insn (gen_addsi3 (hard_frame_pointer_rtx, -- hard_frame_pointer_rtx, -- stack_pointer_rtx)); -+ /* Thumb-2 RTL patterns expect sp as the first input. Thumb-1 -+ expects the first two operands to be the same. */ -+ if (TARGET_THUMB2) -+ { -+ insn = emit_insn (gen_addsi3 (hard_frame_pointer_rtx, -+ stack_pointer_rtx, -+ hard_frame_pointer_rtx)); -+ } -+ else -+ { -+ insn = emit_insn (gen_addsi3 (hard_frame_pointer_rtx, -+ hard_frame_pointer_rtx, -+ stack_pointer_rtx)); -+ } - dwarf = gen_rtx_SET (VOIDmode, hard_frame_pointer_rtx, - plus_constant (stack_pointer_rtx, amount)); - RTX_FRAME_RELATED_P (dwarf) = 1; -@@ -12268,7 +14279,8 @@ arm_expand_prologue (void) - args_to_push = current_function_pretend_args_size; - - /* Compute which register we will have to save onto the stack. */ -- live_regs_mask = arm_compute_save_reg_mask (); -+ offsets = arm_get_frame_offsets (); -+ live_regs_mask = offsets->saved_regs_mask; - - ip_rtx = gen_rtx_REG (SImode, IP_REGNUM); - -@@ -12292,7 +14304,9 @@ arm_expand_prologue (void) - - r0 = gen_rtx_REG (SImode, 0); - r1 = gen_rtx_REG (SImode, 1); -- dwarf = gen_rtx_UNSPEC (SImode, NULL_RTVEC, UNSPEC_STACK_ALIGN); -+ /* Use a real rtvec rather than NULL_RTVEC so the rest of the -+ compiler won't choke. */ -+ dwarf = gen_rtx_UNSPEC (SImode, rtvec_alloc (0), UNSPEC_STACK_ALIGN); - dwarf = gen_rtx_SET (VOIDmode, r0, dwarf); - insn = gen_movsi (r0, stack_pointer_rtx); - RTX_FRAME_RELATED_P (insn) = 1; -@@ -12303,7 +14317,10 @@ arm_expand_prologue (void) - emit_insn (gen_movsi (stack_pointer_rtx, r1)); - } - -- if (frame_pointer_needed && TARGET_ARM) -+ /* For APCS frames, if IP register is clobbered -+ when creating frame, save that register in a special -+ way. */ -+ if (TARGET_APCS_FRAME && frame_pointer_needed && TARGET_ARM) - { - if (IS_INTERRUPT (func_type)) - { -@@ -12347,6 +14364,9 @@ arm_expand_prologue (void) - insn = emit_set_insn (gen_rtx_REG (SImode, 3), ip_rtx); - else if (args_to_push == 0) - { -+ gcc_assert(arm_compute_static_chain_stack_bytes() == 4); -+ saved_regs += 4; -+ - rtx dwarf; - - insn = gen_rtx_PRE_DEC (SImode, stack_pointer_rtx); -@@ -12402,13 +14422,13 @@ arm_expand_prologue (void) - } - - /* If this is an interrupt service routine, and the link register -- is going to be pushed, and we are not creating a stack frame, -- (which would involve an extra push of IP and a pop in the epilogue) -+ is going to be pushed, and we're not generating extra -+ push of IP (needed when frame is needed and frame layout if apcs), - subtracting four from LR now will mean that the function return - can be done with a single instruction. */ - if ((func_type == ARM_FT_ISR || func_type == ARM_FT_FIQ) - && (live_regs_mask & (1 << LR_REGNUM)) != 0 -- && ! frame_pointer_needed -+ && !(frame_pointer_needed && TARGET_APCS_FRAME) - && TARGET_ARM) - { - rtx lr = gen_rtx_REG (SImode, LR_REGNUM); -@@ -12418,8 +14438,28 @@ arm_expand_prologue (void) - - if (live_regs_mask) - { -- insn = emit_multi_reg_push (live_regs_mask); - saved_regs += bit_count (live_regs_mask) * 4; -+ if (optimize_size && !frame_pointer_needed -+ && saved_regs == offsets->saved_regs - offsets->saved_args) -+ { -+ /* If no coprocessor registers are being pushed and we don't have -+ to worry about a frame pointer then push extra registers to -+ create the stack frame. This is done is a way that does not -+ alter teh frame layout, so is independent of the epilogue. */ -+ int n; -+ int frame; -+ n = 0; -+ while (n < 8 && (live_regs_mask & (1 << n)) == 0) -+ n++; -+ frame = offsets->outgoing_args - (offsets->saved_args + saved_regs); -+ if (frame && n * 4 >= frame) -+ { -+ n = frame / 4; -+ live_regs_mask |= (1 << n) - 1; -+ saved_regs += frame; -+ } -+ } -+ insn = emit_multi_reg_push (live_regs_mask); - RTX_FRAME_RELATED_P (insn) = 1; - } - -@@ -12429,6 +14469,7 @@ arm_expand_prologue (void) - if (frame_pointer_needed && TARGET_ARM) - { - /* Create the new frame pointer. */ -+ if (TARGET_APCS_FRAME) - { - insn = GEN_INT (-(4 + args_to_push + fp_offset)); - insn = emit_insn (gen_addsi3 (hard_frame_pointer_rtx, ip_rtx, insn)); -@@ -12450,9 +14491,15 @@ arm_expand_prologue (void) - emit_insn (gen_prologue_use (ip_rtx)); - } - } -+ else -+ { -+ insn = GEN_INT (saved_regs - 4); -+ insn = emit_insn (gen_addsi3 (hard_frame_pointer_rtx, -+ stack_pointer_rtx, insn)); -+ RTX_FRAME_RELATED_P (insn) = 1; -+ } - } - -- offsets = arm_get_frame_offsets (); - if (offsets->outgoing_args != offsets->saved_args + saved_regs) - { - /* This add can produce multiple insns for a large constant, so we -@@ -12633,10 +14680,21 @@ arm_print_operand (FILE *stream, rtx x, - } - return; - -- /* An integer without a preceding # sign. */ -+ /* An integer or symbol address without a preceding # sign. */ - case 'c': -- gcc_assert (GET_CODE (x) == CONST_INT); -- fprintf (stream, HOST_WIDE_INT_PRINT_DEC, INTVAL (x)); -+ switch (GET_CODE (x)) -+ { -+ case CONST_INT: -+ fprintf (stream, HOST_WIDE_INT_PRINT_DEC, INTVAL (x)); -+ break; -+ -+ case SYMBOL_REF: -+ output_addr_const (stream, x); -+ break; -+ -+ default: -+ gcc_unreachable (); -+ } - return; - - case 'B': -@@ -12693,7 +14751,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); - } -@@ -13031,6 +15093,49 @@ arm_print_operand (FILE *stream, rtx x, - } - return; - -+ /* Memory operand for vld1/vst1 instruction. */ -+ case 'A': -+ { -+ rtx addr; -+ bool postinc = FALSE; -+ gcc_assert (GET_CODE (x) == MEM); -+ addr = XEXP (x, 0); -+ if (GET_CODE (addr) == POST_INC) -+ { -+ postinc = 1; -+ addr = XEXP (addr, 0); -+ } -+ asm_fprintf (stream, "[%r]", REGNO (addr)); -+ 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) - { -@@ -13064,6 +15169,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; - } -@@ -13104,28 +15215,16 @@ arm_assemble_integer (rtx x, unsigned in - if (arm_vector_mode_supported_p (mode)) - { - int i, units; -- unsigned int invmask = 0, parts_per_word; - - gcc_assert (GET_CODE (x) == CONST_VECTOR); - - units = CONST_VECTOR_NUNITS (x); - size = GET_MODE_SIZE (GET_MODE_INNER (mode)); - -- /* For big-endian Neon vectors, we must permute the vector to the form -- which, when loaded by a VLDR or VLDM instruction, will give a vector -- with the elements in the right order. */ -- if (TARGET_NEON && WORDS_BIG_ENDIAN) -- { -- parts_per_word = UNITS_PER_WORD / size; -- /* FIXME: This might be wrong for 64-bit vector elements, but we don't -- support those anywhere yet. */ -- invmask = (parts_per_word == 0) ? 0 : (1 << (parts_per_word - 1)) - 1; -- } -- - if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT) - for (i = 0; i < units; i++) - { -- rtx elt = CONST_VECTOR_ELT (x, i ^ invmask); -+ rtx elt = CONST_VECTOR_ELT (x, i); - assemble_integer - (elt, size, i == 0 ? BIGGEST_ALIGNMENT : size * BITS_PER_UNIT, 1); - } -@@ -13467,6 +15566,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) -@@ -13840,6 +15943,12 @@ 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 the NEON extensions for -+ loading/storing them, too. */ -+ if (mode == HFmode) -+ return TARGET_NEON_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) -@@ -13859,16 +15968,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) -@@ -14913,6 +17022,24 @@ arm_init_neon_builtins (void) - TYPE_PRECISION (neon_float_type_node) = FLOAT_TYPE_SIZE; - layout_type (neon_float_type_node); - -+ /* Define typedefs which exactly correspond to the modes we are basing vector -+ types on. If you change these names you'll need to change -+ the table used by arm_mangle_type too. */ -+ (*lang_hooks.types.register_builtin_type) (neon_intQI_type_node, -+ "__builtin_neon_qi"); -+ (*lang_hooks.types.register_builtin_type) (neon_intHI_type_node, -+ "__builtin_neon_hi"); -+ (*lang_hooks.types.register_builtin_type) (neon_intSI_type_node, -+ "__builtin_neon_si"); -+ (*lang_hooks.types.register_builtin_type) (neon_float_type_node, -+ "__builtin_neon_sf"); -+ (*lang_hooks.types.register_builtin_type) (neon_intDI_type_node, -+ "__builtin_neon_di"); -+ (*lang_hooks.types.register_builtin_type) (neon_polyQI_type_node, -+ "__builtin_neon_poly8"); -+ (*lang_hooks.types.register_builtin_type) (neon_polyHI_type_node, -+ "__builtin_neon_poly16"); -+ - intQI_pointer_node = build_pointer_type (neon_intQI_type_node); - intHI_pointer_node = build_pointer_type (neon_intHI_type_node); - intSI_pointer_node = build_pointer_type (neon_intSI_type_node); -@@ -14965,12 +17092,32 @@ arm_init_neon_builtins (void) - intUSI_type_node = make_unsigned_type (GET_MODE_PRECISION (SImode)); - intUDI_type_node = make_unsigned_type (GET_MODE_PRECISION (DImode)); - -+ (*lang_hooks.types.register_builtin_type) (intUQI_type_node, -+ "__builtin_neon_uqi"); -+ (*lang_hooks.types.register_builtin_type) (intUHI_type_node, -+ "__builtin_neon_uhi"); -+ (*lang_hooks.types.register_builtin_type) (intUSI_type_node, -+ "__builtin_neon_usi"); -+ (*lang_hooks.types.register_builtin_type) (intUDI_type_node, -+ "__builtin_neon_udi"); -+ - /* Opaque integer types for structures of vectors. */ - intEI_type_node = make_signed_type (GET_MODE_PRECISION (EImode)); - intOI_type_node = make_signed_type (GET_MODE_PRECISION (OImode)); - intCI_type_node = make_signed_type (GET_MODE_PRECISION (CImode)); - intXI_type_node = make_signed_type (GET_MODE_PRECISION (XImode)); - -+ (*lang_hooks.types.register_builtin_type) (intTI_type_node, -+ "__builtin_neon_ti"); -+ (*lang_hooks.types.register_builtin_type) (intEI_type_node, -+ "__builtin_neon_ei"); -+ (*lang_hooks.types.register_builtin_type) (intOI_type_node, -+ "__builtin_neon_oi"); -+ (*lang_hooks.types.register_builtin_type) (intCI_type_node, -+ "__builtin_neon_ci"); -+ (*lang_hooks.types.register_builtin_type) (intXI_type_node, -+ "__builtin_neon_xi"); -+ - /* Pointers to vector types. */ - V8QI_pointer_node = build_pointer_type (V8QI_type_node); - V4HI_pointer_node = build_pointer_type (V4HI_type_node); -@@ -15014,44 +17161,6 @@ arm_init_neon_builtins (void) - build_function_type_list (void_type_node, V2DI_pointer_node, V2DI_type_node, - V2DI_type_node, NULL); - -- /* Define typedefs which exactly correspond to the modes we are basing vector -- types on. If you change these names you'll need to change -- the table used by arm_mangle_type too. */ -- (*lang_hooks.types.register_builtin_type) (neon_intQI_type_node, -- "__builtin_neon_qi"); -- (*lang_hooks.types.register_builtin_type) (neon_intHI_type_node, -- "__builtin_neon_hi"); -- (*lang_hooks.types.register_builtin_type) (neon_intSI_type_node, -- "__builtin_neon_si"); -- (*lang_hooks.types.register_builtin_type) (neon_float_type_node, -- "__builtin_neon_sf"); -- (*lang_hooks.types.register_builtin_type) (neon_intDI_type_node, -- "__builtin_neon_di"); -- -- (*lang_hooks.types.register_builtin_type) (neon_polyQI_type_node, -- "__builtin_neon_poly8"); -- (*lang_hooks.types.register_builtin_type) (neon_polyHI_type_node, -- "__builtin_neon_poly16"); -- (*lang_hooks.types.register_builtin_type) (intUQI_type_node, -- "__builtin_neon_uqi"); -- (*lang_hooks.types.register_builtin_type) (intUHI_type_node, -- "__builtin_neon_uhi"); -- (*lang_hooks.types.register_builtin_type) (intUSI_type_node, -- "__builtin_neon_usi"); -- (*lang_hooks.types.register_builtin_type) (intUDI_type_node, -- "__builtin_neon_udi"); -- -- (*lang_hooks.types.register_builtin_type) (intTI_type_node, -- "__builtin_neon_ti"); -- (*lang_hooks.types.register_builtin_type) (intEI_type_node, -- "__builtin_neon_ei"); -- (*lang_hooks.types.register_builtin_type) (intOI_type_node, -- "__builtin_neon_oi"); -- (*lang_hooks.types.register_builtin_type) (intCI_type_node, -- "__builtin_neon_ci"); -- (*lang_hooks.types.register_builtin_type) (intXI_type_node, -- "__builtin_neon_xi"); -- - dreg_types[0] = V8QI_type_node; - dreg_types[1] = V4HI_type_node; - dreg_types[2] = V2SI_type_node; -@@ -15325,6 +17434,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 (); -@@ -15334,6 +17452,52 @@ 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. */ -+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; - } - - /* Errors in the source file can cause expand_expr to return const0_rtx -@@ -16514,6 +18678,7 @@ is_called_in_ARM_mode (tree func) - const char * - thumb_unexpanded_epilogue (void) - { -+ arm_stack_offsets *offsets; - int regno; - unsigned long live_regs_mask = 0; - int high_regs_pushed = 0; -@@ -16526,7 +18691,8 @@ thumb_unexpanded_epilogue (void) - if (IS_NAKED (arm_current_func_type ())) - return ""; - -- live_regs_mask = thumb1_compute_save_reg_mask (); -+ offsets = arm_get_frame_offsets (); -+ live_regs_mask = offsets->saved_regs_mask; - high_regs_pushed = bit_count (live_regs_mask & 0x0f00); - - /* If we can deduce the registers used from the function's return value. -@@ -16788,7 +18954,8 @@ thumb1_expand_prologue (void) - return; - } - -- live_regs_mask = thumb1_compute_save_reg_mask (); -+ offsets = arm_get_frame_offsets (); -+ live_regs_mask = offsets->saved_regs_mask; - /* Load the pic register before setting the frame pointer, - so we can use r7 as a temporary work register. */ - if (flag_pic && arm_pic_register != INVALID_REGNUM) -@@ -16798,7 +18965,6 @@ thumb1_expand_prologue (void) - emit_move_insn (gen_rtx_REG (Pmode, ARM_HARD_FRAME_POINTER_REGNUM), - stack_pointer_rtx); - -- offsets = arm_get_frame_offsets (); - amount = offsets->outgoing_args - offsets->saved_regs; - if (amount) - { -@@ -16827,62 +18993,25 @@ thumb1_expand_prologue (void) - been pushed at the start of the prologue and so we can corrupt - it now. */ - for (regno = LAST_ARG_REGNUM + 1; regno <= LAST_LO_REGNUM; regno++) -- if (live_regs_mask & (1 << regno) -- && !(frame_pointer_needed -- && (regno == THUMB_HARD_FRAME_POINTER_REGNUM))) -+ if (live_regs_mask & (1 << regno)) - break; - -- if (regno > LAST_LO_REGNUM) /* Very unlikely. */ -- { -- rtx spare = gen_rtx_REG (SImode, IP_REGNUM); -- -- /* Choose an arbitrary, non-argument low register. */ -- reg = gen_rtx_REG (SImode, LAST_LO_REGNUM); -- -- /* Save it by copying it into a high, scratch register. */ -- emit_insn (gen_movsi (spare, reg)); -- /* Add a USE to stop propagate_one_insn() from barfing. */ -- emit_insn (gen_prologue_use (spare)); -+ gcc_assert(regno <= LAST_LO_REGNUM); - -- /* Decrement the stack. */ -- emit_insn (gen_movsi (reg, GEN_INT (- amount))); -- insn = emit_insn (gen_addsi3 (stack_pointer_rtx, -- stack_pointer_rtx, reg)); -- RTX_FRAME_RELATED_P (insn) = 1; -- dwarf = gen_rtx_SET (VOIDmode, stack_pointer_rtx, -- plus_constant (stack_pointer_rtx, -- -amount)); -- RTX_FRAME_RELATED_P (dwarf) = 1; -- REG_NOTES (insn) -- = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, dwarf, -- REG_NOTES (insn)); -- -- /* Restore the low register's original value. */ -- emit_insn (gen_movsi (reg, spare)); -- -- /* Emit a USE of the restored scratch register, so that flow -- analysis will not consider the restore redundant. The -- register won't be used again in this function and isn't -- restored by the epilogue. */ -- emit_insn (gen_prologue_use (reg)); -- } -- else -- { -- reg = gen_rtx_REG (SImode, regno); -+ reg = gen_rtx_REG (SImode, regno); - -- emit_insn (gen_movsi (reg, GEN_INT (- amount))); -+ emit_insn (gen_movsi (reg, GEN_INT (- amount))); - -- insn = emit_insn (gen_addsi3 (stack_pointer_rtx, -- stack_pointer_rtx, reg)); -- RTX_FRAME_RELATED_P (insn) = 1; -- dwarf = gen_rtx_SET (VOIDmode, stack_pointer_rtx, -- plus_constant (stack_pointer_rtx, -- -amount)); -- RTX_FRAME_RELATED_P (dwarf) = 1; -- REG_NOTES (insn) -- = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, dwarf, -- REG_NOTES (insn)); -- } -+ insn = emit_insn (gen_addsi3 (stack_pointer_rtx, -+ stack_pointer_rtx, reg)); -+ RTX_FRAME_RELATED_P (insn) = 1; -+ dwarf = gen_rtx_SET (VOIDmode, stack_pointer_rtx, -+ plus_constant (stack_pointer_rtx, -+ -amount)); -+ RTX_FRAME_RELATED_P (dwarf) = 1; -+ REG_NOTES (insn) -+ = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, dwarf, -+ REG_NOTES (insn)); - } - } - -@@ -16960,6 +19089,7 @@ thumb1_expand_epilogue (void) - static void - thumb1_output_function_prologue (FILE *f, HOST_WIDE_INT size ATTRIBUTE_UNUSED) - { -+ arm_stack_offsets *offsets; - unsigned long live_regs_mask = 0; - unsigned long l_mask; - unsigned high_regs_pushed = 0; -@@ -17044,7 +19174,8 @@ thumb1_output_function_prologue (FILE *f - } - - /* Get the registers we are going to push. */ -- live_regs_mask = thumb1_compute_save_reg_mask (); -+ offsets = arm_get_frame_offsets (); -+ live_regs_mask = offsets->saved_regs_mask; - /* Extract a mask of the ones we can give to the Thumb's push instruction. */ - l_mask = live_regs_mask & 0x40ff; - /* Then count how many other high registers will need to be pushed. */ -@@ -17551,14 +19682,22 @@ arm_file_start (void) - 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 = "vfp3"; -+ fpu_name = "vfpv3"; - set_float_abi_attributes = 1; - break; - case FPUTYPE_NEON: - fpu_name = "neon"; - set_float_abi_attributes = 1; - break; -+ case FPUTYPE_NEON_FP16: -+ fpu_name = "neon-fp16"; -+ set_float_abi_attributes = 1; -+ break; - default: - abort(); - } -@@ -17612,6 +19751,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(); - } -@@ -17694,12 +19838,23 @@ arm_output_mi_thunk (FILE *file, tree th - ? 1 : 0); - if (mi_delta < 0) - mi_delta = - mi_delta; -- /* When generating 16-bit thumb code, thunks are entered in arm mode. */ -+ - if (TARGET_THUMB1) - { - int labelno = thunk_label++; - ASM_GENERATE_INTERNAL_LABEL (label, "LTHUMBFUNC", labelno); -- fputs ("\tldr\tr12, ", file); -+ /* Thunks are entered in arm mode when avaiable. */ -+ if (TARGET_THUMB1_ONLY) -+ { -+ /* push r3 so we can use it as a temporary. */ -+ /* TODO: Omit this save if r3 is not used. */ -+ fputs ("\tpush {r3}\n", file); -+ fputs ("\tldr\tr3, ", file); -+ } -+ else -+ { -+ fputs ("\tldr\tr12, ", file); -+ } - assemble_name (file, label); - fputc ('\n', file); - if (flag_pic) -@@ -17713,29 +19868,63 @@ arm_output_mi_thunk (FILE *file, tree th - - Note that we have "+ 1" because some versions of GNU ld - don't set the low bit of the result for R_ARM_REL32 -- relocations against thumb function symbols. */ -+ relocations against thumb function symbols. -+ On ARMV6M this is +4, not +8. */ - ASM_GENERATE_INTERNAL_LABEL (labelpc, "LTHUNKPC", labelno); - assemble_name (file, labelpc); - fputs (":\n", file); -- fputs ("\tadd\tr12, pc, r12\n", file); -+ if (TARGET_THUMB1_ONLY) -+ { -+ /* This is 2 insns after the start of the thunk, so we know it -+ is 4-byte aligned. */ -+ fputs ("\tadd\tr3, pc, r3\n", file); -+ fputs ("\tmov r12, r3\n", file); -+ } -+ else -+ fputs ("\tadd\tr12, pc, r12\n", file); - } -+ else if (TARGET_THUMB1_ONLY) -+ fputs ("\tmov r12, r3\n", file); - } -- /* TODO: Use movw/movt for large constants when available. */ -- while (mi_delta != 0) -+ if (TARGET_THUMB1_ONLY) - { -- if ((mi_delta & (3 << shift)) == 0) -- shift += 2; -- else -- { -- asm_fprintf (file, "\t%s\t%r, %r, #%d\n", -- mi_op, this_regno, this_regno, -- mi_delta & (0xff << shift)); -- mi_delta &= ~(0xff << shift); -- shift += 8; -- } -+ if (mi_delta > 255) -+ { -+ fputs ("\tldr\tr3, ", file); -+ assemble_name (file, label); -+ fputs ("+4\n", file); -+ asm_fprintf (file, "\t%s\t%r, %r, r3\n", -+ mi_op, this_regno, this_regno); -+ } -+ else if (mi_delta != 0) -+ { -+ asm_fprintf (file, "\t%s\t%r, %r, #%d\n", -+ mi_op, this_regno, this_regno, -+ mi_delta); -+ } -+ } -+ else -+ { -+ /* TODO: Use movw/movt for large constants when available. */ -+ while (mi_delta != 0) -+ { -+ if ((mi_delta & (3 << shift)) == 0) -+ shift += 2; -+ else -+ { -+ asm_fprintf (file, "\t%s\t%r, %r, #%d\n", -+ mi_op, this_regno, this_regno, -+ mi_delta & (0xff << shift)); -+ mi_delta &= ~(0xff << shift); -+ shift += 8; -+ } -+ } - } - if (TARGET_THUMB1) - { -+ if (TARGET_THUMB1_ONLY) -+ fputs ("\tpop\t{r3}\n", file); -+ - fprintf (file, "\tbx\tr12\n"); - ASM_OUTPUT_ALIGN (file, 2); - assemble_name (file, label); -@@ -17754,6 +19943,9 @@ arm_output_mi_thunk (FILE *file, tree th - else - /* Output ".word .LTHUNKn". */ - assemble_integer (XEXP (DECL_RTL (function), 0), 4, BITS_PER_WORD, 1); -+ -+ if (TARGET_THUMB1_ONLY && mi_delta > 255) -+ assemble_integer (GEN_INT(mi_delta), 4, BITS_PER_WORD, 1); - } - else - { -@@ -17793,6 +19985,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) - { -@@ -17830,19 +20039,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; - } -@@ -17956,8 +20170,14 @@ arm_no_early_mul_dep (rtx producer, rtx - op = XVECEXP (op, 0, 0); - op = XEXP (op, 1); - -- return (GET_CODE (op) == PLUS -- && !reg_overlap_mentioned_p (value, XEXP (op, 0))); -+ if (GET_CODE (op) == PLUS || GET_CODE (op) == MINUS) -+ { -+ if (GET_CODE (XEXP (op, 0)) == MULT) -+ return !reg_overlap_mentioned_p (value, XEXP (op, 0)); -+ else -+ return !reg_overlap_mentioned_p (value, XEXP (op, 1)); -+ } -+ return 0; - } - - /* We can't rely on the caller doing the proper promotion when -@@ -18084,7 +20304,8 @@ arm_cxx_key_method_may_be_inline (void) - static void - arm_cxx_determine_class_data_visibility (tree decl) - { -- if (!TARGET_AAPCS_BASED) -+ if (!TARGET_AAPCS_BASED -+ || !TARGET_DLLIMPORT_DECL_ATTRIBUTES) - return; - - /* In general, \S 3.2.5.5 of the ARM EABI requires that class data -@@ -18124,7 +20345,8 @@ arm_set_return_address (rtx source, rtx - rtx addr; - unsigned long saved_regs; - -- saved_regs = arm_compute_save_reg_mask (); -+ offsets = arm_get_frame_offsets (); -+ saved_regs = offsets->saved_regs_mask; - - if ((saved_regs & (1 << LR_REGNUM)) == 0) - emit_move_insn (gen_rtx_REG (Pmode, LR_REGNUM), source); -@@ -18135,7 +20357,6 @@ arm_set_return_address (rtx source, rtx - else - { - /* LR will be the first saved register. */ -- offsets = arm_get_frame_offsets (); - delta = offsets->outgoing_args - (offsets->frame + 4); - - -@@ -18168,11 +20389,10 @@ thumb_set_return_address (rtx source, rt - - emit_insn (gen_rtx_USE (VOIDmode, source)); - -- mask = thumb1_compute_save_reg_mask (); -+ offsets = arm_get_frame_offsets (); -+ mask = offsets->saved_regs_mask; - if (mask & (1 << LR_REGNUM)) - { -- offsets = arm_get_frame_offsets (); -- - limit = 1024; - /* Find the saved regs. */ - if (frame_pointer_needed) -@@ -18219,9 +20439,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; -@@ -18252,9 +20473,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; -@@ -18265,6 +20491,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 -@@ -18483,6 +20742,11 @@ arm_unwind_emit (FILE * asm_out_file, rt - if (!ARM_EABI_UNWIND_TABLES) - return; - -+ if (!(flag_unwind_tables || cfun->uses_eh_lsda) -+ && (TREE_NOTHROW (current_function_decl) -+ || cfun->all_throwers_are_sibcalls)) -+ return; -+ - if (GET_CODE (insn) == NOTE || !RTX_FRAME_RELATED_P (insn)) - return; - -@@ -18563,7 +20827,17 @@ arm_output_fn_unwind (FILE * f, bool pro - if (prologue) - fputs ("\t.fnstart\n", f); - else -- fputs ("\t.fnend\n", f); -+ { -+ /* If this function will never be unwound, then mark it as such. -+ The came condition is used in arm_unwind_emit to suppress -+ the frame annotations. */ -+ if (!(flag_unwind_tables || cfun->uses_eh_lsda) -+ && (TREE_NOTHROW (current_function_decl) -+ || cfun->all_throwers_are_sibcalls)) -+ fputs("\t.cantunwind\n", f); -+ -+ fputs ("\t.fnend\n", f); -+ } - } - - static bool -@@ -18757,6 +21031,17 @@ arm_mangle_type (const_tree type) - { - arm_mangle_map_entry *pos = arm_mangle_map; - -+ /* Half-precision float. */ -+ if (TREE_CODE (type) == REAL_TYPE && TYPE_PRECISION (type) == 16) -+ return "Dh"; -+ -+ /* Although the ARM ABI documents do not specifically say that -+ "__va_list" has to be managled as if it is in the "std" -+ namespace, that is what RealView does. */ -+ if (TARGET_AAPCS_BASED -+ && lang_hooks.types_compatible_p (type, va_list_type)) -+ return "St9__va_list"; -+ - if (TREE_CODE (type) != VECTOR_TYPE) - return NULL; - -@@ -18779,5 +21064,91 @@ arm_mangle_type (const_tree type) - vector types. */ - return NULL; - } -+ -+/* Return how many instructions the machine can issue per cycle. */ -+static int -+arm_issue_rate (void) -+{ -+ switch (arm_tune) -+ { -+ case marvell_f: -+ case cortexr4: -+ case cortexr4f: -+ case cortexa8: -+ case cortexa9: -+ return 2; -+ default: -+ return 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; -+} -+ -+/* Set default optimization options. */ -+void -+arm_optimization_options (int level, int size ATTRIBUTE_UNUSED) -+{ -+ /* Enable section anchors by default at -O1 or higher. */ -+ flag_section_anchors = (level > 0 ? 1 : 0); -+ -+ 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); -+ } -+} -+ -+/* Order of allocation of core registers for Thumb: this allocation is -+ written over the corresponding initial entries of the array -+ initialized with REG_ALLOC_ORDER. We allocate all low registers -+ first. Saving and restoring a low register is usually cheaper than -+ using a call-clobbered high register. */ -+ -+static const int thumb_core_reg_alloc_order[] = -+{ -+ 3, 2, 1, 0, 4, 5, 6, 7, -+ 14, 12, 8, 9, 10, 11, 13, 15 -+}; -+ -+/* Adjust register allocation order when compiling for Thumb. */ -+ -+void -+arm_adjust_reg_alloc_order (int *order) -+{ -+ if (TARGET_THUMB) -+ memcpy (order, thumb_core_reg_alloc_order, -+ sizeof (thumb_core_reg_alloc_order)); -+} - - #include "gt-arm.h" -+ ---- a/gcc/config/arm/arm.h -+++ b/gcc/config/arm/arm.h -@@ -84,6 +84,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. */ -@@ -198,6 +202,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) - -@@ -207,24 +218,36 @@ extern void (*arm_lang_output_object_att - #define TARGET_32BIT (TARGET_ARM || arm_arch_thumb2) - /* 32-bit Thumb-2 code. */ - #define TARGET_THUMB2 (TARGET_THUMB && arm_arch_thumb2) -+/* Thumb-1 only. */ -+#define TARGET_THUMB1_ONLY (TARGET_THUMB1 && !arm_arch_notm) - - /* The following two macros concern the ability to execute coprocessor -- instructions for VFPv3 or NEON. TARGET_VFP3 is 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. */ -+ 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 \ -+ || arm_fpu_arch == FPUTYPE_NEON_FP16)) - --/* FPU is VFPv3 (with twice the number of D registers). Setting the FPU to -- Neon automatically enables VFPv3 too. */ -+/* FPU supports VFPv3 instructions. */ - #define TARGET_VFP3 (arm_fp_model == ARM_FP_MODEL_VFP \ -- && (arm_fpu_arch == FPUTYPE_VFP3 \ -- || arm_fpu_arch == FPUTYPE_NEON)) -+ && (arm_fpu_arch == FPUTYPE_VFP3D16 \ -+ || TARGET_VFPD32)) -+ -+/* FPU supports NEON/VFP half-precision floating-point. */ -+#define TARGET_NEON_FP16 (arm_fpu_arch == FPUTYPE_NEON_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) -+ && (arm_fpu_arch == FPUTYPE_NEON \ -+ || arm_fpu_arch == FPUTYPE_NEON_FP16)) - - /* "DSP" multiply instructions, eg. SMULxy. */ - #define TARGET_DSP_MULTIPLY \ -@@ -233,6 +256,9 @@ extern void (*arm_lang_output_object_att - #define TARGET_INT_SIMD \ - (TARGET_32BIT && arm_arch6 && arm_arch_notm) - -+/* Should MOVW/MOVT be used in preference to a constant pool. */ -+#define TARGET_USE_MOVT (arm_arch_thumb2 && !optimize_size) -+ - /* We could use unified syntax for arm mode, but for now we just use it - for Thumb-2. */ - #define TARGET_UNIFIED_ASM TARGET_THUMB2 -@@ -296,10 +322,14 @@ enum fputype - FPUTYPE_MAVERICK, - /* VFP. */ - FPUTYPE_VFP, -+ /* VFPv3-D16. */ -+ FPUTYPE_VFP3D16, - /* VFPv3. */ - FPUTYPE_VFP3, - /* Neon. */ -- FPUTYPE_NEON -+ FPUTYPE_NEON, -+ /* Neon with half-precision float extensions. */ -+ FPUTYPE_NEON_FP16 - }; - - /* Recast the floating point class to be the floating point attribute. */ -@@ -324,6 +354,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 - { -@@ -376,6 +421,9 @@ 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; - -@@ -391,9 +439,15 @@ 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; - -+/* Nonzero if tuning for Cortex-A9. */ -+extern int arm_tune_cortex_a9; -+ - /* 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 -@@ -407,6 +461,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 -@@ -417,6 +475,9 @@ extern int arm_arch_hwdiv; - - #define OVERRIDE_OPTIONS arm_override_options () - -+#define OPTIMIZATION_OPTIONS(LEVEL,SIZE) \ -+ arm_optimization_options ((LEVEL), (SIZE)) -+ - /* Nonzero if PIC code requires explicit qualifiers to generate - PLT and GOT relocs rather than the assembler doing so implicitly. - Subtargets can override these if required. */ -@@ -725,12 +786,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; \ -@@ -849,6 +909,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) - -@@ -942,7 +1005,7 @@ extern int arm_structure_size_boundary; - #define FIRST_VFP_REGNUM 63 - #define D7_VFP_REGNUM 78 /* Registers 77 and 78 == VFP reg D7. */ - #define LAST_VFP_REGNUM \ -- (TARGET_VFP3 ? LAST_HI_VFP_REGNUM : LAST_LO_VFP_REGNUM) -+ (TARGET_VFPD32 ? LAST_HI_VFP_REGNUM : LAST_LO_VFP_REGNUM) - - #define IS_VFP_REGNUM(REGNUM) \ - (((REGNUM) >= FIRST_VFP_REGNUM) && ((REGNUM) <= LAST_VFP_REGNUM)) -@@ -1027,7 +1090,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) \ -@@ -1053,7 +1116,10 @@ extern int arm_structure_size_boundary; - For VFP/VFPv3, allocate D16-D31 first, then caller-saved registers (D0-D7), - then D8-D15. The reason for doing this is to attempt to reduce register - pressure when both single- and double-precision registers are used in a -- function. */ -+ function. -+ -+ The allocation order for Thumb differs from that given here: -+ see arm.c:adjust_reg_alloc_order. */ - - #define REG_ALLOC_ORDER \ - { \ -@@ -1106,6 +1172,7 @@ enum reg_class - CC_REG, - VFPCC_REG, - GENERAL_REGS, -+ CORE_REGS, - ALL_REGS, - LIM_REG_CLASSES - }; -@@ -1131,6 +1198,7 @@ enum reg_class - "CC_REG", \ - "VFPCC_REG", \ - "GENERAL_REGS", \ -+ "CORE_REGS", \ - "ALL_REGS", \ - } - -@@ -1151,10 +1219,11 @@ enum reg_class - { 0x000000FF, 0x00000000, 0x00000000, 0x00000000 }, /* LO_REGS */ \ - { 0x00002000, 0x00000000, 0x00000000, 0x00000000 }, /* STACK_REG */ \ - { 0x000020FF, 0x00000000, 0x00000000, 0x00000000 }, /* BASE_REGS */ \ -- { 0x0000FF00, 0x00000000, 0x00000000, 0x00000000 }, /* HI_REGS */ \ -+ { 0x0000DF00, 0x00000000, 0x00000000, 0x00000000 }, /* HI_REGS */ \ - { 0x01000000, 0x00000000, 0x00000000, 0x00000000 }, /* CC_REG */ \ - { 0x00000000, 0x00000000, 0x00000000, 0x80000000 }, /* VFPCC_REG */ \ -- { 0x0200FFFF, 0x00000000, 0x00000000, 0x00000000 }, /* GENERAL_REGS */ \ -+ { 0x0200DFFF, 0x00000000, 0x00000000, 0x00000000 }, /* GENERAL_REGS */ \ -+ { 0x0200FFFF, 0x00000000, 0x00000000, 0x00000000 }, /* CORE_REGS */ \ - { 0xFAFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x7FFFFFFF } /* ALL_REGS */ \ - } - -@@ -1178,22 +1247,25 @@ 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. */ - #define INDEX_REG_CLASS (TARGET_THUMB1 ? LO_REGS : GENERAL_REGS) --#define BASE_REG_CLASS (TARGET_THUMB1 ? LO_REGS : GENERAL_REGS) -+#define BASE_REG_CLASS (TARGET_THUMB1 ? LO_REGS : CORE_REGS) - - /* For the Thumb the high registers cannot be used as base registers - 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 ? GENERAL_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 -@@ -1213,7 +1285,8 @@ enum reg_class - #define PREFERRED_RELOAD_CLASS(X, CLASS) \ - (TARGET_ARM ? (CLASS) : \ - ((CLASS) == GENERAL_REGS || (CLASS) == HI_REGS \ -- || (CLASS) == NO_REGS ? LO_REGS : (CLASS))) -+ || (CLASS) == NO_REGS || (CLASS) == STACK_REG \ -+ ? LO_REGS : (CLASS))) - - /* Must leave BASE_REGS reloads alone */ - #define THUMB_SECONDARY_INPUT_RELOAD_CLASS(CLASS, MODE, X) \ -@@ -1293,6 +1366,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)) \ -@@ -1438,9 +1514,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 \ -@@ -1449,33 +1526,22 @@ 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 - registers. */ - #define APPLY_RESULT_SIZE arm_apply_result_size() - --/* 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. */ --#define RETURN_IN_MEMORY(TYPE) arm_return_in_memory (TYPE) -- - /* Define DEFAULT_PCC_STRUCT_RETURN to 1 if all structure and union return - values must be in memory. On the ARM, they need only do so if larger - than a word, or if they contain elements offset from zero in the struct. */ -@@ -1531,6 +1597,7 @@ typedef struct arm_stack_offsets GTY(()) - int soft_frame; /* FRAME_POINTER_REGNUM. */ - int locals_base; /* THUMB_HARD_FRAME_POINTER_REGNUM. */ - int outgoing_args; /* STACK_POINTER_REGNUM. */ -+ unsigned int saved_regs_mask; - } - arm_stack_offsets; - -@@ -1568,9 +1635,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. */ -@@ -1579,9 +1664,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. -@@ -1625,13 +1734,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, -@@ -1643,9 +1746,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))) - - -@@ -1908,12 +2013,13 @@ typedef struct - /* Nonzero if X can be the base register in a reg+reg addressing mode. - For Thumb, we can not use SP + reg, so reject SP. */ - #define REGNO_MODE_OK_FOR_REG_BASE_P(X, MODE) \ -- REGNO_OK_FOR_INDEX_P (X) -+ REGNO_MODE_OK_FOR_BASE_P (X, QImode) - - /* For ARM code, we don't care about the mode, but for Thumb, the index - must be suitable for use in a QImode load. */ - #define REGNO_OK_FOR_INDEX_P(REGNO) \ -- REGNO_MODE_OK_FOR_BASE_P (REGNO, QImode) -+ (REGNO_MODE_OK_FOR_BASE_P (REGNO, QImode) \ -+ && !TEST_REGNO (REGNO, ==, STACK_POINTER_REGNUM)) - - /* Maximum number of registers that can appear in a valid memory address. - Shifts in addresses can't be by a register. */ -@@ -1931,6 +2037,11 @@ typedef struct - SYMBOL's section. */ - #define ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P 0 - -+/* Nonzero if all target requires all absolute relocations be R_ARM_ABS32. */ -+#ifndef TARGET_DEFAULT_WORD_RELOCATIONS -+#define TARGET_DEFAULT_WORD_RELOCATIONS 0 -+#endif -+ - /* Nonzero if the constant value X is a legitimate general operand. - It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE. - -@@ -2051,6 +2162,13 @@ typedef struct - || REGNO (X) == FRAME_POINTER_REGNUM \ - || REGNO (X) == ARG_POINTER_REGNUM) - -+#define ARM_REG_OK_FOR_INDEX_P(X) \ -+ ((REGNO (X) <= LAST_ARM_REGNUM \ -+ && REGNO (X) != STACK_POINTER_REGNUM) \ -+ || REGNO (X) >= FIRST_PSEUDO_REGISTER \ -+ || REGNO (X) == FRAME_POINTER_REGNUM \ -+ || REGNO (X) == ARG_POINTER_REGNUM) -+ - #define THUMB1_REG_MODE_OK_FOR_BASE_P(X, MODE) \ - (REGNO (X) <= LAST_LO_REGNUM \ - || REGNO (X) >= FIRST_PSEUDO_REGISTER \ -@@ -2066,6 +2184,9 @@ typedef struct - #define ARM_REG_OK_FOR_BASE_P(X) \ - ARM_REGNO_OK_FOR_BASE_P (REGNO (X)) - -+#define ARM_REG_OK_FOR_INDEX_P(X) \ -+ ARM_REGNO_OK_FOR_INDEX_P (REGNO (X)) -+ - #define THUMB1_REG_MODE_OK_FOR_BASE_P(X, MODE) \ - THUMB1_REGNO_MODE_OK_FOR_BASE_P (REGNO (X), MODE) - -@@ -2080,8 +2201,6 @@ typedef struct - ? THUMB1_REG_MODE_OK_FOR_BASE_P (X, MODE) \ - : ARM_REG_OK_FOR_BASE_P (X)) - --#define ARM_REG_OK_FOR_INDEX_P(X) ARM_REG_OK_FOR_BASE_P (X) -- - /* For 16-bit Thumb, a valid index register is anything that can be used in - a byte load instruction. */ - #define THUMB1_REG_OK_FOR_INDEX_P(X) \ -@@ -2259,7 +2378,8 @@ do { \ - /* Try to generate sequences that don't involve branches, we can then use - conditional instructions */ - #define BRANCH_COST \ -- (TARGET_32BIT ? 4 : (optimize > 0 ? 2 : 0)) -+ (TARGET_32BIT ? (TARGET_THUMB2 && optimize_size ? 1 : 4) \ -+ : (optimize > 0 ? 2 : 0)) - - /* Position Independent Code. */ - /* We decide which register to use based on the compilation options and -@@ -2339,6 +2459,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) -@@ -2350,6 +2483,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) -@@ -2384,7 +2525,8 @@ extern int making_const_table; - if (TARGET_THUMB) \ - { \ - if (is_called_in_ARM_mode (DECL) \ -- || (TARGET_THUMB1 && current_function_is_thunk)) \ -+ || (TARGET_THUMB1 && !TARGET_THUMB1_ONLY \ -+ && current_function_is_thunk)) \ - fprintf (STREAM, "\t.code 32\n") ; \ - else if (TARGET_THUMB1) \ - fprintf (STREAM, "\t.code\t16\n\t.thumb_func\n") ; \ -@@ -2479,10 +2621,12 @@ extern int making_const_table; - rtx base = XEXP (X, 0); \ - rtx index = XEXP (X, 1); \ - HOST_WIDE_INT offset = 0; \ -- if (GET_CODE (base) != REG) \ -+ if (GET_CODE (base) != REG \ -+ || (GET_CODE (index) == REG && REGNO (index) == SP_REGNUM)) \ - { \ - /* Ensure that BASE is a register. */ \ - /* (one of them must be). */ \ -+ /* Also ensure the SP is not used as in index register. */ \ - rtx temp = base; \ - base = index; \ - index = temp; \ ---- a/gcc/config/arm/arm.md -+++ b/gcc/config/arm/arm.md -@@ -93,9 +93,9 @@ - (UNSPEC_TLS 20) ; A symbol that has been treated properly for TLS usage. - (UNSPEC_PIC_LABEL 21) ; A label used for PIC access that does not appear in the - ; instruction stream. -- (UNSPEC_STACK_ALIGN 20) ; Doubleword aligned stack pointer. Used to -+ (UNSPEC_STACK_ALIGN 22) ; Doubleword aligned stack pointer. Used to - ; generate correct unwind information. -- (UNSPEC_PIC_OFFSET 22) ; A symbolic 12-bit OFFSET that has been treated -+ (UNSPEC_PIC_OFFSET 23) ; A symbolic 12-bit OFFSET that has been treated - ; correctly for PIC usage. - ] - ) -@@ -129,6 +129,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. - ] -@@ -142,6 +144,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"))) -@@ -156,7 +162,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" -+(define_attr "fpu" "none,fpa,fpe2,fpe3,maverick,vfp,vfpv3d16,vfpv3,neon,neon_fp16" - (const (symbol_ref "arm_fpu_attr"))) - - ; LENGTH of an instruction (in bytes) -@@ -183,7 +189,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,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,smmls,umaal,smlald,smlsld,clz,mrs,msr,xtab,sdiv,udiv,other" - (const_string "other")) - - ; TYPE attribute is used to detect floating point instructions which, if -@@ -192,6 +198,8 @@ - ; scheduling of writes. - - ; Classification of each insn -+; Note: vfp.md has different meanings for some of these, and some further -+; types as well. See that file for details. - ; alu any alu instruction that doesn't hit memory or fp - ; regs or have a shifted source operand - ; alu_shift any data instruction that doesn't hit memory or fp -@@ -236,7 +244,7 @@ - ; - - (define_attr "type" -- "alu,alu_shift,alu_shift_reg,mult,block,float,fdivx,fdivd,fdivs,fmul,fmuls,fmuld,fmacs,fmacd,ffmul,farith,ffarith,f_flag,float_em,f_load,f_store,f_loads,f_loadd,f_stores,f_stored,f_mem_r,r_mem_f,f_2_r,r_2_f,f_cvt,branch,call,load_byte,load1,load2,load3,load4,store1,store2,store3,store4,mav_farith,mav_dmult" -+ "alu,alu_shift,alu_shift_reg,mult,block,float,fdivx,fdivd,fdivs,fmul,fmuls,fmuld,fmacs,fmacd,ffmul,farith,ffarith,f_flag,float_em,f_load,f_store,f_loads,f_loadd,f_stores,f_stored,f_mem_r,r_mem_f,f_2_r,r_2_f,f_cvt,branch,call,load_byte,load1,load2,load3,load4,store1,store2,store3,store4,mav_farith,mav_dmult,fconsts,fconstd,fadds,faddd,ffariths,ffarithd,fcmps,fcmpd,fcpys" - (if_then_else - (eq_attr "insn" "smulxy,smlaxy,smlalxy,smulwy,smlawx,mul,muls,mla,mlas,umull,umulls,umlal,umlals,smull,smulls,smlal,smlals") - (const_string "mult") -@@ -246,6 +254,73 @@ - ; initialized by arm_override_options() - (define_attr "ldsched" "no,yes" (const (symbol_ref "arm_ld_sched"))) - -+;; Classification of NEON instructions for scheduling purposes. -+(define_attr "neon_type" -+ "neon_int_1,\ -+ neon_int_2,\ -+ neon_int_3,\ -+ neon_int_4,\ -+ neon_int_5,\ -+ neon_vqneg_vqabs,\ -+ neon_vmov,\ -+ neon_vaba,\ -+ neon_vsma,\ -+ neon_vaba_qqq,\ -+ neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\ -+ neon_mul_qqq_8_16_32_ddd_32,\ -+ neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar,\ -+ neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\ -+ neon_mla_qqq_8_16,\ -+ neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long,\ -+ neon_mla_qqq_32_qqd_32_scalar,\ -+ neon_mul_ddd_16_scalar_32_16_long_scalar,\ -+ neon_mul_qqd_32_scalar,\ -+ neon_mla_ddd_16_scalar_qdd_32_16_long_scalar,\ -+ neon_shift_1,\ -+ neon_shift_2,\ -+ neon_shift_3,\ -+ neon_vshl_ddd,\ -+ neon_vqshl_vrshl_vqrshl_qqq,\ -+ neon_vsra_vrsra,\ -+ neon_fp_vadd_ddd_vabs_dd,\ -+ neon_fp_vadd_qqq_vabs_qq,\ -+ neon_fp_vsum,\ -+ neon_fp_vmul_ddd,\ -+ neon_fp_vmul_qqd,\ -+ neon_fp_vmla_ddd,\ -+ neon_fp_vmla_qqq,\ -+ neon_fp_vmla_ddd_scalar,\ -+ neon_fp_vmla_qqq_scalar,\ -+ neon_fp_vrecps_vrsqrts_ddd,\ -+ neon_fp_vrecps_vrsqrts_qqq,\ -+ neon_bp_simple,\ -+ neon_bp_2cycle,\ -+ neon_bp_3cycle,\ -+ neon_ldr,\ -+ neon_str,\ -+ neon_vld1_1_2_regs,\ -+ neon_vld1_3_4_regs,\ -+ neon_vld2_2_regs_vld1_vld2_all_lanes,\ -+ neon_vld2_4_regs,\ -+ neon_vld3_vld4,\ -+ neon_vst1_1_2_regs_vst2_2_regs,\ -+ neon_vst1_3_4_regs,\ -+ neon_vst2_4_regs_vst3_vst4,\ -+ neon_vst3_vst4,\ -+ neon_vld1_vld2_lane,\ -+ neon_vld3_vld4_lane,\ -+ neon_vst1_vst2_lane,\ -+ neon_vst3_vst4_lane,\ -+ neon_vld3_vld4_all_lanes,\ -+ neon_mcr,\ -+ neon_mcr_2_mcrr,\ -+ neon_mrc,\ -+ neon_mrrc,\ -+ neon_ldm_2,\ -+ neon_stm_2,\ -+ none" -+ (const_string "none")) -+ - ; condition codes: this one is used by final_prescan_insn to speed up - ; conditionalizing instructions. It saves having to scan the rtl to see if - ; it uses or alters the condition codes. -@@ -263,13 +338,17 @@ - ; JUMP_CLOB is used when the condition cannot be represented by a single - ; instruction (UNEQ and LTGT). These cannot be predicated. - ; -+; UNCONDITIONAL means the instions can not be conditionally executed. -+; - ; NOCOND means that the condition codes are neither altered nor affect the - ; output of this insn - --(define_attr "conds" "use,set,clob,jump_clob,nocond" -+(define_attr "conds" "use,set,clob,jump_clob,unconditional,nocond" - (if_then_else (eq_attr "type" "call") - (const_string "clob") -- (const_string "nocond"))) -+ (if_then_else (eq_attr "neon_type" "none") -+ (const_string "nocond") -+ (const_string "unconditional")))) - - ; Predicable means that the insn can be conditionally executed based on - ; an automatically added predicate (additional patterns are generated by -@@ -328,18 +407,26 @@ - ;; Processor type. This is created automatically from arm-cores.def. - (include "arm-tune.md") - -+(define_attr "tune_cortexr4" "yes,no" -+ (const (if_then_else -+ (eq_attr "tune" "cortexr4,cortexr4f") -+ (const_string "yes") -+ (const_string "no")))) -+ - ;; True if the generic scheduling description should be used. - - (define_attr "generic_sched" "yes,no" - (const (if_then_else -- (eq_attr "tune" "arm926ejs,arm1020e,arm1026ejs,arm1136js,arm1136jfs,cortexa8") -+ (ior (eq_attr "tune" "arm926ejs,arm1020e,arm1026ejs,arm1136js,arm1136jfs,marvell_f,cortexa8,cortexa9") -+ (eq_attr "tune_cortexr4" "yes")) - (const_string "no") - (const_string "yes")))) - - (define_attr "generic_vfp" "yes,no" - (const (if_then_else - (and (eq_attr "fpu" "vfp") -- (eq_attr "tune" "!arm1020e,arm1022e,cortexa8")) -+ (eq_attr "tune" "!arm1020e,arm1022e,marvell_f,cortexa8,cortexa9") -+ (eq_attr "tune_cortexr4" "no")) - (const_string "yes") - (const_string "no")))) - -@@ -348,7 +435,13 @@ - (include "arm1020e.md") - (include "arm1026ejs.md") - (include "arm1136jfs.md") -+(include "marvell-f.md") -+(include "marvell-f-vfp.md") - (include "cortex-a8.md") -+(include "cortex-a9.md") -+(include "cortex-r4.md") -+(include "cortex-r4f.md") -+(include "vfp11.md") - - - ;;--------------------------------------------------------------------------- -@@ -516,13 +609,19 @@ - "" - ) - -+;; The r/r/k alternative is required when reloading the address -+;; (plus (reg rN) (reg sp)) into (reg rN). In this case reload will -+;; put the duplicated register first, and not try the commutative version. - (define_insn_and_split "*arm_addsi3" -- [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") -- (plus:SI (match_operand:SI 1 "s_register_operand" "%r,r,r") -- (match_operand:SI 2 "reg_or_int_operand" "rI,L,?n")))] -+ [(set (match_operand:SI 0 "s_register_operand" "=r, !k, r,r, !k,r") -+ (plus:SI (match_operand:SI 1 "s_register_operand" "%rk,!k, r,rk,!k,rk") -+ (match_operand:SI 2 "reg_or_int_operand" "rI, rI,!k,L, L,?n")))] - "TARGET_32BIT" - "@ - add%?\\t%0, %1, %2 -+ add%?\\t%0, %1, %2 -+ add%?\\t%0, %2, %1 -+ sub%?\\t%0, %1, #%n2 - sub%?\\t%0, %1, #%n2 - #" - "TARGET_32BIT && -@@ -536,7 +635,7 @@ - operands[1], 0); - DONE; - " -- [(set_attr "length" "4,4,16") -+ [(set_attr "length" "4,4,4,4,4,16") - (set_attr "predicable" "yes")] - ) - -@@ -545,9 +644,9 @@ - ;; 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,*r,*h,l,!k") -+ [(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,*h,*r,!M,!O")))] -+ (match_operand:SI 2 "nonmemory_operand" "I,J,lL,*hk,*rk,!M,!O")))] - "TARGET_THUMB1" - "* - static const char * const asms[] = -@@ -759,7 +858,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" -@@ -991,12 +1094,13 @@ - - ; ??? Check Thumb-2 split length - (define_insn_and_split "*arm_subsi3_insn" -- [(set (match_operand:SI 0 "s_register_operand" "=r,r") -- (minus:SI (match_operand:SI 1 "reg_or_int_operand" "rI,?n") -- (match_operand:SI 2 "s_register_operand" "r,r")))] -+ [(set (match_operand:SI 0 "s_register_operand" "=r,rk,r") -+ (minus:SI (match_operand:SI 1 "reg_or_int_operand" "rI,!k,?n") -+ (match_operand:SI 2 "s_register_operand" "r, r, r")))] - "TARGET_32BIT" - "@ - rsb%?\\t%0, %2, %1 -+ sub%?\\t%0, %1, %2 - #" - "TARGET_32BIT - && GET_CODE (operands[1]) == CONST_INT -@@ -1007,7 +1111,7 @@ - INTVAL (operands[1]), operands[0], operands[2], 0); - DONE; - " -- [(set_attr "length" "4,16") -+ [(set_attr "length" "4,4,16") - (set_attr "predicable" "yes")] - ) - -@@ -1236,6 +1340,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 -+; r3, r3, -+; 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 -@@ -1864,6 +2011,7 @@ - DONE; - " - [(set_attr "length" "4,4,16") -+ (set_attr "insn" "and") - (set_attr "predicable" "yes")] - ) - -@@ -1873,7 +2021,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" -@@ -1888,7 +2037,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" -@@ -2140,13 +2290,12 @@ - ;;; the value before we insert. This loses some of the advantage of having - ;;; this insv pattern, so this pattern needs to be reevalutated. - --; ??? Use Thumb-2 bitfield insert/extract instructions - (define_expand "insv" - [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "") - (match_operand:SI 1 "general_operand" "") - (match_operand:SI 2 "general_operand" "")) - (match_operand:SI 3 "reg_or_int_operand" ""))] -- "TARGET_ARM" -+ "TARGET_ARM || arm_arch_thumb2" - " - { - int start_bit = INTVAL (operands[2]); -@@ -2154,7 +2303,38 @@ - HOST_WIDE_INT mask = (((HOST_WIDE_INT)1) << width) - 1; - rtx target, subtarget; - -- target = operands[0]; -+ if (arm_arch_thumb2) -+ { -+ bool use_bfi = TRUE; -+ -+ if (GET_CODE (operands[3]) == CONST_INT) -+ { -+ HOST_WIDE_INT val = INTVAL (operands[3]) & mask; -+ -+ if (val == 0) -+ { -+ emit_insn (gen_insv_zero (operands[0], operands[1], -+ operands[2])); -+ DONE; -+ } -+ -+ /* See if the set can be done with a single orr instruction. */ -+ if (val == mask && const_ok_for_arm (val << start_bit)) -+ use_bfi = FALSE; -+ } -+ -+ if (use_bfi) -+ { -+ if (GET_CODE (operands[3]) != REG) -+ operands[3] = force_reg (SImode, operands[3]); -+ -+ emit_insn (gen_insv_t2 (operands[0], operands[1], operands[2], -+ operands[3])); -+ DONE; -+ } -+ } -+ -+ 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) -@@ -2277,6 +2457,28 @@ - }" - ) - -+(define_insn "insv_zero" -+ [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r") -+ (match_operand:SI 1 "const_int_operand" "M") -+ (match_operand:SI 2 "const_int_operand" "M")) -+ (const_int 0))] -+ "arm_arch_thumb2" -+ "bfc%?\t%0, %2, %1" -+ [(set_attr "length" "4") -+ (set_attr "predicable" "yes")] -+) -+ -+(define_insn "insv_t2" -+ [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r") -+ (match_operand:SI 1 "const_int_operand" "M") -+ (match_operand:SI 2 "const_int_operand" "M")) -+ (match_operand:SI 3 "s_register_operand" "r"))] -+ "arm_arch_thumb2" -+ "bfi%?\t%0, %3, %2, %1" -+ [(set_attr "length" "4") -+ (set_attr "predicable" "yes")] -+) -+ - ; constants for op 2 will never be given to these patterns. - (define_insn_and_split "*anddi_notdi_di" - [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") -@@ -2380,7 +2582,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" -@@ -2428,6 +2634,7 @@ - orr%?\\t%Q0, %Q1, %2 - #" - [(set_attr "length" "4,8") -+ (set_attr "insn" "orr") - (set_attr "predicable" "yes")] - ) - -@@ -2490,7 +2697,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 -@@ -2515,7 +2723,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" -@@ -2526,7 +2735,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" -@@ -2549,7 +2759,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" -@@ -2580,7 +2791,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" -@@ -2589,7 +2801,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" -@@ -2601,7 +2814,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" -@@ -2758,7 +2972,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) - { -@@ -2785,7 +2999,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" -@@ -2793,7 +3008,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" -@@ -2807,7 +3022,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) - { -@@ -2825,7 +3040,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" -@@ -2833,7 +3049,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" -@@ -2847,7 +3063,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" - "" - ) - -@@ -2856,7 +3072,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 -@@ -2871,7 +3087,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" - "" - ) - -@@ -2880,7 +3096,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 -@@ -2895,7 +3111,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]); -@@ -3015,11 +3231,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" "") -@@ -3052,6 +3280,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")] - ) - -@@ -3071,11 +3300,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" "") -@@ -3108,6 +3348,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")] - ) - -@@ -3130,11 +3371,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" "") -@@ -3176,11 +3428,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" -@@ -3192,7 +3453,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" -@@ -3209,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_scratch" -@@ -3222,7 +3491,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" -@@ -3234,9 +3507,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" -@@ -3251,9 +3529,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" -@@ -3267,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)))] - ) - - ;; We don't really have extzv, but defining this using shifts helps -@@ -3282,12 +3570,19 @@ - (set (match_operand:SI 0 "register_operand" "") - (lshiftrt:SI (match_dup 4) - (match_operand:SI 3 "const_int_operand" "")))] -- "TARGET_THUMB1" -+ "TARGET_THUMB1 || arm_arch_thumb2" - " - { - HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]); - HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]); - -+ if (arm_arch_thumb2) -+ { -+ emit_insn (gen_extzv_t2 (operands[0], operands[1], operands[2], -+ operands[3])); -+ DONE; -+ } -+ - operands[3] = GEN_INT (rshift); - - if (lshift == 0) -@@ -3301,6 +3596,28 @@ - }" - ) - -+(define_insn "extv" -+ [(set (match_operand:SI 0 "s_register_operand" "=r") -+ (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r") -+ (match_operand:SI 2 "const_int_operand" "M") -+ (match_operand:SI 3 "const_int_operand" "M")))] -+ "arm_arch_thumb2" -+ "sbfx%?\t%0, %1, %3, %2" -+ [(set_attr "length" "4") -+ (set_attr "predicable" "yes")] -+) -+ -+(define_insn "extzv_t2" -+ [(set (match_operand:SI 0 "s_register_operand" "=r") -+ (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r") -+ (match_operand:SI 2 "const_int_operand" "M") -+ (match_operand:SI 3 "const_int_operand" "M")))] -+ "arm_arch_thumb2" -+ "ubfx%?\t%0, %1, %3, %2" -+ [(set_attr "length" "4") -+ (set_attr "predicable" "yes")] -+) -+ - - ;; Unary arithmetic insns - -@@ -3378,7 +3695,7 @@ - - ;; 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" -@@ -3390,22 +3707,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" -@@ -3423,17 +3746,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" -@@ -3450,6 +3773,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" "")))] -@@ -3505,7 +3915,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" -@@ -3513,7 +3924,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" -@@ -3524,7 +3936,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" -@@ -3534,11 +3947,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")] - ) - - ;; 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" "")))] -@@ -3563,6 +4005,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" ""))))] -@@ -3602,6 +4068,22 @@ - "TARGET_32BIT && TARGET_HARD_FLOAT" - "" - ) -+ -+/* 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; -+ }" -+) - - ;; Zero and sign extension instructions. - -@@ -3623,6 +4105,7 @@ - return \"mov%?\\t%R0, #0\"; - " - [(set_attr "length" "8") -+ (set_attr "insn" "mov") - (set_attr "predicable" "yes")] - ) - -@@ -3666,6 +4149,7 @@ - " - [(set_attr "length" "8") - (set_attr "shift" "1") -+ (set_attr "insn" "mov") - (set_attr "predicable" "yes")] - ) - -@@ -4464,6 +4948,21 @@ - "TARGET_32BIT && TARGET_HARD_FLOAT" - "" - ) -+ -+/* 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; -+ }" -+) - - ;; Move insns (including loads and stores) - -@@ -4699,6 +5198,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,*,*")] - ) - -@@ -4785,23 +5285,38 @@ - " - ) - -+;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and -+;; LO_SUM adds in the high bits. Fortunately these are opaque opearsions -+;; so this does not matter. -+(define_insn "*arm_movt" -+ [(set (match_operand:SI 0 "nonimmediate_operand" "=r") -+ (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0") -+ (match_operand:SI 2 "general_operand" "i")))] -+ "TARGET_32BIT" -+ "movt%?\t%0, #:upper16:%c2" -+ [(set_attr "predicable" "yes") -+ (set_attr "length" "4")] -+) -+ - (define_insn "*arm_movsi_insn" -- [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r, m") -- (match_operand:SI 1 "general_operand" "rI,K,N,mi,r"))] -+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m") -+ (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) - || register_operand (operands[1], SImode))" - "@ - mov%?\\t%0, %1 -+ mov%?\\t%0, %1 - mvn%?\\t%0, #%B1 - movw%?\\t%0, %1 - ldr%?\\t%0, %1 - str%?\\t%1, %0" -- [(set_attr "type" "*,*,*,load1,store1") -+ [(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,*")] -+ (set_attr "pool_range" "*,*,*,*,4096,*") -+ (set_attr "neg_pool_range" "*,*,*,*,4084,*")] - ) - - (define_split -@@ -4818,9 +5333,22 @@ - " - ) - -+(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,*lh") -- (match_operand:SI 1 "general_operand" "l, I,J,K,>,l,mi,l,*lh"))] -+ [(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"))] - "TARGET_THUMB1 - && ( register_operand (operands[0], SImode) - || register_operand (operands[1], SImode))" -@@ -5418,6 +5946,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")] - ) -@@ -5429,7 +5958,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" -@@ -5560,6 +6090,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")] - ) - -@@ -5578,9 +6109,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_NEON_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" ""))] -@@ -5633,6 +6266,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,*")] - ) -@@ -6088,7 +6722,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) - { -@@ -7298,7 +7932,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" -@@ -7313,7 +7951,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" -@@ -7328,7 +7970,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 -@@ -7670,77 +8316,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);" - ) -@@ -7748,7 +8394,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);" - ) -@@ -7756,7 +8402,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);" - ) -@@ -7764,7 +8410,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);" - ) -@@ -7772,7 +8418,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);" - ) -@@ -7780,7 +8426,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);" - ) -@@ -7809,6 +8455,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")] - ) - -@@ -7819,6 +8466,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")] - ) - -@@ -7829,6 +8477,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")] - ) - -@@ -8032,7 +8681,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]); -@@ -8051,7 +8700,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_32BIT && !TARGET_NO_COND_EXEC" - " - { - enum rtx_code code = GET_CODE (operands[1]); -@@ -8076,7 +8725,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) && !TARGET_NO_COND_EXEC" - " - { - enum rtx_code code = GET_CODE (operands[1]); -@@ -8108,7 +8757,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" -@@ -8121,7 +8771,8 @@ - "@ - mov%D3\\t%0, %2 - mov%d3\\t%0, %1" -- [(set_attr "conds" "use")] -+ [(set_attr "conds" "use") -+ (set_attr "insn" "mov")] - ) - - -@@ -8524,7 +9175,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) -@@ -8545,7 +9196,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) -@@ -8864,7 +9515,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 -@@ -8902,7 +9557,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" -@@ -8920,7 +9579,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" -@@ -8935,7 +9598,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" -@@ -8955,7 +9622,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" -@@ -8973,7 +9644,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)))] - ) - - -@@ -8986,6 +9661,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")] - ) - -@@ -8999,6 +9675,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")] - ) - -@@ -9008,7 +9685,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) - { -@@ -9063,6 +9740,7 @@ - return \"\"; - " - [(set_attr "conds" "use") -+ (set_attr "insn" "mov") - (set_attr "length" "4,4,8")] - ) - -@@ -9074,7 +9752,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\"; -@@ -9470,7 +10148,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)) -@@ -9536,7 +10214,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")] -@@ -9572,7 +10250,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")] -@@ -9610,7 +10288,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")] -@@ -9760,7 +10438,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")] -@@ -9779,6 +10457,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")] - ) - -@@ -9792,7 +10471,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")] -@@ -9811,6 +10490,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")] - ) - -@@ -9825,7 +10505,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")] -@@ -9847,10 +10527,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" -@@ -9864,7 +10557,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")] -@@ -9886,10 +10579,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" -@@ -9905,7 +10612,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")] -@@ -9926,12 +10633,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" -@@ -9945,7 +10656,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")] -@@ -9963,6 +10674,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")] - ) - -@@ -9977,7 +10689,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")] -@@ -9995,6 +10707,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")] - ) - -@@ -10007,7 +10720,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")] -@@ -10038,7 +10751,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")] -@@ -10181,13 +10894,13 @@ - ; reversed, check that the memory references aren't volatile. - - (define_peephole -- [(set (match_operand:SI 0 "s_register_operand" "=r") -+ [(set (match_operand:SI 0 "s_register_operand" "=rk") - (match_operand:SI 4 "memory_operand" "m")) -- (set (match_operand:SI 1 "s_register_operand" "=r") -+ (set (match_operand:SI 1 "s_register_operand" "=rk") - (match_operand:SI 5 "memory_operand" "m")) -- (set (match_operand:SI 2 "s_register_operand" "=r") -+ (set (match_operand:SI 2 "s_register_operand" "=rk") - (match_operand:SI 6 "memory_operand" "m")) -- (set (match_operand:SI 3 "s_register_operand" "=r") -+ (set (match_operand:SI 3 "s_register_operand" "=rk") - (match_operand:SI 7 "memory_operand" "m"))] - "TARGET_ARM && load_multiple_sequence (operands, 4, NULL, NULL, NULL)" - "* -@@ -10196,11 +10909,11 @@ - ) - - (define_peephole -- [(set (match_operand:SI 0 "s_register_operand" "=r") -+ [(set (match_operand:SI 0 "s_register_operand" "=rk") - (match_operand:SI 3 "memory_operand" "m")) -- (set (match_operand:SI 1 "s_register_operand" "=r") -+ (set (match_operand:SI 1 "s_register_operand" "=rk") - (match_operand:SI 4 "memory_operand" "m")) -- (set (match_operand:SI 2 "s_register_operand" "=r") -+ (set (match_operand:SI 2 "s_register_operand" "=rk") - (match_operand:SI 5 "memory_operand" "m"))] - "TARGET_ARM && load_multiple_sequence (operands, 3, NULL, NULL, NULL)" - "* -@@ -10209,9 +10922,9 @@ - ) - - (define_peephole -- [(set (match_operand:SI 0 "s_register_operand" "=r") -+ [(set (match_operand:SI 0 "s_register_operand" "=rk") - (match_operand:SI 2 "memory_operand" "m")) -- (set (match_operand:SI 1 "s_register_operand" "=r") -+ (set (match_operand:SI 1 "s_register_operand" "=rk") - (match_operand:SI 3 "memory_operand" "m"))] - "TARGET_ARM && load_multiple_sequence (operands, 2, NULL, NULL, NULL)" - "* -@@ -10221,13 +10934,13 @@ - - (define_peephole - [(set (match_operand:SI 4 "memory_operand" "=m") -- (match_operand:SI 0 "s_register_operand" "r")) -+ (match_operand:SI 0 "s_register_operand" "rk")) - (set (match_operand:SI 5 "memory_operand" "=m") -- (match_operand:SI 1 "s_register_operand" "r")) -+ (match_operand:SI 1 "s_register_operand" "rk")) - (set (match_operand:SI 6 "memory_operand" "=m") -- (match_operand:SI 2 "s_register_operand" "r")) -+ (match_operand:SI 2 "s_register_operand" "rk")) - (set (match_operand:SI 7 "memory_operand" "=m") -- (match_operand:SI 3 "s_register_operand" "r"))] -+ (match_operand:SI 3 "s_register_operand" "rk"))] - "TARGET_ARM && store_multiple_sequence (operands, 4, NULL, NULL, NULL)" - "* - return emit_stm_seq (operands, 4); -@@ -10236,11 +10949,11 @@ - - (define_peephole - [(set (match_operand:SI 3 "memory_operand" "=m") -- (match_operand:SI 0 "s_register_operand" "r")) -+ (match_operand:SI 0 "s_register_operand" "rk")) - (set (match_operand:SI 4 "memory_operand" "=m") -- (match_operand:SI 1 "s_register_operand" "r")) -+ (match_operand:SI 1 "s_register_operand" "rk")) - (set (match_operand:SI 5 "memory_operand" "=m") -- (match_operand:SI 2 "s_register_operand" "r"))] -+ (match_operand:SI 2 "s_register_operand" "rk"))] - "TARGET_ARM && store_multiple_sequence (operands, 3, NULL, NULL, NULL)" - "* - return emit_stm_seq (operands, 3); -@@ -10249,9 +10962,9 @@ - - (define_peephole - [(set (match_operand:SI 2 "memory_operand" "=m") -- (match_operand:SI 0 "s_register_operand" "r")) -+ (match_operand:SI 0 "s_register_operand" "rk")) - (set (match_operand:SI 3 "memory_operand" "=m") -- (match_operand:SI 1 "s_register_operand" "r"))] -+ (match_operand:SI 1 "s_register_operand" "rk"))] - "TARGET_ARM && store_multiple_sequence (operands, 2, NULL, NULL, NULL)" - "* - return emit_stm_seq (operands, 2); -@@ -10406,7 +11119,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)))] -@@ -10434,7 +11147,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)))] -@@ -10455,7 +11168,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))) -@@ -10487,7 +11200,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))) -@@ -10522,6 +11235,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")] - ) - -@@ -10610,8 +11324,8 @@ - - (define_insn "stack_tie" - [(set (mem:BLK (scratch)) -- (unspec:BLK [(match_operand:SI 0 "s_register_operand" "r") -- (match_operand:SI 1 "s_register_operand" "r")] -+ (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk") -+ (match_operand:SI 1 "s_register_operand" "rk")] - UNSPEC_PRLG_STK))] - "" - "" -@@ -10656,6 +11370,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" -@@ -10682,6 +11414,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 \"\"; -@@ -10694,18 +11427,29 @@ - "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); -+ /* 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); - break; - } - return \"\"; -@@ -10808,13 +11552,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 -@@ -156,3 +168,16 @@ Assume big endian bytes, little endian w - 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. -+ -+mfix-cortex-m3-ldrd -+Target Report Var(fix_cm3_ldrd) Init(2) -+Avoid overlapping destination and address registers on LDRD instructions -+that may trigger Cortex-M3 errata. ---- a/gcc/config/arm/arm1020e.md -+++ b/gcc/config/arm/arm1020e.md -@@ -281,12 +281,12 @@ - ;; first execute state. We model this by using 1020a_e in the first cycle. - (define_insn_reservation "v10_ffarith" 5 - (and (eq_attr "vfp10" "yes") -- (eq_attr "type" "ffarith")) -+ (eq_attr "type" "fcpys,ffariths,ffarithd,fcmps,fcmpd")) - "1020a_e+v10_fmac") - - (define_insn_reservation "v10_farith" 5 - (and (eq_attr "vfp10" "yes") -- (eq_attr "type" "farith")) -+ (eq_attr "type" "faddd,fadds")) - "1020a_e+v10_fmac") - - (define_insn_reservation "v10_cvt" 5 ---- a/gcc/config/arm/arm_neon.h -+++ b/gcc/config/arm/arm_neon.h -@@ -39,7 +39,11 @@ - extern "C" { - #endif - -+#if defined (__vxworks) && defined (_WRS_KERNEL) -+#include -+#else - #include -+#endif - - typedef __builtin_neon_qi int8x8_t __attribute__ ((__vector_size__ (8))); - typedef __builtin_neon_hi int16x4_t __attribute__ ((__vector_size__ (8))); ---- /dev/null -+++ b/gcc/config/arm/bpabi-v6m.S -@@ -0,0 +1,325 @@ -+/* Miscellaneous BPABI functions. ARMv6M implementation -+ -+ Copyright (C) 2006 Free Software Foundation, Inc. -+ Contributed by CodeSourcery, LLC. -+ -+ 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 2, or (at your option) any -+ later version. -+ -+ In addition to the permissions in the GNU General Public License, the -+ Free Software Foundation gives you unlimited permission to link the -+ compiled version of this file into combinations with other programs, -+ and to distribute those combinations without any restriction coming -+ from the use of this file. (The General Public License restrictions -+ do apply in other respects; for example, they cover modification of -+ the file, and distribution when not linked into a combine -+ executable.) -+ -+ 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. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. */ -+ -+#ifdef __ARMEB__ -+#define xxh r0 -+#define xxl r1 -+#define yyh r2 -+#define yyl r3 -+#else -+#define xxh r1 -+#define xxl r0 -+#define yyh r3 -+#define yyl r2 -+#endif -+ -+#ifdef L_aeabi_lcmp -+ -+FUNC_START aeabi_lcmp -+ cmp xxh, yyh -+ beq 1f -+ bgt 2f -+ mov r0, #1 -+ neg r0, r0 -+ RET -+2: -+ mov r0, #1 -+ RET -+1: -+ sub r0, xxl, yyl -+ beq 1f -+ bhi 2f -+ mov r0, #1 -+ neg r0, r0 -+ RET -+2: -+ mov r0, #1 -+1: -+ RET -+ FUNC_END aeabi_lcmp -+ -+#endif /* L_aeabi_lcmp */ -+ -+#ifdef L_aeabi_ulcmp -+ -+FUNC_START aeabi_ulcmp -+ cmp xxh, yyh -+ bne 1f -+ sub r0, xxl, yyl -+ beq 2f -+1: -+ bcs 1f -+ mov r0, #1 -+ neg r0, r0 -+ RET -+1: -+ mov r0, #1 -+2: -+ RET -+ FUNC_END 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} -+ ldr r0, [sp, #8] -+ bl SYM(__gnu_ldivmod_helper) -+ ldr r3, [sp, #4] -+ mov lr, r3 -+ add sp, sp, #8 -+ pop {r2, r3} -+ RET -+ FUNC_END aeabi_ldivmod -+ -+#endif /* L_aeabi_ldivmod */ -+ -+#ifdef L_aeabi_uldivmod -+ -+FUNC_START aeabi_uldivmod -+ test_div_by_zero unsigned -+ -+ push {r0, r1} -+ mov r0, sp -+ push {r0, lr} -+ ldr r0, [sp, #8] -+ bl SYM(__gnu_uldivmod_helper) -+ ldr r3, [sp, #4] -+ mov lr, r3 -+ add sp, sp, #8 -+ pop {r2, r3} -+ RET -+ FUNC_END aeabi_uldivmod -+ -+#endif /* L_aeabi_uldivmod */ -+ -+#ifdef L_arm_addsubsf3 -+ -+FUNC_START aeabi_frsub -+ -+ push {r4, lr} -+ mov r4, #1 -+ lsl r4, #31 -+ eor r0, r0, r4 -+ bl __aeabi_fadd -+ pop {r4, pc} -+ -+ FUNC_END aeabi_frsub -+ -+#endif /* L_arm_addsubsf3 */ -+ -+#ifdef L_arm_cmpsf2 -+ -+FUNC_START aeabi_cfrcmple -+ -+ mov ip, r0 -+ mov r0, r1 -+ mov r1, ip -+ b 6f -+ -+FUNC_START aeabi_cfcmpeq -+FUNC_ALIAS aeabi_cfcmple aeabi_cfcmpeq -+ -+ @ The status-returning routines are required to preserve all -+ @ registers except ip, lr, and cpsr. -+6: push {r0, r1, r2, r3, r4, lr} -+ bl __lesf2 -+ @ Set the Z flag correctly, and the C flag unconditionally. -+ cmp r0, #0 -+ @ Clear the C flag if the return value was -1, indicating -+ @ that the first operand was smaller than the second. -+ bmi 1f -+ mov r1, #0 -+ cmn r0, r1 -+1: -+ pop {r0, r1, r2, r3, r4, pc} -+ -+ FUNC_END aeabi_cfcmple -+ FUNC_END aeabi_cfcmpeq -+ FUNC_END aeabi_cfrcmple -+ -+FUNC_START aeabi_fcmpeq -+ -+ push {r4, lr} -+ bl __eqsf2 -+ neg r0, r0 -+ add r0, r0, #1 -+ pop {r4, pc} -+ -+ FUNC_END aeabi_fcmpeq -+ -+.macro COMPARISON cond, helper, mode=sf2 -+FUNC_START aeabi_fcmp\cond -+ -+ push {r4, lr} -+ bl __\helper\mode -+ cmp r0, #0 -+ b\cond 1f -+ mov r0, #0 -+ pop {r4, pc} -+1: -+ mov r0, #1 -+ pop {r4, pc} -+ -+ FUNC_END aeabi_fcmp\cond -+.endm -+ -+COMPARISON lt, le -+COMPARISON le, le -+COMPARISON gt, ge -+COMPARISON ge, ge -+ -+#endif /* L_arm_cmpsf2 */ -+ -+#ifdef L_arm_addsubdf3 -+ -+FUNC_START aeabi_drsub -+ -+ push {r4, lr} -+ mov r4, #1 -+ lsl r4, #31 -+ eor xxh, xxh, r4 -+ bl __aeabi_dadd -+ pop {r4, pc} -+ -+ FUNC_END aeabi_drsub -+ -+#endif /* L_arm_addsubdf3 */ -+ -+#ifdef L_arm_cmpdf2 -+ -+FUNC_START aeabi_cdrcmple -+ -+ mov ip, r0 -+ mov r0, r2 -+ mov r2, ip -+ mov ip, r1 -+ mov r1, r3 -+ mov r3, ip -+ b 6f -+ -+FUNC_START aeabi_cdcmpeq -+FUNC_ALIAS aeabi_cdcmple aeabi_cdcmpeq -+ -+ @ The status-returning routines are required to preserve all -+ @ registers except ip, lr, and cpsr. -+6: push {r0, r1, r2, r3, r4, lr} -+ bl __ledf2 -+ @ Set the Z flag correctly, and the C flag unconditionally. -+ cmp r0, #0 -+ @ Clear the C flag if the return value was -1, indicating -+ @ that the first operand was smaller than the second. -+ bmi 1f -+ mov r1, #0 -+ cmn r0, r1 -+1: -+ pop {r0, r1, r2, r3, r4, pc} -+ -+ FUNC_END aeabi_cdcmple -+ FUNC_END aeabi_cdcmpeq -+ FUNC_END aeabi_cdrcmple -+ -+FUNC_START aeabi_dcmpeq -+ -+ push {r4, lr} -+ bl __eqdf2 -+ neg r0, r0 -+ add r0, r0, #1 -+ pop {r4, pc} -+ -+ FUNC_END aeabi_dcmpeq -+ -+.macro COMPARISON cond, helper, mode=df2 -+FUNC_START aeabi_dcmp\cond -+ -+ push {r4, lr} -+ bl __\helper\mode -+ cmp r0, #0 -+ b\cond 1f -+ mov r0, #0 -+ pop {r4, pc} -+1: -+ mov r0, #1 -+ pop {r4, pc} -+ -+ FUNC_END aeabi_dcmp\cond -+.endm -+ -+COMPARISON lt, le -+COMPARISON le, le -+COMPARISON gt, ge -+COMPARISON ge, ge -+ -+#endif /* L_arm_cmpdf2 */ ---- a/gcc/config/arm/bpabi.S -+++ b/gcc/config/arm/bpabi.S -@@ -81,20 +81,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 */ -@@ -102,17 +151,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 -@@ -51,15 +51,25 @@ - /* The BPABI integer comparison routines return { -1, 0, 1 }. */ - #define TARGET_LIB_INT_CMP_BIASED !TARGET_BPABI - -+#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-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=4}" -+#define SUBTARGET_EXTRA_ASM_SPEC "%{mabi=apcs-gnu|mabi=atpcs:-meabi=gnu;:-meabi=5}" TARGET_FIX_V4BX_SPEC -+ -+#ifndef SUBTARGET_EXTRA_LINK_SPEC -+#define SUBTARGET_EXTRA_LINK_SPEC "" -+#endif - - /* The generic link spec in elf.h does not support shared libraries. */ - #undef LINK_SPEC - #define LINK_SPEC "%{mbig-endian:-EB} %{mlittle-endian:-EL} " \ - "%{static:-Bstatic} %{shared:-shared} %{symbolic:-Bsymbolic} " \ -- "-X" -+ "-X" SUBTARGET_EXTRA_LINK_SPEC TARGET_FIX_V4BX_SPEC \ -+ BE8_LINK_SPEC \ -+ " %{mfix-janus-2cc:--fix-janus-2cc}" - - #if defined (__thumb__) - #define RENAME_LIBRARY_SET ".thumb_set" -@@ -81,16 +91,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) -@@ -99,6 +115,21 @@ - #define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (floatdisf, l2f) - #endif - -+/* These renames are needed on ARMv6M. Other targets get them from -+ assembly routines. */ -+#ifdef L_fixunsdfsi -+#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (fixunsdfsi, d2uiz) -+#endif -+#ifdef L_fixunssfsi -+#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (fixunssfsi, f2uiz) -+#endif -+#ifdef L_floatundidf -+#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (floatundidf, ul2d) -+#endif -+#ifdef L_floatundisf -+#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (floatundisf, ul2f) -+#endif -+ - /* The BPABI requires that we always use an out-of-line implementation - of RTTI comparison, even if the target supports weak symbols, - because the same object file might be used on a target that does -@@ -123,3 +154,26 @@ - #undef FINI_SECTION_ASM_OP - #define INIT_ARRAY_SECTION_ASM_OP ARM_EABI_CTORS_SECTION_OP - #define FINI_ARRAY_SECTION_ASM_OP ARM_EABI_DTORS_SECTION_OP -+ -+/* The legacy _mcount implementation assumes r11 points to a -+ 4-word APCS frame. This is generally not true for EABI targets, -+ particularly not in Thumb mode. We assume the mcount -+ implementation does not require a counter variable (No Counter). -+ Note that __gnu_mcount_nc will be entered with a misaligned stack. -+ This is OK because it uses a special calling convention anyway. */ -+ -+#undef NO_PROFILE_COUNTERS -+#define NO_PROFILE_COUNTERS 1 -+#undef ARM_FUNCTION_PROFILER -+#define ARM_FUNCTION_PROFILER(STREAM, LABELNO) \ -+{ \ -+ fprintf (STREAM, "\tpush\t{lr}\n"); \ -+ fprintf (STREAM, "\tbl\t__gnu_mcount_nc\n"); \ -+} -+ -+#undef SUBTARGET_FRAME_POINTER_REQUIRED -+#define SUBTARGET_FRAME_POINTER_REQUIRED 0 -+ -+/* __gnu_mcount_nc restores the original LR value before returning. Ensure -+ that there is no unnecessary hook set up. */ -+#undef PROFILE_HOOK ---- a/gcc/config/arm/constraints.md -+++ b/gcc/config/arm/constraints.md -@@ -20,19 +20,19 @@ - - ;; The following register constraints have been used: - ;; - in ARM/Thumb-2 state: f, t, v, w, x, y, z --;; - in Thumb state: h, k, b --;; - in both states: l, c -+;; - in Thumb state: h, b -+;; - in both states: l, c, k - ;; 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 - - ;; 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 - - -@@ -46,7 +46,7 @@ - "The Cirrus Maverick co-processor registers.") - - (define_register_constraint "w" -- "TARGET_32BIT ? (TARGET_VFP3 ? VFP_REGS : VFP_LO_REGS) : NO_REGS" -+ "TARGET_32BIT ? (TARGET_VFPD32 ? VFP_REGS : VFP_LO_REGS) : NO_REGS" - "The VFP registers @code{d0}-@code{d15}, or @code{d0}-@code{d31} for VFPv3.") - - (define_register_constraint "x" "TARGET_32BIT ? VFP_D0_D7_REGS : NO_REGS" -@@ -65,9 +65,15 @@ - (define_register_constraint "h" "TARGET_THUMB ? HI_REGS : NO_REGS" - "In Thumb state the core registers @code{r8}-@code{r15}.") - --(define_register_constraint "k" "TARGET_THUMB ? STACK_REG : NO_REGS" -- "@internal -- Thumb only. The stack register.") -+(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.") - - (define_register_constraint "b" "TARGET_THUMB ? BASE_REGS : NO_REGS" - "@internal -@@ -117,11 +123,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 -@@ -215,17 +219,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 ---- a/gcc/config/arm/cortex-a8-neon.md -+++ b/gcc/config/arm/cortex-a8-neon.md -@@ -134,7 +134,7 @@ - - (define_insn_reservation "cortex_a8_vfp_add_sub" 10 - (and (eq_attr "tune" "cortexa8") -- (eq_attr "type" "farith")) -+ (eq_attr "type" "fconsts,fconstd,fadds,faddd")) - "cortex_a8_vfp,cortex_a8_vfplite*9") - - (define_insn_reservation "cortex_a8_vfp_muls" 12 -@@ -172,7 +172,7 @@ - ;; take four cycles, we pick that latency. - (define_insn_reservation "cortex_a8_vfp_farith" 4 - (and (eq_attr "tune" "cortexa8") -- (eq_attr "type" "ffarith")) -+ (eq_attr "type" "fcpys,ffariths,ffarithd,fconsts,fconstd,fcmps,fcmpd")) - "cortex_a8_vfp,cortex_a8_vfplite*3") - - (define_insn_reservation "cortex_a8_vfp_cvt" 7 ---- /dev/null -+++ b/gcc/config/arm/cortex-a9.md -@@ -0,0 +1,65 @@ -+;; ARM Cortex-A9 VFP pipeline description -+;; Copyright (C) 2008 Free Software Foundation, Inc. -+;; Written by CodeSourcery. -+;; -+;; 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 -+;; . -+ -+(define_automaton "cortex_a9") -+ -+;; FIXME: We model aingle pipeline for all instructions. -+;; Is dual-issue possible, and do we have other pipelines? -+(define_cpu_unit "cortex_a9_vfp" "cortex_a9") -+ -+(define_insn_reservation "cortex_a9_ffarith" 1 -+ (and (eq_attr "tune" "cortexa9") -+ (eq_attr "type" "fcpys,ffariths,ffarithd,fcmps,fcmpd,fconsts,fconstd")) -+ "cortex_a9_vfp") -+ -+(define_insn_reservation "cortex_a9_fadd" 4 -+ (and (eq_attr "tune" "cortexa9") -+ (eq_attr "type" "fadds,faddd,f_cvt")) -+ "cortex_a9_vfp") -+ -+(define_insn_reservation "cortex_a9_fmuls" 5 -+ (and (eq_attr "tune" "cortexa9") -+ (eq_attr "type" "fmuls")) -+ "cortex_a9_vfp") -+ -+(define_insn_reservation "cortex_a9_fmuld" 6 -+ (and (eq_attr "tune" "cortexa9") -+ (eq_attr "type" "fmuld")) -+ "cortex_a9_vfp*2") -+ -+(define_insn_reservation "cortex_a9_fmacs" 8 -+ (and (eq_attr "tune" "cortexa9") -+ (eq_attr "type" "fmacs")) -+ "cortex_a9_vfp") -+ -+(define_insn_reservation "cortex_a9_fmacd" 8 -+ (and (eq_attr "tune" "cortexa9") -+ (eq_attr "type" "fmacd")) -+ "cortex_a9_vfp*2") -+ -+(define_insn_reservation "cortex_a9_fdivs" 15 -+ (and (eq_attr "tune" "cortexa9") -+ (eq_attr "type" "fdivs")) -+ "cortex_a9_vfp*10") -+ -+(define_insn_reservation "cortex_a9_fdivd" 25 -+ (and (eq_attr "tune" "cortexa9") -+ (eq_attr "type" "fdivd")) -+ "cortex_a9_vfp*20") ---- /dev/null -+++ b/gcc/config/arm/cortex-r4.md -@@ -0,0 +1,292 @@ -+;; ARM Cortex-R4 scheduling description. -+;; Copyright (C) 2007 Free Software Foundation, Inc. -+;; Contributed by CodeSourcery. -+ -+;; 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 -+;; . -+ -+(define_automaton "cortex_r4") -+ -+;; We approximate the dual-issue constraints of this core using four -+;; "issue units" and a reservation matrix as follows. The numbers indicate -+;; the instruction groups' preferences in order. Multiple entries for -+;; the same numbered preference indicate units that must be reserved -+;; together. -+;; -+;; Issue unit: A B C ALU -+;; -+;; ALU w/o reg shift 1st 2nd 1st and 2nd -+;; ALU w/ reg shift 1st 2nd 2nd 1st and 2nd -+;; Moves 1st 2nd 2nd -+;; Multiplication 1st 1st -+;; Division 1st 1st -+;; Load/store single 1st 1st -+;; Other load/store 1st 1st -+;; Branches 1st -+ -+(define_cpu_unit "cortex_r4_issue_a" "cortex_r4") -+(define_cpu_unit "cortex_r4_issue_b" "cortex_r4") -+(define_cpu_unit "cortex_r4_issue_c" "cortex_r4") -+(define_cpu_unit "cortex_r4_issue_alu" "cortex_r4") -+ -+(define_reservation "cortex_r4_alu" -+ "(cortex_r4_issue_a+cortex_r4_issue_alu)|\ -+ (cortex_r4_issue_b+cortex_r4_issue_alu)") -+(define_reservation "cortex_r4_alu_shift_reg" -+ "(cortex_r4_issue_a+cortex_r4_issue_alu)|\ -+ (cortex_r4_issue_b+cortex_r4_issue_c+\ -+ cortex_r4_issue_alu)") -+(define_reservation "cortex_r4_mov" -+ "cortex_r4_issue_a|(cortex_r4_issue_b+\ -+ cortex_r4_issue_alu)") -+(define_reservation "cortex_r4_mul" "cortex_r4_issue_a+cortex_r4_issue_alu") -+(define_reservation "cortex_r4_mul_2" -+ "(cortex_r4_issue_a+cortex_r4_issue_alu)*2") -+;; Division instructions execute out-of-order with respect to the -+;; rest of the pipeline and only require reservations on their first and -+;; final cycles. -+(define_reservation "cortex_r4_div_9" -+ "cortex_r4_issue_a+cortex_r4_issue_alu,\ -+ nothing*7,\ -+ cortex_r4_issue_a+cortex_r4_issue_alu") -+(define_reservation "cortex_r4_div_10" -+ "cortex_r4_issue_a+cortex_r4_issue_alu,\ -+ nothing*8,\ -+ cortex_r4_issue_a+cortex_r4_issue_alu") -+(define_reservation "cortex_r4_load_store" -+ "cortex_r4_issue_a+cortex_r4_issue_c") -+(define_reservation "cortex_r4_load_store_2" -+ "(cortex_r4_issue_a+cortex_r4_issue_b)*2") -+(define_reservation "cortex_r4_branch" "cortex_r4_issue_b") -+ -+;; We assume that all instructions are unconditional. -+ -+;; Data processing instructions. Moves without shifts are kept separate -+;; for the purposes of the dual-issue constraints above. -+(define_insn_reservation "cortex_r4_alu" 2 -+ (and (eq_attr "tune_cortexr4" "yes") -+ (and (eq_attr "type" "alu") -+ (not (eq_attr "insn" "mov")))) -+ "cortex_r4_alu") -+ -+(define_insn_reservation "cortex_r4_mov" 2 -+ (and (eq_attr "tune_cortexr4" "yes") -+ (and (eq_attr "type" "alu") -+ (eq_attr "insn" "mov"))) -+ "cortex_r4_mov") -+ -+(define_insn_reservation "cortex_r4_alu_shift" 2 -+ (and (eq_attr "tune_cortexr4" "yes") -+ (eq_attr "type" "alu_shift")) -+ "cortex_r4_alu") -+ -+(define_insn_reservation "cortex_r4_alu_shift_reg" 2 -+ (and (eq_attr "tune_cortexr4" "yes") -+ (eq_attr "type" "alu_shift_reg")) -+ "cortex_r4_alu_shift_reg") -+ -+;; An ALU instruction followed by an ALU instruction with no early dep. -+(define_bypass 1 "cortex_r4_alu,cortex_r4_alu_shift,cortex_r4_alu_shift_reg,\ -+ cortex_r4_mov" -+ "cortex_r4_alu") -+(define_bypass 1 "cortex_r4_alu,cortex_r4_alu_shift,cortex_r4_alu_shift_reg,\ -+ cortex_r4_mov" -+ "cortex_r4_alu_shift" -+ "arm_no_early_alu_shift_dep") -+(define_bypass 1 "cortex_r4_alu,cortex_r4_alu_shift,cortex_r4_alu_shift_reg,\ -+ cortex_r4_mov" -+ "cortex_r4_alu_shift_reg" -+ "arm_no_early_alu_shift_value_dep") -+ -+;; In terms of availabilities, a consumer mov could theoretically be -+;; issued together with a producer ALU instruction, without stalls. -+;; In practice this cannot happen because mov;add (in that order) is not -+;; eligible for dual issue and furthermore dual issue is not permitted -+;; when a dependency is involved. We therefore note it as latency one. -+;; A mov followed by another of the same is also latency one. -+(define_bypass 1 "cortex_r4_alu,cortex_r4_alu_shift,cortex_r4_alu_shift_reg,\ -+ cortex_r4_mov" -+ "cortex_r4_mov") -+ -+;; qadd, qdadd, qsub and qdsub are not currently emitted, and neither are -+;; media data processing instructions nor sad instructions. -+ -+;; Multiplication instructions. -+ -+(define_insn_reservation "cortex_r4_mul_4" 4 -+ (and (eq_attr "tune_cortexr4" "yes") -+ (eq_attr "insn" "mul,smmul")) -+ "cortex_r4_mul_2") -+ -+(define_insn_reservation "cortex_r4_mul_3" 3 -+ (and (eq_attr "tune_cortexr4" "yes") -+ (eq_attr "insn" "smulxy,smulwy,smuad,smusd")) -+ "cortex_r4_mul") -+ -+(define_insn_reservation "cortex_r4_mla_4" 4 -+ (and (eq_attr "tune_cortexr4" "yes") -+ (eq_attr "insn" "mla,smmla,smmls")) -+ "cortex_r4_mul_2") -+ -+(define_insn_reservation "cortex_r4_mla_3" 3 -+ (and (eq_attr "tune_cortexr4" "yes") -+ (eq_attr "insn" "smlaxy,smlawy,smlad,smlsd")) -+ "cortex_r4_mul") -+ -+(define_insn_reservation "cortex_r4_smlald" 3 -+ (and (eq_attr "tune_cortexr4" "yes") -+ (eq_attr "insn" "smlald,smlsld")) -+ "cortex_r4_mul") -+ -+(define_insn_reservation "cortex_r4_mull" 4 -+ (and (eq_attr "tune_cortexr4" "yes") -+ (eq_attr "insn" "smull,umull,umlal,umaal")) -+ "cortex_r4_mul_2") -+ -+;; A multiply or an MLA with a single-register result, followed by an -+;; MLA with an accumulator dependency, has its result forwarded. -+(define_bypass 2 "cortex_r4_mul_3,cortex_r4_mla_3" -+ "cortex_r4_mla_3,cortex_r4_mla_4" -+ "arm_mac_accumulator_is_mul_result") -+ -+(define_bypass 3 "cortex_r4_mul_4,cortex_r4_mla_4" -+ "cortex_r4_mla_3,cortex_r4_mla_4" -+ "arm_mac_accumulator_is_mul_result") -+ -+;; A multiply followed by an ALU instruction needing the multiply -+;; result only at ALU has lower latency than one needing it at Shift. -+(define_bypass 2 "cortex_r4_mul_3,cortex_r4_mla_3,cortex_r4_smlald" -+ "cortex_r4_alu") -+(define_bypass 2 "cortex_r4_mul_3,cortex_r4_mla_3,cortex_r4_smlald" -+ "cortex_r4_alu_shift" -+ "arm_no_early_alu_shift_dep") -+(define_bypass 2 "cortex_r4_mul_3,cortex_r4_mla_3,cortex_r4_smlald" -+ "cortex_r4_alu_shift_reg" -+ "arm_no_early_alu_shift_value_dep") -+(define_bypass 3 "cortex_r4_mul_4,cortex_r4_mla_4,cortex_r4_mull" -+ "cortex_r4_alu") -+(define_bypass 3 "cortex_r4_mul_4,cortex_r4_mla_4,cortex_r4_mull" -+ "cortex_r4_alu_shift" -+ "arm_no_early_alu_shift_dep") -+(define_bypass 3 "cortex_r4_mul_4,cortex_r4_mla_4,cortex_r4_mull" -+ "cortex_r4_alu_shift_reg" -+ "arm_no_early_alu_shift_value_dep") -+ -+;; A multiply followed by a mov has one cycle lower latency again. -+(define_bypass 1 "cortex_r4_mul_3,cortex_r4_mla_3,cortex_r4_smlald" -+ "cortex_r4_mov") -+(define_bypass 2 "cortex_r4_mul_4,cortex_r4_mla_4,cortex_r4_mull" -+ "cortex_r4_mov") -+ -+;; We guess that division of A/B using sdiv or udiv, on average, -+;; is performed with B having ten more leading zeros than A. -+;; This gives a latency of nine for udiv and ten for sdiv. -+(define_insn_reservation "cortex_r4_udiv" 9 -+ (and (eq_attr "tune_cortexr4" "yes") -+ (eq_attr "insn" "udiv")) -+ "cortex_r4_div_9") -+ -+(define_insn_reservation "cortex_r4_sdiv" 10 -+ (and (eq_attr "tune_cortexr4" "yes") -+ (eq_attr "insn" "sdiv")) -+ "cortex_r4_div_10") -+ -+;; Branches. We assume correct prediction. -+ -+(define_insn_reservation "cortex_r4_branch" 0 -+ (and (eq_attr "tune_cortexr4" "yes") -+ (eq_attr "type" "branch")) -+ "cortex_r4_branch") -+ -+;; Call latencies are not predictable. A semi-arbitrary very large -+;; number is used as "positive infinity" so that everything should be -+;; finished by the time of return. -+(define_insn_reservation "cortex_r4_call" 32 -+ (and (eq_attr "tune_cortexr4" "yes") -+ (eq_attr "type" "call")) -+ "nothing") -+ -+;; Status register access instructions are not currently emitted. -+ -+;; Load instructions. -+;; We do not model the "addr_md_3cycle" cases and assume that -+;; accesses following are correctly aligned. -+ -+(define_insn_reservation "cortex_r4_load_1_2" 3 -+ (and (eq_attr "tune_cortexr4" "yes") -+ (eq_attr "type" "load1,load2")) -+ "cortex_r4_load_store") -+ -+(define_insn_reservation "cortex_r4_load_3_4" 4 -+ (and (eq_attr "tune_cortexr4" "yes") -+ (eq_attr "type" "load3,load4")) -+ "cortex_r4_load_store_2") -+ -+;; If a producing load is followed by an instruction consuming only -+;; as a Normal Reg, there is one fewer cycle of latency. -+ -+(define_bypass 2 "cortex_r4_load_1_2" -+ "cortex_r4_alu") -+(define_bypass 2 "cortex_r4_load_1_2" -+ "cortex_r4_alu_shift" -+ "arm_no_early_alu_shift_dep") -+(define_bypass 2 "cortex_r4_load_1_2" -+ "cortex_r4_alu_shift_reg" -+ "arm_no_early_alu_shift_value_dep") -+ -+(define_bypass 3 "cortex_r4_load_3_4" -+ "cortex_r4_alu") -+(define_bypass 3 "cortex_r4_load_3_4" -+ "cortex_r4_alu_shift" -+ "arm_no_early_alu_shift_dep") -+(define_bypass 3 "cortex_r4_load_3_4" -+ "cortex_r4_alu_shift_reg" -+ "arm_no_early_alu_shift_value_dep") -+ -+;; If a producing load is followed by an instruction consuming only -+;; as a Late Reg, there are two fewer cycles of latency. Such consumer -+;; instructions are moves and stores. -+ -+(define_bypass 1 "cortex_r4_load_1_2" -+ "cortex_r4_mov,cortex_r4_store_1_2,cortex_r4_store_3_4") -+(define_bypass 2 "cortex_r4_load_3_4" -+ "cortex_r4_mov,cortex_r4_store_1_2,cortex_r4_store_3_4") -+ -+;; If a producer's result is required as the base or offset of a load, -+;; there is an extra cycle latency. -+ -+(define_bypass 3 "cortex_r4_alu,cortex_r4_mov,cortex_r4_alu_shift,\ -+ cortex_r4_alu_shift_reg" -+ "cortex_r4_load_1_2,cortex_r4_load_3_4") -+ -+(define_bypass 4 "cortex_r4_mul_3,cortex_r4_mla_3,cortex_r4_smlald" -+ "cortex_r4_load_1_2,cortex_r4_load_3_4") -+ -+(define_bypass 5 "cortex_r4_mul_4,cortex_r4_mla_4,cortex_r4_mull" -+ "cortex_r4_load_1_2,cortex_r4_load_3_4") -+ -+;; Store instructions. -+ -+(define_insn_reservation "cortex_r4_store_1_2" 0 -+ (and (eq_attr "tune_cortexr4" "yes") -+ (eq_attr "type" "store1,store2")) -+ "cortex_r4_load_store") -+ -+(define_insn_reservation "cortex_r4_store_3_4" 0 -+ (and (eq_attr "tune_cortexr4" "yes") -+ (eq_attr "type" "store3,store4")) -+ "cortex_r4_load_store_2") -+ ---- /dev/null -+++ b/gcc/config/arm/cortex-r4f.md -@@ -0,0 +1,161 @@ -+;; ARM Crotex-R4F VFP pipeline description -+;; Copyright (C) 2007 Free Software Foundation, Inc. -+;; Written by CodeSourcery. -+;; -+;; 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 -+;; . -+ -+;; With the exception of simple VMOV , instructions and -+;; the accululate operand of a multiply-accumulate instruction, all -+;; registers are early registers. Thus base latencies are 1 more than -+;; those listed in the TRM. -+ -+;; We use the A, B abd C units from the integer core, plus two additional -+;; units to enforce VFP dual issue constraints. -+ -+;; A B C V1 VMLA -+;; fcpy 1 2 -+;; farith 1 2 1 -+;; fmrc 1 2 -+;; fconst 1 2 * * -+;; ffarith 1 2 * * -+;; fmac 1 2 1 2 -+;; fdiv 1 2 * -+;; f_loads * * * -+;; f_stores * * * -+ -+(define_cpu_unit "cortex_r4_v1" "cortex_r4") -+ -+(define_cpu_unit "cortex_r4_vmla" "cortex_r4") -+ -+(define_reservation "cortex_r4_issue_ab" -+ "(cortex_r4_issue_a|cortex_r4_issue_b)") -+(define_reservation "cortex_r4_single_issue" -+ "cortex_r4_issue_a+cortex_r4_issue_b") -+ -+(define_insn_reservation "cortex_r4_fcpys" 2 -+ (and (eq_attr "tune_cortexr4" "yes") -+ (eq_attr "type" "fcpys")) -+ "cortex_r4_issue_ab") -+ -+(define_insn_reservation "cortex_r4_ffariths" 2 -+ (and (eq_attr "tune_cortexr4" "yes") -+ (eq_attr "type" "ffariths,fconsts,fcmps")) -+ "cortex_r4_issue_ab+cortex_r4_issue_c+cortex_r4_v1") -+ -+(define_insn_reservation "cortex_r4_fariths" 3 -+ (and (eq_attr "tune_cortexr4" "yes") -+ (eq_attr "type" "fadds,fmuls")) -+ "(cortex_r4_issue_a+cortex_r4_v1)|cortex_r4_issue_b") -+ -+(define_insn_reservation "cortex_r4_fmacs" 6 -+ (and (eq_attr "tune_cortexr4" "yes") -+ (eq_attr "type" "fmacs")) -+ "(cortex_r4_issue_a+cortex_r4_v1)|(cortex_r4_issue_b+cortex_r4_vmla)") -+ -+(define_insn_reservation "cortex_r4_fdivs" 17 -+ (and (eq_attr "tune_cortexr4" "yes") -+ (eq_attr "type" "fdivs")) -+ "cortex_r4_issue_ab+cortex_r4_v1,cortex_r4_issue_a+cortex_r4_v1") -+ -+(define_insn_reservation "cortex_r4_floads" 2 -+ (and (eq_attr "tune_cortexr4" "yes") -+ (eq_attr "type" "f_loads")) -+ "cortex_r4_issue_a+cortex_r4_issue_c+cortex_r4_v1") -+ -+(define_insn_reservation "cortex_r4_fstores" 1 -+ (and (eq_attr "tune_cortexr4" "yes") -+ (eq_attr "type" "f_stores")) -+ "cortex_r4_issue_a+cortex_r4_issue_c+cortex_r4_vmla") -+ -+(define_insn_reservation "cortex_r4_mcr" 2 -+ (and (eq_attr "tune_cortexr4" "yes") -+ (eq_attr "type" "r_2_f")) -+ "cortex_r4_issue_ab") -+ -+(define_insn_reservation "cortex_r4_mrc" 3 -+ (and (eq_attr "tune_cortexr4" "yes") -+ (eq_attr "type" "f_2_r")) -+ "cortex_r4_issue_ab") -+ -+;; Bypasses for normal (not early) regs. -+(define_bypass 1 "cortex_r4_ffariths,cortex_r4_fcpys,cortex_r4_mcr" -+ "cortex_r4_fcpys") -+(define_bypass 2 "cortex_r4_fariths" -+ "cortex_r4_fcpys") -+(define_bypass 5 "cortex_r4_fmacs" -+ "cortex_r4_fcpys") -+(define_bypass 16 "cortex_r4_fdivs" -+ "cortex_r4_fcpys") -+ -+(define_bypass 1 "cortex_r4_ffariths,cortex_r4_fcpys,cortex_r4_mcr" -+ "cortex_r4_fmacs" -+ "arm_no_early_mul_dep") -+(define_bypass 2 "cortex_r4_fariths" -+ "cortex_r4_fmacs" -+ "arm_no_early_mul_dep") -+;; mac->mac has an extra forwarding path. -+(define_bypass 3 "cortex_r4_fmacs" -+ "cortex_r4_fmacs" -+ "arm_no_early_mul_dep") -+(define_bypass 16 "cortex_r4_fdivs" -+ "cortex_r4_fmacs" -+ "arm_no_early_mul_dep") -+ -+;; Double precision operations. These can not dual issue. -+ -+(define_insn_reservation "cortex_r4_fmacd" 20 -+ (and (eq_attr "tune_cortexr4" "yes") -+ (eq_attr "type" "fmacd")) -+ "cortex_r4_single_issue*13") -+ -+(define_insn_reservation "cortex_r4_farith" 10 -+ (and (eq_attr "tune_cortexr4" "yes") -+ (eq_attr "type" "faddd,fmuld")) -+ "cortex_r4_single_issue*3") -+ -+;; FIXME: The short cycle count suggests these instructions complete -+;; out of order. Chances are this is not a pipelined operation. -+(define_insn_reservation "cortex_r4_fdivd" 97 -+ (and (eq_attr "tune_cortexr4" "yes") -+ (eq_attr "type" "fdivd")) -+ "cortex_r4_single_issue*3") -+ -+(define_insn_reservation "cortex_r4_ffarithd" 2 -+ (and (eq_attr "tune_cortexr4" "yes") -+ (eq_attr "type" "ffarithd,fconstd")) -+ "cortex_r4_single_issue") -+ -+(define_insn_reservation "cortex_r4_fcmpd" 2 -+ (and (eq_attr "tune_cortexr4" "yes") -+ (eq_attr "type" "fcmpd")) -+ "cortex_r4_single_issue*2") -+ -+(define_insn_reservation "cortex_r4_f_cvt" 8 -+ (and (eq_attr "tune_cortexr4" "yes") -+ (eq_attr "type" "f_cvt")) -+ "cortex_r4_single_issue*3") -+ -+(define_insn_reservation "cortex_r4_f_memd" 8 -+ (and (eq_attr "tune_cortexr4" "yes") -+ (eq_attr "type" "f_loadd,f_stored")) -+ "cortex_r4_single_issue") -+ -+(define_insn_reservation "cortex_r4_f_flag" 1 -+ (and (eq_attr "tune_cortexr4" "yes") -+ (eq_attr "type" "f_stores")) -+ "cortex_r4_single_issue") -+ ---- a/gcc/config/arm/crti.asm -+++ b/gcc/config/arm/crti.asm -@@ -64,8 +64,6 @@ - #endif - .endm - -- .file "crti.asm" -- - .section ".init" - .align 2 - .global _init ---- a/gcc/config/arm/crtn.asm -+++ b/gcc/config/arm/crtn.asm -@@ -72,8 +72,6 @@ - .endm - - -- .file "crtn.asm" -- - .section ".init" - ;; - FUNC_END ---- a/gcc/config/arm/elf.h -+++ b/gcc/config/arm/elf.h -@@ -145,3 +145,17 @@ - } \ - while (0) - -+/* Horrible hack: We want to prevent some libgcc routines being included -+ for some multilibs. */ -+#ifndef __ARM_ARCH_6M__ -+#undef L_fixdfsi -+#undef L_fixunsdfsi -+#undef L_truncdfsf2 -+#undef L_fixsfsi -+#undef L_fixunssfsi -+#undef L_floatdidf -+#undef L_floatdisf -+#undef L_floatundidf -+#undef L_floatundisf -+#endif -+ ---- /dev/null -+++ b/gcc/config/arm/fp16.c -@@ -0,0 +1,150 @@ -+/* Half-float conversion routines. -+ -+ Copyright (C) 2008 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 2, or (at your option) any -+ later version. -+ -+ In addition to the permissions in the GNU General Public License, the -+ Free Software Foundation gives you unlimited permission to link the -+ compiled version of this file into combinations with other programs, -+ and to distribute those combinations without any restriction coming -+ from the use of this file. (The General Public License restrictions -+ do apply in other respects; for example, they cover modification of -+ the file, and distribution when not linked into a combine -+ executable.) -+ -+ 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. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. */ -+ -+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); -+} ---- /dev/null -+++ b/gcc/config/arm/hwdiv.md -@@ -0,0 +1,40 @@ -+;; 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 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 -+;; . -+ -+(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 -@@ -56,7 +56,7 @@ - #endif - - --#ifdef L_negdf2 -+#ifdef L_arm_negdf2 - - ARM_FUNC_START negdf2 - ARM_FUNC_ALIAS aeabi_dneg negdf2 -@@ -70,7 +70,7 @@ ARM_FUNC_ALIAS aeabi_dneg negdf2 - - #endif - --#ifdef L_addsubdf3 -+#ifdef L_arm_addsubdf3 - - ARM_FUNC_START aeabi_drsub - -@@ -88,7 +88,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 -@@ -432,7 +432,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 -@@ -452,7 +452,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 -@@ -486,7 +486,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 -@@ -513,9 +513,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 -@@ -539,9 +539,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 -@@ -590,7 +590,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 - -@@ -603,11 +603,11 @@ LSYM(f0_ret): - - #endif /* L_addsubdf3 */ - --#ifdef L_muldivdf3 -+#ifdef L_arm_muldivdf3 - - 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 -@@ -840,7 +840,7 @@ LSYM(Lml_d): - orr xh, xh, r6 - teq r5, #0 - do_it ne -- movne pc, lr -+ RETc(ne) - 2: and r6, yh, #0x80000000 - 3: movs yl, yl, lsl #1 - adc yh, yh, yh -@@ -849,7 +849,7 @@ LSYM(Lml_d): - subeq r5, r5, #1 - beq 3b - orr yh, yh, r6 -- mov pc, lr -+ RET - - LSYM(Lml_s): - @ Isolate the INF and NAN cases away -@@ -915,7 +915,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 -@@ -1103,7 +1103,7 @@ LSYM(Ldv_s): - - #endif /* L_muldivdf3 */ - --#ifdef L_cmpdf2 -+#ifdef L_arm_cmpdf2 - - @ Note: only r0 (return value) and ip are clobbered here. - -@@ -1122,7 +1122,7 @@ ARM_FUNC_ALIAS nedf2 cmpdf2 - ARM_FUNC_ALIAS eqdf2 cmpdf2 - mov ip, #1 @ how should we specify unordered here? - --1: str ip, [sp, #-4] -+1: str ip, [sp, #-4]! - - @ Trap any INF/NAN first. - mov ip, xh, lsl #1 -@@ -1134,7 +1134,8 @@ ARM_FUNC_ALIAS eqdf2 cmpdf2 - - @ Test for equality. - @ Note that 0.0 is equal to -0.0. --2: orrs ip, xl, xh, lsl #1 @ if x == 0.0 or -0.0 -+2: add sp, sp, #4 -+ orrs ip, xl, xh, lsl #1 @ if x == 0.0 or -0.0 - do_it eq, e - COND(orr,s,eq) ip, yl, yh, lsl #1 @ and y == 0.0 or -0.0 - teqne xh, yh @ or xh == yh -@@ -1173,7 +1174,7 @@ ARM_FUNC_ALIAS eqdf2 cmpdf2 - bne 2b - orrs ip, yl, yh, lsl #12 - beq 2b @ y is not NAN --5: ldr r0, [sp, #-4] @ unordered return code -+5: ldr r0, [sp], #4 @ unordered return code - RET - - FUNC_END gedf2 -@@ -1199,7 +1200,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 -@@ -1271,7 +1272,7 @@ ARM_FUNC_START aeabi_dcmpgt - - #endif /* L_cmpdf2 */ - --#ifdef L_unorddf2 -+#ifdef L_arm_unorddf2 - - ARM_FUNC_START unorddf2 - ARM_FUNC_ALIAS aeabi_dcmpun unorddf2 -@@ -1297,7 +1298,7 @@ ARM_FUNC_ALIAS aeabi_dcmpun unorddf2 - - #endif /* L_unorddf2 */ - --#ifdef L_fixdfsi -+#ifdef L_arm_fixdfsi - - ARM_FUNC_START fixdfsi - ARM_FUNC_ALIAS aeabi_d2iz fixdfsi -@@ -1339,7 +1340,7 @@ ARM_FUNC_ALIAS aeabi_d2iz fixdfsi - - #endif /* L_fixdfsi */ - --#ifdef L_fixunsdfsi -+#ifdef L_arm_fixunsdfsi - - ARM_FUNC_START fixunsdfsi - ARM_FUNC_ALIAS aeabi_d2uiz fixunsdfsi -@@ -1377,7 +1378,7 @@ ARM_FUNC_ALIAS aeabi_d2uiz fixunsdfsi - - #endif /* L_fixunsdfsi */ - --#ifdef L_truncdfsf2 -+#ifdef L_arm_truncdfsf2 - - ARM_FUNC_START truncdfsf2 - ARM_FUNC_ALIAS aeabi_d2f truncdfsf2 ---- a/gcc/config/arm/ieee754-sf.S -+++ b/gcc/config/arm/ieee754-sf.S -@@ -38,7 +38,7 @@ - * if necessary without impacting performances. - */ - --#ifdef L_negsf2 -+#ifdef L_arm_negsf2 - - ARM_FUNC_START negsf2 - ARM_FUNC_ALIAS aeabi_fneg negsf2 -@@ -51,7 +51,7 @@ ARM_FUNC_ALIAS aeabi_fneg negsf2 - - #endif - --#ifdef L_addsubsf3 -+#ifdef L_arm_addsubsf3 - - ARM_FUNC_START aeabi_frsub - -@@ -448,7 +448,7 @@ LSYM(f0_ret): - - #endif /* L_addsubsf3 */ - --#ifdef L_muldivsf3 -+#ifdef L_arm_muldivsf3 - - ARM_FUNC_START mulsf3 - ARM_FUNC_ALIAS aeabi_fmul mulsf3 -@@ -486,7 +486,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 -@@ -497,7 +497,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 - -@@ -795,7 +795,7 @@ LSYM(Ldv_s): - - #endif /* L_muldivsf3 */ - --#ifdef L_cmpsf2 -+#ifdef L_arm_cmpsf2 - - @ The return value in r0 is - @ -@@ -827,7 +827,7 @@ ARM_FUNC_ALIAS nesf2 cmpsf2 - ARM_FUNC_ALIAS eqsf2 cmpsf2 - mov ip, #1 @ how should we specify unordered here? - --1: str ip, [sp, #-4] -+1: str ip, [sp, #-4]! - - @ Trap any INF/NAN first. - mov r2, r0, lsl #1 -@@ -839,7 +839,8 @@ ARM_FUNC_ALIAS eqsf2 cmpsf2 - - @ Compare values. - @ Note that 0.0 is equal to -0.0. --2: orrs ip, r2, r3, lsr #1 @ test if both are 0, clear C flag -+2: add sp, sp, #4 -+ orrs ip, r2, r3, lsr #1 @ test if both are 0, clear C flag - do_it ne - teqne r0, r1 @ if not 0 compare sign - do_it pl -@@ -863,7 +864,7 @@ ARM_FUNC_ALIAS eqsf2 cmpsf2 - bne 2b - movs ip, r1, lsl #9 - beq 2b @ r1 is not NAN --5: ldr r0, [sp, #-4] @ return unordered code. -+5: ldr r0, [sp], #4 @ return unordered code. - RET - - FUNC_END gesf2 -@@ -886,7 +887,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 -@@ -958,7 +959,7 @@ ARM_FUNC_START aeabi_fcmpgt - - #endif /* L_cmpsf2 */ - --#ifdef L_unordsf2 -+#ifdef L_arm_unordsf2 - - ARM_FUNC_START unordsf2 - ARM_FUNC_ALIAS aeabi_fcmpun unordsf2 -@@ -983,7 +984,7 @@ ARM_FUNC_ALIAS aeabi_fcmpun unordsf2 - - #endif /* L_unordsf2 */ - --#ifdef L_fixsfsi -+#ifdef L_arm_fixsfsi - - ARM_FUNC_START fixsfsi - ARM_FUNC_ALIAS aeabi_f2iz fixsfsi -@@ -1025,7 +1026,7 @@ ARM_FUNC_ALIAS aeabi_f2iz fixsfsi - - #endif /* L_fixsfsi */ - --#ifdef L_fixunssfsi -+#ifdef L_arm_fixunssfsi - - ARM_FUNC_START fixunssfsi - ARM_FUNC_ALIAS aeabi_f2uiz fixunssfsi ---- a/gcc/config/arm/iwmmxt.md -+++ b/gcc/config/arm/iwmmxt.md -@@ -105,8 +105,8 @@ - ) - - (define_insn "*iwmmxt_movsi_insn" -- [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r, m,z,r,?z,Uy,z") -- (match_operand:SI 1 "general_operand" "rI,K,mi,r,r,z,Uy,z,z"))] -+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,rk, m,z,r,?z,Uy,z") -+ (match_operand:SI 1 "general_operand" "rk, I,K,mi,rk,r,z,Uy,z, z"))] - "TARGET_REALLY_IWMMXT - && ( register_operand (operands[0], SImode) - || register_operand (operands[1], SImode))" -@@ -114,19 +114,20 @@ - switch (which_alternative) - { - case 0: return \"mov\\t%0, %1\"; -- case 1: return \"mvn\\t%0, #%B1\"; -- case 2: return \"ldr\\t%0, %1\"; -- case 3: return \"str\\t%1, %0\"; -- case 4: return \"tmcr\\t%0, %1\"; -- case 5: return \"tmrc\\t%0, %1\"; -- case 6: return arm_output_load_gr (operands); -- case 7: return \"wstrw\\t%1, %0\"; -+ case 1: return \"mov\\t%0, %1\"; -+ case 2: return \"mvn\\t%0, #%B1\"; -+ case 3: return \"ldr\\t%0, %1\"; -+ case 4: return \"str\\t%1, %0\"; -+ case 5: return \"tmcr\\t%0, %1\"; -+ case 6: return \"tmrc\\t%0, %1\"; -+ case 7: return arm_output_load_gr (operands); -+ case 8: return \"wstrw\\t%1, %0\"; - default:return \"wstrw\\t%1, [sp, #-4]!\;wldrw\\t%0, [sp], #4\\t@move CG reg\"; - }" -- [(set_attr "type" "*,*,load1,store1,*,*,load1,store1,*") -- (set_attr "length" "*,*,*, *,*,*, 16, *,8") -- (set_attr "pool_range" "*,*,4096, *,*,*,1024, *,*") -- (set_attr "neg_pool_range" "*,*,4084, *,*,*, *, 1012,*") -+ [(set_attr "type" "*,*,*,load1,store1,*,*,load1,store1,*") -+ (set_attr "length" "*,*,*,*, *,*,*, 16, *,8") -+ (set_attr "pool_range" "*,*,*,4096, *,*,*,1024, *,*") -+ (set_attr "neg_pool_range" "*,*,*,4084, *,*,*, *, 1012,*") - ;; Note - the "predicable" attribute is not allowed to have alternatives. - ;; Since the wSTRw wCx instruction is not predicable, we cannot support - ;; predicating any of the alternatives in this template. Instead, -@@ -166,9 +167,9 @@ - (set_attr "neg_pool_range" "*,*,4084, *,*,*")] - ) - --(define_insn "movv8qi_internal" -- [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,m,y,?r,?y,?r,?r,?m") -- (match_operand:V8QI 1 "general_operand" "y,y,mi,y,r,r,mi,r"))] -+(define_insn "mov_internal" -+ [(set (match_operand:VMMX 0 "nonimmediate_operand" "=y,m,y,?r,?y,?r,?r,?m") -+ (match_operand:VMMX 1 "general_operand" "y,y,mi,y,r,r,mi,r"))] - "TARGET_REALLY_IWMMXT" - "* - switch (which_alternative) -@@ -187,64 +188,6 @@ - (set_attr "pool_range" "*, *, 256,*,*,*, 256,*") - (set_attr "neg_pool_range" "*, *, 244,*,*,*, 244,*")]) - --(define_insn "movv4hi_internal" -- [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,m,y,?r,?y,?r,?r,?m") -- (match_operand:V4HI 1 "general_operand" "y,y,mi,y,r,r,mi,r"))] -- "TARGET_REALLY_IWMMXT" -- "* -- switch (which_alternative) -- { -- case 0: return \"wmov%?\\t%0, %1\"; -- case 1: return \"wstrd%?\\t%1, %0\"; -- case 2: return \"wldrd%?\\t%0, %1\"; -- case 3: return \"tmrrc%?\\t%Q0, %R0, %1\"; -- case 4: return \"tmcrr%?\\t%0, %Q1, %R1\"; -- case 5: return \"#\"; -- default: return output_move_double (operands); -- }" -- [(set_attr "predicable" "yes") -- (set_attr "length" "4, 4, 4,4,4,8, 8,8") -- (set_attr "type" "*,store1,load1,*,*,*,load1,store1") -- (set_attr "pool_range" "*, *, 256,*,*,*, 256,*") -- (set_attr "neg_pool_range" "*, *, 244,*,*,*, 244,*")]) -- --(define_insn "movv2si_internal" -- [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,m,y,?r,?y,?r,?r,?m") -- (match_operand:V2SI 1 "general_operand" "y,y,mi,y,r,r,mi,r"))] -- "TARGET_REALLY_IWMMXT" -- "* -- switch (which_alternative) -- { -- case 0: return \"wmov%?\\t%0, %1\"; -- case 1: return \"wstrd%?\\t%1, %0\"; -- case 2: return \"wldrd%?\\t%0, %1\"; -- case 3: return \"tmrrc%?\\t%Q0, %R0, %1\"; -- case 4: return \"tmcrr%?\\t%0, %Q1, %R1\"; -- case 5: return \"#\"; -- default: return output_move_double (operands); -- }" -- [(set_attr "predicable" "yes") -- (set_attr "length" "4, 4, 4,4,4,8, 24,8") -- (set_attr "type" "*,store1,load1,*,*,*,load1,store1") -- (set_attr "pool_range" "*, *, 256,*,*,*, 256,*") -- (set_attr "neg_pool_range" "*, *, 244,*,*,*, 244,*")]) -- --;; This pattern should not be needed. It is to match a --;; wierd case generated by GCC when no optimizations are --;; enabled. (Try compiling gcc/testsuite/gcc.c-torture/ --;; compile/simd-5.c at -O0). The mode for operands[1] is --;; deliberately omitted. --(define_insn "movv2si_internal_2" -- [(set (match_operand:V2SI 0 "nonimmediate_operand" "=?r") -- (match_operand 1 "immediate_operand" "mi"))] -- "TARGET_REALLY_IWMMXT" -- "* return output_move_double (operands);" -- [(set_attr "predicable" "yes") -- (set_attr "length" "8") -- (set_attr "type" "load1") -- (set_attr "pool_range" "256") -- (set_attr "neg_pool_range" "244")]) -- - ;; Vector add/subtract - - (define_insn "*add3_iwmmxt" ---- a/gcc/config/arm/lib1funcs.asm -+++ b/gcc/config/arm/lib1funcs.asm -@@ -94,7 +94,8 @@ Boston, MA 02110-1301, USA. */ - - #if defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \ - || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) \ -- || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) -+ || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) \ -+ || defined(__ARM_ARCH_6M__) - # define __ARM_ARCH__ 6 - #endif - -@@ -237,8 +238,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. */ -@@ -252,24 +253,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) -@@ -281,18 +391,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 -@@ -367,6 +478,9 @@ _L__\name: - - #else /* !(__INTERWORKING_STUBS__ || __thumb2__) */ - -+#ifdef __ARM_ARCH_6M__ -+#define EQUIV .thumb_set -+#else - .macro ARM_FUNC_START name - .text - .globl SYM (__\name) -@@ -379,6 +493,7 @@ SYM (__\name): - .macro ARM_CALL name - bl __\name - .endm -+#endif - - #endif - -@@ -391,6 +506,7 @@ SYM (__\name): - #endif - .endm - -+#ifndef __ARM_ARCH_6M__ - .macro ARM_FUNC_ALIAS new old - .globl SYM (__\new) - EQUIV SYM (__\new), SYM (__\old) -@@ -398,6 +514,13 @@ SYM (__\name): - .set SYM (_L__\new), SYM (_L__\old) - #endif - .endm -+#endif -+ -+#ifdef __ARM_EABI__ -+.macro WEAK name -+ .weak SYM (__\name) -+.endm -+#endif - - #ifdef __thumb__ - /* Register aliases. */ -@@ -423,6 +546,23 @@ pc .req r15 - - #if __ARM_ARCH__ >= 5 && ! defined (__OPTIMIZE_SIZE__) - -+#if 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 -@@ -438,6 +578,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 -@@ -792,6 +933,7 @@ LSYM(Lgot_result): - - cmp divisor, #0 - beq LSYM(Ldiv0) -+LSYM(udivsi3_nodiv0): - mov curbit, #1 - mov result, #0 - -@@ -807,6 +949,9 @@ LSYM(Lgot_result): - - #else /* ARM version. */ - -+ /* Note: if called via udivsi3_nodiv0, this will unnecessarily check -+ for division-by-zero a second time. */ -+LSYM(udivsi3_nodiv0): - subs r2, r1, #1 - RETc(eq) - bcc LSYM(Ldiv0) -@@ -831,19 +976,23 @@ LSYM(Lgot_result): - - #endif /* ARM version */ - -- DIV_FUNC_END udivsi3 -+ DIV_FUNC_END udivsi3 unsigned - - 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 -+ 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 -@@ -890,7 +1039,7 @@ LSYM(Lover10): - - #endif /* ARM version. */ - -- DIV_FUNC_END umodsi3 -+ DIV_FUNC_END umodsi3 unsigned - - #endif /* L_umodsi3 */ - /* ------------------------------------------------------------------------ */ -@@ -902,7 +1051,7 @@ LSYM(Lover10): - #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. -@@ -934,8 +1083,9 @@ LSYM(Lover12): - #else /* ARM version. */ - - 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. - rsbmi r1, r1, #0 @ loops below use unsigned. - subs r2, r1, #1 @ division by 1 or -1 ? - beq 10f -@@ -970,19 +1120,23 @@ LSYM(Lover12): - - #endif /* ARM version */ - -- DIV_FUNC_END divsi3 -+ DIV_FUNC_END divsi3 signed - - 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 -+ 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 -@@ -1048,21 +1202,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 */ - /* ------------------------------------------------------------------------ */ -@@ -1072,14 +1230,26 @@ LSYM(Lover12): - /* Constant taken from . */ - #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 */ - /* ------------------------------------------------------------------------ */ -@@ -1256,8 +1426,8 @@ LSYM(Lover12): - #endif /* L_call_via_rX */ - - /* Don't bother with the old interworking routines for Thumb-2. */ --/* ??? Maybe only omit these on v7m. */ --#ifndef __thumb2__ -+/* ??? Maybe only omit these on "m" variants. */ -+#if !defined(__thumb2__) && !defined(__ARM_ARCH_6M__) - - #if defined L_interwork_call_via_rX - -@@ -1387,7 +1557,11 @@ LSYM(Lchange_\register): - #endif /* Arch supports thumb. */ - - #ifndef __symbian__ -+#ifndef __ARM_ARCH_6M__ - #include "ieee754-df.S" - #include "ieee754-sf.S" - #include "bpabi.S" --#endif /* __symbian__ */ -+#else /* __ARM_ARCH_6M__ */ -+#include "bpabi-v6m.S" -+#endif /* __ARM_ARCH_6M__ */ -+#endif /* !__symbian__ */ ---- a/gcc/config/arm/libunwind.S -+++ b/gcc/config/arm/libunwind.S -@@ -53,6 +53,119 @@ - #endif - #endif - -+#ifdef __ARM_ARCH_6M__ -+ -+/* r0 points to a 16-word block. Upload these values to the actual core -+ state. */ -+FUNC_START restore_core_regs -+ mov r1, r0 -+ add r1, r1, #52 -+ ldmia r1!, {r3, r4, r5} -+ sub r3, r3, #4 -+ mov ip, r3 -+ str r5, [r3] -+ mov lr, r4 -+ /* Restore r8-r11. */ -+ mov r1, r0 -+ add r1, r1, #32 -+ ldmia r1!, {r2, r3, r4, r5} -+ mov r8, r2 -+ mov r9, r3 -+ mov sl, r4 -+ mov fp, r5 -+ mov r1, r0 -+ add r1, r1, #8 -+ ldmia r1!, {r2, r3, r4, r5, r6, r7} -+ ldr r1, [r0, #4] -+ ldr r0, [r0] -+ mov sp, ip -+ pop {pc} -+ FUNC_END restore_core_regs -+ UNPREFIX restore_core_regs -+ -+/* ARMV6M does not have coprocessors, so these should never be used. */ -+FUNC_START gnu_Unwind_Restore_VFP -+ RET -+ -+/* Store VFR regsters d0-d15 to the address in r0. */ -+FUNC_START gnu_Unwind_Save_VFP -+ RET -+ -+/* Load VFP registers d0-d15 from the address in r0. -+ Use this to load from FSTMD format. */ -+FUNC_START gnu_Unwind_Restore_VFP_D -+ RET -+ -+/* Store VFP registers d0-d15 to the address in r0. -+ Use this to store in FLDMD format. */ -+FUNC_START gnu_Unwind_Save_VFP_D -+ RET -+ -+/* Load VFP registers d16-d31 from the address in r0. -+ Use this to load from FSTMD (=VSTM) format. Needs VFPv3. */ -+FUNC_START gnu_Unwind_Restore_VFP_D_16_to_31 -+ RET -+ -+/* Store VFP registers d16-d31 to the address in r0. -+ Use this to store in FLDMD (=VLDM) format. Needs VFPv3. */ -+FUNC_START gnu_Unwind_Save_VFP_D_16_to_31 -+ RET -+ -+FUNC_START gnu_Unwind_Restore_WMMXD -+ RET -+ -+FUNC_START gnu_Unwind_Save_WMMXD -+ RET -+ -+FUNC_START gnu_Unwind_Restore_WMMXC -+ RET -+ -+FUNC_START gnu_Unwind_Save_WMMXC -+ RET -+ -+.macro UNWIND_WRAPPER name nargs -+ FUNC_START \name -+ /* Create a phase2_vrs structure. */ -+ /* Save r0 in the PC slot so we can use it as a scratch register. */ -+ push {r0} -+ add r0, sp, #4 -+ push {r0, lr} /* Push original SP and LR. */ -+ /* Make space for r8-r12. */ -+ sub sp, sp, #20 -+ /* Save low registers. */ -+ push {r0, r1, r2, r3, r4, r5, r6, r7} -+ /* Save high registers. */ -+ add r0, sp, #32 -+ mov r1, r8 -+ mov r2, r9 -+ mov r3, sl -+ mov r4, fp -+ mov r5, ip -+ stmia r0!, {r1, r2, r3, r4, r5} -+ /* Restore original low register values. */ -+ add r0, sp, #4 -+ ldmia r0!, {r1, r2, r3, r4, r5} -+ /* Restore orginial r0. */ -+ ldr r0, [sp, #60] -+ str r0, [sp] -+ /* Demand-save flags, plus an extra word for alignment. */ -+ mov r3, #0 -+ push {r2, r3} -+ /* Point r1 at the block. Pass r[0..nargs) unchanged. */ -+ add r\nargs, sp, #4 -+ -+ bl SYM (__gnu\name) -+ -+ ldr r3, [sp, #64] -+ add sp, sp, #72 -+ bx r3 -+ -+ FUNC_END \name -+ UNPREFIX \name -+.endm -+ -+#else /* !__ARM_ARCH_6M__ */ -+ - /* r0 points to a 16-word block. Upload these values to the actual core - state. */ - ARM_FUNC_START restore_core_regs -@@ -233,6 +346,8 @@ ARM_FUNC_START gnu_Unwind_Save_WMMXC - UNPREFIX \name - .endm - -+#endif /* !__ARM_ARCH_6M__ */ -+ - UNWIND_WRAPPER _Unwind_RaiseException 1 - UNWIND_WRAPPER _Unwind_Resume 1 - UNWIND_WRAPPER _Unwind_Resume_or_Rethrow 1 ---- /dev/null -+++ b/gcc/config/arm/linux-atomic.c -@@ -0,0 +1,280 @@ -+/* Linux-specific atomic operations for ARM EABI. -+ Copyright (C) 2008 Free Software Foundation, Inc. -+ Contributed by CodeSourcery. -+ -+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. -+ -+In addition to the permissions in the GNU General Public License, the -+Free Software Foundation gives you unlimited permission to link the -+compiled version of this file into combinations with other programs, -+and to distribute those combinations without any restriction coming -+from the use of this file. (The General Public License restrictions -+do apply in other respects; for example, they cover modification of -+the file, and distribution when not linked into a combine -+executable.) -+ -+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. */ -+ -+/* Kernel helper for compare-and-exchange. */ -+typedef int (__kernel_cmpxchg_t) (int oldval, int newval, int *ptr); -+#define __kernel_cmpxchg (*(__kernel_cmpxchg_t *) 0xffff0fc0) -+ -+/* Kernel helper for memory barrier. */ -+typedef void (__kernel_dmb_t) (void); -+#define __kernel_dmb (*(__kernel_dmb_t *) 0xffff0fa0) -+ -+/* Note: we implement byte, short and int versions of atomic operations using -+ the above kernel helpers, but there is no support for "long long" (64-bit) -+ operations as yet. */ -+ -+#define HIDDEN __attribute__ ((visibility ("hidden"))) -+ -+#ifdef __ARMEL__ -+#define INVERT_MASK_1 0 -+#define INVERT_MASK_2 0 -+#else -+#define INVERT_MASK_1 24 -+#define INVERT_MASK_2 16 -+#endif -+ -+#define MASK_1 0xffu -+#define MASK_2 0xffffu -+ -+#define FETCH_AND_OP_WORD(OP, PFX_OP, INF_OP) \ -+ int HIDDEN \ -+ __sync_fetch_and_##OP##_4 (int *ptr, int val) \ -+ { \ -+ int failure, tmp; \ -+ \ -+ do { \ -+ tmp = *ptr; \ -+ failure = __kernel_cmpxchg (tmp, PFX_OP tmp INF_OP val, ptr); \ -+ } while (failure != 0); \ -+ \ -+ return tmp; \ -+ } -+ -+FETCH_AND_OP_WORD (add, , +) -+FETCH_AND_OP_WORD (sub, , -) -+FETCH_AND_OP_WORD (or, , |) -+FETCH_AND_OP_WORD (and, , &) -+FETCH_AND_OP_WORD (xor, , ^) -+FETCH_AND_OP_WORD (nand, ~, &) -+ -+#define NAME_oldval(OP, WIDTH) __sync_fetch_and_##OP##_##WIDTH -+#define NAME_newval(OP, WIDTH) __sync_##OP##_and_fetch_##WIDTH -+ -+/* Implement both __sync__and_fetch and __sync_fetch_and_ for -+ subword-sized quantities. */ -+ -+#define SUBWORD_SYNC_OP(OP, PFX_OP, INF_OP, TYPE, WIDTH, RETURN) \ -+ TYPE HIDDEN \ -+ NAME##_##RETURN (OP, WIDTH) (TYPE *ptr, TYPE val) \ -+ { \ -+ int *wordptr = (int *) ((unsigned int) ptr & ~3); \ -+ unsigned int mask, shift, oldval, newval; \ -+ int failure; \ -+ \ -+ shift = (((unsigned int) ptr & 3) << 3) ^ INVERT_MASK_##WIDTH; \ -+ mask = MASK_##WIDTH << shift; \ -+ \ -+ do { \ -+ oldval = *wordptr; \ -+ newval = ((PFX_OP ((oldval & mask) >> shift) \ -+ INF_OP (unsigned int) val) << shift) & mask; \ -+ newval |= oldval & ~mask; \ -+ failure = __kernel_cmpxchg (oldval, newval, wordptr); \ -+ } while (failure != 0); \ -+ \ -+ return (RETURN & mask) >> shift; \ -+ } -+ -+SUBWORD_SYNC_OP (add, , +, short, 2, oldval) -+SUBWORD_SYNC_OP (sub, , -, short, 2, oldval) -+SUBWORD_SYNC_OP (or, , |, short, 2, oldval) -+SUBWORD_SYNC_OP (and, , &, short, 2, oldval) -+SUBWORD_SYNC_OP (xor, , ^, short, 2, oldval) -+SUBWORD_SYNC_OP (nand, ~, &, short, 2, oldval) -+ -+SUBWORD_SYNC_OP (add, , +, char, 1, oldval) -+SUBWORD_SYNC_OP (sub, , -, char, 1, oldval) -+SUBWORD_SYNC_OP (or, , |, char, 1, oldval) -+SUBWORD_SYNC_OP (and, , &, char, 1, oldval) -+SUBWORD_SYNC_OP (xor, , ^, char, 1, oldval) -+SUBWORD_SYNC_OP (nand, ~, &, char, 1, oldval) -+ -+#define OP_AND_FETCH_WORD(OP, PFX_OP, INF_OP) \ -+ int HIDDEN \ -+ __sync_##OP##_and_fetch_4 (int *ptr, int val) \ -+ { \ -+ int tmp, failure; \ -+ \ -+ do { \ -+ tmp = *ptr; \ -+ failure = __kernel_cmpxchg (tmp, PFX_OP tmp INF_OP val, ptr); \ -+ } while (failure != 0); \ -+ \ -+ return PFX_OP tmp INF_OP val; \ -+ } -+ -+OP_AND_FETCH_WORD (add, , +) -+OP_AND_FETCH_WORD (sub, , -) -+OP_AND_FETCH_WORD (or, , |) -+OP_AND_FETCH_WORD (and, , &) -+OP_AND_FETCH_WORD (xor, , ^) -+OP_AND_FETCH_WORD (nand, ~, &) -+ -+SUBWORD_SYNC_OP (add, , +, short, 2, newval) -+SUBWORD_SYNC_OP (sub, , -, short, 2, newval) -+SUBWORD_SYNC_OP (or, , |, short, 2, newval) -+SUBWORD_SYNC_OP (and, , &, short, 2, newval) -+SUBWORD_SYNC_OP (xor, , ^, short, 2, newval) -+SUBWORD_SYNC_OP (nand, ~, &, short, 2, newval) -+ -+SUBWORD_SYNC_OP (add, , +, char, 1, newval) -+SUBWORD_SYNC_OP (sub, , -, char, 1, newval) -+SUBWORD_SYNC_OP (or, , |, char, 1, newval) -+SUBWORD_SYNC_OP (and, , &, char, 1, newval) -+SUBWORD_SYNC_OP (xor, , ^, char, 1, newval) -+SUBWORD_SYNC_OP (nand, ~, &, char, 1, newval) -+ -+int HIDDEN -+__sync_val_compare_and_swap_4 (int *ptr, int oldval, int newval) -+{ -+ int actual_oldval, fail; -+ -+ while (1) -+ { -+ actual_oldval = *ptr; -+ -+ if (oldval != actual_oldval) -+ return actual_oldval; -+ -+ fail = __kernel_cmpxchg (actual_oldval, newval, ptr); -+ -+ if (!fail) -+ return oldval; -+ } -+} -+ -+#define SUBWORD_VAL_CAS(TYPE, WIDTH) \ -+ TYPE HIDDEN \ -+ __sync_val_compare_and_swap_##WIDTH (TYPE *ptr, TYPE oldval, \ -+ TYPE newval) \ -+ { \ -+ int *wordptr = (int *)((unsigned int) ptr & ~3), fail; \ -+ unsigned int mask, shift, actual_oldval, actual_newval; \ -+ \ -+ shift = (((unsigned int) ptr & 3) << 3) ^ INVERT_MASK_##WIDTH; \ -+ mask = MASK_##WIDTH << shift; \ -+ \ -+ while (1) \ -+ { \ -+ actual_oldval = *wordptr; \ -+ \ -+ if (((actual_oldval & mask) >> shift) != (unsigned int) oldval) \ -+ return (actual_oldval & mask) >> shift; \ -+ \ -+ actual_newval = (actual_oldval & ~mask) \ -+ | (((unsigned int) newval << shift) & mask); \ -+ \ -+ fail = __kernel_cmpxchg (actual_oldval, actual_newval, \ -+ wordptr); \ -+ \ -+ if (!fail) \ -+ return oldval; \ -+ } \ -+ } -+ -+SUBWORD_VAL_CAS (short, 2) -+SUBWORD_VAL_CAS (char, 1) -+ -+typedef unsigned char bool; -+ -+bool HIDDEN -+__sync_bool_compare_and_swap_4 (int *ptr, int oldval, int newval) -+{ -+ int failure = __kernel_cmpxchg (oldval, newval, ptr); -+ return (failure == 0); -+} -+ -+#define SUBWORD_BOOL_CAS(TYPE, WIDTH) \ -+ bool HIDDEN \ -+ __sync_bool_compare_and_swap_##WIDTH (TYPE *ptr, TYPE oldval, \ -+ TYPE newval) \ -+ { \ -+ TYPE actual_oldval \ -+ = __sync_val_compare_and_swap_##WIDTH (ptr, oldval, newval); \ -+ return (oldval == actual_oldval); \ -+ } -+ -+SUBWORD_BOOL_CAS (short, 2) -+SUBWORD_BOOL_CAS (char, 1) -+ -+void HIDDEN -+__sync_synchronize (void) -+{ -+ __kernel_dmb (); -+} -+ -+int HIDDEN -+__sync_lock_test_and_set_4 (int *ptr, int val) -+{ -+ int failure, oldval; -+ -+ do { -+ oldval = *ptr; -+ failure = __kernel_cmpxchg (oldval, val, ptr); -+ } while (failure != 0); -+ -+ return oldval; -+} -+ -+#define SUBWORD_TEST_AND_SET(TYPE, WIDTH) \ -+ TYPE HIDDEN \ -+ __sync_lock_test_and_set_##WIDTH (TYPE *ptr, TYPE val) \ -+ { \ -+ int failure; \ -+ unsigned int oldval, newval, shift, mask; \ -+ int *wordptr = (int *) ((unsigned int) ptr & ~3); \ -+ \ -+ shift = (((unsigned int) ptr & 3) << 3) ^ INVERT_MASK_##WIDTH; \ -+ mask = MASK_##WIDTH << shift; \ -+ \ -+ do { \ -+ oldval = *wordptr; \ -+ newval = (oldval & ~mask) \ -+ | (((unsigned int) val << shift) & mask); \ -+ failure = __kernel_cmpxchg (oldval, newval, wordptr); \ -+ } while (failure != 0); \ -+ \ -+ return (oldval & mask) >> shift; \ -+ } -+ -+SUBWORD_TEST_AND_SET (short, 2) -+SUBWORD_TEST_AND_SET (char, 1) -+ -+#define SYNC_LOCK_RELEASE(TYPE, WIDTH) \ -+ void HIDDEN \ -+ __sync_lock_release_##WIDTH (TYPE *ptr) \ -+ { \ -+ *ptr = 0; \ -+ __kernel_dmb (); \ -+ } -+ -+SYNC_LOCK_RELEASE (int, 4) -+SYNC_LOCK_RELEASE (short, 2) -+SYNC_LOCK_RELEASE (char, 1) ---- a/gcc/config/arm/linux-eabi.h -+++ b/gcc/config/arm/linux-eabi.h -@@ -66,7 +66,7 @@ - /* 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. */ ---- /dev/null -+++ b/gcc/config/arm/marvell-f-vfp.md -@@ -0,0 +1,157 @@ -+;; Marvell 2850 VFP pipeline description -+;; Copyright (C) 2007 Free Software Foundation, Inc. -+;; Written by 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 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 -+;; . -+ -+;; 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" "fadds,faddd")) -+ "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" "fcpys,ffariths,ffarithd,fcmps,fcmpd")) -+ "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,364 @@ -+;; 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 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 -+;; . -+ -+;; 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") -+ ---- /dev/null -+++ b/gcc/config/arm/montavista-linux.h -@@ -0,0 +1,33 @@ -+/* MontaVista GNU/Linux Configuration. -+ 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 -+. */ -+ -+/* Add -tarmv6 and -tthumb2 options for convenience in generating multilibs. -+*/ -+#undef CC1_SPEC -+#define CC1_SPEC " \ -+ %{tarmv6: -march=armv6 -mfloat-abi=softfp ; \ -+ tthumb2: -mthumb -march=armv7-a -mfloat-abi=softfp ; \ -+ : -march=armv5t}" -+ -+/* The various C libraries each have their own subdirectory. */ -+#undef SYSROOT_SUFFIX_SPEC -+#define SYSROOT_SUFFIX_SPEC \ -+ "%{tarmv6:/armv6 ; \ -+ tthumb2:/thumb2}" ---- a/gcc/config/arm/neon-gen.ml -+++ b/gcc/config/arm/neon-gen.ml -@@ -402,7 +402,11 @@ let _ = - "extern \"C\" {"; - "#endif"; - ""; -+"#if defined (__vxworks) && defined (_WRS_KERNEL)"; -+"#include "; -+"#else"; - "#include "; -+"#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]) -@@ -427,76 +428,7 @@ - ;; neon_type attribute definitions. - (define_attr "vqh_mnem" "vadd,vmin,vmax" (const_string "vadd")) - --;; 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,\ -- neon_int_3,\ -- neon_int_4,\ -- neon_int_5,\ -- neon_vqneg_vqabs,\ -- neon_vmov,\ -- neon_vaba,\ -- neon_vsma,\ -- neon_vaba_qqq,\ -- neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\ -- neon_mul_qqq_8_16_32_ddd_32,\ -- neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar,\ -- neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\ -- neon_mla_qqq_8_16,\ -- neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long,\ -- neon_mla_qqq_32_qqd_32_scalar,\ -- neon_mul_ddd_16_scalar_32_16_long_scalar,\ -- neon_mul_qqd_32_scalar,\ -- neon_mla_ddd_16_scalar_qdd_32_16_long_scalar,\ -- neon_shift_1,\ -- neon_shift_2,\ -- neon_shift_3,\ -- neon_vshl_ddd,\ -- neon_vqshl_vrshl_vqrshl_qqq,\ -- neon_vsra_vrsra,\ -- neon_fp_vadd_ddd_vabs_dd,\ -- neon_fp_vadd_qqq_vabs_qq,\ -- neon_fp_vsum,\ -- neon_fp_vmul_ddd,\ -- neon_fp_vmul_qqd,\ -- neon_fp_vmla_ddd,\ -- neon_fp_vmla_qqq,\ -- neon_fp_vmla_ddd_scalar,\ -- neon_fp_vmla_qqq_scalar,\ -- neon_fp_vrecps_vrsqrts_ddd,\ -- neon_fp_vrecps_vrsqrts_qqq,\ -- neon_bp_simple,\ -- neon_bp_2cycle,\ -- neon_bp_3cycle,\ -- neon_ldr,\ -- neon_str,\ -- neon_vld1_1_2_regs,\ -- neon_vld1_3_4_regs,\ -- neon_vld2_2_regs_vld1_vld2_all_lanes,\ -- neon_vld2_4_regs,\ -- neon_vld3_vld4,\ -- neon_vst1_1_2_regs_vst2_2_regs,\ -- neon_vst1_3_4_regs,\ -- neon_vst2_4_regs_vst3_vst4,\ -- neon_vst3_vst4,\ -- neon_vld1_vld2_lane,\ -- neon_vld3_vld4_lane,\ -- neon_vst1_vst2_lane,\ -- neon_vst3_vst4_lane,\ -- neon_vld3_vld4_all_lanes,\ -- neon_mcr,\ -- neon_mcr_2_mcrr,\ -- neon_mrc,\ -- neon_mrrc,\ -- neon_ldm_2,\ -- neon_stm_2,\ -- none" -- (const_string "none")) -- --;; Predicates used for setting the above attribute. -+;; Predicates used for setting neon_type - - (define_mode_attr Is_float_mode [(V8QI "false") (V16QI "false") - (V4HI "false") (V8HI "false") -@@ -550,7 +482,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) -@@ -639,7 +571,8 @@ - default: gcc_unreachable (); - } - } -- [(set_attr "length" ",,")]) -+ [(set_attr "neon_type" "neon_int_1,neon_stm_2,neon_ldm_2") -+ (set_attr "length" ",,")]) - - (define_split - [(set (match_operand:EI 0 "s_register_operand" "") -@@ -726,6 +659,41 @@ - neon_disambiguate_copy (operands, dest, src, 4); - }) - -+(define_expand "movmisalign" -+ [(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) -+ && !s_register_operand (operands[1], mode)) -+ FAIL; -+}) -+ -+(define_insn "*movmisalign_neon" -+ [(set (match_operand:VDX 0 "nonimmediate_operand" "=Um,w") -+ (unspec:VDX [(match_operand:VDX 1 "general_operand" " w, Um")] -+ UNSPEC_MISALIGNED_ACCESS))] -+ "TARGET_NEON && !BYTES_BIG_ENDIAN -+ && ( s_register_operand (operands[0], mode) -+ || s_register_operand (operands[1], mode))" -+ "@ -+ vst1.\t{%P1}, %A0 -+ vld1.\t{%P0}, %A1" -+ [(set_attr "neon_type" "neon_vst1_1_2_regs_vst2_2_regs,neon_vld1_1_2_regs")]) -+ -+(define_insn "*movmisalign_neon" -+ [(set (match_operand:VQX 0 "nonimmediate_operand" "=Um,w") -+ (unspec:VQX [(match_operand:VQX 1 "general_operand" " w, Um")] -+ UNSPEC_MISALIGNED_ACCESS))] -+ "TARGET_NEON && !BYTES_BIG_ENDIAN -+ && ( s_register_operand (operands[0], mode) -+ || s_register_operand (operands[1], mode))" -+ "@ -+ vst1.\t{%q1}, %A0 -+ vld1.\t{%q0}, %A1" -+ [(set_attr "neon_type" "neon_vst1_1_2_regs_vst2_2_regs,neon_vld1_1_2_regs")]) -+ - (define_insn "vec_set_internal" - [(set (match_operand:VD 0 "s_register_operand" "=w") - (vec_merge:VD -@@ -735,7 +703,10 @@ - (match_operand:SI 2 "immediate_operand" "i")))] - "TARGET_NEON" - { -- operands[2] = GEN_INT (ffs ((int) INTVAL (operands[2]) - 1)); -+ int elt = ffs ((int) INTVAL (operands[2]) - 1); -+ if (BYTES_BIG_ENDIAN) -+ elt = GET_MODE_NUNITS (mode) - 1 - elt; -+ operands[2] = GEN_INT (elt); - - return "vmov%?.\t%P0[%c2], %1"; - } -@@ -757,6 +728,9 @@ - int hi = (elem / half_elts) * 2; - int regno = REGNO (operands[0]); - -+ if (BYTES_BIG_ENDIAN) -+ elt = half_elts - 1 - elt; -+ - operands[0] = gen_rtx_REG (mode, regno + hi); - operands[2] = GEN_INT (elt); - -@@ -804,7 +778,15 @@ - (match_operand:VD 1 "s_register_operand" "w") - (parallel [(match_operand:SI 2 "immediate_operand" "i")])))] - "TARGET_NEON" -- "vmov%?.\t%0, %P1[%c2]" -+{ -+ if (BYTES_BIG_ENDIAN) -+ { -+ int elt = INTVAL (operands[2]); -+ elt = GET_MODE_NUNITS (mode) - 1 - elt; -+ operands[2] = GEN_INT (elt); -+ } -+ return "vmov%?.\t%0, %P1[%c2]"; -+} - [(set_attr "predicable" "yes") - (set_attr "neon_type" "neon_bp_simple")] - ) -@@ -821,6 +803,9 @@ - int hi = (INTVAL (operands[2]) / half_elts) * 2; - int regno = REGNO (operands[1]); - -+ if (BYTES_BIG_ENDIAN) -+ elt = half_elts - 1 - elt; -+ - operands[1] = gen_rtx_REG (mode, regno + hi); - operands[2] = GEN_INT (elt); - -@@ -913,6 +898,50 @@ - (const_string "neon_mul_qqq_8_16_32_ddd_32")))))] - ) - -+(define_insn "*mul3add_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.\t%0, %2, %3" -+ [(set (attr "neon_type") -+ (if_then_else (ne (symbol_ref "") (const_int 0)) -+ (if_then_else (ne (symbol_ref "") (const_int 0)) -+ (const_string "neon_fp_vmla_ddd") -+ (const_string "neon_fp_vmla_qqq")) -+ (if_then_else (ne (symbol_ref "") (const_int 0)) -+ (if_then_else -+ (ne (symbol_ref "") (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 "") (const_int 0)) -+ (const_string "neon_mla_qqq_8_16") -+ (const_string "neon_mla_qqq_32_qqd_32_scalar")))))] -+) -+ -+(define_insn "*mul3negadd_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.\t%0, %2, %3" -+ [(set (attr "neon_type") -+ (if_then_else (ne (symbol_ref "") (const_int 0)) -+ (if_then_else (ne (symbol_ref "") (const_int 0)) -+ (const_string "neon_fp_vmla_ddd") -+ (const_string "neon_fp_vmla_qqq")) -+ (if_then_else (ne (symbol_ref "") (const_int 0)) -+ (if_then_else -+ (ne (symbol_ref "") (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 "") (const_int 0)) -+ (const_string "neon_mla_qqq_8_16") -+ (const_string "neon_mla_qqq_32_qqd_32_scalar")))))] -+) -+ - (define_insn "ior3" - [(set (match_operand:VDQ 0 "s_register_operand" "=w,w") - (ior:VDQ (match_operand:VDQ 1 "s_register_operand" "w,0") -@@ -2413,7 +2442,15 @@ - (match_operand:VD 1 "s_register_operand" "w") - (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))] - "TARGET_NEON" -- "vmov%?.s\t%0, %P1[%c2]" -+{ -+ if (BYTES_BIG_ENDIAN) -+ { -+ int elt = INTVAL (operands[2]); -+ elt = GET_MODE_NUNITS (mode) - 1 - elt; -+ operands[2] = GEN_INT (elt); -+ } -+ return "vmov%?.s\t%0, %P1[%c2]"; -+} - [(set_attr "predicable" "yes") - (set_attr "neon_type" "neon_bp_simple")] - ) -@@ -2425,7 +2462,15 @@ - (match_operand:VD 1 "s_register_operand" "w") - (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))] - "TARGET_NEON" -- "vmov%?.u\t%0, %P1[%c2]" -+{ -+ if (BYTES_BIG_ENDIAN) -+ { -+ int elt = INTVAL (operands[2]); -+ elt = GET_MODE_NUNITS (mode) - 1 - elt; -+ operands[2] = GEN_INT (elt); -+ } -+ return "vmov%?.u\t%0, %P1[%c2]"; -+} - [(set_attr "predicable" "yes") - (set_attr "neon_type" "neon_bp_simple")] - ) -@@ -2442,10 +2487,14 @@ - int regno = REGNO (operands[1]); - unsigned int halfelts = GET_MODE_NUNITS (mode) / 2; - unsigned int elt = INTVAL (operands[2]); -+ unsigned int elt_adj = elt % halfelts; -+ -+ if (BYTES_BIG_ENDIAN) -+ elt_adj = halfelts - 1 - elt_adj; - - ops[0] = operands[0]; - ops[1] = gen_rtx_REG (mode, regno + 2 * (elt / halfelts)); -- ops[2] = GEN_INT (elt % halfelts); -+ ops[2] = GEN_INT (elt_adj); - output_asm_insn ("vmov%?.s\t%0, %P1[%c2]", ops); - - return ""; -@@ -2466,10 +2515,14 @@ - int regno = REGNO (operands[1]); - unsigned int halfelts = GET_MODE_NUNITS (mode) / 2; - unsigned int elt = INTVAL (operands[2]); -+ unsigned int elt_adj = elt % halfelts; -+ -+ if (BYTES_BIG_ENDIAN) -+ elt_adj = halfelts - 1 - elt_adj; - - ops[0] = operands[0]; - ops[1] = gen_rtx_REG (mode, regno + 2 * (elt / halfelts)); -- ops[2] = GEN_INT (elt % halfelts); -+ ops[2] = GEN_INT (elt_adj); - output_asm_insn ("vmov%?.u\t%0, %P1[%c2]", ops); - - return ""; -@@ -2490,6 +2543,20 @@ - - neon_lane_bounds (operands[2], 0, GET_MODE_NUNITS (mode)); - -+ if (BYTES_BIG_ENDIAN) -+ { -+ /* The intrinsics are defined in terms of a model where the -+ element ordering in memory is vldm order, whereas the generic -+ RTL is defined in terms of a model where the element ordering -+ in memory is array order. Convert the lane number to conform -+ to this model. */ -+ unsigned int elt = INTVAL (operands[2]); -+ unsigned int reg_nelts -+ = 64 / GET_MODE_BITSIZE (GET_MODE_INNER (mode)); -+ elt ^= reg_nelts - 1; -+ operands[2] = GEN_INT (elt); -+ } -+ - if ((magic & 3) == 3 || GET_MODE_BITSIZE (GET_MODE_INNER (mode)) == 32) - insn = gen_vec_extract (operands[0], operands[1], operands[2]); - else ---- a/gcc/config/arm/netbsd.h -+++ b/gcc/config/arm/netbsd.h -@@ -101,7 +101,7 @@ - /* Although not normally relevant (since by default, all aggregates - are returned in memory) compiling some parts of libc requires - non-APCS style struct returns. */ --#undef RETURN_IN_MEMORY -+#undef TARGET_RETURN_IN_MEMORY - - /* VERY BIG NOTE : Change of structure alignment for RiscBSD. - There are consequences you should be aware of... ---- /dev/null -+++ b/gcc/config/arm/nocrt0.h -@@ -0,0 +1,24 @@ -+/* 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 -+ . */ -+ -+#undef STARTFILE_SPEC -+#define STARTFILE_SPEC " crti%O%s crtbegin%O%s" -+ -+#define LIB_SPEC "-lc" ---- a/gcc/config/arm/predicates.md -+++ b/gcc/config/arm/predicates.md -@@ -168,6 +168,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") -@@ -291,6 +296,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; -@@ -348,6 +356,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; ---- /dev/null -+++ b/gcc/config/arm/sfp-machine.h -@@ -0,0 +1,100 @@ -+#define _FP_W_TYPE_SIZE 32 -+#define _FP_W_TYPE unsigned long -+#define _FP_WS_TYPE signed long -+#define _FP_I_TYPE long -+ -+#define _FP_MUL_MEAT_S(R,X,Y) \ -+ _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,umul_ppmm) -+#define _FP_MUL_MEAT_D(R,X,Y) \ -+ _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm) -+#define _FP_MUL_MEAT_Q(R,X,Y) \ -+ _FP_MUL_MEAT_4_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm) -+ -+#define _FP_DIV_MEAT_S(R,X,Y) _FP_DIV_MEAT_1_loop(S,R,X,Y) -+#define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_2_udiv(D,R,X,Y) -+#define _FP_DIV_MEAT_Q(R,X,Y) _FP_DIV_MEAT_4_udiv(Q,R,X,Y) -+ -+#define _FP_NANFRAC_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 -+ -+#define _FP_KEEPNANFRACP 1 -+ -+/* Someone please check this. */ -+#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \ -+ do { \ -+ if ((_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs) \ -+ && !(_FP_FRAC_HIGH_RAW_##fs(Y) & _FP_QNANBIT_##fs)) \ -+ { \ -+ R##_s = Y##_s; \ -+ _FP_FRAC_COPY_##wc(R,Y); \ -+ } \ -+ else \ -+ { \ -+ R##_s = X##_s; \ -+ _FP_FRAC_COPY_##wc(R,X); \ -+ } \ -+ R##_c = FP_CLS_NAN; \ -+ } while (0) -+ -+#define __LITTLE_ENDIAN 1234 -+#define __BIG_ENDIAN 4321 -+ -+#if defined __ARMEB__ -+# define __BYTE_ORDER __BIG_ENDIAN -+#else -+# define __BYTE_ORDER __LITTLE_ENDIAN -+#endif -+ -+ -+/* Define ALIASNAME as a strong alias for NAME. */ -+# define strong_alias(name, aliasname) _strong_alias(name, aliasname) -+# define _strong_alias(name, aliasname) \ -+ extern __typeof (name) aliasname __attribute__ ((alias (#name))); -+ -+#ifdef __ARM_EABI__ -+/* Rename functions to their EABI names. */ -+/* The comparison functions need wrappers for EABI semantics, so -+ leave them unmolested. */ -+#define __negsf2 __aeabi_fneg -+#define __subsf3 __aeabi_fsub -+#define __addsf3 __aeabi_fadd -+#define __floatunsisf __aeabi_ui2f -+#define __floatsisf __aeabi_i2f -+#define __floatundisf __aeabi_ul2f -+#define __floatdisf __aeabi_l2f -+#define __mulsf3 __aeabi_fmul -+#define __divsf3 __aeabi_fdiv -+#define __unordsf2 __aeabi_fcmpun -+#define __fixsfsi __aeabi_f2iz -+#define __fixunssfsi __aeabi_f2uiz -+#define __fixsfdi __aeabi_f2lz -+#define __fixunssfdi __aeabi_f2ulz -+#define __floatdisf __aeabi_l2f -+ -+#define __negdf2 __aeabi_dneg -+#define __subdf3 __aeabi_dsub -+#define __adddf3 __aeabi_dadd -+#define __floatunsidf __aeabi_ui2d -+#define __floatsidf __aeabi_i2d -+#define __extendsfdf2 __aeabi_f2d -+#define __truncdfsf2 __aeabi_d2f -+#define __floatundidf __aeabi_ul2d -+#define __floatdidf __aeabi_l2d -+#define __muldf3 __aeabi_dmul -+#define __divdf3 __aeabi_ddiv -+#define __unorddf2 __aeabi_dcmpun -+#define __fixdfsi __aeabi_d2iz -+#define __fixunsdfsi __aeabi_d2uiz -+#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/symbian.h -+++ b/gcc/config/arm/symbian.h -@@ -101,3 +101,5 @@ - - /* SymbianOS cannot merge entities with vague linkage at runtime. */ - #define TARGET_ARM_DYNAMIC_VAGUE_LINKAGE_P false -+ -+#define TARGET_DEFAULT_WORD_RELOCATIONS 1 ---- 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 -@@ -1,25 +1,68 @@ - LIB1ASMSRC = arm/lib1funcs.asm -+# For most CPUs we have an assembly soft-float implementations. -+# However this is not true for ARMv6M. Here we want to use the soft-fp C -+# implementation. The soft-fp code is only build for ARMv6M. This pulls -+# in the asm implementation for other CPUs. - LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_tls _bb_init_func \ - _call_via_rX _interwork_call_via_rX \ - _lshrdi3 _ashrdi3 _ashldi3 \ -- _negdf2 _addsubdf3 _muldivdf3 _cmpdf2 _unorddf2 _fixdfsi _fixunsdfsi \ -- _truncdfsf2 _negsf2 _addsubsf3 _muldivsf3 _cmpsf2 _unordsf2 \ -- _fixsfsi _fixunssfsi _floatdidf _floatdisf _floatundidf _floatundisf -+ _arm_negdf2 _arm_addsubdf3 _arm_muldivdf3 _arm_cmpdf2 _arm_unorddf2 \ -+ _arm_fixdfsi _arm_fixunsdfsi \ -+ _arm_truncdfsf2 _arm_negsf2 _arm_addsubsf3 _arm_muldivsf3 \ -+ _arm_cmpsf2 _arm_unordsf2 _arm_fixsfsi _arm_fixunssfsi \ -+ _arm_floatdidf _arm_floatdisf _arm_floatundidf _arm_floatundisf -+ -+# We build 4 multilibs: -+# ./ (default) -+# thumb/ -mthumb -+# thumb2/ -mthumb -march=armv7 -+# armv6-m/ -mthumb -march=armv6-m - --MULTILIB_OPTIONS = marm/mthumb --MULTILIB_DIRNAMES = arm thumb -+MULTILIB_OPTIONS = mthumb -+MULTILIB_DIRNAMES = thumb - MULTILIB_EXCEPTIONS = - MULTILIB_MATCHES = - --#MULTILIB_OPTIONS += march=armv7 --#MULTILIB_DIRNAMES += thumb2 --#MULTILIB_EXCEPTIONS += march=armv7* marm/*march=armv7* --#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=mcpu?cortex-a8 --#MULTILIB_MATCHES += march?armv7=mcpu?cortex-r4 --#MULTILIB_MATCHES += march?armv7=mcpu?cortex-m3 -+MULTILIB_OPTIONS += march=armv7/march=armv6-m -+MULTILIB_DIRNAMES += v7 v6-m -+MULTILIB_EXCEPTIONS += march=armv7* -+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=mcpu?cortex-a9 -+MULTILIB_MATCHES += march?armv7=mcpu?cortex-a8 -+MULTILIB_MATCHES += march?armv7=mcpu?cortex-r4 -+MULTILIB_MATCHES += march?armv7=mcpu?cortex-r4f -+MULTILIB_MATCHES += march?armv7=mcpu?cortex-m3 -+ -+MULTILIB_EXCEPTIONS += march=armv6-m -+MULTILIB_MATCHES += march?armv6-m=mcpu?cortex-m1 -+MULTILIB_MATCHES += march?armv6-m=mcpu?cortex-m0 -+ -+# FIXME: We need a sane way of doing this. -+# This isn't really a multilib, it's a hack to add an extra option -+# to the v7-m multilib. -+MULTILIB_OPTIONS += mfix-cortex-m3-ldrd -+MULTILIB_DIRNAMES += broken_ldrd -+ -+MULTILIB_EXCEPTIONS += mfix-cortex-m3-ldrd -+MULTILIB_EXCEPTIONS += mthumb/mfix-cortex-m3-ldrd -+MULTILIB_EXCEPTIONS += *march=armv6-m*mfix-cortex-m3-ldrd -+ -+MULTILIB_ALIASES += mthumb/march?armv7/mfix-cortex-m3-ldrd=mthumb/march?armv7 -+ -+# As of at least 4.2, gcc passes the wrong -L options if some multilibs are -+# omitted from MULTILIB_OSDIRNAMES -+MULTILIB_OSDIRNAMES = mthumb=!thumb -+MULTILIB_OSDIRNAMES += mthumb/march.armv7/mfix-cortex-m3-ldrd=!thumb2 -+MULTILIB_OSDIRNAMES += mthumb/march.armv6-m=!armv6-m -+ -+# 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 ---- /dev/null -+++ b/gcc/config/arm/t-arm-softfp -@@ -0,0 +1,11 @@ -+softfp_float_modes := sf df -+softfp_int_modes := si di -+softfp_extensions := sfdf -+softfp_truncations := dfsf -+softfp_machine_header := arm/sfp-machine.h -+softfp_exclude_libgcc2 := y -+softfp_wrap_start := '\#ifdef __ARM_ARCH_6M__' -+softfp_wrap_end := '\#endif' -+ -+# softfp seems to be missing a whole bunch of prototypes. -+TARGET_LIBGCC2_CFLAGS += -Wno-missing-prototypes ---- /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 \ ---- /dev/null -+++ b/gcc/config/arm/t-cs-eabi -@@ -0,0 +1,193 @@ -+# Multilibs for SourceryG++ arm-none-eabi -+ -+MULTILIB_OPTIONS = mthumb -+MULTILIB_DIRNAMES = t -+MULTILIB_EXCEPTIONS = -+MULTILIB_MATCHES = -+MULTILIB_ALIASES = -+ -+MULTILIB_OPTIONS += march=armv7/march=armv7-a/march=armv5t/march=armv6-m -+MULTILIB_DIRNAMES += v7 v7a v5t v6m -+MULTILIB_MATCHES += march?armv7-a=march?armv7a -+MULTILIB_MATCHES += march?armv7=march?armv7r -+MULTILIB_MATCHES += march?armv7=march?armv7m -+MULTILIB_MATCHES += march?armv7=march?armv7-r -+MULTILIB_MATCHES += march?armv7=march?armv7-m -+MULTILIB_MATCHES += march?armv7-a=mcpu?cortex-a9 -+MULTILIB_MATCHES += march?armv7-a=mcpu?cortex-a8 -+MULTILIB_MATCHES += march?armv7=mcpu?cortex-r4 -+MULTILIB_MATCHES += march?armv7=mcpu?cortex-r4f -+MULTILIB_MATCHES += march?armv7=mcpu?cortex-m3 -+MULTILIB_MATCHES += march?armv6-m=mcpu?cortex-m1 -+MULTILIB_MATCHES += march?armv6-m=mcpu?cortex-m0 -+MULTILIB_MATCHES += march?armv5t=march?armv5te -+MULTILIB_MATCHES += march?armv5t=march?armv6 -+MULTILIB_MATCHES += march?armv5t=march?armv6j -+MULTILIB_MATCHES += march?armv5t=march?armv6k -+MULTILIB_MATCHES += march?armv5t=march?armv6z -+MULTILIB_MATCHES += march?armv5t=march?armv6zk -+MULTILIB_MATCHES += march?armv5t=march?armv6t2 -+MULTILIB_MATCHES += march?armv5t=march?iwmmxt -+MULTILIB_MATCHES += march?armv5t=march?iwmmxt2 -+MULTILIB_MATCHES += march?armv5t=mcpu?arm10tdmi -+MULTILIB_MATCHES += march?armv5t=mcpu?arm1020t -+MULTILIB_MATCHES += march?armv5t=mcpu?arm9e -+MULTILIB_MATCHES += march?armv5t=mcpu?arm946e-s -+MULTILIB_MATCHES += march?armv5t=mcpu?arm966e-s -+MULTILIB_MATCHES += march?armv5t=mcpu?arm968e-s -+MULTILIB_MATCHES += march?armv5t=mcpu?arm10e -+MULTILIB_MATCHES += march?armv5t=mcpu?arm1020e -+MULTILIB_MATCHES += march?armv5t=mcpu?arm1022e -+MULTILIB_MATCHES += march?armv5t=mcpu?xscale -+MULTILIB_MATCHES += march?armv5t=mcpu?iwmmxt -+MULTILIB_MATCHES += march?armv5t=mcpu?iwmmxt2 -+MULTILIB_MATCHES += march?armv5t=mcpu?marvell-f -+MULTILIB_MATCHES += march?armv5t=mcpu?arm926ej-s -+MULTILIB_MATCHES += march?armv5t=mcpu?arm1026ej-s -+MULTILIB_MATCHES += march?armv5t=mcpu?arm1136j-s -+MULTILIB_MATCHES += march?armv5t=mcpu?arm1136jf-s -+MULTILIB_MATCHES += march?armv5t=mcpu?arm1176jz-s -+MULTILIB_MATCHES += march?armv5t=mcpu?arm1176jzf-s -+MULTILIB_MATCHES += march?armv5t=mcpu?mpcorenovfp -+MULTILIB_MATCHES += march?armv5t=mcpu?mpcore -+MULTILIB_MATCHES += march?armv5t=mcpu?arm1156t2-s -+ -+MULTILIB_OPTIONS += mfloat-abi=softfp/mfloat-abi=hard -+MULTILIB_DIRNAMES += softfp hard -+MULTILIB_MATCHES += mfloat-abi?hard=mhard-float -+ -+MULTILIB_OPTIONS += mfpu=neon -+MULTILIB_DIRNAMES += neon -+MULTILIB_EXCEPTIONS += mfpu=neon -+MULTILIB_MATCHES += mfpu?neon=mfpu?neon-fp16 -+ -+MULTILIB_ALIASES += mthumb=mthumb/mfpu?neon -+MULTILIB_ALIASES += mthumb=mthumb/march?armv5t/mfpu?neon -+MULTILIB_ALIASES += mbig-endian=mthumb/mfpu?neon/mbig-endian -+MULTILIB_ALIASES += mfloat-abi?softfp=mthumb/mfloat-abi?softfp/mfpu?neon -+MULTILIB_ALIASES += mfloat-abi?softfp=mfloat-abi?softfp/mfpu?neon -+MULTILIB_ALIASES += mfloat-abi?softfp/mbig-endian=mfloat-abi?softfp/mfpu?neon/mbig-endian -+MULTILIB_ALIASES += mfloat-abi?softfp/mbig-endian=mthumb/mfloat-abi?softfp/mfpu?neon/mbig-endian -+MULTILIB_ALIASES += mthumb/march?armv7/mfix-cortex-m3-ldrd=mthumb/march?armv7-a/mfpu?neon -+MULTILIB_ALIASES += mthumb/march?armv7/mbig-endian=mthumb/march?armv7-a/mfpu?neon/mbig-endian -+MULTILIB_ALIASES += march?armv7-a/mfloat-abi?softfp/mfpu?neon=mthumb/march?armv7-a/mfloat-abi?softfp/mfpu?neon -+MULTILIB_ALIASES += march?armv7-a/mfloat-abi?hard/mfpu?neon=mthumb/march?armv7-a/mfloat-abi?hard/mfpu?neon -+ -+MULTILIB_OPTIONS += mbig-endian -+MULTILIB_DIRNAMES += be -+MULTILIB_ALIASES += mbig-endian=mfpu?neon/mbig-endian -+ -+# ARMv6-M does not have ARM mode. -+MULTILIB_EXCEPTIONS += march=armv6-m -+ -+# Some ARMv7 variants have ARM mode. Use the ARM libraries. -+MULTILIB_EXCEPTIONS += march=armv7 march=armv7/* -+MULTILIB_ALIASES += mbig-endian=march?armv7/mbig-endian -+MULTILIB_ALIASES += mfloat-abi?softfp=march?armv7/mfloat-abi?softfp -+MULTILIB_ALIASES += mfloat-abi?softfp=march?armv7/mfloat-abi?softfp/mfpu?neon -+MULTILIB_ALIASES += mfloat-abi?softfp/mbig-endian=march?armv7/mfloat-abi?softfp/mbig-endian -+MULTILIB_ALIASES += mfloat-abi?softfp/mbig-endian=march?armv7/mfloat-abi?softfp/mfpu?neon/mbig-endian -+MULTILIB_ALIASES += mbig-endian=march?armv7/mfpu?neon/mbig-endian -+MULTILIB_ALIASES += mthumb/march?armv7/mfix-cortex-m3-ldrd=mthumb/march?armv7/mfloat-abi?softfp/mfpu?neon -+MULTILIB_ALIASES += mthumb/march?armv7/mfix-cortex-m3-ldrd=mthumb/march?armv7/mfpu?neon -+MULTILIB_ALIASES += mthumb/march?armv7/mbig-endian=mthumb/march?armv7/mfpu?neon/mbig-endian -+MULTILIB_ALIASES += mthumb/march?armv7/mbig-endian=mthumb/march?armv7/mfloat-abi?softfp/mfpu?neon/mbig-endian -+ -+# ARMv7-A is specially useful used with VFPv3 (enabled by NEON). Rest of the cases behaves as ARMv7. -+MULTILIB_ALIASES += mthumb/march?armv7/mfix-cortex-m3-ldrd=mthumb/march?armv7-a -+MULTILIB_ALIASES += mbig-endian=march?armv7-a/mbig-endian -+MULTILIB_ALIASES += mfloat-abi?softfp/mbig-endian=march?armv7-a/mfloat-abi?softfp/mbig-endian -+MULTILIB_ALIASES += mfloat-abi?softfp/mbig-endian=march?armv7-a/mfloat-abi?softfp/mfpu?neon/mbig-endian -+MULTILIB_ALIASES += mthumb/march?armv7/mfix-cortex-m3-ldrd=mthumb/march?armv7-a/mfloat-abi?softfp -+MULTILIB_ALIASES += mthumb/march?armv7/mbig-endian=mthumb/march?armv7-a/mbig-endian -+MULTILIB_ALIASES += mthumb/march?armv7/mbig-endian=mthumb/march?armv7-a/mfloat-abi?softfp/mbig-endian -+MULTILIB_ALIASES += mthumb/march?armv7/mfix-cortex-m3-ldrd=mthumb/march?armv7/mfloat-abi?softfp -+MULTILIB_ALIASES += march?armv5t=march?armv7-a -+MULTILIB_ALIASES += march?armv5t=march?armv7-a/mfloat-abi?softfp -+MULTILIB_ALIASES += march?armv5t=march?armv7-a/mfpu?neon -+MULTILIB_ALIASES += mbig-endian=march?armv7-a/mfpu?neon/mbig-endian -+MULTILIB_ALIASES += mthumb/march?armv7/mbig-endian=mthumb/march?armv7-a/mfloat-abi?softfp/mfpu?neon/mbig-endian -+ -+# ARMv5T thumb uses the ARMv5T ARM libraries (with or without VFP). -+MULTILIB_ALIASES += mthumb=mthumb/march?armv5t -+MULTILIB_ALIASES += march?armv5t/mfloat-abi?softfp=mthumb/march?armv5t/mfloat-abi?softfp -+MULTILIB_ALIASES += march?armv5t/mfloat-abi?softfp=march?armv5t/mfloat-abi?softfp/mfpu?neon -+MULTILIB_ALIASES += march?armv5t/mfloat-abi?softfp=mthumb/march?armv5t/mfloat-abi?softfp/mfpu?neon -+MULTILIB_ALIASES += march?armv5t=march?armv5t/mfpu?neon -+MULTILIB_ALIASES += mbig-endian=march?armv5t/mfpu?neon/mbig-endian -+MULTILIB_ALIASES += mbig-endian=march?armv5t/mfloat-abi?softfp/mfpu?neon/mbig-endian -+MULTILIB_ALIASES += mbig-endian=mthumb/march?armv5t/mfpu?neon/mbig-endian -+MULTILIB_ALIASES += mbig-endian=mthumb/march?armv5t/mfloat-abi?softfp/mfpu?neon/mbig-endian -+ -+# ARMv6-M and VFP are incompatible. -+# FIXME: The compiler should probably error. -+MULTILIB_EXCEPTIONS += *march=armv6-m/mfloat-abi=softfp -+MULTILIB_ALIASES += mthumb/march?armv6-m=mthumb/march?armv6-m/mfpu?neon -+MULTILIB_EXCEPTIONS += march=armv6-m*mfpu=neon -+MULTILIB_EXCEPTIONS += mthumb/march=armv6-m/mfloat-abi=softfp/mfpu=neon -+ -+# Thumb-1 VFP isn't really a meaningful combination. Use the ARM VFP. -+MULTILIB_ALIASES += mfloat-abi?softfp=mthumb/mfloat-abi?softfp -+MULTILIB_ALIASES += mfloat-abi?softfp/mbig-endian=mthumb/mfloat-abi?softfp/mbig-endian -+ -+# We don't have a big-endian ARMv6-M compatible multilibs. -+MULTILIB_EXCEPTIONS += *march=armv6-m*mbig-endian -+ -+# Use the generic libraries for big-endian ARMv5T -+MULTILIB_ALIASES += mbig-endian=march?armv5t/mbig-endian -+MULTILIB_ALIASES += mbig-endian=march?armv5t/mfloat-abi?softfp/mbig-endian -+MULTILIB_ALIASES += mbig-endian=mthumb/march?armv5t/mbig-endian -+MULTILIB_ALIASES += mbig-endian=mthumb/march?armv5t/mfloat-abi?softfp/mbig-endian -+ -+# Use ARM libraries for big-endian Thumb. -+MULTILIB_ALIASES += mbig-endian=mthumb/mbig-endian -+ -+# Don't bother with big-endian Thumb-2 VFP. Use the soft-float libraries -+# for now. -+MULTILIB_ALIASES += mthumb/march?armv7/mbig-endian=mthumb/march?armv7/mfloat-abi?softfp/mbig-endian -+ -+# The only -mfloat-abi=hard libraries provided are for little-endian -+# v7-A NEON. -+MULTILIB_EXCEPTIONS += mfloat-abi=hard* -+MULTILIB_EXCEPTIONS += *march=armv5t*mfloat-abi=hard* -+MULTILIB_EXCEPTIONS += *march=armv7/*mfloat-abi=hard* -+MULTILIB_EXCEPTIONS += *march=armv6-m*mfloat-abi=hard* -+MULTILIB_EXCEPTIONS += mthumb/mfloat-abi=hard* -+MULTILIB_EXCEPTIONS += *mfloat-abi=hard*mbig-endian -+MULTILIB_EXCEPTIONS += *mfloat-abi=hard -+ -+# FIXME: We need a sane way of doing this. -+# This isn't really a multilib, it's a hack to add an extra option -+# to the v7-m multilib. -+MULTILIB_OPTIONS += mfix-cortex-m3-ldrd -+MULTILIB_DIRNAMES += broken_ldrd -+ -+MULTILIB_EXCEPTIONS += mfix-cortex-m3-ldrd -+MULTILIB_EXCEPTIONS += mthumb/mfix-cortex-m3-ldrd -+MULTILIB_EXCEPTIONS += *march=armv6-m*mfix-cortex-m3-ldrd -+MULTILIB_EXCEPTIONS += *march=armv7-a*mfix-cortex-m3-ldrd -+MULTILIB_EXCEPTIONS += *mcpu=*mfix-cortex-m3-ldrd -+MULTILIB_EXCEPTIONS += *mbig-endian*mfix-cortex-m3-ldrd -+MULTILIB_EXCEPTIONS += *mfloat-abi=softfp*mfix-cortex-m3-ldrd -+MULTILIB_EXCEPTIONS += mfloat-abi=softfp*mfpu=neon* -+MULTILIB_EXCEPTIONS += *march=armv5t*mfix-cortex-m3-ldrd -+MULTILIB_EXCEPTIONS += *mfpu=neon*mfix-cortex-m3-ldrd -+ -+MULTILIB_ALIASES += mthumb/march?armv7/mfix-cortex-m3-ldrd=mthumb/march?armv7 -+MULTILIB_ALIASES += mthumb/march?armv7/mfix-cortex-m3-ldrd=mthumb/march?armv7-a/mfix-cortex-m3-ldrd -+MULTILIB_ALIASES += mthumb/march?armv7/mfix-cortex-m3-ldrd=mthumb/march?armv7/mfpu?neon/mfix-cortex-m3-ldrd -+MULTILIB_ALIASES += mthumb/march?armv7/mfix-cortex-m3-ldrd=mthumb/march?armv7-a/mfpu?neon/mfix-cortex-m3-ldrd -+ -+# As of at least 4.2, gcc passes the wrong -L options if some multilibs are -+# omitted from MULTILIB_OSDIRNAMES -+MULTILIB_OSDIRNAMES = mthumb=!thumb -+MULTILIB_OSDIRNAMES += mbig-endian=!be -+MULTILIB_OSDIRNAMES += mfloat-abi.softfp=!vfp -+MULTILIB_OSDIRNAMES += mfloat-abi.softfp/mbig-endian=!vfp-be -+MULTILIB_OSDIRNAMES += march.armv5t=!armv5t -+MULTILIB_OSDIRNAMES += march.armv5t/mfloat-abi.softfp=!armv5t-vfp -+MULTILIB_OSDIRNAMES += mthumb/march.armv7/mfix-cortex-m3-ldrd=!thumb2 -+MULTILIB_OSDIRNAMES += march.armv7-a/mfloat-abi.softfp/mfpu.neon=!armv7-a-neon -+MULTILIB_OSDIRNAMES += march.armv7-a/mfloat-abi.hard/mfpu.neon=!armv7-a-hard -+MULTILIB_OSDIRNAMES += mthumb/march.armv7/mbig-endian=!thumb2-be -+MULTILIB_OSDIRNAMES += mthumb/march.armv6-m=!armv6-m ---- /dev/null -+++ b/gcc/config/arm/t-cs-linux -@@ -0,0 +1,106 @@ -+# Multilibs for SourceryG++ arm-none-linux-gnueabi -+ -+MULTILIB_OPTIONS = mthumb -+MULTILIB_DIRNAMES = t -+MULTILIB_EXCEPTIONS = -+MULTILIB_MATCHES = -+MULTILIB_ALIASES = -+ -+MULTILIB_OPTIONS += march=armv4t/march=armv7-a -+MULTILIB_DIRNAMES += v4t v7a -+ -+MULTILIB_MATCHES += march?armv7-a=march?armv7a -+MULTILIB_MATCHES += march?armv7-a=mcpu?cortex-a9 -+MULTILIB_MATCHES += march?armv7-a=mcpu?cortex-a8 -+MULTILIB_MATCHES += march?armv4t=march?ep9312 -+MULTILIB_MATCHES += march?armv4t=mcpu?arm7tdmi -+MULTILIB_MATCHES += march?armv4t=mcpu?arm7tdmi-s -+MULTILIB_MATCHES += march?armv4t=mcpu?arm710t -+MULTILIB_MATCHES += march?armv4t=mcpu?arm720t -+MULTILIB_MATCHES += march?armv4t=mcpu?arm740t -+MULTILIB_MATCHES += march?armv4t=mcpu?arm9 -+MULTILIB_MATCHES += march?armv4t=mcpu?arm9tdmi -+MULTILIB_MATCHES += march?armv4t=mcpu?arm920 -+MULTILIB_MATCHES += march?armv4t=mcpu?arm920t -+MULTILIB_MATCHES += march?armv4t=mcpu?arm922t -+MULTILIB_MATCHES += march?armv4t=mcpu?arm940t -+MULTILIB_MATCHES += march?armv4t=mcpu?ep9312 -+ -+MULTILIB_OPTIONS += mfloat-abi=softfp/mfloat-abi=hard -+MULTILIB_DIRNAMES += softfp hard -+MULTILIB_MATCHES += mfloat-abi?hard=mhard-float -+ -+MULTILIB_OPTIONS += mfpu=neon -+MULTILIB_DIRNAMES += neon -+MULTILIB_EXCEPTIONS += mfpu=neon -+MULTILIB_MATCHES += mfpu?neon=mfpu?neon-fp16 -+MULTILIB_ALIASES += mfloat-abi?softfp=mfloat-abi?softfp/mfpu?neon -+MULTILIB_ALIASES += mfloat-abi?softfp=mthumb/mfloat-abi?softfp/mfpu?neon -+MULTILIB_ALIASES += march?armv7-a/mfloat-abi?hard/mfpu?neon=mthumb/march?armv7-a/mfloat-abi?hard/mfpu?neon -+ -+MULTILIB_OPTIONS += mbig-endian -+MULTILIB_DIRNAMES += be -+MULTILIB_ALIASES += mbig-endian=mfpu?neon/mbig-endian -+MULTILIB_ALIASES += mfloat-abi?softfp/mbig-endian=mfloat-abi?softfp/mfpu?neon/mbig-endian -+MULTILIB_ALIASES += mbig-endian=mthumb/mfpu?neon/mbig-endian -+MULTILIB_ALIASES += mfloat-abi?softfp/mbig-endian=mthumb/mfloat-abi?softfp/mfpu?neon/mbig-endian -+ -+# Do not build Thumb libraries. -+MULTILIB_EXCEPTIONS += mthumb -+MULTILIB_EXCEPTIONS += mthumb/mfpu=neon -+ -+# Use ARM libraries for ARMv4t Thumb and VFP. -+MULTILIB_ALIASES += march?armv4t=mthumb/march?armv4t -+MULTILIB_ALIASES += march?armv4t=march?armv4t/mfloat-abi?softfp -+MULTILIB_ALIASES += march?armv4t=mthumb/march?armv4t/mfloat-abi?softfp -+MULTILIB_ALIASES += march?armv4t=march?armv4t/mfpu?neon -+MULTILIB_ALIASES += march?armv4t=march?armv4t/mfloat-abi?softfp/mfpu?neon -+MULTILIB_ALIASES += march?armv4t=mthumb/march?armv4t/mfpu?neon -+MULTILIB_ALIASES += march?armv4t=mthumb/march?armv4t/mfloat-abi?softfp/mfpu?neon -+ -+# We do not support ARMv4t big-endian. -+MULTILIB_EXCEPTIONS += *march=armv4t*mbig-endian -+ -+# Behave ARMv7-A as ARMv7 for some cases. -+MULTILIB_EXCEPTIONS += march=armv7-a -+MULTILIB_EXCEPTIONS += march=armv7-a/mfpu=neon -+MULTILIB_ALIASES += mfloat-abi?softfp=march?armv7-a/mfloat-abi?softfp -+MULTILIB_ALIASES += mbig-endian=march?armv7-a/mbig-endian -+MULTILIB_ALIASES += mbig-endian=march?armv7-a/mfpu?neon/mbig-endian -+MULTILIB_ALIASES += mfloat-abi?softfp/mbig-endian=march?armv7-a/mfloat-abi?softfp/mbig-endian -+MULTILIB_ALIASES += mfloat-abi?softfp/mbig-endian=march?armv7-a/mfloat-abi?softfp/mfpu?neon/mbig-endian -+MULTILIB_ALIASES += mthumb/march?armv7-a=mthumb/march?armv7-a/mfpu?neon -+MULTILIB_ALIASES += mthumb/march?armv7-a/mbig-endian=mthumb/march?armv7-a/mfpu?neon/mbig-endian -+MULTILIB_ALIASES += mthumb/march?armv7-a/mbig-endian=mthumb/march?armv7-a/mfloat-abi?softfp/mfpu?neon/mbig-endian -+MULTILIB_ALIASES += march?armv7-a/mfloat-abi?softfp/mfpu?neon=mthumb/march?armv7-a/mfloat-abi?softfp/mfpu?neon -+MULTILIB_ALIASES += mthumb/march?armv7-a=mthumb/march?armv7-a/mfloat-abi?softfp -+ -+# Thumb-1 VFP isn't really a meaningful combination. Use the ARM VFP. -+MULTILIB_ALIASES += mfloat-abi?softfp=mthumb/mfloat-abi?softfp -+MULTILIB_ALIASES += mfloat-abi?softfp/mbig-endian=mthumb/mfloat-abi?softfp/mbig-endian -+ -+# Use ARM libraries for big-endian Thumb. -+MULTILIB_ALIASES += mbig-endian=mthumb/mbig-endian -+ -+# Don't bother with big-endian Thumb-2 VFP. Use the soft-float libraries -+# for now. -+MULTILIB_ALIASES += mthumb/march?armv7-a/mbig-endian=mthumb/march?armv7-a/mfloat-abi?softfp/mbig-endian -+ -+# The only -mfloat-abi=hard libraries provided are for little-endian -+# v7-A NEON. -+MULTILIB_EXCEPTIONS += mfloat-abi=hard* -+MULTILIB_EXCEPTIONS += *march=armv4t*mfloat-abi=hard* -+MULTILIB_EXCEPTIONS += mthumb/mfloat-abi=hard* -+MULTILIB_EXCEPTIONS += *mfloat-abi=hard*mbig-endian -+MULTILIB_EXCEPTIONS += *mfloat-abi=hard -+ -+# As of at least 4.2, gcc passes the wrong -L options if some multilibs are -+# omitted from MULTILIB_OSDIRNAMES -+MULTILIB_OSDIRNAMES = march.armv4t=!armv4t -+MULTILIB_OSDIRNAMES += mbig-endian=!be -+MULTILIB_OSDIRNAMES += mfloat-abi.softfp=!vfp -+MULTILIB_OSDIRNAMES += mfloat-abi.softfp/mbig-endian=!vfp-be -+MULTILIB_OSDIRNAMES += mthumb/march.armv7-a=!thumb2 -+MULTILIB_OSDIRNAMES += march.armv7-a/mfloat-abi.softfp/mfpu.neon=!armv7-a-neon -+MULTILIB_OSDIRNAMES += march.armv7-a/mfloat-abi.hard/mfpu.neon=!armv7-a-hard -+MULTILIB_OSDIRNAMES += mthumb/march.armv7-a/mbig-endian=!thumb2-be ---- a/gcc/config/arm/t-linux-eabi -+++ b/gcc/config/arm/t-linux-eabi -@@ -1,10 +1,48 @@ - # These functions are included in shared libraries. - TARGET_LIBGCC2_CFLAGS = -fPIC - --# We do not build a Thumb multilib for Linux because the definition of --# CLEAR_INSN_CACHE in linux-gas.h does not work in Thumb mode. --MULTILIB_OPTIONS = --MULTILIB_DIRNAMES = -+# We build 3 multilibs: -+# ./ (default) -+# armv4t/ -march=armv4t [-mthumb] -+# thumb2/ -mthumb -march=armv7 -+MULTILIB_OPTIONS = mthumb -+MULTILIB_DIRNAMES = thumb -+MULTILIB_OPTIONS += march=armv4t/march=armv7 -+MULTILIB_DIRNAMES += v4t v7 -+MULTILIB_EXCEPTIONS += march=armv7 -+MULTILIB_EXCEPTIONS += mthumb -+ -+MULTILIB_ALIASES = march?armv4t=mthumb/march?armv4t -+ -+# As of at least 4.2, gcc passes the wrong -L options if some multilibs are -+# omitted from MULTILIB_OSDIRNAMES -+MULTILIB_OSDIRNAMES = march.armv4t=!armv4t -+MULTILIB_OSDIRNAMES += mthumb/march.armv7=!thumb2 -+ -+MULTILIB_MATCHES += march?armv7=march?armv7a -+MULTILIB_MATCHES += march?armv7=march?armv7r -+MULTILIB_MATCHES += march?armv7=march?armv7m -+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=mcpu?cortex-a9 -+MULTILIB_MATCHES += march?armv7=mcpu?cortex-a8 -+MULTILIB_MATCHES += march?armv7=mcpu?cortex-r4 -+MULTILIB_MATCHES += march?armv7=mcpu?cortex-r4f -+MULTILIB_MATCHES += march?armv7=mcpu?cortex-m3 -+MULTILIB_MATCHES += march?armv4t=march?ep9312 -+MULTILIB_MATCHES += march?armv4t=mcpu?arm7tdmi -+MULTILIB_MATCHES += march?armv4t=mcpu?arm7tdmi-s -+MULTILIB_MATCHES += march?armv4t=mcpu?arm710t -+MULTILIB_MATCHES += march?armv4t=mcpu?arm720t -+MULTILIB_MATCHES += march?armv4t=mcpu?arm740t -+MULTILIB_MATCHES += march?armv4t=mcpu?arm9 -+MULTILIB_MATCHES += march?armv4t=mcpu?arm9tdmi -+MULTILIB_MATCHES += march?armv4t=mcpu?arm920 -+MULTILIB_MATCHES += march?armv4t=mcpu?arm920t -+MULTILIB_MATCHES += march?armv4t=mcpu?arm922t -+MULTILIB_MATCHES += march?armv4t=mcpu?arm940t -+MULTILIB_MATCHES += march?armv4t=mcpu?ep9312 - - # Use a version of div0 which raises SIGFPE. - LIB1ASMFUNCS := $(filter-out _dvmd_tls,$(LIB1ASMFUNCS)) _dvmd_lnx -@@ -12,3 +50,5 @@ LIB1ASMFUNCS := $(filter-out _dvmd_tls,$ - # Multilib the standard Linux files. Don't include crti.o or crtn.o, - # which are provided by glibc. - EXTRA_MULTILIB_PARTS=crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o -+ -+LIB2FUNCS_STATIC_EXTRA += $(srcdir)/config/arm/linux-atomic.c ---- /dev/null -+++ b/gcc/config/arm/t-montavista-linux -@@ -0,0 +1,33 @@ -+# MontaVista GNU/Linux Configuration. -+# 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 -+# . -+ -+MULTILIB_OPTIONS = tarmv6/tthumb2 -+MULTILIB_DIRNAMES = armv6 thumb2 -+ -+MULTILIB_EXCEPTIONS = -+ -+MULTILIB_OSDIRNAMES = -+ -+MULTILIB_ALIASES = -+ -+MULTILIB_MATCHES = -+ -+# These files must be built for each multilib. -+EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o ---- a/gcc/config/arm/t-symbian -+++ b/gcc/config/arm/t-symbian -@@ -17,12 +17,18 @@ 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 - # enabled, so there are no separate thumb-mode libraries. - MULTILIB_OPTIONS = mfloat-abi=softfp - MULTILIB_DIRNAMES = softfp -+MULTILIB_EXCEPTIONS = -+MULTILIB_MATCHES = -+MULTILIB_ALIASES = - - # There is no C library to link against on Symbian OS -- at least when - # building GCC. ---- /dev/null -+++ b/gcc/config/arm/t-timesys -@@ -0,0 +1,10 @@ -+# Overrides for timesys -+ -+MULTILIB_OPTIONS = march=armv5t/march=armv6/mcpu=xscale mbig-endian -+MULTILIB_DIRNAMES = armv5t armv6 xscale be -+MULTILIB_MATCHES = mbig-endian=mbe -+MULTILIB_EXCEPTIONS = mbig-endian march=*/mbig-endian mcpu=xscale -+MULTILIB_OSDIRNAMES = march.armv5t=!armv5t -+MULTILIB_OSDIRNAMES += march.armv6=!armv6 -+MULTILIB_OSDIRNAMES += mcpu.xscale/mbig-endian=!xscale/be -+MULTILIB_ALIASES = ---- /dev/null -+++ b/gcc/config/arm/t-uclinux-eabi -@@ -0,0 +1,53 @@ -+# EABI uClinux multilib selection. Other setting are inherited from t-arm-elf -+ -+# We build 3 multilibs: -+# . (default) -+# thumb2/ -mthumb -march=armv7 -mfix-cortex-m3-ldrd -+# armv6-m/ -mthumb -march=armv6-m -+ -+MULTILIB_OPTIONS = mthumb -+MULTILIB_DIRNAMES = thumb -+MULTILIB_EXCEPTIONS = -+MULTILIB_MATCHES = -+ -+MULTILIB_OPTIONS += march=armv7/march=armv6-m -+MULTILIB_DIRNAMES += armv7 armv6-m -+ -+MULTILIB_EXCEPTIONS += mthumb -+ -+MULTILIB_EXCEPTIONS += march=armv7 -+MULTILIB_MATCHES += march?armv7=march?armv7a -+MULTILIB_MATCHES += march?armv7=march?armv7r -+MULTILIB_MATCHES += march?armv7=march?armv7m -+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=mcpu?cortex-a9 -+MULTILIB_MATCHES += march?armv7=mcpu?cortex-a8 -+MULTILIB_MATCHES += march?armv7=mcpu?cortex-r4 -+MULTILIB_MATCHES += march?armv7=mcpu?cortex-r4f -+MULTILIB_MATCHES += march?armv7=mcpu?cortex-m3 -+ -+MULTILIB_EXCEPTIONS += march=armv6-m -+MULTILIB_MATCHES += march?armv6-m=mcpu?cortex-m1 -+MULTILIB_MATCHES += march?armv6-m=mcpu?cortex-m0 -+ -+MULTILIB_ALIASES = -+ -+# FIXME: We need a sane way of doing this. -+# This isn't really a multilib, it's a hack to add an extra option -+# to the v7-m multilib. -+MULTILIB_OPTIONS += mfix-cortex-m3-ldrd -+MULTILIB_DIRNAMES += broken_ldrd -+ -+MULTILIB_EXCEPTIONS += mfix-cortex-m3-ldrd -+MULTILIB_EXCEPTIONS += mthumb/mfix-cortex-m3-ldrd -+MULTILIB_EXCEPTIONS += march=armv7/mfix-cortex-m3-ldrd -+MULTILIB_EXCEPTIONS += *march=armv6-m*mfix-cortex-m3-ldrd -+ -+MULTILIB_ALIASES += mthumb/march?armv7/mfix-cortex-m3-ldrd=mthumb/march?armv7 -+ -+ -+MULTILIB_OSDIRNAMES = mthumb/march.armv7/mfix-cortex-m3-ldrd=!thumb2 -+MULTILIB_OSDIRNAMES += mthumb/march.armv6-m=!armv6-m -+ ---- /dev/null -+++ b/gcc/config/arm/t-wrs-linux -@@ -0,0 +1,43 @@ -+# Wind River GNU/Linux Configuration. -+# Copyright (C) 2006, 2007, 2008 -+# 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 -+# . -+ -+MULTILIB_OPTIONS = muclibc -+MULTILIB_OPTIONS += tarm926ej-s/tiwmmxt/txscale/tarm920t/tthumb2/tcortex-a8-be8 -+MULTILIB_OPTIONS += mfloat-abi=softfp -+MULTILIB_DIRNAMES = uclibc -+MULTILIB_DIRNAMES += tarm926ej-s tiwmmxt txscale tarm920t thumb2 cortex-a8-be8 -+MULTILIB_DIRNAMES += softfp -+ -+MULTILIB_EXCEPTIONS = *muclibc*/*tarm920t* -+MULTILIB_EXCEPTIONS += *muclibc*/*cortex-a8-be8* -+ -+MULTILIB_EXCEPTIONS += *tiwmmxt*/*mfloat-abi=softfp* -+MULTILIB_EXCEPTIONS += *txscale*/*mfloat-abi=softfp* -+MULTILIB_EXCEPTIONS += *tarm920t*/*mfloat-abi=softfp* -+MULTILIB_EXCEPTIONS += *thumb2*/*mfloat-abi=softfp* -+ -+MULTILIB_MATCHES = tiwmmxt=tiwmmxt2 -+ -+MULTILIB_ALIASES = tcortex-a8-be8=tcortex-a8-be8/mfloat-abi?softfp -+MULTILIB_OSDIRNAMES = -+ -+# These files must be built for each multilib. -+EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o -+ ---- a/gcc/config/arm/thumb2.md -+++ b/gcc/config/arm/thumb2.md -@@ -1,5 +1,5 @@ - ;; ARM Thumb-2 Machine Description --;; Copyright (C) 2007 Free Software Foundation, Inc. -+;; Copyright (C) 2005, 2006, 2007, 2008 Free Software Foundation, Inc. - ;; Written by CodeSourcery, LLC. - ;; - ;; This file is part of GCC. -@@ -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,23 +197,31 @@ - (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" "=r,r,r,r, m") -- (match_operand:SI 1 "general_operand" "rI,K,N,mi,r"))] -+ [(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) - || register_operand (operands[1], SImode))" - "@ - mov%?\\t%0, %1 -+ mov%?\\t%0, %1 - 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 -@@ -754,15 +736,12 @@ - (clobber (reg:CC CC_REGNUM))] - "TARGET_THUMB2" - "* -- if (GET_CODE (operands[3]) == LT && operands[3] == const0_rtx) -+ if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx) - return \"asr\\t%0, %1, #31\"; - - if (GET_CODE (operands[3]) == NE) - return \"subs\\t%0, %1, %2\;it\\tne\;mvnne\\t%0, #0\"; - -- if (GET_CODE (operands[3]) == GT) -- return \"subs\\t%0, %1, %2\;it\\tne\;mvnne\\t%0, %0, asr #31\"; -- - output_asm_insn (\"cmp\\t%1, %2\", operands); - output_asm_insn (\"ite\\t%D3\", operands); - output_asm_insn (\"mov%D3\\t%0, #0\", operands); -@@ -951,7 +930,7 @@ - (label_ref (match_operand 2 "" "")))) - (label_ref (match_operand 3 "" "")))) - (clobber (reg:CC CC_REGNUM)) -- (clobber (match_scratch:SI 4 "=r")) -+ (clobber (match_scratch:SI 4 "=&r")) - (use (label_ref (match_dup 2)))])] - "TARGET_THUMB2 && !flag_pic" - "* return thumb2_output_casesi(operands);" -@@ -968,7 +947,7 @@ - (label_ref (match_operand 2 "" "")))) - (label_ref (match_operand 3 "" "")))) - (clobber (reg:CC CC_REGNUM)) -- (clobber (match_scratch:SI 4 "=r")) -+ (clobber (match_scratch:SI 4 "=&r")) - (clobber (match_scratch:SI 5 "=r")) - (use (label_ref (match_dup 2)))])] - "TARGET_THUMB2 && flag_pic" -@@ -1001,7 +980,10 @@ - (match_operator:SI 3 "thumb_16bit_operator" - [(match_operand:SI 1 "low_register_operand" "") - (match_operand:SI 2 "low_register_operand" "")]))] -- "TARGET_THUMB2 && rtx_equal_p(operands[0], operands[1]) -+ "TARGET_THUMB2 -+ && (rtx_equal_p(operands[0], operands[1]) -+ || GET_CODE(operands[3]) == PLUS -+ || GET_CODE(operands[3]) == MINUS) - && peep2_regno_dead_p(0, CC_REGNUM)" - [(parallel - [(set (match_dup 0) -@@ -1018,7 +1000,9 @@ - [(match_operand:SI 1 "s_register_operand" "0") - (match_operand:SI 2 "s_register_operand" "l")])) - (clobber (reg:CC CC_REGNUM))] -- "TARGET_THUMB2 && reload_completed" -+ "TARGET_THUMB2 && reload_completed -+ && GET_CODE(operands[3]) != PLUS -+ && GET_CODE(operands[3]) != MINUS" - "%I3%!\\t%0, %1, %2" - [(set_attr "predicable" "yes") - (set_attr "length" "2")] -@@ -1104,16 +1088,20 @@ - "" - ) - --(define_insn "*thumb2_addsi_shortim" -+(define_insn "*thumb2_addsi_short" - [(set (match_operand:SI 0 "low_register_operand" "=l") - (plus:SI (match_operand:SI 1 "low_register_operand" "l") -- (match_operand:SI 2 "const_int_operand" "IL"))) -+ (match_operand:SI 2 "low_reg_or_int_operand" "lIL"))) - (clobber (reg:CC CC_REGNUM))] - "TARGET_THUMB2 && reload_completed" - "* - HOST_WIDE_INT val; - -- val = INTVAL(operands[2]); -+ if (GET_CODE (operands[2]) == CONST_INT) -+ val = INTVAL(operands[2]); -+ else -+ val = 0; -+ - /* We prefer eg. subs rn, rn, #1 over adds rn, rn, #0xffffffff. */ - if (val < 0 && const_ok_for_arm(ARM_SIGN_EXTEND (-val))) - return \"sub%!\\t%0, %1, #%n2\"; -@@ -1124,24 +1112,82 @@ - (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")] --) -- --(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")] -+(define_insn "*thumb2_subsi_short" -+ [(set (match_operand:SI 0 "low_register_operand" "=l") -+ (minus:SI (match_operand:SI 1 "low_register_operand" "l") -+ (match_operand:SI 2 "low_register_operand" "l"))) -+ (clobber (reg:CC CC_REGNUM))] -+ "TARGET_THUMB2 && reload_completed" -+ "sub%!\\t%0, %1, %2" -+ [(set_attr "predicable" "yes") -+ (set_attr "length" "2")] -+) -+ -+;; 16-bit encodings of "muls" and "mul". We only use these when -+;; optimizing for size since "muls" is slow on all known -+;; implementations and since "mul" will be generated by -+;; "*arm_mulsi3_v6" anyhow. The assembler will use a 16-bit encoding -+;; for "mul" 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") -@@ -1185,3 +1231,50 @@ - (const_int 2) - (const_int 8)))] - ) -+ -+;; 16-bit complement -+(define_peephole2 -+ [(set (match_operand:SI 0 "low_register_operand" "") -+ (not:SI (match_operand:SI 1 "low_register_operand" "")))] -+ "TARGET_THUMB2 -+ && peep2_regno_dead_p(0, CC_REGNUM)" -+ [(parallel -+ [(set (match_dup 0) -+ (not:SI (match_dup 1))) -+ (clobber (reg:CC CC_REGNUM))])] -+ "" -+) -+ -+(define_insn "*thumb2_one_cmplsi2_short" -+ [(set (match_operand:SI 0 "low_register_operand" "=l") -+ (not:SI (match_operand:SI 1 "low_register_operand" "l"))) -+ (clobber (reg:CC CC_REGNUM))] -+ "TARGET_THUMB2 && reload_completed" -+ "mvn%!\t%0, %1" -+ [(set_attr "predicable" "yes") -+ (set_attr "length" "2")] -+) -+ -+;; 16-bit negate -+(define_peephole2 -+ [(set (match_operand:SI 0 "low_register_operand" "") -+ (neg:SI (match_operand:SI 1 "low_register_operand" "")))] -+ "TARGET_THUMB2 -+ && peep2_regno_dead_p(0, CC_REGNUM)" -+ [(parallel -+ [(set (match_dup 0) -+ (neg:SI (match_dup 1))) -+ (clobber (reg:CC CC_REGNUM))])] -+ "" -+) -+ -+(define_insn "*thumb2_negsi2_short" -+ [(set (match_operand:SI 0 "low_register_operand" "=l") -+ (neg:SI (match_operand:SI 1 "low_register_operand" "l"))) -+ (clobber (reg:CC CC_REGNUM))] -+ "TARGET_THUMB2 && reload_completed" -+ "neg%!\t%0, %1" -+ [(set_attr "predicable" "yes") -+ (set_attr "length" "2")] -+) -+ ---- a/gcc/config/arm/uclinux-eabi.h -+++ b/gcc/config/arm/uclinux-eabi.h -@@ -42,7 +42,8 @@ - while (false) - - #undef SUBTARGET_EXTRA_LINK_SPEC --#define SUBTARGET_EXTRA_LINK_SPEC " -m armelf_linux_eabi" -+#define SUBTARGET_EXTRA_LINK_SPEC " -m armelf_linux_eabi -elf2flt" \ -+ " --pic-veneer --target2=abs" - - /* We default to the "aapcs-linux" ABI so that enums are int-sized by - default. */ -@@ -62,4 +63,3 @@ - : "=r" (_beg) \ - : "0" (_beg), "r" (_end), "r" (_flg), "r" (_scno)); \ - } -- ---- a/gcc/config/arm/uclinux-elf.h -+++ b/gcc/config/arm/uclinux-elf.h -@@ -83,3 +83,5 @@ - "%{pthread:-lpthread} \ - %{shared:-lc} \ - %{!shared:%{profile:-lc_p}%{!profile:-lc}}" -+ -+#define TARGET_DEFAULT_WORD_RELOCATIONS 1 ---- a/gcc/config/arm/unwind-arm.c -+++ b/gcc/config/arm/unwind-arm.c -@@ -1201,8 +1201,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. */ -@@ -1212,6 +1210,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 -@@ -232,11 +232,11 @@ extern "C" { - if (!tmp) - return 0; - --#if defined(linux) || defined(__NetBSD__) -+#if (defined(linux) && !defined(__uClinux__)) || defined(__NetBSD__) - /* Pc-relative indirect. */ - tmp += ptr; - tmp = *(_Unwind_Word *) tmp; --#elif defined(__symbian__) -+#elif defined(__symbian__) || defined(__uClinux__) - /* Absolute pointer. Nothing more to do. */ - #else - /* Pc-relative pointer. */ ---- a/gcc/config/arm/vfp.md -+++ b/gcc/config/arm/vfp.md -@@ -1,6 +1,6 @@ --;; ARM VFP coprocessor Machine Description --;; Copyright (C) 2003, 2005, 2006, 2007 Free Software Foundation, Inc. --;; Written by CodeSourcery, LLC. -+;; ARM VFP instruction patterns -+;; Copyright (C) 2003, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. -+;; Written by CodeSourcery. - ;; - ;; This file is part of GCC. - ;; -@@ -23,45 +23,20 @@ - [(VFPCC_REGNUM 127)] - ) - --;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; --;; Pipeline description --;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -- --(define_automaton "vfp11") -- --;; There are 3 pipelines in the VFP11 unit. --;; --;; - A 8-stage FMAC pipeline (7 execute + writeback) with forward from --;; fourth stage for simple operations. --;; --;; - A 5-stage DS pipeline (4 execute + writeback) for divide/sqrt insns. --;; These insns also uses first execute stage of FMAC pipeline. --;; --;; - A 4-stage LS pipeline (execute + 2 memory + writeback) with forward from --;; second memory stage for loads. -- --;; We do not model Write-After-Read hazards. --;; We do not do write scheduling with the arm core, so it is only necessary --;; to model the first stage of each pipeline --;; ??? Need to model LS pipeline properly for load/store multiple? --;; We do not model fmstat properly. This could be done by modeling pipelines --;; properly and defining an absence set between a dummy fmstat unit and all --;; other vfp units. -- --(define_cpu_unit "fmac" "vfp11") -- --(define_cpu_unit "ds" "vfp11") -- --(define_cpu_unit "vfp_ls" "vfp11") -- --(define_cpu_unit "fmstat" "vfp11") -- --(exclusion_set "fmac,ds" "fmstat") -- - ;; The VFP "type" attributes differ from those used in the FPA model. --;; ffarith Fast floating point insns, e.g. abs, neg, cpy, cmp. --;; farith Most arithmetic insns. --;; fmul Double precision multiply. -+;; fcpys Single precision cpy. -+;; ffariths Single precision abs, neg. -+;; ffarithd Double precision abs, neg, cpy. -+;; fadds Single precision add/sub. -+;; faddd Double precision add/sub. -+;; fconsts Single precision load immediate. -+;; fconstd Double precision load immediate. -+;; fcmps Single precision comparison. -+;; fcmpd Double precision comparison. -+;; fmuls Single precision multiply. -+;; fmuld Double precision multiply. -+;; fmacs Single precision multiply-accumulate. -+;; fmacd Double precision multiply-accumulate. - ;; fdivs Single precision sqrt or division. - ;; fdivd Double precision sqrt or division. - ;; f_flag fmstat operation -@@ -71,126 +46,89 @@ - ;; r_2_f Transfer arm to vfp reg. - ;; f_cvt Convert floating<->integral - --(define_insn_reservation "vfp_ffarith" 4 -- (and (eq_attr "generic_vfp" "yes") -- (eq_attr "type" "ffarith")) -- "fmac") -- --(define_insn_reservation "vfp_farith" 8 -- (and (eq_attr "generic_vfp" "yes") -- (eq_attr "type" "farith,f_cvt")) -- "fmac") -- --(define_insn_reservation "vfp_fmul" 9 -- (and (eq_attr "generic_vfp" "yes") -- (eq_attr "type" "fmul")) -- "fmac*2") -- --(define_insn_reservation "vfp_fdivs" 19 -- (and (eq_attr "generic_vfp" "yes") -- (eq_attr "type" "fdivs")) -- "ds*15") -- --(define_insn_reservation "vfp_fdivd" 33 -- (and (eq_attr "generic_vfp" "yes") -- (eq_attr "type" "fdivd")) -- "fmac+ds*29") -- --;; Moves to/from arm regs also use the load/store pipeline. --(define_insn_reservation "vfp_fload" 4 -- (and (eq_attr "generic_vfp" "yes") -- (eq_attr "type" "f_loads,f_loadd,r_2_f")) -- "vfp_ls") -- --(define_insn_reservation "vfp_fstore" 4 -- (and (eq_attr "generic_vfp" "yes") -- (eq_attr "type" "f_stores,f_stored,f_2_r")) -- "vfp_ls") -- --(define_insn_reservation "vfp_to_cpsr" 4 -- (and (eq_attr "generic_vfp" "yes") -- (eq_attr "type" "f_flag")) -- "fmstat,vfp_ls*3") -- --;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; --;; Insn pattern --;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -- - ;; SImode moves - ;; ??? For now do not allow loading constants into vfp regs. This causes - ;; problems because small constants get converted into adds. - (define_insn "*arm_movsi_vfp" -- [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r ,m,*t,r,*t,*t, *Uv") -- (match_operand:SI 1 "general_operand" "rI,K,N,mi,r,r,*t,*t,*Uvi,*t"))] -+ [(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,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))" - "* - switch (which_alternative) - { -- case 0: -+ case 0: case 1: - return \"mov%?\\t%0, %1\"; -- case 1: -- return \"mvn%?\\t%0, #%B1\"; - case 2: -- return \"movw%?\\t%0, %1\"; -+ return \"mvn%?\\t%0, #%B1\"; - case 3: -- return \"ldr%?\\t%0, %1\"; -+ return \"movw%?\\t%0, %1\"; - case 4: -- return \"str%?\\t%1, %0\"; -+ return \"ldr%?\\t%0, %1\"; - case 5: -- return \"fmsr%?\\t%0, %1\\t%@ int\"; -+ return \"str%?\\t%1, %0\"; - case 6: -- return \"fmrs%?\\t%0, %1\\t%@ int\"; -+ return \"fmsr%?\\t%0, %1\\t%@ int\"; - case 7: -+ return \"fmrs%?\\t%0, %1\\t%@ int\"; -+ case 8: - return \"fcpys%?\\t%0, %1\\t%@ int\"; -- case 8: case 9: -+ case 9: case 10: - return output_move_vfp (operands); - default: - gcc_unreachable (); - } - " - [(set_attr "predicable" "yes") -- (set_attr "type" "*,*,*,load1,store1,r_2_f,f_2_r,ffarith,f_loads,f_stores") -- (set_attr "pool_range" "*,*,*,4096,*,*,*,*,1020,*") -- (set_attr "neg_pool_range" "*,*,*,4084,*,*,*,*,1008,*")] -+ (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" "=r,r,r,r,m,*t,r,*t,*t, *Uv") -- (match_operand:SI 1 "general_operand" "rI,K,N,mi,r,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))" - "* - switch (which_alternative) - { -- case 0: -+ case 0: case 1: - return \"mov%?\\t%0, %1\"; -- case 1: -- return \"mvn%?\\t%0, #%B1\"; - case 2: -- return \"movw%?\\t%0, %1\"; -+ return \"mvn%?\\t%0, #%B1\"; - case 3: -- return \"ldr%?\\t%0, %1\"; -+ return \"movw%?\\t%0, %1\"; - case 4: -- return \"str%?\\t%1, %0\"; - case 5: -- return \"fmsr%?\\t%0, %1\\t%@ int\"; -+ return \"ldr%?\\t%0, %1\"; - case 6: -- return \"fmrs%?\\t%0, %1\\t%@ int\"; - case 7: -+ 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 8: case 9: -+ 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,ffarith,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,*")] - ) - - -@@ -222,7 +160,8 @@ - gcc_unreachable (); - } - " -- [(set_attr "type" "*,load2,store2,r_2_f,f_2_r,ffarith,f_loadd,f_stored") -+ [(set_attr "type" "*,load2,store2,r_2_f,f_2_r,ffarithd,f_loadd,f_stored") -+ (set_attr "neon_type" "*,*,*,neon_mcr_2_mcrr,neon_mrrc,neon_vmov,*,*") - (set_attr "length" "8,8,8,4,4,4,4,4") - (set_attr "pool_range" "*,1020,*,*,*,*,1020,*") - (set_attr "neg_pool_range" "*,1008,*,*,*,*,1008,*")] -@@ -249,12 +188,68 @@ - abort (); - } - " -- [(set_attr "type" "*,load2,store2,r_2_f,f_2_r,ffarith,f_load,f_store") -+ [(set_attr "type" "*,load2,store2,r_2_f,f_2_r,ffarithd,f_load,f_store") -+ (set_attr "neon_type" "*,*,*,neon_mcr_2_mcrr,neon_mrrc,neon_vmov,*,*") - (set_attr "length" "8,8,8,4,4,4,4,4") - (set_attr "pool_range" "*,4096,*,*,*,*,1020,*") - (set_attr "neg_pool_range" "*, 0,*,*,*,*,1008,*")] - ) - -+;; HFmode moves -+(define_insn "*movhf_vfp" -+ [(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")] -+) -+ - - ;; SFmode moves - ;; Disparage the w<->r cases because reloading an invalid address is -@@ -291,7 +286,8 @@ - " - [(set_attr "predicable" "yes") - (set_attr "type" -- "r_2_f,f_2_r,farith,f_loads,f_stores,load1,store1,ffarith,*") -+ "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 "pool_range" "*,*,*,1020,*,4096,*,*,*") - (set_attr "neg_pool_range" "*,*,*,1008,*,4080,*,*,*")] - ) -@@ -327,7 +323,8 @@ - " - [(set_attr "predicable" "yes") - (set_attr "type" -- "r_2_f,f_2_r,farith,f_load,f_store,load1,store1,ffarith,*") -+ "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 "pool_range" "*,*,*,1020,*,4092,*,*,*") - (set_attr "neg_pool_range" "*,*,*,1008,*,0,*,*,*")] - ) -@@ -365,7 +362,8 @@ - } - " - [(set_attr "type" -- "r_2_f,f_2_r,farith,f_loadd,f_stored,load2,store2,ffarith,*") -+ "r_2_f,f_2_r,fconstd,f_loadd,f_stored,load2,store2,ffarithd,*") -+ (set_attr "neon_type" "neon_mcr_2_mcrr,neon_mrrc,*,*,*,*,*,neon_vmov,*") - (set_attr "length" "4,4,4,8,8,4,4,4,8") - (set_attr "pool_range" "*,*,*,1020,*,1020,*,*,*") - (set_attr "neg_pool_range" "*,*,*,1008,*,1008,*,*,*")] -@@ -397,7 +395,8 @@ - } - " - [(set_attr "type" -- "r_2_f,f_2_r,farith,load2,store2,f_load,f_store,ffarith,*") -+ "r_2_f,f_2_r,fconstd,load2,store2,f_load,f_store,ffarithd,*") -+ (set_attr "neon_type" "neon_mcr_2_mcrr,neon_mrrc,*,*,*,*,*,neon_vmov,*") - (set_attr "length" "4,4,4,8,8,4,4,4,8") - (set_attr "pool_range" "*,*,*,4096,*,1020,*,*,*") - (set_attr "neg_pool_range" "*,*,*,0,*,1008,*,*,*")] -@@ -426,7 +425,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" "ffarith,ffarith,ffarith,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" -@@ -449,7 +449,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" "ffarith,ffarith,ffarith,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" -@@ -472,7 +473,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" "ffarith,ffarith,ffarith,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" -@@ -495,7 +497,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" "ffarith,ffarith,ffarith,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")] - ) - - -@@ -507,7 +510,7 @@ - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" - "fabss%?\\t%0, %1" - [(set_attr "predicable" "yes") -- (set_attr "type" "ffarith")] -+ (set_attr "type" "ffariths")] - ) - - (define_insn "*absdf2_vfp" -@@ -516,7 +519,7 @@ - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" - "fabsd%?\\t%P0, %P1" - [(set_attr "predicable" "yes") -- (set_attr "type" "ffarith")] -+ (set_attr "type" "ffarithd")] - ) - - (define_insn "*negsf2_vfp" -@@ -527,7 +530,7 @@ - fnegs%?\\t%0, %1 - eor%?\\t%0, %1, #-2147483648" - [(set_attr "predicable" "yes") -- (set_attr "type" "ffarith")] -+ (set_attr "type" "ffariths")] - ) - - (define_insn_and_split "*negdf2_vfp" -@@ -573,7 +576,7 @@ - " - [(set_attr "predicable" "yes") - (set_attr "length" "4,4,8") -- (set_attr "type" "ffarith")] -+ (set_attr "type" "ffarithd")] - ) - - -@@ -586,7 +589,7 @@ - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" - "fadds%?\\t%0, %1, %2" - [(set_attr "predicable" "yes") -- (set_attr "type" "farith")] -+ (set_attr "type" "fadds")] - ) - - (define_insn "*adddf3_vfp" -@@ -596,7 +599,7 @@ - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" - "faddd%?\\t%P0, %P1, %P2" - [(set_attr "predicable" "yes") -- (set_attr "type" "farith")] -+ (set_attr "type" "faddd")] - ) - - -@@ -607,7 +610,7 @@ - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" - "fsubs%?\\t%0, %1, %2" - [(set_attr "predicable" "yes") -- (set_attr "type" "farith")] -+ (set_attr "type" "fadds")] - ) - - (define_insn "*subdf3_vfp" -@@ -617,7 +620,7 @@ - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" - "fsubd%?\\t%P0, %P1, %P2" - [(set_attr "predicable" "yes") -- (set_attr "type" "farith")] -+ (set_attr "type" "faddd")] - ) - - -@@ -653,7 +656,7 @@ - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" - "fmuls%?\\t%0, %1, %2" - [(set_attr "predicable" "yes") -- (set_attr "type" "farith")] -+ (set_attr "type" "fmuls")] - ) - - (define_insn "*muldf3_vfp" -@@ -663,7 +666,7 @@ - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" - "fmuld%?\\t%P0, %P1, %P2" - [(set_attr "predicable" "yes") -- (set_attr "type" "fmul")] -+ (set_attr "type" "fmuld")] - ) - - -@@ -674,7 +677,7 @@ - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" - "fnmuls%?\\t%0, %1, %2" - [(set_attr "predicable" "yes") -- (set_attr "type" "farith")] -+ (set_attr "type" "fmuls")] - ) - - (define_insn "*muldf3negdf_vfp" -@@ -684,7 +687,7 @@ - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" - "fnmuld%?\\t%P0, %P1, %P2" - [(set_attr "predicable" "yes") -- (set_attr "type" "fmul")] -+ (set_attr "type" "fmuld")] - ) - - -@@ -696,10 +699,11 @@ - (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" "farith")] -+ (set_attr "type" "fmacs")] - ) - - (define_insn "*muldf3adddf_vfp" -@@ -707,10 +711,11 @@ - (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 -+ && (!arm_tune_marvell_f || optimize_size)" - "fmacd%?\\t%P0, %P2, %P3" - [(set_attr "predicable" "yes") -- (set_attr "type" "fmul")] -+ (set_attr "type" "fmacd")] - ) - - ;; 0 = 1 * 2 - 0 -@@ -719,10 +724,11 @@ - (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" "farith")] -+ (set_attr "type" "fmacs")] - ) - - (define_insn "*muldf3subdf_vfp" -@@ -730,10 +736,11 @@ - (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 -+ && (!arm_tune_marvell_f || optimize_size)" - "fmscd%?\\t%P0, %P2, %P3" - [(set_attr "predicable" "yes") -- (set_attr "type" "fmul")] -+ (set_attr "type" "fmacd")] - ) - - ;; 0 = -(1 * 2) + 0 -@@ -742,10 +749,11 @@ - (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" "farith")] -+ (set_attr "type" "fmacs")] - ) - - (define_insn "*fmuldf3negdfadddf_vfp" -@@ -753,10 +761,11 @@ - (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 -+ && (!arm_tune_marvell_f || optimize_size)" - "fnmacd%?\\t%P0, %P2, %P3" - [(set_attr "predicable" "yes") -- (set_attr "type" "fmul")] -+ (set_attr "type" "fmacd")] - ) - - -@@ -767,10 +776,11 @@ - (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" "farith")] -+ (set_attr "type" "fmacs")] - ) - - (define_insn "*muldf3negdfsubdf_vfp" -@@ -779,10 +789,11 @@ - (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 -+ && (!arm_tune_marvell_f || optimize_size)" - "fnmscd%?\\t%P0, %P2, %P3" - [(set_attr "predicable" "yes") -- (set_attr "type" "fmul")] -+ (set_attr "type" "fmacd")] - ) - - -@@ -806,6 +817,24 @@ - (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_NEON_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_NEON_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"))))] -@@ -986,7 +1015,7 @@ - fcmps%?\\t%0, %1 - fcmpzs%?\\t%0" - [(set_attr "predicable" "yes") -- (set_attr "type" "ffarith")] -+ (set_attr "type" "fcmps")] - ) - - (define_insn "*cmpsf_trap_vfp" -@@ -998,7 +1027,7 @@ - fcmpes%?\\t%0, %1 - fcmpezs%?\\t%0" - [(set_attr "predicable" "yes") -- (set_attr "type" "ffarith")] -+ (set_attr "type" "fcmpd")] - ) - - (define_insn "*cmpdf_vfp" -@@ -1010,7 +1039,7 @@ - fcmpd%?\\t%P0, %P1 - fcmpzd%?\\t%P0" - [(set_attr "predicable" "yes") -- (set_attr "type" "ffarith")] -+ (set_attr "type" "fcmpd")] - ) - - (define_insn "*cmpdf_trap_vfp" -@@ -1022,7 +1051,7 @@ - fcmped%?\\t%P0, %P1 - fcmpezd%?\\t%P0" - [(set_attr "predicable" "yes") -- (set_attr "type" "ffarith")] -+ (set_attr "type" "fcmpd")] - ) - - ---- /dev/null -+++ b/gcc/config/arm/vfp11.md -@@ -0,0 +1,92 @@ -+;; ARM VFP11 pipeline description -+;; Copyright (C) 2003, 2005, 2007, 2008 Free Software Foundation, Inc. -+;; Written by CodeSourcery. -+;; -+;; 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 -+;; . -+ -+(define_automaton "vfp11") -+ -+;; There are 3 pipelines in the VFP11 unit. -+;; -+;; - A 8-stage FMAC pipeline (7 execute + writeback) with forward from -+;; fourth stage for simple operations. -+;; -+;; - A 5-stage DS pipeline (4 execute + writeback) for divide/sqrt insns. -+;; These insns also uses first execute stage of FMAC pipeline. -+;; -+;; - A 4-stage LS pipeline (execute + 2 memory + writeback) with forward from -+;; second memory stage for loads. -+ -+;; We do not model Write-After-Read hazards. -+;; We do not do write scheduling with the arm core, so it is only necessary -+;; to model the first stage of each pipeline -+;; ??? Need to model LS pipeline properly for load/store multiple? -+;; We do not model fmstat properly. This could be done by modeling pipelines -+;; properly and defining an absence set between a dummy fmstat unit and all -+;; other vfp units. -+ -+(define_cpu_unit "fmac" "vfp11") -+ -+(define_cpu_unit "ds" "vfp11") -+ -+(define_cpu_unit "vfp_ls" "vfp11") -+ -+(define_cpu_unit "fmstat" "vfp11") -+ -+(exclusion_set "fmac,ds" "fmstat") -+ -+(define_insn_reservation "vfp_ffarith" 4 -+ (and (eq_attr "generic_vfp" "yes") -+ (eq_attr "type" "fcpys,ffariths,ffarithd,fcmps,fcmpd")) -+ "fmac") -+ -+(define_insn_reservation "vfp_farith" 8 -+ (and (eq_attr "generic_vfp" "yes") -+ (eq_attr "type" "fadds,faddd,fconsts,fconstd,f_cvt,fmuls,fmacs")) -+ "fmac") -+ -+(define_insn_reservation "vfp_fmul" 9 -+ (and (eq_attr "generic_vfp" "yes") -+ (eq_attr "type" "fmuld,fmacd")) -+ "fmac*2") -+ -+(define_insn_reservation "vfp_fdivs" 19 -+ (and (eq_attr "generic_vfp" "yes") -+ (eq_attr "type" "fdivs")) -+ "ds*15") -+ -+(define_insn_reservation "vfp_fdivd" 33 -+ (and (eq_attr "generic_vfp" "yes") -+ (eq_attr "type" "fdivd")) -+ "fmac+ds*29") -+ -+;; Moves to/from arm regs also use the load/store pipeline. -+(define_insn_reservation "vfp_fload" 4 -+ (and (eq_attr "generic_vfp" "yes") -+ (eq_attr "type" "f_loads,f_loadd,r_2_f")) -+ "vfp_ls") -+ -+(define_insn_reservation "vfp_fstore" 4 -+ (and (eq_attr "generic_vfp" "yes") -+ (eq_attr "type" "f_stores,f_stored,f_2_r")) -+ "vfp_ls") -+ -+(define_insn_reservation "vfp_to_cpsr" 4 -+ (and (eq_attr "generic_vfp" "yes") -+ (eq_attr "type" "f_flag")) -+ "fmstat,vfp_ls*3") -+ ---- a/gcc/config/arm/vxworks.h -+++ b/gcc/config/arm/vxworks.h -@@ -113,3 +113,6 @@ along with GCC; see the file COPYING3. - cannot allow arbitrary offsets for shared libraries either. */ - #undef ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P - #define ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P 1 -+ -+#undef TARGET_DEFAULT_WORD_RELOCATIONS -+#define TARGET_DEFAULT_WORD_RELOCATIONS 1 ---- /dev/null -+++ b/gcc/config/arm/wrs-linux.h -@@ -0,0 +1,76 @@ -+/* Wind River GNU/Linux Configuration. -+ Copyright (C) 2006, 2007, 2008 -+ 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 -+. */ -+ -+/* Use the ARM926EJ-S by default. */ -+#undef SUBTARGET_CPU_DEFAULT -+#define SUBTARGET_CPU_DEFAULT TARGET_CPU_arm926ejs -+ -+/* Add a -tiwmmxt option for convenience in generating multilibs. -+ This option generates big-endian IWMMXT code. */ -+#undef CC1_SPEC -+#define CC1_SPEC " \ -+ %{tarm926ej-s: -mcpu=arm926ej-s ; \ -+ tiwmmxt: -mcpu=iwmmxt ; \ -+ tiwmmxt2: -mcpu=iwmmxt ; \ -+ txscale: -mcpu=xscale -mbig-endian ; \ -+ tarm920t: -mcpu=arm920t ; \ -+ tthumb2: %{!mcpu=*:%{!march=*:-march=armv6t2}} -mthumb ; \ -+ tcortex-a8-be8: -mcpu=cortex-a8 -mbig-endian -mfloat-abi=softfp \ -+ -mfpu=neon } \ -+ %{txscale:%{mfloat-abi=softfp:%eXScale VFP multilib not provided}} \ -+ %{tarm920t:%{mfloat-abi=softfp:%eARM920T VFP multilib not provided}} \ -+ %{profile:-p}" -+ -+/* Since the ARM926EJ-S is the default processor, we do not need to -+ provide an explicit multilib for that processor. */ -+#undef MULTILIB_DEFAULTS -+#define MULTILIB_DEFAULTS \ -+ { "tarm926ej-s" } -+ -+/* The GLIBC headers are in /usr/include, relative to the sysroot; the -+ uClibc headers are in /uclibc/usr/include. */ -+#undef SYSROOT_HEADERS_SUFFIX_SPEC -+#define SYSROOT_HEADERS_SUFFIX_SPEC \ -+ "%{muclibc:/uclibc}" -+ -+/* Translate -tiwmmxt appropriately for the assembler. The -meabi=5 -+ option is the relevant part of SUBTARGET_EXTRA_ASM_SPEC in bpabi.h. */ -+#undef SUBTARGET_EXTRA_ASM_SPEC -+#define SUBTARGET_EXTRA_ASM_SPEC \ -+ "%{tiwmmxt2:-mcpu=iwmmxt2} %{tiwmmxt:-mcpu=iwmmxt} %{txscale:-mcpu=xscale -EB} %{tcortex-a8-be8:-mcpu=cortex-a8 -EB} -meabi=5" -+ -+/* Translate -tiwmmxt for the linker. */ -+#undef SUBTARGET_EXTRA_LINK_SPEC -+#define SUBTARGET_EXTRA_LINK_SPEC \ -+ " %{tiwmmxt:-m armelf_linux_eabi ; \ -+ txscale:-m armelfb_linux_eabi ; \ -+ tcortex-a8-be8:-m armelfb_linux_eabi %{!r:--be8} ; \ -+ : -m armelf_linux_eabi}" -+ -+/* The various C libraries each have their own subdirectory. */ -+#undef SYSROOT_SUFFIX_SPEC -+#define SYSROOT_SUFFIX_SPEC \ -+ "%{muclibc:/uclibc}%{tiwmmxt:/tiwmmxt ; \ -+ tiwmmxt2:/tiwmmxt ; \ -+ txscale:/txscale ; \ -+ tarm920t:/tarm920t ; \ -+ tthumb2:/thumb2 ; \ -+ tcortex-a8-be8:/cortex-a8-be8}%{!tthumb2:%{!tcortex-a8-be8:%{mfloat-abi=softfp:/softfp}}}" -+ ---- /dev/null -+++ b/gcc/config/i386/cs-linux.h -@@ -0,0 +1,41 @@ -+/* Sourcery G++ IA32 GNU/Linux Configuration. -+ Copyright (C) 2007 -+ 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 -+. */ -+ -+/* This configuration may be used either with the system glibc (in -+ system32 and system64 subdirectories) or with the included glibc -+ (in the sgxx-glibc subdirectory). */ -+ -+#undef SYSROOT_SUFFIX_SPEC -+#define SYSROOT_SUFFIX_SPEC \ -+ "%{msgxx-glibc:/sgxx-glibc ; \ -+ m64:/system64 ; \ -+ mrhel3:/system64 ; \ -+ mrh73:/system32-old ; \ -+ :/system32}" -+ -+#undef SYSROOT_HEADERS_SUFFIX_SPEC -+#define SYSROOT_HEADERS_SUFFIX_SPEC SYSROOT_SUFFIX_SPEC -+ -+/* See mips/wrs-linux.h for details on this use of -+ STARTFILE_PREFIX_SPEC. */ -+#undef STARTFILE_PREFIX_SPEC -+#define STARTFILE_PREFIX_SPEC \ -+ "%{m64: /usr/local/lib64/ /lib64/ /usr/lib64/} \ -+ %{!m64: /usr/local/lib/ /lib/ /usr/lib/}" ---- /dev/null -+++ b/gcc/config/i386/cs-linux.opt -@@ -0,0 +1,11 @@ -+; Additional options for Sourcery G++. -+ -+mrh73 -+Target Undocumented -+ -+mrhel3 -+Target Undocumented -+ -+msgxx-glibc -+Target -+Use included version of GLIBC ---- a/gcc/config/i386/i386.c -+++ b/gcc/config/i386/i386.c -@@ -2700,6 +2700,18 @@ override_options (void) - target_flags |= MASK_ACCUMULATE_OUTGOING_ARGS; - } - -+ /* If stack probes are required, the space used for large function -+ arguments on the stack must also be probed, so enable -+ -maccumulate-outgoing-args so this happens in the prologue. */ -+ if (TARGET_STACK_PROBE -+ && !(target_flags & MASK_ACCUMULATE_OUTGOING_ARGS)) -+ { -+ if (target_flags_explicit & MASK_ACCUMULATE_OUTGOING_ARGS) -+ warning (0, "stack probing requires -maccumulate-outgoing-args " -+ "for correctness"); -+ target_flags |= MASK_ACCUMULATE_OUTGOING_ARGS; -+ } -+ - /* For sane SSE instruction set generation we need fcomi instruction. - It is safe to enable all CMOVE instructions. */ - if (TARGET_SSE) ---- a/gcc/config/i386/i386.h -+++ b/gcc/config/i386/i386.h -@@ -476,13 +476,23 @@ extern const char *host_detect_local_cpu - #define HAVE_LOCAL_CPU_DETECT - #endif - -+#if TARGET_64BIT_DEFAULT -+#define OPT_ARCH64 "!m32" -+#define OPT_ARCH32 "m32" -+#else -+#define OPT_ARCH64 "m64" -+#define OPT_ARCH32 "!m64" -+#endif -+ - /* Support for configure-time defaults of some command line options. - The order here is important so that -march doesn't squash the - tune or cpu values. */ - #define OPTION_DEFAULT_SPECS \ - {"tune", "%{!mtune=*:%{!mcpu=*:%{!march=*:-mtune=%(VALUE)}}}" }, \ - {"cpu", "%{!mtune=*:%{!mcpu=*:%{!march=*:-mtune=%(VALUE)}}}" }, \ -- {"arch", "%{!march=*:-march=%(VALUE)}"} -+ {"arch", "%{!march=*:-march=%(VALUE)}"}, \ -+ {"arch32", "%{" OPT_ARCH32 ":%{!march=*:-march=%(VALUE)}}"}, \ -+ {"arch64", "%{" OPT_ARCH64 ":%{!march=*:-march=%(VALUE)}}"}, - - /* Specs for the compiler proper */ - ---- a/gcc/config/i386/mingw32.h -+++ b/gcc/config/i386/mingw32.h -@@ -79,7 +79,7 @@ along with GCC; see the file COPYING3. - /* Include in the mingw32 libraries with libgcc */ - #undef LIBGCC_SPEC - #define LIBGCC_SPEC \ -- "%{mthreads:-lmingwthrd} -lmingw32 -lgcc -lmoldname -lmingwex -lmsvcrt" -+ "-lgcc %{mthreads:-lmingwthrd} -lmingw32 -lgcc -lmoldname -lmingwex -lmsvcrt" - - #undef STARTFILE_SPEC - #define STARTFILE_SPEC "%{shared|mdll:dllcrt2%O%s} \ ---- /dev/null -+++ b/gcc/config/i386/t-cs-linux -@@ -0,0 +1,25 @@ -+# Sourcery G++ IA32 GNU/Linux Configuration. -+# Copyright (C) 2007 -+# 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 -+# . -+ -+MULTILIB_OPTIONS = m64/m32 msgxx-glibc/mrh73/mrhel3 -+MULTILIB_DIRNAMES = 64 32 sgxx-glibc rh73 rhel3 -+MULTILIB_OSDIRNAMES = ../lib64 ../lib sgxx-glibc rh73 rhel3 -+MULTILIB_EXCEPTIONS = m64/mrh73 m64/mrhel3 -+ ---- a/gcc/config/i386/x-mingw32 -+++ b/gcc/config/i386/x-mingw32 -@@ -8,6 +8,6 @@ local_includedir=$(libsubdir)/$(unlibsub - WERROR_FLAGS += -Wno-format - - host-mingw32.o : $(srcdir)/config/i386/host-mingw32.c $(CONFIG_H) $(SYSTEM_H) \ -- coretypes.h hosthooks.h hosthooks-def.h toplev.h diagnostic.h $(HOOKS_H) -+ coretypes.h hosthooks.h hosthooks-def.h toplev.h $(DIAGNOSTIC_H) $(HOOKS_H) - $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ - $(srcdir)/config/i386/host-mingw32.c ---- a/gcc/config/m68k/cf.md -+++ b/gcc/config/m68k/cf.md -@@ -1,6 +1,6 @@ --;; ColdFire V2 DFA description. -+;; ColdFire V1, V2, V3 and V4/V4e DFA description. - ;; Copyright (C) 2007 Free Software Foundation, Inc. --;; Contributed by CodeSourcery Inc. -+;; Contributed by CodeSourcery Inc., www.codesourcery.com - ;; - ;; This file is part of GCC. - ;; -@@ -19,661 +19,2236 @@ - ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor, - ;; Boston, MA 02110-1301, USA. - --;; ??? To let genattrtab live, implement this attribute in C. --(define_attr "type2" -- "alu, alu_l, bcc, bra, call, jmp, lea, move, move_l, mul, pea, rts, unlk, -- unknown" -- (symbol_ref "m68k_sched_attr_type2 (insn)")) -- - ;; Instruction Buffer --(define_automaton "cf_v2_ib") -+(define_automaton "cfv123_ib") - --;; If one of these cpu units is occupied, that means that corresponding --;; word in the buffer is empty. --(define_cpu_unit "cf_v2_ib_w0, cf_v2_ib_w1, cf_v2_ib_w2, cf_v2_ib_w3, cf_v2_ib_w4, cf_v2_ib_w5" "cf_v2_ib") -- --(final_presence_set "cf_v2_ib_w1, cf_v2_ib_w2, cf_v2_ib_w3, cf_v2_ib_w4, cf_v2_ib_w5" "cf_v2_ib_w0") --(final_presence_set "cf_v2_ib_w2, cf_v2_ib_w3, cf_v2_ib_w4, cf_v2_ib_w5" "cf_v2_ib_w1") --(final_presence_set "cf_v2_ib_w3, cf_v2_ib_w4, cf_v2_ib_w5" "cf_v2_ib_w2") --(final_presence_set "cf_v2_ib_w4, cf_v2_ib_w5" "cf_v2_ib_w3") --(final_presence_set "cf_v2_ib_w5" "cf_v2_ib_w4") -- --;; Occupy 1 word. --(define_reservation "cf_v2_ib1" "cf_v2_ib_w0|cf_v2_ib_w1|cf_v2_ib_w2|cf_v2_ib_w3|cf_v2_ib_w4|cf_v2_ib_w5") -- --;; Occupy 2 words. --(define_reservation "cf_v2_ib2" "(cf_v2_ib_w0+cf_v2_ib_w1)|(cf_v2_ib_w1+cf_v2_ib_w2)|(cf_v2_ib_w2+cf_v2_ib_w3)|(cf_v2_ib_w3+cf_v2_ib_w4)|(cf_v2_ib_w4+cf_v2_ib_w5)") -- --;; Occupy 3 words. --(define_reservation "cf_v2_ib3" "(cf_v2_ib_w0+cf_v2_ib_w1+cf_v2_ib_w2)|(cf_v2_ib_w1+cf_v2_ib_w2+cf_v2_ib_w3)|(cf_v2_ib_w2+cf_v2_ib_w3+cf_v2_ib_w4)|(cf_v2_ib_w3+cf_v2_ib_w4+cf_v2_ib_w5)") -- --;; Reservation to subscribe 1 word in the instruction buffer. If a given --;; word in the instruction buffer is subscribed, that means it is empty. --;; This reservation is used at the start of each cycle to setup the number --;; of prefetched instruction words in the instruction buffer. --;; At each cycle, given that memory bus is available (i.e. there is no --;; pending memory operation), IFP prefetches two instruction words into IB. --(define_insn_reservation "cf_v2_ib" 0 -- (and (eq_attr "cpu" "cf_v2") -+;; These pseudo units are used to model instruction buffer of ColdFire cores. -+;; Instruction of size N can be issued only when cf_ib_wN is available. -+(define_cpu_unit "cf_ib_w1, cf_ib_w2, cf_ib_w3" "cfv123_ib") -+ -+;; Instruction occupies 1 word in the instruction buffer. -+(define_reservation "cf_ib1" "cf_ib_w1") -+;; Instruction occupies 2 words in the instruction buffer. -+(define_reservation "cf_ib2" "cf_ib_w1+cf_ib_w2") -+;; Instruction occupies 3 words in the instruction buffer. -+(define_reservation "cf_ib3" "cf_ib_w1+cf_ib_w2+cf_ib_w3") -+ -+;; This reservation is used at the start of each cycle to setup the maximal -+;; length of instruction that can be issued on current cycle. -+;; E.g., when this reservation is applied for the first time, cf_ib_w3 -+;; resource is marked busy, thus filtering out all 3-word insns. -+;; -+;; This reservation requires deterministic automaton. -+;; -+;; At each cycle, given that memory bus is available (i.e., there is no -+;; pending memory operation), instruction fetch pipeline (IFP) prefetches -+;; two instruction words into instruction buffer (IB). -+(define_insn_reservation "cf_ib1" 0 -+ (and (eq_attr "cpu" "cfv1,cfv2,cfv3") - (eq_attr "type" "ib")) -- "cf_v2_ib1") -+ "cf_ib_w3|cf_ib_w2|cf_ib_w1") - - ;; Operand Execution Pipeline --(define_automaton "cf_v2_oep") -+(define_automaton "cfv123_oep") - --(define_cpu_unit "cf_v2_dsoc, cf_v2_agex" "cf_v2_oep") -+(define_cpu_unit "cf_dsoc,cf_agex" "cfv123_oep") - - ;; A memory unit that is reffered to as 'certain hardware resources' in - ;; ColdFire reference manuals. This unit remains occupied for two cycles - ;; after last dsoc cycle of a store - hence there is a 2 cycle delay between - ;; two consecutive stores. --(define_automaton "cf_v2_chr") -+(define_automaton "cfv123_chr") - --(define_cpu_unit "cf_v2_chr" "cf_v2_chr") -+(define_cpu_unit "cf_chr" "cfv123_chr") - - ;; Memory bus --(define_automaton "cf_v2_mem") -+(define_automaton "cfv123_mem") - - ;; When memory bus is subscribed, that implies that instruction buffer won't --;; get its portion this cycle. To model that we query if cf_v2_mem unit is -+;; get its portion this cycle. To model that we query if cf_mem unit is - ;; subscribed and adjust number of prefetched instruction words accordingly. - ;; --(define_query_cpu_unit "cf_v2_mem" "cf_v2_mem") -+(define_query_cpu_unit "cf_mem1, cf_mem2" "cfv123_mem") -+ -+(define_reservation "cf_mem" "cf_mem1+cf_mem2") -+ -+(define_automaton "cf_mac") -+ -+(define_cpu_unit "cf_mac1,cf_mac2,cf_mac3,cf_mac4" -+ "cf_mac") -+ -+(define_automaton "cfv123_guess") -+ -+(define_query_cpu_unit "cfv123_guess" "cfv123_guess") - - ;; Register to register move. - ;; Takes 1 cycle. --(define_reservation "cf_v2_move_00" -- "cf_v2_dsoc+cf_v2_agex") -+(define_reservation "cfv123_alu_00" -+ "cf_dsoc,cf_agex") - - ;; Load from a memory location. - ;; Takes 3 cycles. --(define_reservation "cf_v2_move_10" -- "cf_v2_dsoc,cf_v2_agex,cf_v2_dsoc+cf_v2_mem,cf_v2_agex") -- --;; Long load from a memory location. -+(define_reservation "cfv12_alu_10" -+ "cf_dsoc,cf_agex,cf_dsoc+cf_mem,cf_agex") - ;; Takes 2 cycles. --(define_reservation "cf_v2_move_l_10" -- "cf_v2_dsoc+cf_v2_agex,cf_v2_dsoc+cf_v2_mem,cf_v2_agex") -+(define_reservation "cfv12_omove_10" -+ "cf_dsoc+cf_agex,cf_dsoc+cf_mem,cf_agex") -+;; Takes 4 cycles. -+(define_reservation "cfv3_alu_10" -+ "cf_dsoc,cf_agex,cf_dsoc+cf_mem1,cf_dsoc+cf_mem2,cf_agex") -+;; Takes 3 cycles. -+(define_reservation "cfv3_omove_10" -+ "cf_dsoc+cf_agex,cf_dsoc+cf_mem1,cf_dsoc+cf_mem2,cf_agex") - - ;; Load from an indexed location. - ;; Takes 4 cycles. --(define_reservation "cf_v2_move_i0" -- "cf_v2_dsoc,cf_v2_agex,cf_v2_agex,cf_v2_dsoc+cf_v2_mem,cf_v2_agex") -- --;; Long load from an indexed location. -+(define_reservation "cfv12_alu_i0" -+ "cf_dsoc,cf_agex,cf_agex,cf_dsoc+cf_mem,cf_agex") - ;; Takes 3 cycles. --(define_reservation "cf_v2_move_l_i0" -- "cf_v2_dsoc+cf_v2_agex,cf_v2_agex,cf_v2_dsoc+cf_v2_mem,cf_v2_agex") -+(define_reservation "cfv12_omove_i0" -+ "cf_dsoc+cf_agex,cf_agex,cf_dsoc+cf_mem,cf_agex") -+;; Takes 5 cycles. -+(define_reservation "cfv3_alu_i0" -+ "cf_dsoc,cf_agex,cf_agex,cf_dsoc+cf_mem1,cf_dsoc+cf_mem2,cf_agex") -+;; Takes 4 cycles. -+(define_reservation "cfv3_omove_i0" -+ "cf_dsoc+cf_agex,cf_agex,cf_dsoc+cf_mem1,cf_dsoc+cf_mem2,cf_agex") - - ;; Store to a memory location. - ;; Takes 1 cycle. --(define_reservation "cf_v2_move_01" -- "cf_v2_dsoc+cf_v2_agex+cf_v2_chr,cf_v2_mem+cf_v2_chr,cf_v2_chr") -+(define_reservation "cfv12_alu_01" -+ "cf_dsoc+cf_agex+cf_chr,cf_mem+cf_chr,cf_chr") -+;; Takes 1 cycle. -+(define_reservation "cfv3_alu_01" -+ "cf_dsoc+cf_agex+cf_chr,cf_mem1+cf_chr,cf_mem2+cf_chr") - - ;; Store to an indexed location. --;; Takes 2 cycle. --(define_reservation "cf_v2_move_0i" -- "cf_v2_dsoc+cf_v2_agex,cf_v2_agex+cf_v2_chr,cf_v2_mem+cf_v2_chr,cf_v2_chr") -+;; Takes 2 cycles. -+(define_reservation "cfv12_alu_0i" -+ "cf_dsoc+cf_agex,cf_agex+cf_chr,cf_mem+cf_chr,cf_chr") -+;; Takes 2 cycles. -+(define_reservation "cfv3_alu_0i" -+ "cf_dsoc+cf_agex,cf_agex+cf_chr,cf_mem1+cf_chr,cf_mem2+cf_chr") - - ;; Load from a memory location and store to a memory location. - ;; Takes 3 cycles --(define_reservation "cf_v2_move_11" -- "cf_v2_dsoc,cf_v2_agex,cf_v2_dsoc+cf_v2_agex+cf_v2_mem+cf_v2_chr,cf_v2_mem+cf_v2_chr,cf_v2_chr") -- --;; Long load from a memory location and store to a memory location. -+(define_reservation "cfv12_alu_11" -+ "cf_dsoc,cf_agex,cf_dsoc+cf_mem,cf_agex+cf_chr,cf_mem+cf_chr,cf_chr") - ;; Takes 2 cycles. --(define_reservation "cf_v2_move_l_11" -- "cf_v2_dsoc+cf_v2_agex,cf_v2_dsoc+cf_v2_agex+cf_v2_mem+cf_v2_chr,cf_v2_mem+cf_v2_chr,cf_v2_chr") -+(define_reservation "cfv12_omove_11" -+ "cf_dsoc+cf_agex,cf_dsoc+cf_mem,cf_agex+cf_chr,cf_mem+cf_chr,cf_chr") -+;; Takes 4 cycles -+(define_reservation "cfv3_alu_11" -+ "cf_dsoc,cf_agex,cf_dsoc+cf_mem1,cf_dsoc+cf_mem2,cf_agex+cf_chr,cf_mem1+cf_chr,cf_mem2+cf_chr") -+;; Takes 3 cycles. -+(define_reservation "cfv3_omove_11" -+ "cf_dsoc+cf_agex,cf_dsoc+cf_mem1,cf_dsoc+cf_mem2,cf_agex+cf_chr,cf_mem1+cf_chr,cf_mem2+cf_chr") - - ;; Load from an indexed location and store to a memory location. - ;; Takes 4 cycles. --(define_reservation "cf_v2_move_i1" -- "cf_v2_dsoc,cf_v2_agex,cf_v2_agex,cf_v2_dsoc+cf_v2_agex+cf_v2_mem+cf_v2_chr,cf_v2_mem+cf_v2_chr,cf_v2_chr") -- --;; Long load from an indexed location and store to a memory location. -+(define_reservation "cfv12_alu_i1" -+ "cf_dsoc,cf_agex,cf_agex,cf_dsoc+cf_mem,cf_agex+cf_chr,cf_mem+cf_chr,cf_chr") - ;; Takes 3 cycles. --(define_reservation "cf_v2_move_l_i1" -- "cf_v2_dsoc+cf_v2_agex,cf_v2_agex,cf_v2_dsoc+cf_v2_agex+cf_v2_mem+cf_v2_chr,cf_v2_mem+cf_v2_chr,cf_v2_chr") -+(define_reservation "cfv12_omove_i1" -+ "cf_dsoc+cf_agex,cf_agex,cf_dsoc+cf_mem,cf_agex+cf_chr,cf_mem+cf_chr,cf_chr") -+;; Takes 5 cycles. -+(define_reservation "cfv3_alu_i1" -+ "cf_dsoc,cf_agex,cf_agex,cf_dsoc+cf_mem1,cf_dsoc+cf_mem2,cf_agex+cf_chr,cf_mem1+cf_chr,cf_mem2+cf_chr") -+;; Takes 4 cycles. -+(define_reservation "cfv3_omove_i1" -+ "cf_dsoc+cf_agex,cf_agex,cf_dsoc+cf_mem1,cf_dsoc+cf_mem2,cf_agex+cf_chr,cf_mem1+cf_chr,cf_mem2+cf_chr") - - ;; Load from a memory location and store to an indexed location. - ;; Takes 4 cycles. --(define_reservation "cf_v2_move_1i" -- "cf_v2_dsoc,cf_v2_agex,cf_v2_dsoc+cf_v2_agex+cf_v2_mem,cf_v2_agex,cf_v2_mem") -- --;; Long load from a memory location and store to an indexed location. -+(define_reservation "cfv12_alu_1i" -+ "cf_dsoc,cf_agex,cf_dsoc+cf_mem,cf_agex,cf_agex+cf_chr,cf_mem+cf_chr,cf_chr") - ;; Takes 3 cycles. --(define_reservation "cf_v2_move_l_1i" -- "cf_v2_dsoc+cf_v2_agex,cf_v2_dsoc+cf_v2_agex+cf_v2_mem,cf_v2_agex,cf_v2_mem") -+(define_reservation "cfv12_omove_1i" -+ "cf_dsoc+cf_agex,cf_dsoc+cf_mem,cf_agex,cf_agex+cf_chr,cf_mem+cf_chr,cf_chr") -+;; Takes 5 cycles. -+(define_reservation "cfv3_alu_1i" -+ "cf_dsoc,cf_agex,cf_dsoc+cf_mem1,cf_dsoc+cf_mem2,cf_agex,cf_agex+cf_chr,cf_mem1+cf_chr,cf_mem2+cf_chr") -+;; Takes 4 cycles. -+(define_reservation "cfv3_omove_1i" -+ "cf_dsoc+cf_agex,cf_dsoc+cf_mem1,cf_dsoc+cf_mem2,cf_agex,cf_agex+cf_chr,cf_mem1+cf_chr,cf_mem2+cf_chr") - - ;; Lea operation for a memory location. - ;; Takes 1 cycle. --(define_reservation "cf_v2_lea_10" -- "cf_v2_dsoc+cf_v2_agex") -+(define_reservation "cfv123_lea_10" -+ "cf_dsoc,cf_agex") - - ;; Lea operation for an indexed location. - ;; Takes 2 cycles. --(define_reservation "cf_v2_lea_i0" -- "cf_v2_dsoc+cf_v2_agex,cf_v2_agex") -+(define_reservation "cfv123_lea_i0" -+ "cf_dsoc,cf_agex,cf_agex") - - ;; Pea operation for a memory location. --;; Takes 2 cycle. --(define_reservation "cf_v2_pea_11" -- "cf_v2_dsoc+cf_v2_agex,cf_v2_agex+cf_v2_chr,cf_v2_mem+cf_v2_chr,cf_v2_chr") -+;; Takes 2 cycles. -+(define_reservation "cfv12_pea_11" -+ "cf_dsoc,cf_agex,cf_agex+cf_chr,cf_mem+cf_chr,cf_chr") -+;; Takes 2 cycles. -+(define_reservation "cfv3_pea_11" -+ "cf_dsoc,cf_agex,cf_agex+cf_chr,cf_mem1+cf_chr,cf_mem2+cf_chr") - - ;; Pea operation for an indexed location. - ;; Takes 3 cycles. --(define_reservation "cf_v2_pea_i1" -- "cf_v2_dsoc+cf_v2_agex,cf_v2_agex,cf_v2_agex+cf_v2_chr,cf_v2_mem+cf_v2_chr,cf_v2_chr") -- --(define_automaton "cf_v2_emac") -+(define_reservation "cfv12_pea_i1" -+ "cf_dsoc,cf_agex,cf_agex,cf_agex+cf_chr,cf_mem+cf_chr,cf_chr") -+;; Takes 3 cycles. -+(define_reservation "cfv3_pea_i1" -+ "cf_dsoc,cf_agex,cf_agex,cf_agex+cf_chr,cf_mem1+cf_chr,cf_mem2+cf_chr") - --(define_cpu_unit "cf_v2_emac1,cf_v2_emac2,cf_v2_emac3,cf_v2_emac4" -- "cf_v2_emac") -+;; Long multiplication with no mac. -+;; Takes 9-18 cycles. -+(define_reservation "cfv123_mul_l_00" -+ "cf_dsoc,(cf_agex+cf_dsoc)*17,cf_agex") -+ -+;; Word multiplication with no mac. -+;; Takes 9 cycles. -+(define_reservation "cfv123_mul_w_00" -+ "cf_dsoc,(cf_agex+cf_dsoc)*8,cf_agex") -+ -+;; Long multiplication with no mac. -+;; Takes 11-20 cycles. -+(define_reservation "cfv12_mul_l_10" -+ "cf_dsoc,cf_agex,cf_dsoc+cf_mem,(cf_agex+cf_dsoc)*17,cf_agex") -+;; Takes 12-21 cycles. -+(define_reservation "cfv3_mul_l_10" -+ "cf_dsoc,cf_agex,cf_dsoc+cf_mem1,cf_dsoc+cf_mem2,(cf_agex+cf_dsoc)*17,cf_agex") -+ -+;; Word multiplication with no mac. -+;; Takes 11 cycles. -+(define_reservation "cfv12_mul_w_10" -+ "cf_dsoc,cf_agex,cf_dsoc+cf_mem,(cf_agex+cf_dsoc)*8,cf_agex") -+;; Takes 12 cycles. -+(define_reservation "cfv3_mul_w_10" -+ "cf_dsoc,cf_agex,cf_dsoc+cf_mem1,cf_dsoc+cf_mem2,(cf_agex+cf_dsoc)*8,cf_agex") -+ -+;; Word multiplication with no mac. -+;; Takes 12 cycles. -+(define_reservation "cfv12_mul_w_i0" -+ "cf_dsoc,cf_agex,cf_agex,cf_dsoc+cf_mem,(cf_agex+cf_dsoc)*8,cf_agex") -+;; Takes 13 cycles. -+(define_reservation "cfv3_mul_w_i0" -+ "cf_dsoc,cf_agex,cf_agex,cf_dsoc+cf_mem1,cf_dsoc+cf_mem2,(cf_agex+cf_dsoc)*8,cf_agex") -+ -+;; Long multiplication with mac. -+;; Takes 5 cycles. -+(define_reservation "cfv123_mac_l_00" -+ "cf_dsoc,cf_agex,cf_mac1,cf_mac2,cf_mac3,cf_mac4") - --;; Mul operation with register operands. --;; Takes 4 cycles. --(define_reservation "cf_v2_mul_00" -- "cf_v2_dsoc,cf_v2_agex+cf_v2_emac1,cf_v2_emac2,cf_v2_emac3,cf_v2_emac4") -+;; Word multiplication with mac. -+;; Takes 3 cycles. -+(define_reservation "cfv123_mac_w_00" -+ "cf_dsoc,cf_agex,cf_mac1,cf_mac2") - --;; Mul operation with implicit load from a memory location. -+;; Long multiplication with mac. -+;; Takes 7 cycles. -+(define_reservation "cfv12_mac_l_10" -+ "cf_dsoc,cf_agex,cf_dsoc+cf_mem,cf_agex,cf_mac1,cf_mac2,cf_mac3,cf_mac4") -+;; Takes 8 cycles. -+(define_reservation "cfv3_mac_l_10" -+ "cf_dsoc,cf_agex,cf_dsoc+cf_mem1,cf_dsoc+cf_mem2,cf_agex,cf_mac1,cf_mac2,cf_mac3,cf_mac4") -+ -+;; Word multiplication with mac. -+;; Takes 5 cycles. -+(define_reservation "cfv12_mac_w_10" -+ "cf_dsoc,cf_agex,cf_dsoc+cf_mem,cf_agex,cf_mac1,cf_mac2") - ;; Takes 6 cycles. --(define_reservation "cf_v2_mul_10" -- "cf_v2_dsoc,cf_v2_agex,cf_v2_dsoc+cf_v2_mem,cf_v2_agex+cf_v2_emac1,cf_v2_emac2,cf_v2_emac3,cf_v2_emac4") -+(define_reservation "cfv3_mac_w_10" -+ "cf_dsoc,cf_agex,cf_dsoc+cf_mem1,cf_dsoc+cf_mem2,cf_agex,cf_mac1,cf_mac2") - --;; Mul operation with implicit load from an indexed location. -+;; Word multiplication with mac. -+;; Takes 6 cycles. -+(define_reservation "cfv12_mac_w_i0" -+ "cf_dsoc,cf_agex,cf_agex,cf_dsoc+cf_mem,cf_agex,cf_mac1,cf_mac2") - ;; Takes 7 cycles. --(define_reservation "cf_v2_mul_i0" -- "cf_v2_dsoc,cf_v2_agex,cf_v2_agex,cf_v2_dsoc+cf_v2_mem,cf_v2_agex+cf_v2_emac1,cf_v2_emac2,cf_v2_emac3,cf_v2_emac4") -- --;; Instruction reservations. -- --;; Below reservations are simple derivation from the above reservations. --;; Each reservation from the above expands into 3 reservations below - one --;; for each instruction size. --;; A number in the end of reservation's name is the size of the instruction. -- --(define_insn_reservation "cf_v2_move_00_1" 1 -- (and (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "type2" "alu,alu_l,move,move_l")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 1))) -- (eq_attr "op_mem" "00")) -- "cf_v2_ib1+cf_v2_move_00") -- --(define_insn_reservation "cf_v2_move_00_2" 1 -- (and (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "type2" "alu,alu_l,move,move_l")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 2))) -- (eq_attr "op_mem" "00")) -- "cf_v2_ib2+cf_v2_move_00") -- --(define_insn_reservation "cf_v2_move_00_3" 1 -- (and (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "type2" "alu,alu_l,move,move_l")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 3))) -- (eq_attr "op_mem" "00")) -- "cf_v2_ib3+cf_v2_move_00") -- --(define_insn_reservation "cf_v2_move_10_1" 4 -- (and (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "type2" "alu_l,move")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 1))) -- (eq_attr "op_mem" "10")) -- "cf_v2_ib1+cf_v2_move_10") -- --(define_insn_reservation "cf_v2_move_10_2" 4 -- (and (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "type2" "alu_l,move")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 2))) -- (eq_attr "op_mem" "10")) -- "cf_v2_ib2+cf_v2_move_10") -- --(define_insn_reservation "cf_v2_move_10_3" 4 -- (and (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "type2" "alu_l,move")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 3))) -- (eq_attr "op_mem" "10")) -- "cf_v2_ib3+cf_v2_move_10") -- --(define_insn_reservation "cf_v2_move_l_10_1" 3 -- (and (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "type2" "move_l")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 1))) -- (eq_attr "op_mem" "10")) -- "cf_v2_ib1+cf_v2_move_l_10") -- --(define_insn_reservation "cf_v2_move_l_10_2" 3 -- (and (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "type2" "move_l")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 2))) -- (eq_attr "op_mem" "10")) -- "cf_v2_ib2+cf_v2_move_l_10") -- --(define_insn_reservation "cf_v2_move_l_10_3" 3 -- (and (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "type2" "move_l")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 3))) -- (eq_attr "op_mem" "10")) -- "cf_v2_ib3+cf_v2_move_l_10") -- --(define_insn_reservation "cf_v2_move_i0_2" 5 -- (and (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "type2" "alu_l,move")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 2))) -- (eq_attr "op_mem" "i0")) -- "cf_v2_ib2+cf_v2_move_i0") -- --(define_insn_reservation "cf_v2_move_i0_3" 5 -- (and (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "type2" "alu_l,move")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 3))) -- (eq_attr "op_mem" "i0")) -- "cf_v2_ib3+cf_v2_move_i0") -- --(define_insn_reservation "cf_v2_move_l_i0_2" 4 -- (and (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "type2" "move_l")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 2))) -- (eq_attr "op_mem" "i0")) -- "cf_v2_ib2+cf_v2_move_l_i0") -- --(define_insn_reservation "cf_v2_move_l_i0_3" 4 -- (and (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "type2" "move_l")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 3))) -- (eq_attr "op_mem" "i0")) -- "cf_v2_ib3+cf_v2_move_l_i0") -- --(define_insn_reservation "cf_v2_move_01_1" 0 -- (and (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "type2" "alu_l,move,move_l")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 1))) -- (eq_attr "op_mem" "01")) -- "cf_v2_ib1+cf_v2_move_01") -- --(define_insn_reservation "cf_v2_move_01_2" 0 -- (and (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "type2" "alu_l,move,move_l")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 2))) -- (eq_attr "op_mem" "01")) -- "cf_v2_ib2+cf_v2_move_01") -- --(define_insn_reservation "cf_v2_move_01_3" 0 -- (and (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "type2" "alu_l,move,move_l")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 3))) -- (eq_attr "op_mem" "01")) -- "cf_v2_ib3+cf_v2_move_01") -+(define_reservation "cfv3_mac_w_i0" -+ "cf_dsoc,cf_agex,cf_agex,cf_dsoc+cf_mem1,cf_dsoc+cf_mem2,cf_agex,cf_mac1,cf_mac2") - --(define_insn_reservation "cf_v2_move_0i_2" 0 -- (and (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "type2" "alu_l,move,move_l")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 2))) -- (eq_attr "op_mem" "0i")) -- "cf_v2_ib2+cf_v2_move_0i") -- --(define_insn_reservation "cf_v2_move_0i_3" 0 -- (and (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "type2" "alu_l,move,move_l")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 3))) -- (eq_attr "op_mem" "0i")) -- "cf_v2_ib3+cf_v2_move_0i") -- --(define_insn_reservation "cf_v2_move_11_1" 0 -- (and (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "type2" "alu_l,move")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 1))) -- (eq_attr "op_mem" "11")) -- "cf_v2_ib1+cf_v2_move_11") -- --(define_insn_reservation "cf_v2_move_11_2" 0 -- (and (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "type2" "alu_l,move")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 2))) -- (eq_attr "op_mem" "11")) -- "cf_v2_ib2+cf_v2_move_11") -- --(define_insn_reservation "cf_v2_move_11_3" 0 -- (and (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "type2" "alu_l,move")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 3))) -- (eq_attr "op_mem" "11")) -- "cf_v2_ib3+cf_v2_move_11") -- --(define_insn_reservation "cf_v2_move_l_11_1" 0 -- (and (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "type2" "move_l")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 1))) -- (eq_attr "op_mem" "11")) -- "cf_v2_ib1+cf_v2_move_l_11") -- --(define_insn_reservation "cf_v2_move_l_11_2" 0 -- (and (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "type2" "move_l")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 2))) -- (eq_attr "op_mem" "11")) -- "cf_v2_ib2+cf_v2_move_l_11") -- --(define_insn_reservation "cf_v2_move_l_11_3" 0 -- (and (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "type2" "move_l")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 3))) -- (eq_attr "op_mem" "11")) -- "cf_v2_ib3+cf_v2_move_l_11") -- --(define_insn_reservation "cf_v2_move_i1_2" 0 -- (and (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "type2" "alu_l,move")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 2))) -- (eq_attr "op_mem" "i1")) -- "cf_v2_ib2+cf_v2_move_i1") -- --(define_insn_reservation "cf_v2_move_i1_3" 0 -- (and (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "type2" "alu_l,move")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 3))) -- (eq_attr "op_mem" "i1")) -- "cf_v2_ib3+cf_v2_move_i1") -- --(define_insn_reservation "cf_v2_move_l_i1_2" 0 -- (and (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "type2" "move_l")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 2))) -- (eq_attr "op_mem" "i1")) -- "cf_v2_ib2+cf_v2_move_l_i1") -- --(define_insn_reservation "cf_v2_move_l_i1_3" 0 -- (and (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "type2" "move_l")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 3))) -- (eq_attr "op_mem" "i1")) -- "cf_v2_ib3+cf_v2_move_l_i1") -+;; Multiplication with emac. -+;; Takes 4 cycles. -+(define_reservation "cfv123_emac_00" -+ "cf_dsoc,cf_agex+cf_mac1,cf_mac2,cf_mac3,cf_mac4") - --(define_insn_reservation "cf_v2_move_1i_2" 0 -- (and (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "type2" "alu_l,move")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 2))) -- (eq_attr "op_mem" "1i")) -- "cf_v2_ib2+cf_v2_move_1i") -+;; Multiplication with emac. -+;; Takes 6 cycles. -+(define_reservation "cfv12_emac_10" -+ "cf_dsoc,cf_agex,cf_dsoc+cf_mem,cf_agex+cf_mac1,cf_mac2,cf_mac3,cf_mac4") -+;; Takes 7 cycles. -+(define_reservation "cfv3_emac_10" -+ "cf_dsoc,cf_agex,cf_dsoc+cf_mem1,cf_dsoc+cf_mem2,cf_agex+cf_mac1,cf_mac2,cf_mac3,cf_mac4") - --(define_insn_reservation "cf_v2_move_1i_3" 0 -- (and (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "type2" "alu_l,move")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 3))) -- (eq_attr "op_mem" "1i")) -- "cf_v2_ib3+cf_v2_move_1i") -+;; Word multiplication with emac. -+;; Takes 7 cycles. -+(define_reservation "cfv12_emac_w_i0" -+ "cf_dsoc,cf_agex,cf_agex,cf_dsoc+cf_mem,cf_agex+cf_mac1,cf_mac2,cf_mac3,cf_mac4") -+;; Takes 8 cycles. -+(define_reservation "cfv3_emac_w_i0" -+ "cf_dsoc,cf_agex,cf_agex,cf_dsoc+cf_mem1,cf_dsoc+cf_mem2,cf_agex+cf_mac1,cf_mac2,cf_mac3,cf_mac4") - --(define_insn_reservation "cf_v2_move_l_1i_2" 0 -- (and (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "type2" "move_l")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 2))) -- (eq_attr "op_mem" "1i")) -- "cf_v2_ib2+cf_v2_move_l_1i") -+;; Return instruction. -+;; ??? As return reads target address from stack, use a mem-read reservation -+;; ??? for it. -+;; ??? It's not clear what the core does during these 5 cycles. -+;; ??? Luckily, we don't care that much about an insn that won't be moved. -+;; Takes 5 cycles. -+(define_reservation "cfv12_rts" "cfv12_alu_10") -+;; Takes 8 cycles. -+(define_reservation "cfv3_rts" "cfv3_alu_10") - --(define_insn_reservation "cf_v2_move_l_1i_3" 0 -- (and (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "type2" "move_l")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 3))) -- (eq_attr "op_mem" "1i")) -- "cf_v2_ib3+cf_v2_move_l_1i") -+;; Call instruction. -+;; ??? It's not clear what reservation is best to use for calls. -+;; ??? For now we use mem-write + return reservations to reflect the fact of -+;; ??? pushing and poping return address to and from the stack. -+;; Takes 3 cycles. -+(define_reservation "cfv12_call" "cfv12_alu_01,cfv12_rts") -+;; Takes 1/5 cycles. -+(define_reservation "cfv3_call" "cfv3_alu_01,cfv3_rts") - --(define_insn_reservation "cf_v2_lea_10_1" 1 -- (and (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "type2" "lea")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 1))) -- (eq_attr "op_mem" "10")) -- "cf_v2_ib1+cf_v2_lea_10") -+;; Conditional branch instruction. -+;; ??? Branch reservations are unclear to me so far. Luckily, we don't care -+;; ??? that much about branches. -+;; Takes 2 cycles. -+(define_reservation "cfv12_bcc" "cfv123_alu_00") -+;; Takes 1 cycles. -+(define_reservation "cfv3_bcc" "cfv123_alu_00") - --(define_insn_reservation "cf_v2_lea_10_2" 1 -- (and (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "type2" "lea")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 2))) -- (eq_attr "op_mem" "10")) -- "cf_v2_ib2+cf_v2_lea_10") -+;; Unconditional branch instruciton. -+;; Takes 2 cycles. -+(define_reservation "cfv12_bra" "cfv12_alu_01") -+;; Takes 1 cycles. -+(define_reservation "cfv3_bra" "cfv3_alu_01") - --(define_insn_reservation "cf_v2_lea_10_3" 1 -- (and (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "type2" "lea")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 3))) -- (eq_attr "op_mem" "10")) -- "cf_v2_ib3+cf_v2_lea_10") -+;; Computed jump instruction. -+;; Takes 3 cycles. -+(define_reservation "cfv12_jmp" -+ "(cf_dsoc+cf_agex)*3") -+;; Takes 5 cycles. -+(define_reservation "cfv3_jmp" -+ "(cf_dsoc+cf_agex)*5") - --(define_insn_reservation "cf_v2_lea_i0_2" 2 -- (and (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "type2" "lea")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 2))) -- (eq_attr "op_mem" "i0")) -- "cf_v2_ib2+cf_v2_lea_i0") -+;; Instruction reservations. - --(define_insn_reservation "cf_v2_lea_i0_3" 2 -- (and (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "type2" "lea")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 3))) -- (eq_attr "op_mem" "i0")) -- "cf_v2_ib3+cf_v2_lea_i0") -+;; Below reservations are simple derivation from the above reservations. -+;; Each reservation from the above expands into 3 reservations below - one -+;; for each instruction size. -+;; A number in the end of reservation's name is the size of the instruction. - --(define_insn_reservation "cf_v2_pea_11_1" 0 -- (and (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "type2" "pea")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 1))) -+(define_insn_reservation "cfv123_alu_00_1" 1 -+ (and (and (and (eq_attr "cpu" "cfv1,cfv2,cfv3") -+ (eq_attr "type" " -+alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift, -+clr,clr_l,mov3q_l,move,moveq_l,tst, -+move_l,tst_l")) -+ (eq_attr "op_mem" "00")) -+ (eq_attr "size" "1")) -+ "cf_ib1+cfv123_alu_00") -+ -+(define_insn_reservation "cfv123_alu_00_2" 1 -+ (and (and (and (eq_attr "cpu" "cfv1,cfv2,cfv3") -+ (eq_attr "type" " -+alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift, -+clr,clr_l,mov3q_l,move,moveq_l,tst, -+move_l,tst_l")) -+ (eq_attr "op_mem" "00")) -+ (eq_attr "size" "2")) -+ "cf_ib2+cfv123_alu_00") -+ -+(define_insn_reservation "cfv123_alu_00_3" 1 -+ (and (and (and (eq_attr "cpu" "cfv1,cfv2,cfv3") -+ (eq_attr "type" " -+alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift, -+clr,clr_l,mov3q_l,move,moveq_l,tst, -+move_l,tst_l")) -+ (eq_attr "op_mem" "00")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv123_alu_00") -+ -+(define_insn_reservation "cfv1_alu_10_1" 3 -+ (and (and (and (eq_attr "cpu" "cfv1") -+ (eq_attr "type" " -+alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift")) -+ (eq_attr "op_mem" "10")) -+ (eq_attr "size" "1")) -+ "cf_ib1+cfv12_alu_10") -+ -+(define_insn_reservation "cfv1_alu_10_2" 3 -+ (and (and (and (eq_attr "cpu" "cfv1") -+ (eq_attr "type" " -+alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift")) -+ (eq_attr "op_mem" "10")) -+ (eq_attr "size" "2")) -+ "cf_ib2+cfv12_alu_10") -+ -+(define_insn_reservation "cfv1_alu_10_3" 3 -+ (and (and (and (eq_attr "cpu" "cfv1") -+ (eq_attr "type" " -+alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift")) -+ (eq_attr "op_mem" "10")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv12_alu_10") -+ -+(define_insn_reservation "cfv1_omove_10_1" 2 -+ (and (and (and (eq_attr "cpu" "cfv1") -+ (eq_attr "type" " -+clr,clr_l,mov3q_l,move,moveq_l,tst, -+move_l,tst_l")) -+ (eq_attr "op_mem" "10")) -+ (eq_attr "size" "1")) -+ "cf_ib1+cfv12_omove_10") -+ -+(define_insn_reservation "cfv1_omove_10_2" 2 -+ (and (and (and (eq_attr "cpu" "cfv1") -+ (eq_attr "type" " -+clr,clr_l,mov3q_l,move,moveq_l,tst, -+move_l,tst_l")) -+ (eq_attr "op_mem" "10")) -+ (eq_attr "size" "2")) -+ "cf_ib2+cfv12_omove_10") -+ -+(define_insn_reservation "cfv1_omove_10_3" 2 -+ (and (and (and (eq_attr "cpu" "cfv1") -+ (eq_attr "type" " -+clr,clr_l,mov3q_l,move,moveq_l,tst, -+move_l,tst_l")) -+ (eq_attr "op_mem" "10")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv12_omove_10") -+ -+(define_insn_reservation "cfv2_alu_10_1" 3 -+ (and (and (and (eq_attr "cpu" "cfv2") -+ (eq_attr "type" " -+alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift, -+clr,clr_l,mov3q_l,move,moveq_l,tst")) -+ (eq_attr "op_mem" "10")) -+ (eq_attr "size" "1")) -+ "cf_ib1+cfv12_alu_10") -+ -+(define_insn_reservation "cfv2_alu_10_2" 3 -+ (and (and (and (eq_attr "cpu" "cfv2") -+ (eq_attr "type" " -+alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift, -+clr,clr_l,mov3q_l,move,moveq_l,tst")) -+ (eq_attr "op_mem" "10")) -+ (eq_attr "size" "2")) -+ "cf_ib2+cfv12_alu_10") -+ -+(define_insn_reservation "cfv2_alu_10_3" 3 -+ (and (and (and (eq_attr "cpu" "cfv2") -+ (eq_attr "type" " -+alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift, -+clr,clr_l,mov3q_l,move,moveq_l,tst")) -+ (eq_attr "op_mem" "10")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv12_alu_10") -+ -+(define_insn_reservation "cfv2_omove_10_1" 2 -+ (and (and (and (eq_attr "cpu" "cfv2") -+ (eq_attr "type" " -+move_l,tst_l")) -+ (eq_attr "op_mem" "10")) -+ (eq_attr "size" "1")) -+ "cf_ib1+cfv12_omove_10") -+ -+(define_insn_reservation "cfv2_omove_10_2" 2 -+ (and (and (and (eq_attr "cpu" "cfv2") -+ (eq_attr "type" " -+move_l,tst_l")) -+ (eq_attr "op_mem" "10")) -+ (eq_attr "size" "2")) -+ "cf_ib2+cfv12_omove_10") -+ -+(define_insn_reservation "cfv2_omove_10_3" 2 -+ (and (and (and (eq_attr "cpu" "cfv2") -+ (eq_attr "type" " -+move_l,tst_l")) -+ (eq_attr "op_mem" "10")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv12_omove_10") -+ -+(define_insn_reservation "cfv3_alu_10_1" 4 -+ (and (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "type" " -+alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift, -+clr,clr_l,mov3q_l,move,moveq_l,tst")) -+ (eq_attr "op_mem" "10")) -+ (eq_attr "size" "1")) -+ "cf_ib1+cfv3_alu_10") -+ -+(define_insn_reservation "cfv3_alu_10_2" 4 -+ (and (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "type" " -+alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift, -+clr,clr_l,mov3q_l,move,moveq_l,tst")) -+ (eq_attr "op_mem" "10")) -+ (eq_attr "size" "2")) -+ "cf_ib2+cfv3_alu_10") -+ -+(define_insn_reservation "cfv3_alu_10_3" 4 -+ (and (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "type" " -+alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift, -+clr,clr_l,mov3q_l,move,moveq_l,tst")) -+ (eq_attr "op_mem" "10")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv3_alu_10") -+ -+(define_insn_reservation "cfv3_omove_10_1" 3 -+ (and (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "type" " -+move_l,tst_l")) -+ (eq_attr "op_mem" "10")) -+ (eq_attr "size" "1")) -+ "cf_ib1+cfv3_omove_10") -+ -+(define_insn_reservation "cfv3_omove_10_2" 3 -+ (and (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "type" " -+move_l,tst_l")) -+ (eq_attr "op_mem" "10")) -+ (eq_attr "size" "2")) -+ "cf_ib2+cfv3_omove_10") -+ -+(define_insn_reservation "cfv3_omove_10_3" 3 -+ (and (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "type" " -+move_l,tst_l")) -+ (eq_attr "op_mem" "10")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv3_omove_10") -+ -+(define_insn_reservation "cfv1_alu_i0_2" 4 -+ (and (and (and (eq_attr "cpu" "cfv1") -+ (eq_attr "type" " -+alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift")) -+ (eq_attr "op_mem" "i0")) -+ (eq_attr "size" "1,2")) -+ "cf_ib2+cfv12_alu_i0") -+ -+(define_insn_reservation "cfv1_alu_i0_3" 4 -+ (and (and (and (eq_attr "cpu" "cfv1") -+ (eq_attr "type" " -+alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift")) -+ (eq_attr "op_mem" "i0")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv12_alu_i0") -+ -+(define_insn_reservation "cfv1_omove_i0_2" 3 -+ (and (and (and (eq_attr "cpu" "cfv1") -+ (eq_attr "type" " -+clr,clr_l,mov3q_l,move,moveq_l,tst, -+move_l,tst_l")) -+ (eq_attr "op_mem" "i0")) -+ (eq_attr "size" "1,2")) -+ "cf_ib2+cfv12_omove_i0") -+ -+(define_insn_reservation "cfv1_omove_i0_3" 3 -+ (and (and (and (eq_attr "cpu" "cfv1") -+ (eq_attr "type" " -+clr,clr_l,mov3q_l,move,moveq_l,tst, -+move_l,tst_l")) -+ (eq_attr "op_mem" "i0")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv12_omove_i0") -+ -+(define_insn_reservation "cfv2_alu_i0_2" 4 -+ (and (and (and (eq_attr "cpu" "cfv2") -+ (eq_attr "type" " -+alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift, -+clr,clr_l,mov3q_l,move,moveq_l,tst")) -+ (eq_attr "op_mem" "i0")) -+ (eq_attr "size" "1,2")) -+ "cf_ib2+cfv12_alu_i0") -+ -+(define_insn_reservation "cfv2_alu_i0_3" 4 -+ (and (and (and (eq_attr "cpu" "cfv2") -+ (eq_attr "type" " -+alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift, -+clr,clr_l,mov3q_l,move,moveq_l,tst")) -+ (eq_attr "op_mem" "i0")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv12_alu_i0") -+ -+(define_insn_reservation "cfv2_omove_i0_2" 3 -+ (and (and (and (eq_attr "cpu" "cfv2") -+ (eq_attr "type" " -+move_l,tst_l")) -+ (eq_attr "op_mem" "i0")) -+ (eq_attr "size" "1,2")) -+ "cf_ib2+cfv12_omove_i0") -+ -+(define_insn_reservation "cfv2_omove_i0_3" 3 -+ (and (and (and (eq_attr "cpu" "cfv2") -+ (eq_attr "type" " -+move_l,tst_l")) -+ (eq_attr "op_mem" "i0")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv12_omove_i0") -+ -+(define_insn_reservation "cfv3_alu_i0_2" 5 -+ (and (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "type" " -+alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift, -+clr,clr_l,mov3q_l,move,moveq_l,tst")) -+ (eq_attr "op_mem" "i0")) -+ (eq_attr "size" "1,2")) -+ "cf_ib2+cfv3_alu_i0") -+ -+(define_insn_reservation "cfv3_alu_i0_3" 5 -+ (and (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "type" " -+alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift, -+clr,clr_l,mov3q_l,move,moveq_l,tst")) -+ (eq_attr "op_mem" "i0")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv3_alu_i0") -+ -+(define_insn_reservation "cfv3_omove_i0_2" 4 -+ (and (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "type" " -+move_l,tst_l")) -+ (eq_attr "op_mem" "i0")) -+ (eq_attr "size" "1,2")) -+ "cf_ib2+cfv3_omove_i0") -+ -+(define_insn_reservation "cfv3_omove_i0_3" 4 -+ (and (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "type" " -+move_l,tst_l")) -+ (eq_attr "op_mem" "i0")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv3_omove_i0") -+ -+(define_insn_reservation "cfv12_alu_01_1" 1 -+ (and (and (and (eq_attr "cpu" "cfv1,cfv2") -+ (eq_attr "type" " -+alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift, -+clr,clr_l,mov3q_l,move,moveq_l,tst, -+move_l,tst_l")) -+ (eq_attr "op_mem" "01")) -+ (eq_attr "size" "1")) -+ "cf_ib1+cfv12_alu_01") -+ -+(define_insn_reservation "cfv12_alu_01_2" 1 -+ (and (and (and (eq_attr "cpu" "cfv1,cfv2") -+ (eq_attr "type" " -+alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift, -+clr,clr_l,mov3q_l,move,moveq_l,tst, -+move_l,tst_l")) -+ (eq_attr "op_mem" "01")) -+ (eq_attr "size" "2")) -+ "cf_ib2+cfv12_alu_01") -+ -+(define_insn_reservation "cfv12_alu_01_3" 1 -+ (and (and (and (eq_attr "cpu" "cfv1,cfv2") -+ (eq_attr "type" " -+alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift, -+clr,clr_l,mov3q_l,move,moveq_l,tst, -+move_l,tst_l")) -+ (eq_attr "op_mem" "01")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv12_alu_01") -+ -+(define_insn_reservation "cfv3_alu_01_1" 1 -+ (and (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "type" " -+alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift, -+clr,clr_l,mov3q_l,move,moveq_l,tst, -+move_l,tst_l")) -+ (eq_attr "op_mem" "01")) -+ (eq_attr "size" "1")) -+ "cf_ib1+cfv3_alu_01") -+ -+(define_insn_reservation "cfv3_alu_01_2" 1 -+ (and (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "type" " -+alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift, -+clr,clr_l,mov3q_l,move,moveq_l,tst, -+move_l,tst_l")) -+ (eq_attr "op_mem" "01")) -+ (eq_attr "size" "2")) -+ "cf_ib2+cfv3_alu_01") -+ -+(define_insn_reservation "cfv3_alu_01_3" 1 -+ (and (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "type" " -+alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift, -+clr,clr_l,mov3q_l,move,moveq_l,tst, -+move_l,tst_l")) -+ (eq_attr "op_mem" "01")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv3_alu_01") -+ -+(define_insn_reservation "cfv12_alu_0i_2" 2 -+ (and (and (and (eq_attr "cpu" "cfv1,cfv2") -+ (eq_attr "type" " -+alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift, -+clr,clr_l,mov3q_l,move,moveq_l,tst, -+move_l,tst_l")) -+ (eq_attr "op_mem" "0i")) -+ (eq_attr "size" "1,2")) -+ "cf_ib2+cfv12_alu_0i") -+ -+(define_insn_reservation "cfv12_alu_0i_3" 2 -+ (and (and (and (eq_attr "cpu" "cfv1,cfv2") -+ (eq_attr "type" " -+alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift, -+clr,clr_l,mov3q_l,move,moveq_l,tst, -+move_l,tst_l")) -+ (eq_attr "op_mem" "0i")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv12_alu_0i") -+ -+(define_insn_reservation "cfv3_alu_0i_2" 2 -+ (and (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "type" " -+alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift, -+clr,clr_l,mov3q_l,move,moveq_l,tst, -+move_l,tst_l")) -+ (eq_attr "op_mem" "0i")) -+ (eq_attr "size" "1,2")) -+ "cf_ib2+cfv3_alu_0i") -+ -+(define_insn_reservation "cfv3_alu_0i_3" 2 -+ (and (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "type" " -+alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift, -+clr,clr_l,mov3q_l,move,moveq_l,tst, -+move_l,tst_l")) -+ (eq_attr "op_mem" "0i")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv3_alu_0i") -+ -+(define_insn_reservation "cfv1_alu_11_1" 1 -+ (and (and (and (eq_attr "cpu" "cfv1") -+ (eq_attr "type" " -+alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift")) -+ (eq_attr "op_mem" "11")) -+ (eq_attr "size" "1")) -+ "cf_ib1+cfv12_alu_11") -+ -+(define_insn_reservation "cfv1_alu_11_2" 1 -+ (and (and (and (eq_attr "cpu" "cfv1") -+ (eq_attr "type" " -+alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift")) -+ (eq_attr "op_mem" "11")) -+ (eq_attr "size" "2")) -+ "cf_ib2+cfv12_alu_11") -+ -+(define_insn_reservation "cfv1_alu_11_3" 1 -+ (and (and (and (eq_attr "cpu" "cfv1") -+ (eq_attr "type" " -+alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift")) -+ (eq_attr "op_mem" "11")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv12_alu_11") -+ -+(define_insn_reservation "cfv1_omove_11_1" 1 -+ (and (and (and (eq_attr "cpu" "cfv1") -+ (eq_attr "type" " -+clr,clr_l,mov3q_l,move,moveq_l,tst, -+move_l,tst_l")) -+ (eq_attr "op_mem" "11")) -+ (eq_attr "size" "1")) -+ "cf_ib1+cfv12_omove_11") -+ -+(define_insn_reservation "cfv1_omove_11_2" 1 -+ (and (and (and (eq_attr "cpu" "cfv1") -+ (eq_attr "type" " -+clr,clr_l,mov3q_l,move,moveq_l,tst, -+move_l,tst_l")) -+ (eq_attr "op_mem" "11")) -+ (eq_attr "size" "2")) -+ "cf_ib2+cfv12_omove_11") -+ -+(define_insn_reservation "cfv1_omove_11_3" 1 -+ (and (and (and (eq_attr "cpu" "cfv1") -+ (eq_attr "type" " -+clr,clr_l,mov3q_l,move,moveq_l,tst, -+move_l,tst_l")) -+ (eq_attr "op_mem" "11")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv12_omove_11") -+ -+(define_insn_reservation "cfv2_alu_11_1" 1 -+ (and (and (and (eq_attr "cpu" "cfv2") -+ (eq_attr "type" " -+alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift, -+clr,clr_l,mov3q_l,move,moveq_l,tst")) -+ (eq_attr "op_mem" "11")) -+ (eq_attr "size" "1")) -+ "cf_ib1+cfv12_alu_11") -+ -+(define_insn_reservation "cfv2_alu_11_2" 1 -+ (and (and (and (eq_attr "cpu" "cfv2") -+ (eq_attr "type" " -+alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift, -+clr,clr_l,mov3q_l,move,moveq_l,tst")) -+ (eq_attr "op_mem" "11")) -+ (eq_attr "size" "2")) -+ "cf_ib2+cfv12_alu_11") -+ -+(define_insn_reservation "cfv2_alu_11_3" 1 -+ (and (and (and (eq_attr "cpu" "cfv2") -+ (eq_attr "type" " -+alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift, -+clr,clr_l,mov3q_l,move,moveq_l,tst")) -+ (eq_attr "op_mem" "11")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv12_alu_11") -+ -+(define_insn_reservation "cfv2_omove_11_1" 1 -+ (and (and (and (eq_attr "cpu" "cfv2") -+ (eq_attr "type" " -+move_l,tst_l")) -+ (eq_attr "op_mem" "11")) -+ (eq_attr "size" "1")) -+ "cf_ib1+cfv12_omove_11") -+ -+(define_insn_reservation "cfv2_omove_11_2" 1 -+ (and (and (and (eq_attr "cpu" "cfv2") -+ (eq_attr "type" " -+move_l,tst_l")) -+ (eq_attr "op_mem" "11")) -+ (eq_attr "size" "2")) -+ "cf_ib2+cfv12_omove_11") -+ -+(define_insn_reservation "cfv2_omove_11_3" 1 -+ (and (and (and (eq_attr "cpu" "cfv2") -+ (eq_attr "type" " -+move_l,tst_l")) -+ (eq_attr "op_mem" "11")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv12_omove_11") -+ -+(define_insn_reservation "cfv3_alu_11_1" 1 -+ (and (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "type" " -+alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift, -+clr,clr_l,mov3q_l,move,moveq_l,tst")) -+ (eq_attr "op_mem" "11")) -+ (eq_attr "size" "1")) -+ "cf_ib1+cfv3_alu_11") -+ -+(define_insn_reservation "cfv3_alu_11_2" 1 -+ (and (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "type" " -+alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift, -+clr,clr_l,mov3q_l,move,moveq_l,tst")) -+ (eq_attr "size" "2")) - (eq_attr "op_mem" "11")) -- "cf_v2_ib1+cf_v2_pea_11") -+ "cf_ib2+cfv3_alu_11") - --(define_insn_reservation "cf_v2_pea_11_2" 0 -- (and (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "type2" "pea")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 2))) -+(define_insn_reservation "cfv3_alu_11_3" 1 -+ (and (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "type" " -+alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift, -+clr,clr_l,mov3q_l,move,moveq_l,tst")) -+ (eq_attr "op_mem" "11")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv3_alu_11") -+ -+(define_insn_reservation "cfv3_omove_11_1" 1 -+ (and (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "type" " -+move_l,tst_l")) -+ (eq_attr "op_mem" "11")) -+ (eq_attr "size" "1")) -+ "cf_ib1+cfv3_omove_11") -+ -+(define_insn_reservation "cfv3_omove_11_2" 1 -+ (and (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "type" " -+move_l,tst_l")) -+ (eq_attr "size" "2")) - (eq_attr "op_mem" "11")) -- "cf_v2_ib2+cf_v2_pea_11") -+ "cf_ib2+cfv3_omove_11") - --(define_insn_reservation "cf_v2_pea_11_3" 0 -- (and (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "type2" "pea")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 3))) -- (eq_attr "op_mem" "11")) -- "cf_v2_ib3+cf_v2_pea_11") -+(define_insn_reservation "cfv3_omove_11_3" 1 -+ (and (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "type" " -+move_l,tst_l")) -+ (eq_attr "op_mem" "11")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv3_omove_11") -+ -+(define_insn_reservation "cfv1_alu_i1_2" 2 -+ (and (and (and (eq_attr "cpu" "cfv1") -+ (eq_attr "type" " -+alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift")) -+ (eq_attr "op_mem" "i1")) -+ (eq_attr "size" "1,2")) -+ "cf_ib2+cfv12_alu_i1") -+ -+(define_insn_reservation "cfv1_alu_i1_3" 2 -+ (and (and (and (eq_attr "cpu" "cfv1") -+ (eq_attr "type" " -+alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift")) -+ (eq_attr "op_mem" "i1")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv12_alu_i1") -+ -+(define_insn_reservation "cfv1_omove_i1_2" 2 -+ (and (and (and (eq_attr "cpu" "cfv1") -+ (eq_attr "type" " -+clr,clr_l,mov3q_l,move,moveq_l,tst, -+move_l,tst_l")) -+ (eq_attr "op_mem" "i1")) -+ (eq_attr "size" "1,2")) -+ "cf_ib2+cfv12_omove_i1") -+ -+(define_insn_reservation "cfv1_omove_i1_3" 2 -+ (and (and (and (eq_attr "cpu" "cfv1") -+ (eq_attr "type" " -+clr,clr_l,mov3q_l,move,moveq_l,tst, -+move_l,tst_l")) -+ (eq_attr "op_mem" "i1")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv12_omove_i1") -+ -+(define_insn_reservation "cfv2_alu_i1_2" 2 -+ (and (and (and (eq_attr "cpu" "cfv2") -+ (eq_attr "type" " -+alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift, -+clr,clr_l,mov3q_l,move,moveq_l,tst")) -+ (eq_attr "op_mem" "i1")) -+ (eq_attr "size" "1,2")) -+ "cf_ib2+cfv12_alu_i1") -+ -+(define_insn_reservation "cfv2_alu_i1_3" 2 -+ (and (and (and (eq_attr "cpu" "cfv2") -+ (eq_attr "type" " -+alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift, -+clr,clr_l,mov3q_l,move,moveq_l,tst")) -+ (eq_attr "op_mem" "i1")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv12_alu_i1") -+ -+(define_insn_reservation "cfv2_omove_i1_2" 2 -+ (and (and (and (eq_attr "cpu" "cfv2") -+ (eq_attr "type" " -+move_l,tst_l")) -+ (eq_attr "op_mem" "i1")) -+ (eq_attr "size" "1,2")) -+ "cf_ib2+cfv12_omove_i1") -+ -+(define_insn_reservation "cfv2_omove_i1_3" 2 -+ (and (and (and (eq_attr "cpu" "cfv2") -+ (eq_attr "type" " -+move_l,tst_l")) -+ (eq_attr "op_mem" "i1")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv12_omove_i1") -+ -+(define_insn_reservation "cfv3_alu_i1_2" 2 -+ (and (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "type" " -+alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift, -+clr,clr_l,mov3q_l,move,moveq_l,tst")) -+ (eq_attr "op_mem" "i1")) -+ (eq_attr "size" "1,2")) -+ "cf_ib2+cfv3_alu_i1") -+ -+(define_insn_reservation "cfv3_alu_i1_3" 2 -+ (and (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "type" " -+alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift, -+clr,clr_l,mov3q_l,move,moveq_l,tst")) -+ (eq_attr "op_mem" "i1")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv3_alu_i1") -+ -+(define_insn_reservation "cfv3_omove_i1_2" 2 -+ (and (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "type" " -+move_l,tst_l")) -+ (eq_attr "op_mem" "i1")) -+ (eq_attr "size" "1,2")) -+ "cf_ib2+cfv3_omove_i1") -+ -+(define_insn_reservation "cfv3_omove_i1_3" 2 -+ (and (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "type" " -+move_l,tst_l")) -+ (eq_attr "op_mem" "i1")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv3_omove_i1") -+ -+(define_insn_reservation "cfv1_alu_1i_2" 2 -+ (and (and (and (eq_attr "cpu" "cfv1") -+ (eq_attr "type" " -+alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift")) -+ (eq_attr "op_mem" "1i")) -+ (eq_attr "size" "1,2")) -+ "cf_ib2+cfv12_alu_1i") -+ -+(define_insn_reservation "cfv1_alu_1i_3" 2 -+ (and (and (and (eq_attr "cpu" "cfv1") -+ (eq_attr "type" " -+alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift")) -+ (eq_attr "op_mem" "1i")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv12_alu_1i") -+ -+(define_insn_reservation "cfv1_omove_1i_2" 2 -+ (and (and (and (eq_attr "cpu" "cfv1") -+ (eq_attr "type" " -+clr,clr_l,mov3q_l,move,moveq_l,tst, -+move_l,tst_l")) -+ (eq_attr "op_mem" "1i")) -+ (eq_attr "size" "1,2")) -+ "cf_ib2+cfv12_omove_1i") -+ -+(define_insn_reservation "cfv1_omove_1i_3" 2 -+ (and (and (and (eq_attr "cpu" "cfv1") -+ (eq_attr "type" " -+clr,clr_l,mov3q_l,move,moveq_l,tst, -+move_l,tst_l")) -+ (eq_attr "op_mem" "1i")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv12_omove_1i") -+ -+(define_insn_reservation "cfv2_alu_1i_2" 2 -+ (and (and (and (eq_attr "cpu" "cfv2") -+ (eq_attr "type" " -+alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift, -+clr,clr_l,mov3q_l,move,moveq_l,tst")) -+ (eq_attr "op_mem" "1i")) -+ (eq_attr "size" "1,2")) -+ "cf_ib2+cfv12_alu_1i") -+ -+(define_insn_reservation "cfv2_alu_1i_3" 2 -+ (and (and (and (eq_attr "cpu" "cfv2") -+ (eq_attr "type" " -+alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift, -+clr,clr_l,mov3q_l,move,moveq_l,tst")) -+ (eq_attr "op_mem" "1i")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv12_alu_1i") -+ -+(define_insn_reservation "cfv2_omove_1i_2" 2 -+ (and (and (and (eq_attr "cpu" "cfv2") -+ (eq_attr "type" " -+move_l,tst_l")) -+ (eq_attr "op_mem" "1i")) -+ (eq_attr "size" "1,2")) -+ "cf_ib2+cfv12_omove_1i") -+ -+(define_insn_reservation "cfv2_omove_1i_3" 2 -+ (and (and (and (eq_attr "cpu" "cfv2") -+ (eq_attr "type" " -+move_l,tst_l")) -+ (eq_attr "op_mem" "1i")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv12_omove_1i") -+ -+(define_insn_reservation "cfv3_alu_1i_2" 2 -+ (and (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "type" " -+alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift, -+clr,clr_l,mov3q_l,move,moveq_l,tst")) -+ (eq_attr "op_mem" "1i")) -+ (eq_attr "size" "1,2")) -+ "cf_ib2+cfv3_alu_1i") -+ -+(define_insn_reservation "cfv3_alu_1i_3" 2 -+ (and (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "type" " -+alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift, -+clr,clr_l,mov3q_l,move,moveq_l,tst")) -+ (eq_attr "op_mem" "1i")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv3_alu_1i") -+ -+(define_insn_reservation "cfv3_omove_1i_2" 2 -+ (and (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "type" " -+move_l,tst_l")) -+ (eq_attr "op_mem" "1i")) -+ (eq_attr "size" "1,2")) -+ "cf_ib2+cfv3_omove_1i") -+ -+(define_insn_reservation "cfv3_omove_1i_3" 2 -+ (and (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "type" " -+move_l,tst_l")) -+ (eq_attr "op_mem" "1i")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv3_omove_1i") -+ -+(define_insn_reservation "cfv123_lea_10_1" 1 -+ (and (and (and (eq_attr "cpu" "cfv1,cfv2,cfv3") -+ (eq_attr "type" "lea")) -+ (eq_attr "op_mem" "10,11,1i")) -+ (eq_attr "size" "1")) -+ "cf_ib1+cfv123_lea_10") -+ -+(define_insn_reservation "cfv123_lea_10_2" 1 -+ (and (and (and (eq_attr "cpu" "cfv1,cfv2,cfv3") -+ (eq_attr "type" "lea")) -+ (eq_attr "op_mem" "10,11,1i")) -+ (eq_attr "size" "2")) -+ "cf_ib2+cfv123_lea_10") -+ -+(define_insn_reservation "cfv123_lea_10_3" 1 -+ (and (and (and (eq_attr "cpu" "cfv1,cfv2,cfv3") -+ (eq_attr "type" "lea")) -+ (eq_attr "op_mem" "10,11,1i")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv123_lea_10") -+ -+(define_insn_reservation "cfv123_lea_i0_2" 2 -+ (and (and (and (eq_attr "cpu" "cfv1,cfv2,cfv3") -+ (eq_attr "type" "lea")) -+ (eq_attr "op_mem" "i0,i1")) -+ (eq_attr "size" "1,2")) -+ "cf_ib2+cfv123_lea_i0") -+ -+(define_insn_reservation "cfv123_lea_i0_3" 2 -+ (and (and (and (eq_attr "cpu" "cfv1,cfv2,cfv3") -+ (eq_attr "type" "lea")) -+ (eq_attr "op_mem" "i0,i1")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv123_lea_i0") -+ -+(define_insn_reservation "cfv12_pea_11_1" 1 -+ (and (and (and (eq_attr "cpu" "cfv1,cfv2") -+ (eq_attr "type" "pea")) -+ (eq_attr "op_mem" "11")) -+ (eq_attr "size" "1")) -+ "cf_ib1+cfv12_pea_11") -+ -+(define_insn_reservation "cfv12_pea_11_2" 1 -+ (and (and (and (eq_attr "cpu" "cfv1,cfv2") -+ (eq_attr "type" "pea")) -+ (eq_attr "op_mem" "11")) -+ (eq_attr "size" "2")) -+ "cf_ib2+cfv12_pea_11") -+ -+(define_insn_reservation "cfv12_pea_11_3" 1 -+ (and (and (and (eq_attr "cpu" "cfv1,cfv2") -+ (eq_attr "type" "pea")) -+ (eq_attr "op_mem" "11")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv12_pea_11") -+ -+(define_insn_reservation "cfv3_pea_11_1" 1 -+ (and (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "type" "pea")) -+ (eq_attr "op_mem" "11")) -+ (eq_attr "size" "1")) -+ "cf_ib1+cfv3_pea_11") -+ -+(define_insn_reservation "cfv3_pea_11_2" 1 -+ (and (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "type" "pea")) -+ (eq_attr "op_mem" "11")) -+ (eq_attr "size" "2")) -+ "cf_ib2+cfv3_pea_11") -+ -+(define_insn_reservation "cfv3_pea_11_3" 1 -+ (and (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "type" "pea")) -+ (eq_attr "op_mem" "11")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv3_pea_11") -+ -+(define_insn_reservation "cfv12_pea_i1_2" 2 -+ (and (and (and (eq_attr "cpu" "cfv1,cfv2") -+ (eq_attr "type" "pea")) -+ (eq_attr "op_mem" "i1")) -+ (eq_attr "size" "1,2")) -+ "cf_ib2+cfv12_pea_i1") -+ -+(define_insn_reservation "cfv12_pea_i1_3" 2 -+ (and (and (and (eq_attr "cpu" "cfv1,cfv2") -+ (eq_attr "type" "pea")) -+ (eq_attr "op_mem" "i1")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv12_pea_i1") -+ -+(define_insn_reservation "cfv3_pea_i1_2" 2 -+ (and (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "type" "pea")) -+ (eq_attr "op_mem" "i1")) -+ (eq_attr "size" "1,2")) -+ "cf_ib2+cfv3_pea_i1") -+ -+(define_insn_reservation "cfv3_pea_i1_3" 2 -+ (and (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "type" "pea")) -+ (eq_attr "op_mem" "i1")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv3_pea_i1") -+ -+(define_insn_reservation "cfv123_mul_l_00_1" 18 -+ (and (and (and (and (eq_attr "cpu" "cfv1,cfv2,cfv3") -+ (eq_attr "mac" "no")) -+ (eq_attr "type" "mul_l")) -+ (eq_attr "op_mem" "00,01,0i")) -+ (eq_attr "size" "1")) -+ "cf_ib1+cfv123_mul_l_00") -+ -+(define_insn_reservation "cfv123_mul_l_00_2" 18 -+ (and (and (and (and (eq_attr "cpu" "cfv1,cfv2,cfv3") -+ (eq_attr "mac" "no")) -+ (eq_attr "type" "mul_l")) -+ (eq_attr "op_mem" "00,01,0i")) -+ (eq_attr "size" "2")) -+ "cf_ib2+cfv123_mul_l_00") -+ -+(define_insn_reservation "cfv123_mul_l_00_3" 18 -+ (and (and (and (and (eq_attr "cpu" "cfv1,cfv2,cfv3") -+ (eq_attr "mac" "no")) -+ (eq_attr "type" "mul_l")) -+ (eq_attr "op_mem" "00,01,0i")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv123_mul_l_00") -+ -+(define_insn_reservation "cfv123_mul_w_00_1" 9 -+ (and (and (and (and (eq_attr "cpu" "cfv1,cfv2,cfv3") -+ (eq_attr "mac" "no")) -+ (eq_attr "type" "mul_w")) -+ (eq_attr "op_mem" "00,01,0i")) -+ (eq_attr "size" "1")) -+ "cf_ib1+cfv123_mul_w_00") -+ -+(define_insn_reservation "cfv123_mul_w_00_2" 9 -+ (and (and (and (and (eq_attr "cpu" "cfv1,cfv2,cfv3") -+ (eq_attr "mac" "no")) -+ (eq_attr "type" "mul_w")) -+ (eq_attr "op_mem" "00,01,0i")) -+ (eq_attr "size" "2")) -+ "cf_ib2+cfv123_mul_w_00") -+ -+(define_insn_reservation "cfv123_mul_w_00_3" 9 -+ (and (and (and (and (eq_attr "cpu" "cfv1,cfv2,cfv3") -+ (eq_attr "mac" "no")) -+ (eq_attr "type" "mul_w")) -+ (eq_attr "op_mem" "00,01,0i")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv123_mul_w_00") -+ -+(define_insn_reservation "cfv12_mul_l_10_1" 20 -+ (and (and (and (and (eq_attr "cpu" "cfv1,cfv2") -+ (eq_attr "mac" "no")) -+ (eq_attr "type" "mul_l")) -+ (eq_attr "op_mem" "10,i0,i1,11,1i")) -+ (eq_attr "size" "1")) -+ "cf_ib1+cfv12_mul_l_10") -+ -+(define_insn_reservation "cfv12_mul_l_10_2" 20 -+ (and (and (and (and (eq_attr "cpu" "cfv1,cfv2") -+ (eq_attr "mac" "no")) -+ (eq_attr "type" "mul_l")) -+ (eq_attr "op_mem" "10,i0,i1,11,1i")) -+ (eq_attr "size" "2")) -+ "cf_ib2+cfv12_mul_l_10") -+ -+(define_insn_reservation "cfv12_mul_l_10_3" 20 -+ (and (and (and (and (eq_attr "cpu" "cfv1,cfv2") -+ (eq_attr "mac" "no")) -+ (eq_attr "type" "mul_l")) -+ (eq_attr "op_mem" "10,i0,i1,11,1i")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv12_mul_l_10") -+ -+(define_insn_reservation "cfv3_mul_l_10_1" 21 -+ (and (and (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "mac" "no")) -+ (eq_attr "type" "mul_l")) -+ (eq_attr "op_mem" "10,i0,i1,11,1i")) -+ (eq_attr "size" "1")) -+ "cf_ib1+cfv3_mul_l_10") -+ -+(define_insn_reservation "cfv3_mul_l_10_2" 21 -+ (and (and (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "mac" "no")) -+ (eq_attr "type" "mul_l")) -+ (eq_attr "op_mem" "10,i0,i1,11,1i")) -+ (eq_attr "size" "2")) -+ "cf_ib2+cfv3_mul_l_10") -+ -+(define_insn_reservation "cfv3_mul_l_10_3" 21 -+ (and (and (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "mac" "no")) -+ (eq_attr "type" "mul_l")) -+ (eq_attr "op_mem" "10,i0,i1,11,1i")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv3_mul_l_10") -+ -+(define_insn_reservation "cfv12_mul_w_10_1" 11 -+ (and (and (and (and (eq_attr "cpu" "cfv1,cfv2") -+ (eq_attr "mac" "no")) -+ (eq_attr "type" "mul_w")) -+ (eq_attr "op_mem" "10,11,1i")) -+ (eq_attr "size" "1")) -+ "cf_ib1+cfv12_mul_w_10") -+ -+(define_insn_reservation "cfv12_mul_w_10_2" 11 -+ (and (and (and (and (eq_attr "cpu" "cfv1,cfv2") -+ (eq_attr "mac" "no")) -+ (eq_attr "type" "mul_w")) -+ (eq_attr "op_mem" "10,11,1i")) -+ (eq_attr "size" "2")) -+ "cf_ib2+cfv12_mul_w_10") -+ -+(define_insn_reservation "cfv12_mul_w_10_3" 11 -+ (and (and (and (and (eq_attr "cpu" "cfv1,cfv2") -+ (eq_attr "mac" "no")) -+ (eq_attr "type" "mul_w")) -+ (eq_attr "op_mem" "10,11,1i")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv12_mul_w_10") -+ -+(define_insn_reservation "cfv3_mul_w_10_1" 12 -+ (and (and (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "mac" "no")) -+ (eq_attr "type" "mul_w")) -+ (eq_attr "op_mem" "10,11,1i")) -+ (eq_attr "size" "1")) -+ "cf_ib1+cfv3_mul_w_10") -+ -+(define_insn_reservation "cfv3_mul_w_10_2" 12 -+ (and (and (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "mac" "no")) -+ (eq_attr "type" "mul_w")) -+ (eq_attr "op_mem" "10,11,1i")) -+ (eq_attr "size" "2")) -+ "cf_ib2+cfv3_mul_w_10") -+ -+(define_insn_reservation "cfv3_mul_w_10_3" 12 -+ (and (and (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "mac" "no")) -+ (eq_attr "type" "mul_w")) -+ (eq_attr "op_mem" "10,11,1i")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv3_mul_w_10") -+ -+(define_insn_reservation "cfv12_mul_w_i0_2" 12 -+ (and (and (and (and (eq_attr "cpu" "cfv1,cfv2") -+ (eq_attr "mac" "no")) -+ (eq_attr "type" "mul_w")) -+ (eq_attr "op_mem" "i0,i1")) -+ (eq_attr "size" "1,2")) -+ "cf_ib2+cfv12_mul_w_i0") -+ -+(define_insn_reservation "cfv12_mul_w_i0_3" 12 -+ (and (and (and (and (eq_attr "cpu" "cfv1,cfv2") -+ (eq_attr "mac" "no")) -+ (eq_attr "type" "mul_w")) -+ (eq_attr "op_mem" "i0,i1")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv12_mul_w_i0") -+ -+(define_insn_reservation "cfv3_mul_w_i0_2" 13 -+ (and (and (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "mac" "no")) -+ (eq_attr "type" "mul_w")) -+ (eq_attr "op_mem" "i0,i1")) -+ (eq_attr "size" "1,2")) -+ "cf_ib2+cfv3_mul_w_i0") -+ -+(define_insn_reservation "cfv3_mul_w_i0_3" 13 -+ (and (and (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "mac" "no")) -+ (eq_attr "type" "mul_w")) -+ (eq_attr "op_mem" "i0,i1")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv3_mul_w_i0") -+ -+(define_insn_reservation "cfv123_mac_l_00_1" 5 -+ (and (and (and (and (eq_attr "cpu" "cfv1,cfv2,cfv3") -+ (eq_attr "mac" "cf_mac")) -+ (eq_attr "type" "mul_l")) -+ (eq_attr "op_mem" "00,01,0i")) -+ (eq_attr "size" "1")) -+ "cf_ib1+cfv123_mac_l_00") -+ -+(define_insn_reservation "cfv123_mac_l_00_2" 5 -+ (and (and (and (and (eq_attr "cpu" "cfv1,cfv2,cfv3") -+ (eq_attr "mac" "cf_mac")) -+ (eq_attr "type" "mul_l")) -+ (eq_attr "op_mem" "00,01,0i")) -+ (eq_attr "size" "2")) -+ "cf_ib2+cfv123_mac_l_00") -+ -+(define_insn_reservation "cfv123_mac_l_00_3" 5 -+ (and (and (and (and (eq_attr "cpu" "cfv1,cfv2,cfv3") -+ (eq_attr "mac" "cf_mac")) -+ (eq_attr "type" "mul_l")) -+ (eq_attr "op_mem" "00,01,0i")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv123_mac_l_00") -+ -+(define_insn_reservation "cfv123_mac_w_00_1" 3 -+ (and (and (and (and (eq_attr "cpu" "cfv1,cfv2,cfv3") -+ (eq_attr "mac" "cf_mac")) -+ (eq_attr "type" "mul_w")) -+ (eq_attr "op_mem" "00,01,0i")) -+ (eq_attr "size" "1")) -+ "cf_ib1+cfv123_mac_w_00") -+ -+(define_insn_reservation "cfv123_mac_w_00_2" 3 -+ (and (and (and (and (eq_attr "cpu" "cfv1,cfv2,cfv3") -+ (eq_attr "mac" "cf_mac")) -+ (eq_attr "type" "mul_w")) -+ (eq_attr "op_mem" "00,01,0i")) -+ (eq_attr "size" "2")) -+ "cf_ib2+cfv123_mac_w_00") -+ -+(define_insn_reservation "cfv123_mac_w_00_3" 3 -+ (and (and (and (and (eq_attr "cpu" "cfv1,cfv2,cfv3") -+ (eq_attr "mac" "cf_mac")) -+ (eq_attr "type" "mul_w")) -+ (eq_attr "op_mem" "00,01,0i")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv123_mac_w_00") -+ -+(define_insn_reservation "cfv12_mac_l_10_1" 7 -+ (and (and (and (and (eq_attr "cpu" "cfv1,cfv2") -+ (eq_attr "mac" "cf_mac")) -+ (eq_attr "type" "mul_l")) -+ (eq_attr "op_mem" "10,i0,i1,11,1i")) -+ (eq_attr "size" "1")) -+ "cf_ib1+cfv12_mac_l_10") -+ -+(define_insn_reservation "cfv12_mac_l_10_2" 7 -+ (and (and (and (and (eq_attr "cpu" "cfv1,cfv2") -+ (eq_attr "mac" "cf_mac")) -+ (eq_attr "type" "mul_l")) -+ (eq_attr "op_mem" "10,i0,i1,11,1i")) -+ (eq_attr "size" "2")) -+ "cf_ib2+cfv12_mac_l_10") -+ -+(define_insn_reservation "cfv12_mac_l_10_3" 7 -+ (and (and (and (and (eq_attr "cpu" "cfv1,cfv2") -+ (eq_attr "mac" "cf_mac")) -+ (eq_attr "type" "mul_l")) -+ (eq_attr "op_mem" "10,i0,i1,11,1i")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv12_mac_l_10") -+ -+(define_insn_reservation "cfv3_mac_l_10_1" 8 -+ (and (and (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "mac" "cf_mac")) -+ (eq_attr "type" "mul_l")) -+ (eq_attr "op_mem" "10,i0,i1,11,1i")) -+ (eq_attr "size" "1")) -+ "cf_ib1+cfv3_mac_l_10") -+ -+(define_insn_reservation "cfv3_mac_l_10_2" 8 -+ (and (and (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "mac" "cf_mac")) -+ (eq_attr "type" "mul_l")) -+ (eq_attr "op_mem" "10,i0,i1,11,1i")) -+ (eq_attr "size" "2")) -+ "cf_ib2+cfv3_mac_l_10") -+ -+(define_insn_reservation "cfv3_mac_l_10_3" 8 -+ (and (and (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "mac" "cf_mac")) -+ (eq_attr "type" "mul_l")) -+ (eq_attr "op_mem" "10,i0,i1,11,1i")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv3_mac_l_10") -+ -+(define_insn_reservation "cfv12_mac_w_10_1" 5 -+ (and (and (and (and (eq_attr "cpu" "cfv1,cfv2") -+ (eq_attr "mac" "cf_mac")) -+ (eq_attr "type" "mul_w")) -+ (eq_attr "op_mem" "10,11,1i")) -+ (eq_attr "size" "1")) -+ "cf_ib1+cfv12_mac_w_10") -+ -+(define_insn_reservation "cfv12_mac_w_10_2" 5 -+ (and (and (and (and (eq_attr "cpu" "cfv1,cfv2") -+ (eq_attr "mac" "cf_mac")) -+ (eq_attr "type" "mul_w")) -+ (eq_attr "op_mem" "10,11,1i")) -+ (eq_attr "size" "2")) -+ "cf_ib2+cfv12_mac_w_10") -+ -+(define_insn_reservation "cfv12_mac_w_10_3" 5 -+ (and (and (and (and (eq_attr "cpu" "cfv1,cfv2") -+ (eq_attr "mac" "cf_mac")) -+ (eq_attr "type" "mul_w")) -+ (eq_attr "op_mem" "10,11,1i")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv12_mac_w_10") -+ -+(define_insn_reservation "cfv3_mac_w_10_1" 6 -+ (and (and (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "mac" "cf_mac")) -+ (eq_attr "type" "mul_w")) -+ (eq_attr "op_mem" "10,11,1i")) -+ (eq_attr "size" "1")) -+ "cf_ib1+cfv3_mac_w_10") -+ -+(define_insn_reservation "cfv3_mac_w_10_2" 6 -+ (and (and (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "mac" "cf_mac")) -+ (eq_attr "type" "mul_w")) -+ (eq_attr "op_mem" "10,11,1i")) -+ (eq_attr "size" "2")) -+ "cf_ib2+cfv3_mac_w_10") -+ -+(define_insn_reservation "cfv3_mac_w_10_3" 6 -+ (and (and (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "mac" "cf_mac")) -+ (eq_attr "type" "mul_w")) -+ (eq_attr "op_mem" "10,11,1i")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv3_mac_w_10") -+ -+(define_insn_reservation "cfv12_mac_w_i0_2" 6 -+ (and (and (and (and (eq_attr "cpu" "cfv1,cfv2") -+ (eq_attr "mac" "cf_mac")) -+ (eq_attr "type" "mul_w")) -+ (eq_attr "op_mem" "i0,i1")) -+ (eq_attr "size" "1,2")) -+ "cf_ib2+cfv12_mac_w_i0") -+ -+(define_insn_reservation "cfv12_mac_w_i0_3" 6 -+ (and (and (and (and (eq_attr "cpu" "cfv1,cfv2") -+ (eq_attr "mac" "cf_mac")) -+ (eq_attr "type" "mul_w")) -+ (eq_attr "op_mem" "i0,i1")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv12_mac_w_i0") -+ -+(define_insn_reservation "cfv3_mac_w_i0_2" 7 -+ (and (and (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "mac" "cf_mac")) -+ (eq_attr "type" "mul_w")) -+ (eq_attr "op_mem" "i0,i1")) -+ (eq_attr "size" "1,2")) -+ "cf_ib2+cfv3_mac_w_i0") -+ -+(define_insn_reservation "cfv3_mac_w_i0_3" 7 -+ (and (and (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "mac" "cf_mac")) -+ (eq_attr "type" "mul_w")) -+ (eq_attr "op_mem" "i0,i1")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv3_mac_w_i0") -+ -+(define_insn_reservation "cfv123_emac_00_1" 4 -+ (and (and (and (and (eq_attr "cpu" "cfv1,cfv2,cfv3") -+ (eq_attr "mac" "cf_emac")) -+ (eq_attr "type" "mul_l,mul_w")) -+ (eq_attr "op_mem" "00,01,0i")) -+ (eq_attr "size" "1")) -+ "cf_ib1+cfv123_emac_00") -+ -+(define_insn_reservation "cfv123_emac_00_2" 4 -+ (and (and (and (and (eq_attr "cpu" "cfv1,cfv2,cfv3") -+ (eq_attr "mac" "cf_emac")) -+ (eq_attr "type" "mul_l,mul_w")) -+ (eq_attr "op_mem" "00,01,0i")) -+ (eq_attr "size" "2")) -+ "cf_ib2+cfv123_emac_00") -+ -+(define_insn_reservation "cfv123_emac_00_3" 4 -+ (and (and (and (and (eq_attr "cpu" "cfv1,cfv2,cfv3") -+ (eq_attr "mac" "cf_emac")) -+ (eq_attr "type" "mul_l,mul_w")) -+ (eq_attr "op_mem" "00,01,0i")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv123_emac_00") -+ -+(define_insn_reservation "cfv12_emac_l_10_1" 6 -+ (and (and (and (and (eq_attr "cpu" "cfv1,cfv2") -+ (eq_attr "mac" "cf_emac")) -+ (eq_attr "type" "mul_l")) -+ (eq_attr "op_mem" "10,i0,i1,11,1i")) -+ (eq_attr "size" "1")) -+ "cf_ib1+cfv12_emac_10") -+ -+(define_insn_reservation "cfv12_emac_l_10_2" 6 -+ (and (and (and (and (eq_attr "cpu" "cfv1,cfv2") -+ (eq_attr "mac" "cf_emac")) -+ (eq_attr "type" "mul_l")) -+ (eq_attr "op_mem" "10,i0,i1,11,1i")) -+ (eq_attr "size" "2")) -+ "cf_ib2+cfv12_emac_10") -+ -+(define_insn_reservation "cfv12_emac_l_10_3" 6 -+ (and (and (and (and (eq_attr "cpu" "cfv1,cfv2") -+ (eq_attr "mac" "cf_emac")) -+ (eq_attr "type" "mul_l")) -+ (eq_attr "op_mem" "10,i0,i1,11,1i")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv12_emac_10") -+ -+(define_insn_reservation "cfv3_emac_l_10_1" 7 -+ (and (and (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "mac" "cf_emac")) -+ (eq_attr "type" "mul_l")) -+ (eq_attr "op_mem" "10,i0,i1,11,1i")) -+ (eq_attr "size" "1")) -+ "cf_ib1+cfv3_emac_10") -+ -+(define_insn_reservation "cfv3_emac_l_10_2" 7 -+ (and (and (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "mac" "cf_emac")) -+ (eq_attr "type" "mul_l")) -+ (eq_attr "op_mem" "10,i0,i1,11,1i")) -+ (eq_attr "size" "2")) -+ "cf_ib2+cfv3_emac_10") -+ -+(define_insn_reservation "cfv3_emac_l_10_3" 7 -+ (and (and (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "mac" "cf_emac")) -+ (eq_attr "type" "mul_l")) -+ (eq_attr "op_mem" "10,i0,i1,11,1i")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv3_emac_10") -+ -+(define_insn_reservation "cfv12_emac_w_10_1" 6 -+ (and (and (and (and (eq_attr "cpu" "cfv1,cfv2") -+ (eq_attr "mac" "cf_emac")) -+ (eq_attr "type" "mul_w")) -+ (eq_attr "op_mem" "10,11,1i")) -+ (eq_attr "size" "1")) -+ "cf_ib1+cfv12_emac_10") -+ -+(define_insn_reservation "cfv12_emac_w_10_2" 6 -+ (and (and (and (and (eq_attr "cpu" "cfv1,cfv2") -+ (eq_attr "mac" "cf_emac")) -+ (eq_attr "type" "mul_w")) -+ (eq_attr "op_mem" "10,11,1i")) -+ (eq_attr "size" "2")) -+ "cf_ib2+cfv12_emac_10") -+ -+(define_insn_reservation "cfv12_emac_w_10_3" 6 -+ (and (and (and (and (eq_attr "cpu" "cfv1,cfv2") -+ (eq_attr "mac" "cf_emac")) -+ (eq_attr "type" "mul_w")) -+ (eq_attr "op_mem" "10,11,1i")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv12_emac_10") -+ -+(define_insn_reservation "cfv3_emac_w_10_1" 7 -+ (and (and (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "mac" "cf_emac")) -+ (eq_attr "type" "mul_w")) -+ (eq_attr "op_mem" "10,11,1i")) -+ (eq_attr "size" "1")) -+ "cf_ib1+cfv3_emac_10") -+ -+(define_insn_reservation "cfv3_emac_w_10_2" 7 -+ (and (and (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "mac" "cf_emac")) -+ (eq_attr "type" "mul_w")) -+ (eq_attr "op_mem" "10,11,1i")) -+ (eq_attr "size" "2")) -+ "cf_ib2+cfv3_emac_10") -+ -+(define_insn_reservation "cfv3_emac_w_10_3" 7 -+ (and (and (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "mac" "cf_emac")) -+ (eq_attr "type" "mul_w")) -+ (eq_attr "op_mem" "10,11,1i")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv3_emac_10") -+ -+(define_insn_reservation "cfv12_emac_w_i0_2" 7 -+ (and (and (and (and (eq_attr "cpu" "cfv1,cfv2") -+ (eq_attr "mac" "cf_emac")) -+ (eq_attr "type" "mul_w")) -+ (eq_attr "op_mem" "i0,i1")) -+ (eq_attr "size" "1,2")) -+ "cf_ib2+cfv12_emac_w_i0") -+ -+(define_insn_reservation "cfv12_emac_w_i0_3" 7 -+ (and (and (and (and (eq_attr "cpu" "cfv1,cfv2") -+ (eq_attr "mac" "cf_emac")) -+ (eq_attr "type" "mul_w")) -+ (eq_attr "op_mem" "i0,i1")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv12_emac_w_i0") -+ -+(define_insn_reservation "cfv3_emac_w_i0_2" 8 -+ (and (and (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "mac" "cf_emac")) -+ (eq_attr "type" "mul_w")) -+ (eq_attr "op_mem" "i0,i1")) -+ (eq_attr "size" "1,2")) -+ "cf_ib2+cfv3_emac_w_i0") -+ -+(define_insn_reservation "cfv3_emac_w_i0_3" 8 -+ (and (and (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "mac" "cf_emac")) -+ (eq_attr "type" "mul_w")) -+ (eq_attr "op_mem" "i0,i1")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv3_emac_w_i0") -+ -+(define_insn_reservation "cfv12_rts" 5 -+ (and (eq_attr "cpu" "cfv1,cfv2") -+ (eq_attr "type" "rts")) -+ "cf_ib1+cfv12_rts") -+ -+(define_insn_reservation "cfv3_rts" 8 -+ (and (eq_attr "cpu" "cfv3") -+ (eq_attr "type" "rts")) -+ "cf_ib1+cfv3_rts") -+ -+(define_insn_reservation "cfv12_call_1" 3 -+ (and (and (eq_attr "cpu" "cfv1,cfv2") -+ (eq_attr "type" "bsr,jsr")) -+ (eq_attr "size" "1")) -+ "cf_ib1+cfv12_call") -+ -+(define_insn_reservation "cfv12_call_2" 3 -+ (and (and (eq_attr "cpu" "cfv1,cfv2") -+ (eq_attr "type" "bsr,jsr")) -+ (eq_attr "size" "2")) -+ "cf_ib2+cfv12_call") -+ -+(define_insn_reservation "cfv12_call_3" 3 -+ (and (and (eq_attr "cpu" "cfv1,cfv2") -+ (eq_attr "type" "bsr,jsr")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv12_call") -+ -+(define_insn_reservation "cfv3_call_1" 1 -+ (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "type" "bsr,jsr")) -+ (eq_attr "size" "1")) -+ "cf_ib1+cfv3_call") -+ -+(define_insn_reservation "cfv3_call_2" 1 -+ (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "type" "bsr,jsr")) -+ (eq_attr "size" "2")) -+ "cf_ib2+cfv3_call") -+ -+(define_insn_reservation "cfv3_call_3" 1 -+ (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "type" "bsr,jsr")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv3_call") -+ -+(define_insn_reservation "cfv12_bcc_1" 2 -+ (and (and (eq_attr "cpu" "cfv1,cfv2") -+ (eq_attr "type" "bcc")) -+ (eq_attr "size" "1")) -+ "cf_ib1+cfv12_bcc") -+ -+(define_insn_reservation "cfv12_bcc_2" 2 -+ (and (and (eq_attr "cpu" "cfv1,cfv2") -+ (eq_attr "type" "bcc")) -+ (eq_attr "size" "2")) -+ "cf_ib2+cfv12_bcc") -+ -+(define_insn_reservation "cfv12_bcc_3" 2 -+ (and (and (eq_attr "cpu" "cfv1,cfv2") -+ (eq_attr "type" "bcc")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv12_bcc") -+ -+(define_insn_reservation "cfv3_bcc_1" 1 -+ (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "type" "bcc")) -+ (eq_attr "size" "1")) -+ "cf_ib1+cfv3_bcc") -+ -+(define_insn_reservation "cfv3_bcc_2" 1 -+ (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "type" "bcc")) -+ (eq_attr "size" "2")) -+ "cf_ib2+cfv3_bcc") -+ -+(define_insn_reservation "cfv3_bcc_3" 1 -+ (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "type" "bcc")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv3_bcc") -+ -+(define_insn_reservation "cfv12_bra_1" 2 -+ (and (and (eq_attr "cpu" "cfv1,cfv2") -+ (eq_attr "type" "bra")) -+ (eq_attr "size" "1")) -+ "cf_ib1+cfv12_bra") -+ -+(define_insn_reservation "cfv12_bra_2" 2 -+ (and (and (eq_attr "cpu" "cfv1,cfv2") -+ (eq_attr "type" "bra")) -+ (eq_attr "size" "2")) -+ "cf_ib2+cfv12_bra") -+ -+(define_insn_reservation "cfv12_bra_3" 2 -+ (and (and (eq_attr "cpu" "cfv1,cfv2") -+ (eq_attr "type" "bra")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv12_bra") -+ -+(define_insn_reservation "cfv3_bra_1" 1 -+ (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "type" "bra")) -+ (eq_attr "size" "1")) -+ "cf_ib1+cfv3_bra") -+ -+(define_insn_reservation "cfv3_bra_2" 1 -+ (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "type" "bra")) -+ (eq_attr "size" "2")) -+ "cf_ib2+cfv3_bra") -+ -+(define_insn_reservation "cfv3_bra_3" 1 -+ (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "type" "bra")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv3_bra") -+ -+(define_insn_reservation "cfv12_jmp_1" 3 -+ (and (and (eq_attr "cpu" "cfv1,cfv2") -+ (eq_attr "type" "jmp")) -+ (eq_attr "size" "1")) -+ "cf_ib1+cfv12_jmp") -+ -+(define_insn_reservation "cfv12_jmp_2" 3 -+ (and (and (eq_attr "cpu" "cfv1,cfv2") -+ (eq_attr "type" "jmp")) -+ (eq_attr "size" "2")) -+ "cf_ib2+cfv12_jmp") -+ -+(define_insn_reservation "cfv12_jmp_3" 3 -+ (and (and (eq_attr "cpu" "cfv1,cfv2") -+ (eq_attr "type" "jmp")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv12_jmp") -+ -+(define_insn_reservation "cfv3_jmp_1" 5 -+ (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "type" "jmp")) -+ (eq_attr "size" "1")) -+ "cf_ib1+cfv3_jmp") -+ -+(define_insn_reservation "cfv3_jmp_2" 5 -+ (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "type" "jmp")) -+ (eq_attr "size" "2")) -+ "cf_ib2+cfv3_jmp") -+ -+(define_insn_reservation "cfv3_jmp_3" 5 -+ (and (and (eq_attr "cpu" "cfv3") -+ (eq_attr "type" "jmp")) -+ (eq_attr "size" "3")) -+ "cf_ib3+cfv3_jmp") -+ -+(define_insn_reservation "cfv12_unlk" 2 -+ (and (eq_attr "cpu" "cfv1,cfv2") -+ (eq_attr "type" "unlk")) -+ "cf_ib1+cfv12_alu_10") -+ -+(define_insn_reservation "cfv3_unlk" 3 -+ (and (eq_attr "cpu" "cfv3") -+ (eq_attr "type" "unlk")) -+ "cf_ib1+cfv3_alu_10") -+ -+;; Dummy reservation for instructions that are not handled. -+(define_insn_reservation "cfv123_guess" 3 -+ (and (eq_attr "cpu" "cfv1,cfv2,cfv3") -+ (eq_attr "type" "falu,fbcc,fcmp,fdiv,fmove,fmul,fneg,fsqrt,ftst, -+ div_w,div_l,link,mvsz,nop,trap,unknown")) -+ "cf_ib3+cfv123_guess+cf_dsoc+cf_agex+cf_mem") -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+;; Below is pipeline description of ColdFire V4 core. -+;; It is substantially different from the description of V1, V2 or V3 cores, -+;; primarily due to no need to model the instruction buffer. -+;; -+;; V4 pipeline model uses a completely separate set of cpu units. - --(define_insn_reservation "cf_v2_pea_i1_2" 0 -- (and (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "type2" "pea")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 2))) -- (eq_attr "op_mem" "i1")) -- "cf_v2_ib2+cf_v2_pea_i1") -+;; Operand Execution Pipeline. -+(define_automaton "cfv4_oep") - --(define_insn_reservation "cf_v2_pea_i1_3" 0 -- (and (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "type2" "pea")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 3))) -- (eq_attr "op_mem" "i1")) -- "cf_v2_ib3+cf_v2_pea_i1") -+(define_cpu_unit "cfv4_oag,cfv4_oc1,cfv4_oc2,cfv4_ex,cfv4_da" -+ "cfv4_oep") - --(define_insn_reservation "cf_v2_mul_00_1" 4 -- (and (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "type2" "mul")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 1))) -+;; This automaton is used to support CFv4 dual-issue. -+(define_automaton "cfv4_ds") -+ -+;; V4 has 3 cases of dual-issue. -+;; After issuing a cfv4_pOEPx instruction, it'll be possible to issue -+;; a cfv4_sOEPx instruction on the same cycle (see final_presence_sets below). -+(define_cpu_unit "cfv4_pOEP1,cfv4_sOEP1, -+ cfv4_pOEP2,cfv4_sOEP2, -+ cfv4_pOEP3,cfv4_sOEP3" "cfv4_ds") -+ -+(final_presence_set "cfv4_sOEP1" "cfv4_pOEP1") -+(final_presence_set "cfv4_sOEP2" "cfv4_pOEP2") -+(final_presence_set "cfv4_sOEP3" "cfv4_pOEP3") -+ -+;; Reservation for instructions that don't allow dual-issue. -+(define_reservation "cfv4_ds" "cfv4_pOEP1+cfv4_sOEP1+ -+ cfv4_pOEP2+cfv4_sOEP2+ -+ cfv4_pOEP3+cfv4_sOEP3") -+ -+;; Memory access resource. -+(define_automaton "cfv4_mem") -+ -+(define_cpu_unit "cfv4_mem" "cfv4_mem") -+ -+;; EMAC. -+(define_automaton "cfv4_emac") -+ -+(define_cpu_unit "cfv4_emac" "cfv4_emac") -+ -+;; FPU. -+(define_automaton "cfv4_fp") -+ -+(define_cpu_unit "cfv4_fp" "cfv4_fp") -+ -+;; Automaton for unknown instruction. -+(define_automaton "cfv4_guess") -+ -+(define_query_cpu_unit "cfv4_guess" "cfv4_guess") -+ -+;; This bypass allows 1st case of dual-issue. -+(define_bypass 0 "cfv4_00_oag_pOEP1,cfv4_10_pOEP1,cfv4_i0_pOEP1" -+ "cfv4_00_oag,cfv4_00_oag_pOEP3_sOEP12,cfv4_00_oag_pOEP1, -+ cfv4_00_oag_moveql,cfv4_00_ex_sOEP13") -+ -+;; The following bypasses decrease the latency of producers if it modifies -+;; a target register in the EX stage and the consumer also uses -+;; that register in the EX stage. -+(define_bypass 1 "cfv4_00_ex" "cfv4_00_ex,cfv4_00_ex_sOEP13") -+(define_bypass 1 "cfv4_00_ex" "cfv4_10,cfv4_10_pOEP1,cfv4_i0,cfv4_i0_pOEP1" -+ "!m68k_sched_address_bypass_p") -+ -+;; Indexed loads with scale factors 2 and 4 require an update of the index -+;; register in the register file. Considering that the index register is -+;; only needed at the second cycle of address generation, we get -+;; a latency of 4. -+;; Producers for indexed loads with scale factor 1 should have -+;; a latency of 3. Since we're only allowed one bypass, we handle it -+;; in the adjust_cost hook. -+(define_bypass 4 -+ "cfv4_00_oag,cfv4_00_oag_pOEP3_sOEP12,cfv4_00_oag_lea,cfv4_00_oag_pOEP1, -+ cfv4_00_oag_moveql" -+ "cfv4_i0,cfv4_i0_pOEP1" -+ "m68k_sched_indexed_address_bypass_p") -+ -+;; First part of cfv4_00. -+;; If issued in pairs with cfv4_movel_?0, the cost should be increased. -+;; ??? Is it possible that combined cfv4_movel_00 and cfv4_oag_00 instructions -+;; have longer latency than the two instructions emitted sequentially? -+;; Due to register renaming, the result of the sequence would be available -+;; after 3 cycles, instead of 4 for combined instruction? -+(define_insn_reservation "cfv4_00_oag" 1 -+ (and (and (eq_attr "cpu" "cfv4") -+ (eq_attr "type" "alu_l,aluq_l,clr_l,cmp_l,mov3q_l,neg_l")) - (eq_attr "op_mem" "00")) -- "cf_v2_ib1+cf_v2_mul_00") -+ "cfv4_sOEP1|cfv4_sOEP3|(cfv4_ds,cfv4_oag,cfv4_oc1,cfv4_oc2,cfv4_ex)") - --(define_insn_reservation "cf_v2_mul_00_2" 4 -- (and (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "type2" "mul")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 2))) -+(define_insn_reservation "cfv4_00_oag_pOEP3_sOEP12" 1 -+ (and (and (eq_attr "cpu" "cfv4") -+ (eq_attr "type" "move_l,mov3q_l,clr_l")) -+ (and (eq_attr "op_mem" "00") -+ (and (eq_attr "opx_type" "Rn") -+ (eq_attr "opy_type" "none,imm_q,imm_w,imm_l")))) -+ "cfv4_sOEP1|cfv4_sOEP2|(cfv4_pOEP3,cfv4_oag,cfv4_oc1,cfv4_oc2,cfv4_ex)") -+ -+(define_insn_reservation "cfv4_00_oag_lea" 1 -+ (and (eq_attr "cpu" "cfv4") -+ (eq_attr "type" "lea")) -+ "cfv4_pOEP3,cfv4_oag,cfv4_oc1,cfv4_oc2,cfv4_ex") -+ -+(define_insn_reservation "cfv4_00_oag_pOEP1" 1 -+ (and (and (eq_attr "cpu" "cfv4") -+ (eq_attr "type" "move_l,mov3q_l,clr_l")) -+ (and (eq_attr "op_mem" "00") -+ (ior (eq_attr "opx_type" "!Rn") -+ (eq_attr "opy_type" "!none,imm_q,imm_w,imm_l")))) -+ "cfv4_sOEP1|(cfv4_pOEP1,cfv4_oag,cfv4_oc1,cfv4_oc2,cfv4_ex)") -+ -+(define_insn_reservation "cfv4_00_oag_moveql" 1 -+ (and (and (eq_attr "cpu" "cfv4") -+ (eq_attr "type" "moveq_l")) - (eq_attr "op_mem" "00")) -- "cf_v2_ib2+cf_v2_mul_00") -+ "cfv4_sOEP1|cfv4_sOEP2|cfv4_sOEP3|(cfv4_pOEP3,cfv4_oag,cfv4_oc1,cfv4_oc2,cfv4_ex)") - --(define_insn_reservation "cf_v2_mul_00_3" 4 -- (and (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "type2" "mul")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 3))) -+;; Second part of cfv4_00. -+;; Latency is either 1 or 4 depending on which stage the consumer -+;; will need the data. -+ -+(define_insn_reservation "cfv4_00_ex" 4 -+ (and (and (eq_attr "cpu" "cfv4") -+ (eq_attr "type" "bitr,bitrw,clr,cmp,move,mvsz,scc,tst")) - (eq_attr "op_mem" "00")) -- "cf_v2_ib3+cf_v2_mul_00") -+ "cfv4_ds,cfv4_oag,cfv4_oc1,cfv4_oc2,cfv4_ex") - --(define_insn_reservation "cf_v2_mul_10_1" 6 -- (and (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "type2" "mul")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 1))) -- (eq_attr "op_mem" "10")) -- "cf_v2_ib1+cf_v2_mul_10") -+(define_insn_reservation "cfv4_00_ex_sOEP13" 4 -+ (and (and (eq_attr "cpu" "cfv4") -+ (eq_attr "type" "alux_l,ext,shift,tst_l")) -+ (eq_attr "op_mem" "00")) -+ "cfv4_sOEP1|cfv4_sOEP3|(cfv4_ds,cfv4_oag,cfv4_oc1,cfv4_oc2,cfv4_ex)") - --(define_insn_reservation "cf_v2_mul_10_2" 6 -- (and (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "type2" "mul")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 2))) -+;; Several types mentioned in this reservation (e.g., ext and shift) don't -+;; support implicit load. But we handle them anyway due to first scheduling -+;; pass, which handles non-strict rtl. -+;; -+;; Latency is either 1 or 4 depending in which stage the consumer -+;; will need the data. -+(define_insn_reservation "cfv4_10" 4 -+ (and (and (eq_attr "cpu" "cfv4") -+ (eq_attr "type" "alu_l,aluq_l,alux_l,bitr,bitrw, -+ clr,clr_l,cmp,cmp_l,ext, -+ mov3q_l,move,moveq_l,mvsz,neg_l, -+ shift,tst,tst_l")) - (eq_attr "op_mem" "10")) -- "cf_v2_ib2+cf_v2_mul_10") -+ "cfv4_ds,cfv4_oag,cfv4_oc1+cfv4_mem,cfv4_oc2,cfv4_ex") - --(define_insn_reservation "cf_v2_mul_10_3" 6 -- (and (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "type2" "mul")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 3))) -+;; Specialization of cfv4_10. -+;; move.l has OC2-to-DS forwarding path, that saves one cycle of latency. -+(define_insn_reservation "cfv4_10_pOEP1" 3 -+ (and (and (eq_attr "cpu" "cfv4") -+ (eq_attr "type" "move_l")) - (eq_attr "op_mem" "10")) -- "cf_v2_ib3+cf_v2_mul_10") -+ "cfv4_pOEP1,cfv4_oag,cfv4_oc1+cfv4_mem,cfv4_oc2,cfv4_ex") - --(define_insn_reservation "cf_v2_mul_i0_2" 7 -- (and (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "type2" "mul")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 2))) -+;; Same here. But +1 to latency due to longer OAG. -+(define_insn_reservation "cfv4_i0" 5 -+ (and (and (eq_attr "cpu" "cfv4") -+ (eq_attr "type" "alu_l,aluq_l,alux_l,bitr,bitrw, -+ clr,clr_l,cmp,cmp_l,ext, -+ mov3q_l,move,moveq_l,mvsz,neg_l, -+ shift,tst,tst_l")) - (eq_attr "op_mem" "i0")) -- "cf_v2_ib2+cf_v2_mul_i0") -+ "cfv4_ds,cfv4_oag,cfv4_oag,cfv4_oc1+cfv4_mem,cfv4_oc2,cfv4_ex") - --(define_insn_reservation "cf_v2_mul_i0_3" 7 -- (and (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "type2" "mul")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 3))) -+;; ??? Does indexed load trigger dual-issue? -+;; ??? Does OC2-to-DS forwarding path saves a cycle? -+(define_insn_reservation "cfv4_i0_pOEP1" 4 -+ (and (and (eq_attr "cpu" "cfv4") -+ (eq_attr "type" "move_l")) - (eq_attr "op_mem" "i0")) -- "cf_v2_ib3+cf_v2_mul_i0") -+ "cfv4_ds,cfv4_oag,cfv4_oag,cfv4_oc1+cfv4_mem,cfv4_oc2,cfv4_ex") - --;; ??? As return reads target address from stack, use a mem-read reservation --;; for it. --(define_reservation "cf_v2_rts" "cf_v2_move_10") -- --;; ??? It's not clear what the core does during these 5 cycles. --;; Luckily, we don't care that much about an insn that won't be moved. --(define_insn_reservation "cf_v2_rts_1" 5 -- (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "type2" "rts")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 1))) -- "cf_v2_ib1+cf_v2_rts") -+;; This reservation is for moves and clr. Arithmetic instructions -+;; don't write to memory unless they also read from it. -+;; But, before reload we can have all sorts of things. -+;; With cfv4_pOEP2 allow dual-issue for type 2 cases. -+(define_insn_reservation "cfv4_01" 1 -+ (and (and (eq_attr "cpu" "cfv4") -+ (eq_attr "type" "alu_l,aluq_l,alux_l,bitr,bitrw, -+ clr,clr_l,cmp,cmp_l,ext, -+ mov3q_l,move,move_l,moveq_l,mvsz,neg_l, -+ shift")) -+ (eq_attr "op_mem" "01")) -+ "cfv4_pOEP2,cfv4_oag,cfv4_oc1,cfv4_oc2,cfv4_ex,cfv4_da,cfv4_mem") - --;; Call instructions reservations. -+;; ??? Does indexed store trigger dual-issue? -+(define_insn_reservation "cfv4_0i" 2 -+ (and (and (eq_attr "cpu" "cfv4") -+ (eq_attr "type" "alu_l,aluq_l,alux_l,bitr,bitrw, -+ clr,clr_l,cmp,cmp_l,ext, -+ mov3q_l,move,move_l,moveq_l,mvsz,neg_l, -+ shift")) -+ (eq_attr "op_mem" "0i")) -+ "cfv4_pOEP2,cfv4_oag,cfv4_oag,cfv4_oc1,cfv4_oc2,cfv4_ex,cfv4_da,cfv4_mem") - --;; ??? It's not clear what reservation is best to use for calls. --;; For now we use mem-write + return reservations to reflect the fact of --;; pushing and poping return address to and from the stack. -+(define_insn_reservation "cfv4_11" 1 -+ (and (and (eq_attr "cpu" "cfv4") -+ (eq_attr "type" "alu_l,aluq_l,alux_l,bitr,bitrw, -+ clr,clr_l,cmp,cmp_l,ext, -+ mov3q_l,move,move_l,moveq_l,mvsz,neg_l, -+ shift")) -+ (eq_attr "op_mem" "11")) -+ "cfv4_ds,cfv4_oag,cfv4_oc1+cfv4_mem,cfv4_oc2,cfv4_ex,cfv4_da,cfv4_mem") - --(define_insn_reservation "cf_v2_call_1" 3 -- (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "type2" "call")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 1))) -- "cf_v2_ib1+cf_v2_move_10,cf_v2_rts") -- --(define_insn_reservation "cf_v2_call_2" 3 -- (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "type2" "call")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 2))) -- "cf_v2_ib2+cf_v2_move_10,cf_v2_rts") -- --(define_insn_reservation "cf_v2_call_3" 3 -- (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "type2" "call")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 3))) -- "cf_v2_ib3+cf_v2_move_10,cf_v2_rts") -+;; Latency is 2 due to long OAG stage. -+(define_insn_reservation "cfv4_i1" 2 -+ (and (and (eq_attr "cpu" "cfv4") -+ (eq_attr "type" "alu_l,aluq_l,alux_l,bitr,bitrw, -+ clr,clr_l,cmp,cmp_l,ext, -+ mov3q_l,move,move_l,moveq_l,mvsz,neg_l, -+ shift")) -+ (eq_attr "op_mem" "i1")) -+ "cfv4_ds,cfv4_oag,cfv4_oag,cfv4_oc1+cfv4_mem,cfv4_oc2,cfv4_ex,cfv4_da,cfv4_mem") - --;; Branch reservations. -+;; This one is the same as cfv4_i1. -+;; ??? Should it be different? -+(define_insn_reservation "cfv4_1i" 2 -+ (and (and (eq_attr "cpu" "cfv4") -+ (eq_attr "type" "alu_l,aluq_l,alux_l,bitr,bitrw, -+ clr,clr_l,cmp,cmp_l,ext, -+ mov3q_l,move,move_l,moveq_l,mvsz,neg_l, -+ shift")) -+ (eq_attr "op_mem" "1i")) -+ "cfv4_ds,cfv4_oag,cfv4_oag,cfv4_oc1+cfv4_mem,cfv4_oc2,cfv4_ex,cfv4_da,cfv4_mem") - --;; ??? Branch reservations are unclear to me so far. Luckily, we don't care --;; ??? that much about branches. --(define_reservation "cf_v2_bcc" "cf_v2_move_00") -+;; ??? Does pea indeed support case 2 of dual-issue? -+(define_insn_reservation "cfv4_11_pea" 1 -+ (and (and (eq_attr "cpu" "cfv4") -+ (eq_attr "type" "pea")) -+ (eq_attr "op_mem" "11,00,01,0i,10")) -+ "cfv4_pOEP2,cfv4_oag,cfv4_oc1,cfv4_oc2,cfv4_ex,cfv4_da,cfv4_mem") -+ -+;; ??? Does pea indeed support case 2 of dual-issue? -+;; ??? Does indexed store trigger dual-issue? -+(define_insn_reservation "cfv4_i1_pea" 1 -+ (and (and (eq_attr "cpu" "cfv4") -+ (eq_attr "type" "pea")) -+ (eq_attr "op_mem" "i1,1i")) -+ "cfv4_pOEP2,cfv4_oag,cfv4_oag,cfv4_oc1,cfv4_oc2,cfv4_ex,cfv4_da,cfv4_mem") -+ -+(define_insn_reservation "cfv4_link" 2 -+ (and (eq_attr "cpu" "cfv4") -+ (eq_attr "type" "link")) -+ "cfv4_ds,cfv4_oag,cfv4_oc1,cfv4_oc2,cfv4_ex,cfv4_ex,cfv4_da,cfv4_mem") -+ -+(define_insn_reservation "cfv4_unlink" 2 -+ (and (eq_attr "cpu" "cfv4") -+ (eq_attr "type" "unlk")) -+ "cfv4_ds,cfv4_oag,cfv4_oc1+cfv4_mem,cfv4_oc2,cfv4_ex") -+ -+(define_insn_reservation "cfv4_divw_00" 20 -+ (and (and (eq_attr "cpu" "cfv4") -+ (eq_attr "type" "div_w")) -+ (eq_attr "op_mem" "00,01,0i")) -+ "cfv4_ds,cfv4_oag,cfv4_oc1,cfv4_oc2,cfv4_ex*15") -+ -+(define_insn_reservation "cfv4_divw_10" 20 -+ (and (and (eq_attr "cpu" "cfv4") -+ (eq_attr "type" "div_w")) -+ (eq_attr "op_mem" "10,11,1i")) -+ "cfv4_ds,cfv4_oag,cfv4_oc1+cfv4_mem,cfv4_oc2,cfv4_ex*15") -+ -+(define_insn_reservation "cfv4_divw_i0" 21 -+ (and (and (eq_attr "cpu" "cfv4") -+ (eq_attr "type" "div_w")) -+ (eq_attr "op_mem" "i0,i1")) -+ "cfv4_ds,cfv4_oag,cfv4_oag,cfv4_oc1+cfv4_mem,cfv4_oc2,cfv4_ex*15") -+ -+(define_insn_reservation "cfv4_divl_00" 35 -+ (and (and (eq_attr "cpu" "cfv4") -+ (eq_attr "type" "div_l")) -+ (eq_attr "op_mem" "00,01,0i")) -+ "cfv4_ds,cfv4_oag,cfv4_oc1,cfv4_oc2,cfv4_ex*30") -+ -+(define_insn_reservation "cfv4_divl_10" 35 -+ (and (and (eq_attr "cpu" "cfv4") -+ (eq_attr "type" "div_l")) -+ (eq_attr "op_mem" "10,11,1i,i0,i1")) -+ "cfv4_ds,cfv4_oag,cfv4_oc1+cfv4_mem,cfv4_oc2,cfv4_ex*30") -+ -+(define_insn_reservation "cfv4_emac_mul_00" 7 -+ (and (and (eq_attr "cpu" "cfv4") -+ (eq_attr "type" "mul_w,mul_l")) -+ (eq_attr "op_mem" "00,01,0i")) -+ "cfv4_ds,cfv4_oag,cfv4_oc1,cfv4_oc2,cfv4_ex,cfv4_emac") -+ -+(define_insn_reservation "cfv4_emac_mul_10" 7 -+ (and (and (eq_attr "cpu" "cfv4") -+ (eq_attr "type" "mul_w,mul_l")) -+ (eq_attr "op_mem" "10,11,1i")) -+ "cfv4_ds,cfv4_oag,cfv4_oc1+cfv4_mem,cfv4_oc2,cfv4_ex,cfv4_emac") -+ -+(define_insn_reservation "cfv4_emac_mul_i0" 8 -+ (and (and (eq_attr "cpu" "cfv4") -+ (eq_attr "type" "mul_w,mul_l")) -+ (eq_attr "op_mem" "i0,i1")) -+ "cfv4_ds,cfv4_oag,cfv4_oag,cfv4_oc1+cfv4_mem,cfv4_oc2,cfv4_ex,cfv4_emac") -+ -+(define_insn_reservation "cfv4_falu_00" 7 -+ (and (and (eq_attr "cpu" "cfv4") -+ (eq_attr "type" "falu,fcmp,fmul")) -+ (eq_attr "op_mem" "00,01,0i")) -+ "cfv4_ds,cfv4_oag,cfv4_oc1,cfv4_oc2,cfv4_ex,cfv4_fp") -+ -+(define_insn_reservation "cfv4_falu_10" 7 -+ (and (and (eq_attr "cpu" "cfv4") -+ (eq_attr "type" "falu,fcmp,fmul")) -+ (eq_attr "op_mem" "10,i0,11,1i,i1")) -+ "cfv4_ds,cfv4_oag,cfv4_oc1+cfv4_mem,cfv4_oc2,cfv4_ex,cfv4_fp") -+ -+(define_insn_reservation "cfv4_fneg_00" 4 -+ (and (and (eq_attr "cpu" "cfv4") -+ (eq_attr "type" "fmove,fneg,ftst")) -+ (eq_attr "op_mem" "00")) -+ "cfv4_ds,cfv4_oag,cfv4_oc1,cfv4_oc2,cfv4_ex,cfv4_fp") - --(define_insn_reservation "cf_v2_bcc_1" 2 -- (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "type2" "bcc")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 1))) -- "cf_v2_ib1+cf_v2_bcc") -- --(define_insn_reservation "cf_v2_bcc_2" 2 -- (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "type2" "bcc")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 2))) -- "cf_v2_ib2+cf_v2_bcc") -- --(define_insn_reservation "cf_v2_bcc_3" 2 -- (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "type2" "bcc")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 3))) -- "cf_v2_ib3+cf_v2_bcc") -- --(define_reservation "cf_v2_bra" "cf_v2_move_01") -- --(define_insn_reservation "cf_v2_bra_1" 2 -- (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "type2" "bra")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 1))) -- "cf_v2_ib1+cf_v2_bra") -- --(define_insn_reservation "cf_v2_bra_2" 2 -- (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "type2" "bra")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 2))) -- "cf_v2_ib2+cf_v2_bra") -- --(define_insn_reservation "cf_v2_bra_3" 2 -- (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "type2" "bra")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 3))) -- "cf_v2_ib3+cf_v2_bra") -- --;; Computed jump. --;; Takes 3 cycles. --(define_reservation "cf_v2_jmp" -- "cf_v2_dsoc,cf_v2_agex,cf_v2_dsoc,cf_v2_agex") -- --(define_insn_reservation "cf_v2_jmp_1" 3 -- (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "type2" "jmp")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 1))) -- "cf_v2_ib1+cf_v2_jmp") -- --(define_insn_reservation "cf_v2_jmp_2" 3 -- (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "type2" "jmp")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 2))) -- "cf_v2_ib2+cf_v2_jmp") -- --(define_insn_reservation "cf_v2_jmp_3" 3 -- (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "type2" "jmp")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 3))) -- "cf_v2_ib3+cf_v2_jmp") -- --;; Misc reservations. -- --(define_insn_reservation "cf_v2_unlk_1" 2 -- (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "type2" "unlk")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 1))) -- "cf_v2_ib1+cf_v2_move_l_10") -- --;; This automaton is used to gather statistics on insns that need reservations. --(define_automaton "cf_v2_guess") -- --(define_query_cpu_unit "cf_v2_guess" "cf_v2_guess") -- --;; Dummy reservation for instructions that are not handled yet. -- --(define_insn_reservation "cf_v2_guess_1" 1 -- (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "guess" "yes")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 1))) -- "cf_v2_ib1+cf_v2_guess+cf_v2_dsoc+cf_v2_agex") -- --(define_insn_reservation "cf_v2_guess_2" 1 -- (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "guess" "yes")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 2))) -- "cf_v2_ib2+cf_v2_guess+cf_v2_dsoc+cf_v2_agex") -- --(define_insn_reservation "cf_v2_guess_3" 1 -- (and (and (eq_attr "cpu" "cf_v2") -- (eq_attr "guess" "yes")) -- (eq (symbol_ref "get_attr_size (insn)") (const_int 3))) -- "cf_v2_ib3+cf_v2_guess+cf_v2_dsoc+cf_v2_agex") -+(define_insn_reservation "cfv4_fmove_fneg_10" 4 -+ (and (and (eq_attr "cpu" "cfv4") -+ (eq_attr "type" "fmove,fneg,ftst")) -+ (eq_attr "op_mem" "10,i0,11,1i,i1")) -+ "cfv4_ds,cfv4_oag,cfv4_oc1+cfv4_mem,cfv4_oc2,cfv4_ex,cfv4_fp") -+ -+(define_insn_reservation "cfv4_fmove_01" 1 -+ (and (and (eq_attr "cpu" "cfv4") -+ (eq_attr "type" "fmove,fneg,ftst")) -+ (eq_attr "op_mem" "01,0i")) -+ "cfv4_ds,cfv4_oag,cfv4_oc1,cfv4_oc2,cfv4_ex,cfv4_fp,cfv4_da,cfv4_mem") -+ -+(define_insn_reservation "cfv4_fdiv_00" 23 -+ (and (and (eq_attr "cpu" "cfv4") -+ (eq_attr "type" "fdiv")) -+ (eq_attr "op_mem" "00,01,0i")) -+ "cfv4_ds,cfv4_oag,cfv4_oc1,cfv4_oc2,cfv4_ex,cfv4_fp*17") -+ -+(define_insn_reservation "cfv4_fdiv_10" 23 -+ (and (and (eq_attr "cpu" "cfv4") -+ (eq_attr "type" "fdiv")) -+ (eq_attr "op_mem" "10,i0,11,1i,i1")) -+ "cfv4_ds,cfv4_oag,cfv4_oc1+cfv4_mem,cfv4_oc2,cfv4_ex,cfv4_fp*17") -+ -+(define_insn_reservation "cfv4_fsqrt_00" 56 -+ (and (and (eq_attr "cpu" "cfv4") -+ (eq_attr "type" "fsqrt")) -+ (eq_attr "op_mem" "00,01,0i")) -+ "cfv4_ds,cfv4_oag,cfv4_oc1,cfv4_oc2,cfv4_ex,cfv4_fp*50") -+ -+(define_insn_reservation "cfv4_fsqrt_10" 56 -+ (and (and (eq_attr "cpu" "cfv4") -+ (eq_attr "type" "fsqrt")) -+ (eq_attr "op_mem" "10,i0,11,1i,i1")) -+ "cfv4_ds,cfv4_oag,cfv4_oc1+cfv4_mem,cfv4_oc2,cfv4_ex,cfv4_fp*50") -+ -+(define_insn_reservation "cfv4_bcc" 0 -+ (and (eq_attr "cpu" "cfv4") -+ (eq_attr "type" "bcc")) -+ "cfv4_ds,cfv4_oag,cfv4_oc1,cfv4_oc2,cfv4_ex") -+ -+(define_insn_reservation "cfv4_fbcc" 2 -+ (and (eq_attr "cpu" "cfv4") -+ (eq_attr "type" "fbcc")) -+ "cfv4_ds,cfv4_oag,cfv4_oc1,cfv4_oc2,cfv4_ex,cfv4_fp") -+ -+;; ??? Why is bra said to write to memory: 1(0/1) ? -+(define_insn_reservation "cfv4_bra_bsr" 1 -+ (and (eq_attr "cpu" "cfv4") -+ (eq_attr "type" "bra,bsr")) -+ "cfv4_ds,cfv4_oag,cfv4_oc1,cfv4_oc2,cfv4_ex") -+ -+(define_insn_reservation "cfv4_jmp_jsr" 5 -+ (and (eq_attr "cpu" "cfv4") -+ (eq_attr "type" "jmp,jsr")) -+ "cfv4_ds,cfv4_oag,cfv4_oc1,cfv4_oc2,cfv4_ex") -+ -+(define_insn_reservation "cfv4_rts" 2 -+ (and (eq_attr "cpu" "cfv4") -+ (eq_attr "type" "rts")) -+ "cfv4_ds,cfv4_oag,cfv4_oc1+cfv4_mem,cfv4_oc2,cfv4_ex") -+ -+(define_insn_reservation "cfv4_nop" 1 -+ (and (eq_attr "cpu" "cfv4") -+ (eq_attr "type" "nop")) -+ "cfv4_ds+cfv4_oag+cfv4_oc1+cfv4_mem+cfv4_oc2+cfv4_ex") -+ -+(define_insn_reservation "cfv4_guess" 10 -+ (and (eq_attr "cpu" "cfv4") -+ (eq_attr "type" "trap,unknown")) -+ "cfv4_guess+cfv4_ds,cfv4_oag,cfv4_oc1+cfv4_mem,cfv4_oc2,cfv4_ex,cfv4_emac+cfv4_fp") -+ -+(define_insn_reservation "ignore" 0 -+ (eq_attr "type" "ignore") -+ "nothing") ---- 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 -@@ -129,10 +129,48 @@ Boston, MA 02110-1301, USA. */ - - #else /* __PIC__ */ - -- /* Common for -mid-shared-libary and -msep-data */ -+# if defined (__uClinux__) -+ -+ /* Versions for uClinux */ -+ -+# if defined(__ID_SHARED_LIBRARY__) -+ -+ /* -mid-shared-library versions */ -+ -+ .macro PICLEA sym, reg -+ movel a5@(_current_shared_library_a5_offset_), \reg -+ movel \sym@GOT(\reg), \reg -+ .endm -+ -+ .macro PICPEA sym, areg -+ movel a5@(_current_shared_library_a5_offset_), \areg -+ movel \sym@GOT(\areg), sp@- -+ .endm - - .macro PICCALL addr --#if defined (__mcoldfire__) && !defined (__mcfisab__) -+ PICLEA \addr,a0 -+ jsr a0@ -+ .endm -+ -+ .macro PICJUMP addr -+ PICLEA \addr,a0 -+ jmp a0@ -+ .endm -+ -+# else /* !__ID_SHARED_LIBRARY__ */ -+ -+ /* Versions for -msep-data */ -+ -+ .macro PICLEA sym, reg -+ movel \sym@GOT(a5), \reg -+ .endm -+ -+ .macro PICPEA sym, areg -+ movel \sym@GOT(a5), sp@- -+ .endm -+ -+ .macro PICCALL addr -+#if defined (__mcoldfire__) && !defined (__mcfisab__) && !defined (__mcfisac__) - lea \addr-.-8,a0 - jsr pc@(a0) - #else -@@ -141,6 +179,9 @@ Boston, MA 02110-1301, USA. */ - .endm - - .macro PICJUMP addr -+ /* ISA C has no bra.l instruction, and since this assembly file -+ gets assembled into multiple object files, we avoid the -+ bra instruction entirely. */ - #if defined (__mcoldfire__) && !defined (__mcfisab__) - lea \addr-.-8,a0 - jmp pc@(a0) -@@ -149,33 +190,46 @@ Boston, MA 02110-1301, USA. */ - #endif - .endm - --# if defined(__ID_SHARED_LIBRARY__) -+# endif - -- /* -mid-shared-library versions */ -+# else /* !__uClinux__ */ -+ -+ /* Versions for Linux */ - - .macro PICLEA sym, reg -- movel a5@(_current_shared_library_a5_offset_), \reg -+ movel #_GLOBAL_OFFSET_TABLE_@GOTPC, \reg -+ lea (-6, pc, \reg), \reg - movel \sym@GOT(\reg), \reg - .endm - - .macro PICPEA sym, areg -- movel a5@(_current_shared_library_a5_offset_), \areg -+ movel #_GLOBAL_OFFSET_TABLE_@GOTPC, \areg -+ lea (-6, pc, \areg), \areg - movel \sym@GOT(\areg), sp@- - .endm - --# else /* !__ID_SHARED_LIBRARY__ */ -- -- /* Versions for -msep-data */ -- -- .macro PICLEA sym, reg -- movel \sym@GOT(a5), \reg -+ .macro PICCALL addr -+#if defined (__mcoldfire__) && !defined (__mcfisab__) && !defined (__mcfisac__) -+ lea \addr-.-8,a0 -+ jsr pc@(a0) -+#else -+ bsr \addr -+#endif - .endm - -- .macro PICPEA sym, areg -- movel \sym@GOT(a5), sp@- -+ .macro PICJUMP addr -+ /* ISA C has no bra.l instruction, and since this assembly file -+ gets assembled into multiple object files, we avoid the -+ bra instruction entirely. */ -+#if defined (__mcoldfire__) && !defined (__mcfisab__) -+ lea \addr-.-8,a0 -+ jmp pc@(a0) -+#else -+ bra \addr -+#endif - .endm - --# endif /* !__ID_SHARED_LIBRARY__ */ -+# endif - #endif /* __PIC__ */ - - -@@ -622,6 +676,7 @@ ROUND_TO_MINUS = 3 | round result tow - .globl SYM (__negdf2) - .globl SYM (__cmpdf2) - .globl SYM (__cmpdf2_internal) -+ .hidden SYM (__cmpdf2_internal) - - .text - .even -@@ -2384,7 +2439,7 @@ SYM (__cmpdf2): - movl a6@(16),sp@- - movl a6@(12),sp@- - movl a6@(8),sp@- -- bsr SYM (__cmpdf2_internal) -+ PICCALL SYM (__cmpdf2_internal) - unlk a6 - rts - -@@ -2536,6 +2591,7 @@ ROUND_TO_MINUS = 3 | round result tow - .globl SYM (__negsf2) - .globl SYM (__cmpsf2) - .globl SYM (__cmpsf2_internal) -+ .hidden SYM (__cmpsf2_internal) - - | These are common routines to return and signal exceptions. - -@@ -3790,7 +3846,7 @@ SYM (__cmpsf2): - pea 1 - movl a6@(12),sp@- - movl a6@(8),sp@- -- bsr (__cmpsf2_internal) -+ PICCALL SYM (__cmpsf2_internal) - unlk a6 - rts - -@@ -4063,3 +4119,8 @@ SYM (__lesf2): - unlk a6 - rts - #endif /* L_lesf2 */ -+ -+#if defined (__ELF__) && defined (__linux__) -+ /* Make stack non-executable for ELF linux targets. */ -+ .section .note.GNU-stack,"",@progbits -+#endif ---- a/gcc/config/m68k/m68k-devices.def -+++ b/gcc/config/m68k/m68k-devices.def -@@ -63,13 +63,17 @@ - - There is a bit of duplication between devices in the same family, - but this approach makes scripting easier. We keep each entry on -- a single line for the same reason. */ -+ a single line for the same reason. -+ -+ As the compiler does not (currently) generate MAC or EMAC commands, -+ we do not need separate multilibs for cores that only differ in -+ their MAC functionality. */ - - /* 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) -@@ -77,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) -@@ -86,31 +96,39 @@ M68K_DEVICE ("5206", mcf5206, "5206", - M68K_DEVICE ("5206e", mcf5206e, "5206e", "5206e", cfv2, isa_a, FL_CF_HWDIV | FL_CF_MAC) - M68K_DEVICE ("5207", mcf5207, "5208", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC) - M68K_DEVICE ("5208", mcf5208, "5208", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC) --M68K_DEVICE ("5210a", mcf5210a, "5211a", "5213", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_MAC) --M68K_DEVICE ("5211a", mcf5211a, "5211a", "5213", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_MAC) --M68K_DEVICE ("5211", mcf5211, "5213", "5213", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_MAC) --M68K_DEVICE ("5212", mcf5212, "5213", "5213", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_MAC) --M68K_DEVICE ("5213", mcf5213, "5213", "5213", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_MAC) -+M68K_DEVICE ("5210a", mcf5210a, "5211a", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_MAC) -+M68K_DEVICE ("5211a", mcf5211a, "5211a", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_MAC) -+M68K_DEVICE ("5211", mcf5211, "5213", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_MAC) -+M68K_DEVICE ("5212", mcf5212, "5213", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_MAC) -+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 ("52221", mcf52221, "52223", "5213", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_MAC) --M68K_DEVICE ("52223", mcf52223, "52223", "5213", 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) - M68K_DEVICE ("52231", mcf52231, "52235", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC) - M68K_DEVICE ("52232", mcf52232, "52235", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC) - M68K_DEVICE ("52233", mcf52233, "52235", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC) - M68K_DEVICE ("52234", mcf52234, "52235", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC) - M68K_DEVICE ("52235", mcf52235, "52235", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC) --M68K_DEVICE ("5224", mcf5224, "5225", "5213", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_MAC) --M68K_DEVICE ("5225", mcf5225, "5225", "5213", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_MAC) -+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) - M68K_DEVICE ("5235", mcf5235, "5235", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC) - M68K_DEVICE ("523x", mcf523x, "5235", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC) --M68K_DEVICE ("5249", mcf5249, "5249", "5249", cfv2, isa_a, FL_CF_HWDIV | FL_CF_EMAC) --M68K_DEVICE ("5250", mcf5250, "5250", "5249", cfv2, isa_a, FL_CF_HWDIV | FL_CF_EMAC) --M68K_DEVICE ("5253", mcf5253, "5253", "5249", cfv2, isa_a, FL_CF_HWDIV | FL_CF_EMAC) -+M68K_DEVICE ("5249", mcf5249, "5249", "5206e", cfv2, isa_a, FL_CF_HWDIV | FL_CF_EMAC) -+M68K_DEVICE ("5250", mcf5250, "5250", "5206e", cfv2, isa_a, FL_CF_HWDIV | FL_CF_EMAC) -+M68K_DEVICE ("5253", mcf5253, "5253", "5206e", cfv2, isa_a, FL_CF_HWDIV | FL_CF_EMAC) - M68K_DEVICE ("5270", mcf5270, "5271", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC) - M68K_DEVICE ("5271", mcf5271, "5271", "5208", cfv2, isa_aplus, FL_CF_HWDIV) - M68K_DEVICE ("5272", mcf5272, "5272", "5206e", cfv2, isa_a, FL_CF_HWDIV | FL_CF_MAC) -@@ -122,6 +140,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) -@@ -133,12 +158,12 @@ 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 ("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 -@@ -50,14 +50,19 @@ extern bool strict_low_part_peephole_ok - extern int standard_68881_constant_p (rtx); - extern void print_operand_address (FILE *, rtx); - extern void print_operand (FILE *, rtx, int); -+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_referenced_p (rtx); -+extern bool m68k_tls_mentioned_p (rtx); -+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); -@@ -65,15 +70,19 @@ extern int emit_move_sequence (rtx *, en - extern bool m68k_movem_pattern_p (rtx, rtx, HOST_WIDE_INT, bool); - extern const char *m68k_output_movem (rtx *, rtx, HOST_WIDE_INT, bool); - -+/* 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; - - extern enum attr_opx_type m68k_sched_attr_opx_type (rtx, int); - extern enum attr_opy_type m68k_sched_attr_opy_type (rtx, int); --extern int m68k_sched_attr_size (rtx); -+extern enum attr_size m68k_sched_attr_size (rtx); - extern enum attr_op_mem m68k_sched_attr_op_mem (rtx); - extern enum attr_type m68k_sched_branch_type (rtx); --extern enum attr_type2 m68k_sched_attr_type2 (rtx); - #endif /* HAVE_ATTR_cpu */ - - #endif /* RTX_CODE */ ---- 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[] = - { -@@ -122,12 +123,14 @@ struct m68k_address { - }; - - static int m68k_sched_adjust_cost (rtx, rtx, rtx, int); -+static int m68k_sched_issue_rate (void); - static int m68k_sched_variable_issue (FILE *, int, rtx, int); - static void m68k_sched_md_init_global (FILE *, int, int); - static void m68k_sched_md_finish_global (FILE *, int); - static void m68k_sched_md_init (FILE *, int, int); - static void m68k_sched_dfa_pre_advance_cycle (void); - static void m68k_sched_dfa_post_advance_cycle (void); -+static int m68k_sched_first_cycle_multipass_dfa_lookahead (void); - - static bool m68k_handle_option (size_t, const char *, int); - static rtx find_addr_reg (rtx); -@@ -146,8 +149,9 @@ static bool m68k_save_reg (unsigned int - static bool m68k_ok_for_sibcall_p (tree, tree); - static bool m68k_rtx_costs (rtx, int, int, int *); - #if M68K_HONOR_TARGET_STRICT_ALIGNMENT --static bool m68k_return_in_memory (tree, tree); -+static bool m68k_return_in_memory (const_tree, const_tree); - #endif -+static void m68k_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED; - - - /* Specify the identification number of the library being built */ -@@ -199,6 +203,9 @@ int m68k_last_compare_had_fp_operands; - #undef TARGET_SCHED_ADJUST_COST - #define TARGET_SCHED_ADJUST_COST m68k_sched_adjust_cost - -+#undef TARGET_SCHED_ISSUE_RATE -+#define TARGET_SCHED_ISSUE_RATE m68k_sched_issue_rate -+ - #undef TARGET_SCHED_VARIABLE_ISSUE - #define TARGET_SCHED_VARIABLE_ISSUE m68k_sched_variable_issue - -@@ -217,6 +224,10 @@ int m68k_last_compare_had_fp_operands; - #undef TARGET_SCHED_DFA_POST_ADVANCE_CYCLE - #define TARGET_SCHED_DFA_POST_ADVANCE_CYCLE m68k_sched_dfa_post_advance_cycle - -+#undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD -+#define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD \ -+ m68k_sched_first_cycle_multipass_dfa_lookahead -+ - #undef TARGET_HANDLE_OPTION - #define TARGET_HANDLE_OPTION m68k_handle_option - -@@ -243,6 +254,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 } */ -@@ -382,6 +401,9 @@ enum fpu_type m68k_fpu; - /* The set of FL_* flags that apply to the target processor. */ - unsigned int m68k_cpu_flags; - -+/* The set of FL_* flags that apply to the processor to be tuned for. */ -+unsigned int m68k_tune_flags; -+ - /* Asm templates for calling or jumping to an arbitrary symbolic address, - or NULL if such calls or jumps are not supported. The address is held - in operand 0. */ -@@ -562,13 +584,23 @@ override_options (void) - /* Set the directly-usable versions of the -mcpu and -mtune settings. */ - m68k_cpu = entry->device; - if (m68k_tune_entry) -- m68k_tune = m68k_tune_entry->microarch; -+ { -+ m68k_tune = m68k_tune_entry->microarch; -+ m68k_tune_flags = m68k_tune_entry->flags; -+ } - #ifdef M68K_DEFAULT_TUNE - else if (!m68k_cpu_entry && !m68k_arch_entry) -- m68k_tune = M68K_DEFAULT_TUNE; -+ { -+ enum target_device dev; -+ dev = all_microarchs[M68K_DEFAULT_TUNE].device; -+ m68k_tune_flags = all_devices[dev]->flags; -+ } - #endif - else -- m68k_tune = entry->microarch; -+ { -+ m68k_tune = entry->microarch; -+ m68k_tune_flags = entry->flags; -+ } - - /* Set the type of FPU. */ - m68k_fpu = (!TARGET_HARD_FLOAT ? FPUTYPE_NONE -@@ -666,8 +698,14 @@ override_options (void) - SUBTARGET_OVERRIDE_OPTIONS; - - /* Setup scheduling options. */ -- if (TUNE_CFV2) -- m68k_sched_cpu = CPU_CF_V2; -+ if (TUNE_CFV1) -+ m68k_sched_cpu = CPU_CFV1; -+ else if (TUNE_CFV2) -+ m68k_sched_cpu = CPU_CFV2; -+ else if (TUNE_CFV3) -+ m68k_sched_cpu = CPU_CFV3; -+ else if (TUNE_CFV4) -+ m68k_sched_cpu = CPU_CFV4; - else - { - m68k_sched_cpu = CPU_UNKNOWN; -@@ -675,6 +713,16 @@ override_options (void) - flag_schedule_insns_after_reload = 0; - flag_modulo_sched = 0; - } -+ -+ if (m68k_sched_cpu != CPU_UNKNOWN) -+ { -+ if ((m68k_cpu_flags & (FL_CF_EMAC | FL_CF_EMAC_B)) != 0) -+ m68k_sched_mac = MAC_CF_EMAC; -+ else if ((m68k_cpu_flags & FL_CF_MAC) != 0) -+ m68k_sched_mac = MAC_CF_MAC; -+ else -+ m68k_sched_mac = MAC_NO; -+ } - } - - /* Generate a macro of the form __mPREFIX_cpu_NAME, where PREFIX is the -@@ -1023,6 +1071,11 @@ m68k_expand_prologue (void) - stack_pointer_rtx, - GEN_INT (-fsize_with_regs)))); - } -+ -+ /* If the frame pointer is needed, emit a special barrier that -+ will prevent the scheduler from moving stores to the frame -+ before the stack adjustment. */ -+ emit_insn (gen_stack_tie (stack_pointer_rtx, frame_pointer_rtx)); - } - else if (fsize_with_regs != 0) - m68k_set_frame_related -@@ -1103,8 +1156,7 @@ m68k_expand_prologue (void) - current_frame.reg_mask, true, true)); - } - -- if (flag_pic -- && !TARGET_SEP_DATA -+ if (!TARGET_SEP_DATA - && current_function_uses_pic_offset_table) - insn = emit_insn (gen_load_got (pic_offset_table_rtx)); - } -@@ -1666,15 +1718,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 -@@ -1682,7 +1735,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; - -@@ -1706,7 +1760,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; -@@ -1730,7 +1784,7 @@ m68k_illegitimate_symbolic_constant_p (r - && !offset_within_block_p (base, INTVAL (offset))) - return true; - } -- return false; -+ return m68k_tls_referenced_p (x); - } - - /* Return true if X is a legitimate constant address that can reach -@@ -1758,7 +1812,7 @@ m68k_legitimate_constant_address_p (rtx - return false; - } - -- return true; -+ return !m68k_tls_referenced_p (x); - } - - /* Return true if X is a LABEL_REF for a jump table. Assume that unplaced -@@ -1778,6 +1832,40 @@ m68k_jump_table_ref_p (rtx x) - return x && JUMP_TABLE_DATA_P (x); - } - -+/* Unwrap symbol from UNSPEC_RELOC16 and, if unwrap_reloc32_p, -+ UNSPEC_RELOC32 wrappers. */ -+ -+rtx -+m68k_unwrap_symbol (rtx orig, bool unwrap_reloc32_p) -+{ -+ if (GET_CODE (orig) == CONST) -+ { -+ rtx x; -+ -+ x = XEXP (orig, 0); -+ -+ if (GET_CODE (x) == UNSPEC) -+ { -+ switch (XINT (x, 1)) -+ { -+ case UNSPEC_RELOC16: -+ orig = XVECEXP (x, 0, 0); -+ break; -+ -+ case UNSPEC_RELOC32: -+ if (unwrap_reloc32_p) -+ orig = XVECEXP (x, 0, 0); -+ break; -+ -+ default: -+ break; -+ } -+ } -+ } -+ -+ return orig; -+} -+ - /* Return true if X is a legitimate address for values of mode MODE. - STRICT_P says whether strict checking is needed. If the address - is valid, describe its components in *ADDRESS. */ -@@ -1825,15 +1913,23 @@ 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 -+ if (pic_offset_table_rtx != NULL_RTX - && 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)) -+ && XEXP (x, 0) == pic_offset_table_rtx) - { -- address->base = XEXP (x, 0); -- address->offset = XEXP (x, 1); -- return true; -+ rtx sym; -+ -+ /* As we are processing a PLUS, do not unwrap RELOC32 -+ symbols here; they are invalid in this context. */ -+ sym = m68k_unwrap_symbol (XEXP (x, 1), false); -+ -+ if (GET_CODE (sym) == SYMBOL_REF -+ || GET_CODE (sym) == LABEL_REF) -+ { -+ address->base = XEXP (x, 0); -+ address->offset = XEXP (x, 1); -+ return true; -+ } - } - - /* The ColdFire FPU only accepts addressing modes 2-5. */ -@@ -1858,7 +1954,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; -@@ -1890,7 +1986,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 -@@ -1909,14 +2005,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; -@@ -1978,6 +2074,115 @@ 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); -+ -+ current_function_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. -+ If USE_X_P, use 32-bit relocations, otherwise use 16-bit relocs. -+ 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 @, -+ add.l , */ -+ { -+ /* 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 -+ { -+ /* ??? It would be simplier to wrap 16-bit GOT relocs into UNSPEC too, -+ historically, we don't do this, but I'm not aware of any downside -+ of such a change. */ -+ if (reloc != RELOC_GOT) -+ /* Wrap X into (const (unspec (X))). */ -+ { -+ 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; -+} -+ -+/* 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 -@@ -2029,13 +2234,8 @@ legitimize_pic_address (rtx orig, enum m - { - gcc_assert (reg); - -- pic_ref = gen_rtx_MEM (Pmode, -- gen_rtx_PLUS (Pmode, -- pic_offset_table_rtx, orig)); -- current_function_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) - { -@@ -2046,6 +2246,10 @@ legitimize_pic_address (rtx orig, enum m - && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx) - return orig; - -+ /* Handle the case where we have: const (UNSPEC_RELOC??). */ -+ if (m68k_unwrap_symbol (orig, true) != orig) -+ return orig; -+ - gcc_assert (reg); - - /* legitimize both operands of the PLUS */ -@@ -2056,13 +2260,372 @@ 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_referenced_p_1 (rtx *x, void *data ATTRIBUTE_UNUSED) -+{ -+ if (GET_CODE (*x) == SYMBOL_REF) -+ return SYMBOL_REF_TLS_MODEL (*x) != 0; -+ -+ /* Don't recurse into UNSPEC_TLS looking for TLS symbols; these are -+ TLS offsets, not real symbol references. */ -+ if (GET_CODE (*x) == UNSPEC -+ && (XINT (*x, 1) == UNSPEC_RELOC16 || XINT (*x, 1) == UNSPEC_RELOC32) -+ && TLS_RELOC_P (INTVAL (XVECEXP (*x, 0, 1)))) -+ return -1; -+ -+ return 0; -+} -+ -+/* Return true if X contains any TLS symbol references. */ -+ -+bool -+m68k_tls_referenced_p (rtx x) -+{ -+ if (!TARGET_HAVE_TLS) -+ return false; -+ -+ return for_each_rtx (&x, m68k_tls_referenced_p_1, NULL); -+} -+ -+/* Return true if X is legitimate TLS symbol reference. */ -+ -+bool -+m68k_tls_mentioned_p (rtx x) -+{ -+ switch (GET_CODE (x)) -+ { -+ case CONST: -+ return m68k_tls_mentioned_p (XEXP (x, 0)); -+ -+ case UNSPEC: -+ if ((XINT (x, 1) == UNSPEC_RELOC16 || XINT (x, 1) == UNSPEC_RELOC32) -+ && TLS_RELOC_P (INTVAL (XVECEXP (x, 0, 1)))) -+ return 1; -+ -+ default: -+ return 0; -+ } -+} -+ -+/* Legitimize X. */ -+ -+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) -+ { -+ bool ch; -+ bool copied; -+ -+ ch = (x != oldx); -+ copied = 0; -+ -+ /* 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 = true; } -+ -+ 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); -+ } -+ -+ return x; -+ } -+ -+ if (ch && m68k_legitimate_address_p (mode, x, REG_STRICT_P)) -+ 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; -+ rtx val; -+ -+ temp = gen_reg_rtx (Pmode); -+ 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); -+ -+ return x; -+ } -+ 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; -+ rtx val; -+ -+ temp = gen_reg_rtx (Pmode); -+ 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; -+ } -+ -+#undef COPY_ONCE -+ } -+ -+ return NULL_RTX; -+} -+ - - - #define USE_MOVQ(i) ((unsigned) ((i) + 128) <= 255) -@@ -2175,13 +2738,18 @@ m68k_rtx_costs (rtx x, int code, int out - #define MULL_COST \ - (TUNE_68060 ? 2 \ - : TUNE_68040 ? 5 \ -- : TUNE_CFV2 ? 10 \ -+ : (TUNE_CFV2 && TUNE_EMAC) ? 3 \ -+ : (TUNE_CFV2 && TUNE_MAC) ? 4 \ -+ : TUNE_CFV2 ? 8 \ - : TARGET_COLDFIRE ? 3 : 13) - - #define MULW_COST \ - (TUNE_68060 ? 2 \ - : TUNE_68040 ? 3 \ -- : TUNE_68000_10 || TUNE_CFV2 ? 5 \ -+ : TUNE_68000_10 ? 5 \ -+ : (TUNE_CFV2 && TUNE_EMAC) ? 3 \ -+ : (TUNE_CFV2 && TUNE_MAC) ? 2 \ -+ : TUNE_CFV2 ? 8 \ - : TARGET_COLDFIRE ? 2 : 8) - - #define DIVW_COST \ -@@ -3531,9 +4099,7 @@ notice_update_cc (rtx exp, rtx insn) - case ROTATE: case ROTATERT: - /* These instructions always clear the overflow bit, and set - the carry to the bit shifted out. */ -- /* ??? We don't currently have a way to signal carry not valid, -- nor do we check for it in the branch insns. */ -- CC_STATUS_INIT; -+ cc_status.flags |= CC_OVERFLOW_UNUSABLE | CC_NO_CARRY; - break; - - case PLUS: case MINUS: case MULT: -@@ -3839,7 +4405,75 @@ 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) -+{ -+ switch (reloc) -+ { -+ case RELOC_GOT: -+ return "@GOT"; -+ -+ 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) -+ { -+ switch (XINT (x, 1)) -+ { -+ /* ??? It would be cleaner to wrap normal GOT references into -+ UNSPEC_GOT too, then we won't have to handle them separately -+ in print_operand_address. I'm not aware of any downside of -+ such clean up. */ -+ 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; -+ -+ 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); -+} -+ -+ - /* A C compound statement to output to stdio stream STREAM the - assembler syntax for an instruction operand that is a memory - reference whose address is ADDR. ADDR is an RTL expression. -@@ -3928,7 +4562,9 @@ print_operand_address (FILE *file, rtx a - if (address.offset) - { - output_addr_const (file, address.offset); -- if (flag_pic && address.base == pic_offset_table_rtx) -+ if (flag_pic && address.base == pic_offset_table_rtx -+ && (m68k_unwrap_symbol (address.offset, false) -+ == address.offset)) - { - fprintf (file, "@GOT"); - if (flag_pic == 1 && TARGET_68020) -@@ -4486,7 +5122,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 -@@ -4533,7 +5170,7 @@ m68k_function_value (const_tree valtype, - /* Worker function for TARGET_RETURN_IN_MEMORY. */ - #if M68K_HONOR_TARGET_STRICT_ALIGNMENT - static bool --m68k_return_in_memory (tree type, tree fntype ATTRIBUTE_UNUSED) -+m68k_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED) - { - enum machine_mode mode = TYPE_MODE (type); - -@@ -4555,14 +5192,20 @@ m68k_return_in_memory (tree type, tree f - /* CPU to schedule the program for. */ - enum attr_cpu m68k_sched_cpu; - -+/* MAC to schedule the program for. */ -+enum attr_mac m68k_sched_mac; -+ - /* Operand type. */ - enum attr_op_type - { - /* No operand. */ - OP_TYPE_NONE, - -- /* Register. */ -- OP_TYPE_REG, -+ /* Integer register. */ -+ OP_TYPE_RN, -+ -+ /* FP register. */ -+ OP_TYPE_FPN, - - /* Implicit mem reference (e.g. stack). */ - OP_TYPE_MEM1, -@@ -4589,19 +5232,19 @@ enum attr_op_type - OP_TYPE_IMM_L - }; - --/* True if current insn doesn't have complete pipeline description. */ --static bool sched_guess_p; -- - /* Return type of memory ADDR_RTX refers to. */ - static enum attr_op_type - sched_address_type (enum machine_mode mode, rtx addr_rtx) - { - struct m68k_address address; - -+ if (symbolic_operand (addr_rtx, VOIDmode)) -+ return OP_TYPE_MEM7; -+ - if (!m68k_decompose_address (mode, addr_rtx, - reload_completed, &address)) - { -- gcc_assert (sched_guess_p); -+ gcc_assert (!reload_completed); - /* Reload will likely fix the address to be in the register. */ - return OP_TYPE_MEM234; - } -@@ -4622,12 +5265,42 @@ sched_address_type (enum machine_mode mo - return OP_TYPE_MEM7; - } - --/* Return type of the operand OP. -- If ADDRESS_P is true, return type of memory location OP refers to. */ -+/* Return X or Y (depending on OPX_P) operand of INSN. */ -+static rtx -+sched_get_operand (rtx insn, bool opx_p) -+{ -+ int i; -+ -+ if (recog_memoized (insn) < 0) -+ gcc_unreachable (); -+ -+ extract_constrain_insn_cached (insn); -+ -+ if (opx_p) -+ i = get_attr_opx (insn); -+ else -+ i = get_attr_opy (insn); -+ -+ if (i >= recog_data.n_operands) -+ return NULL; -+ -+ return recog_data.operand[i]; -+} -+ -+/* Return type of INSN's operand X (if OPX_P) or operand Y (if !OPX_P). -+ If ADDRESS_P is true, return type of memory location operand refers to. */ - static enum attr_op_type --sched_operand_type (rtx op, bool address_p) -+sched_attr_op_type (rtx insn, bool opx_p, bool address_p) - { -- gcc_assert (op != NULL_RTX); -+ rtx op; -+ -+ op = sched_get_operand (insn, opx_p); -+ -+ if (op == NULL) -+ { -+ gcc_assert (!reload_completed); -+ return OP_TYPE_RN; -+ } - - if (address_p) - return sched_address_type (QImode, op); -@@ -4636,13 +5309,49 @@ sched_operand_type (rtx op, bool address - return sched_address_type (GET_MODE (op), XEXP (op, 0)); - - if (register_operand (op, VOIDmode)) -- return OP_TYPE_REG; -+ { -+ if ((!reload_completed && FLOAT_MODE_P (GET_MODE (op))) -+ || (reload_completed && FP_REG_P (op))) -+ return OP_TYPE_FPN; -+ -+ return OP_TYPE_RN; -+ } - - if (GET_CODE (op) == CONST_INT) - { -- /* ??? Below condition should probably check if the operation is -- signed or unsigned. */ -- if (IN_RANGE (INTVAL (op), -0x8000, 0x7fff)) -+ int ival; -+ -+ ival = INTVAL (op); -+ -+ /* Check for quick constants. */ -+ switch (get_attr_type (insn)) -+ { -+ case TYPE_ALUQ_L: -+ if (IN_RANGE (ival, 1, 8) || IN_RANGE (ival, -8, -1)) -+ return OP_TYPE_IMM_Q; -+ -+ gcc_assert (!reload_completed); -+ break; -+ -+ case TYPE_MOVEQ_L: -+ if (USE_MOVQ (ival)) -+ return OP_TYPE_IMM_Q; -+ -+ gcc_assert (!reload_completed); -+ break; -+ -+ case TYPE_MOV3Q_L: -+ if (valid_mov3q_const (ival)) -+ return OP_TYPE_IMM_Q; -+ -+ gcc_assert (!reload_completed); -+ break; -+ -+ default: -+ break; -+ } -+ -+ if (IN_RANGE (ival, -0x8000, 0x7fff)) - return OP_TYPE_IMM_W; - - return OP_TYPE_IMM_L; -@@ -4664,7 +5373,8 @@ sched_operand_type (rtx op, bool address - } - } - -- if (symbolic_operand (op, VOIDmode) -+ if (GET_CODE (op) == CONST -+ || symbolic_operand (op, VOIDmode) - || LABEL_P (op)) - { - switch (GET_MODE (op)) -@@ -4679,41 +5389,20 @@ sched_operand_type (rtx op, bool address - 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; - } - } - -- gcc_assert (sched_guess_p); -- -- return OP_TYPE_REG; --} -- --/* Return type of INSN's operand X (if OPX_P) or operand Y (if !OPX_P). -- If ADDRESS_P is true, return type of memory location operand refers to. */ --static enum attr_op_type --sched_attr_op_type (rtx insn, bool opx_p, bool address_p) --{ -- int i; -- -- extract_constrain_insn_cached (insn); -- -- if (opx_p) -- i = get_attr_opx (insn); -- else -- i = get_attr_opy (insn); -+ gcc_assert (!reload_completed); - -- if (i >= recog_data.n_operands) -- { -- gcc_assert (sched_guess_p); -- return OP_TYPE_REG; -- } -+ if (FLOAT_MODE_P (GET_MODE (op))) -+ return OP_TYPE_FPN; - -- return sched_operand_type (recog_data.operand[i], address_p); -+ return OP_TYPE_RN; - } - - /* Implement opx_type attribute. -@@ -4722,12 +5411,13 @@ sched_attr_op_type (rtx insn, bool opx_p - enum attr_opx_type - m68k_sched_attr_opx_type (rtx insn, int address_p) - { -- sched_guess_p = (get_attr_guess (insn) == GUESS_YES); -- - switch (sched_attr_op_type (insn, true, address_p != 0)) - { -- case OP_TYPE_REG: -- return OPX_TYPE_REG; -+ case OP_TYPE_RN: -+ return OPX_TYPE_RN; -+ -+ case OP_TYPE_FPN: -+ return OPX_TYPE_FPN; - - case OP_TYPE_MEM1: - return OPX_TYPE_MEM1; -@@ -4765,12 +5455,13 @@ m68k_sched_attr_opx_type (rtx insn, int - enum attr_opy_type - m68k_sched_attr_opy_type (rtx insn, int address_p) - { -- sched_guess_p = (get_attr_guess (insn) == GUESS_YES); -- - switch (sched_attr_op_type (insn, false, address_p != 0)) - { -- case OP_TYPE_REG: -- return OPY_TYPE_REG; -+ case OP_TYPE_RN: -+ return OPY_TYPE_RN; -+ -+ case OP_TYPE_FPN: -+ return OPY_TYPE_FPN; - - case OP_TYPE_MEM1: - return OPY_TYPE_MEM1; -@@ -4802,17 +5493,21 @@ m68k_sched_attr_opy_type (rtx insn, int - } - } - --/* Return the size of INSN. */ --int --m68k_sched_attr_size (rtx insn) -+/* Return size of INSN as int. */ -+static int -+sched_get_attr_size_int (rtx insn) - { - int size; - -- sched_guess_p = (get_attr_guess (insn) == GUESS_YES); -- -- switch (get_attr_type1 (insn)) -+ switch (get_attr_type (insn)) - { -- case TYPE1_MUL_L: -+ case TYPE_IGNORE: -+ /* There should be no references to m68k_sched_attr_size for 'ignore' -+ instructions. */ -+ gcc_unreachable (); -+ return 0; -+ -+ case TYPE_MUL_L: - size = 2; - break; - -@@ -4824,7 +5519,8 @@ m68k_sched_attr_size (rtx insn) - switch (get_attr_opx_type (insn)) - { - case OPX_TYPE_NONE: -- case OPX_TYPE_REG: -+ case OPX_TYPE_RN: -+ case OPX_TYPE_FPN: - case OPX_TYPE_MEM1: - case OPX_TYPE_MEM234: - case OPY_TYPE_IMM_Q: -@@ -4849,7 +5545,8 @@ m68k_sched_attr_size (rtx insn) - switch (get_attr_opy_type (insn)) - { - case OPY_TYPE_NONE: -- case OPY_TYPE_REG: -+ case OPY_TYPE_RN: -+ case OPY_TYPE_FPN: - case OPY_TYPE_MEM1: - case OPY_TYPE_MEM234: - case OPY_TYPE_IMM_Q: -@@ -4873,7 +5570,7 @@ m68k_sched_attr_size (rtx insn) - - if (size > 3) - { -- gcc_assert (sched_guess_p); -+ gcc_assert (!reload_completed); - - size = 3; - } -@@ -4881,22 +5578,100 @@ m68k_sched_attr_size (rtx insn) - return size; - } - -+/* Return size of INSN as attribute enum value. */ -+enum attr_size -+m68k_sched_attr_size (rtx insn) -+{ -+ switch (sched_get_attr_size_int (insn)) -+ { -+ case 1: -+ return SIZE_1; -+ -+ case 2: -+ return SIZE_2; -+ -+ case 3: -+ return SIZE_3; -+ -+ default: -+ gcc_unreachable (); -+ return 0; -+ } -+} -+ -+/* Return operand X or Y (depending on OPX_P) of INSN, -+ if it is a MEM, or NULL overwise. */ -+static enum attr_op_type -+sched_get_opxy_mem_type (rtx insn, bool opx_p) -+{ -+ if (opx_p) -+ { -+ switch (get_attr_opx_type (insn)) -+ { -+ case OPX_TYPE_NONE: -+ case OPX_TYPE_RN: -+ case OPX_TYPE_FPN: -+ case OPX_TYPE_IMM_Q: -+ case OPX_TYPE_IMM_W: -+ case OPX_TYPE_IMM_L: -+ return OP_TYPE_RN; -+ -+ case OPX_TYPE_MEM1: -+ case OPX_TYPE_MEM234: -+ case OPX_TYPE_MEM5: -+ case OPX_TYPE_MEM7: -+ return OP_TYPE_MEM1; -+ -+ case OPX_TYPE_MEM6: -+ return OP_TYPE_MEM6; -+ -+ default: -+ gcc_unreachable (); -+ return 0; -+ } -+ } -+ else -+ { -+ switch (get_attr_opy_type (insn)) -+ { -+ case OPY_TYPE_NONE: -+ case OPY_TYPE_RN: -+ case OPY_TYPE_FPN: -+ case OPY_TYPE_IMM_Q: -+ case OPY_TYPE_IMM_W: -+ case OPY_TYPE_IMM_L: -+ return OP_TYPE_RN; -+ -+ case OPY_TYPE_MEM1: -+ case OPY_TYPE_MEM234: -+ case OPY_TYPE_MEM5: -+ case OPY_TYPE_MEM7: -+ return OP_TYPE_MEM1; -+ -+ case OPY_TYPE_MEM6: -+ return OP_TYPE_MEM6; -+ -+ default: -+ gcc_unreachable (); -+ return 0; -+ } -+ } -+} -+ - /* Implement op_mem attribute. */ - enum attr_op_mem - m68k_sched_attr_op_mem (rtx insn) - { -- enum attr_opy_mem opy; -- enum attr_opx_mem opx; -+ enum attr_op_type opx; -+ enum attr_op_type opy; - -- sched_guess_p = (get_attr_guess (insn) == GUESS_YES); -+ opx = sched_get_opxy_mem_type (insn, true); -+ opy = sched_get_opxy_mem_type (insn, false); - -- opy = get_attr_opy_mem (insn); -- opx = get_attr_opx_mem (insn); -- -- if (opy == OPY_MEM_R && opx == OPX_MEM_R) -+ if (opy == OP_TYPE_RN && opx == OP_TYPE_RN) - return OP_MEM_00; - -- if (opy == OPY_MEM_R && opx == OPX_MEM_M) -+ if (opy == OP_TYPE_RN && opx == OP_TYPE_MEM1) - { - switch (get_attr_opx_access (insn)) - { -@@ -4910,12 +5685,12 @@ m68k_sched_attr_op_mem (rtx insn) - return OP_MEM_11; - - default: -- gcc_assert (sched_guess_p); -- return OP_MEM_UNKNOWN; -+ gcc_unreachable (); -+ return 0; - } - } - -- if (opy == OPY_MEM_R && opx == OPX_MEM_I) -+ if (opy == OP_TYPE_RN && opx == OP_TYPE_MEM6) - { - switch (get_attr_opx_access (insn)) - { -@@ -4929,15 +5704,15 @@ m68k_sched_attr_op_mem (rtx insn) - return OP_MEM_I1; - - default: -- gcc_assert (sched_guess_p); -- return OP_MEM_UNKNOWN; -+ gcc_unreachable (); -+ return 0; - } - } - -- if (opy == OPY_MEM_M && opx == OPX_MEM_R) -+ if (opy == OP_TYPE_MEM1 && opx == OP_TYPE_RN) - return OP_MEM_10; - -- if (opy == OPY_MEM_M && opx == OPX_MEM_M) -+ if (opy == OP_TYPE_MEM1 && opx == OP_TYPE_MEM1) - { - switch (get_attr_opx_access (insn)) - { -@@ -4945,12 +5720,12 @@ m68k_sched_attr_op_mem (rtx insn) - return OP_MEM_11; - - default: -- gcc_assert (sched_guess_p); -- return OP_MEM_UNKNOWN; -+ gcc_assert (!reload_completed); -+ return OP_MEM_11; - } - } - -- if (opy == OPY_MEM_M && opx == OPX_MEM_I) -+ if (opy == OP_TYPE_MEM1 && opx == OP_TYPE_MEM6) - { - switch (get_attr_opx_access (insn)) - { -@@ -4958,16 +5733,15 @@ m68k_sched_attr_op_mem (rtx insn) - return OP_MEM_1I; - - default: -- gcc_assert (sched_guess_p); -- return OP_MEM_UNKNOWN; -+ gcc_assert (!reload_completed); -+ return OP_MEM_1I; - } - } - -- if (opy == OPY_MEM_I && opx == OPX_MEM_R) -+ if (opy == OP_TYPE_MEM6 && opx == OP_TYPE_RN) - return OP_MEM_I0; - -- -- if (opy == OPY_MEM_I && opx == OPX_MEM_M) -+ if (opy == OP_TYPE_MEM6 && opx == OP_TYPE_MEM1) - { - switch (get_attr_opx_access (insn)) - { -@@ -4975,13 +5749,14 @@ m68k_sched_attr_op_mem (rtx insn) - return OP_MEM_I1; - - default: -- gcc_assert (sched_guess_p); -- return OP_MEM_UNKNOWN; -+ gcc_assert (!reload_completed); -+ return OP_MEM_I1; - } - } - -- gcc_assert (sched_guess_p); -- return OP_MEM_UNKNOWN; -+ gcc_assert (opy == OP_TYPE_MEM6 && opx == OP_TYPE_MEM6); -+ gcc_assert (!reload_completed); -+ return OP_MEM_I1; - } - - /* Jump instructions types. Indexed by INSN_UID. -@@ -5004,66 +5779,21 @@ m68k_sched_branch_type (rtx insn) - return type; - } - --/* Implement type2 attribute. */ --enum attr_type2 --m68k_sched_attr_type2 (rtx insn) -+/* Data for ColdFire V4 index bypass. -+ Producer modifies register that is used as index in consumer with -+ specified scale. */ -+static struct - { -- switch (get_attr_type1 (insn)) -- { -- case TYPE1_ALU_REG1: -- case TYPE1_ALU_REGX: -- return TYPE2_ALU; -- -- case TYPE1_ALU_L: -- case TYPE1_ALUQ_L: -- case TYPE1_CMP_L: -- return TYPE2_ALU_L; -- -- case TYPE1_BCC: -- return TYPE2_BCC; -- -- case TYPE1_BRA: -- return TYPE2_BRA; -- -- case TYPE1_BSR: -- case TYPE1_JSR: -- return TYPE2_CALL; -- -- case TYPE1_JMP: -- return TYPE2_JMP; -- -- case TYPE1_LEA: -- return TYPE2_LEA; -- -- case TYPE1_CLR: -- case TYPE1_MOV3Q_L: -- case TYPE1_MOVE: -- case TYPE1_MOVEQ_L: -- case TYPE1_TST: -- return TYPE2_MOVE; -- -- case TYPE1_MOVE_L: -- case TYPE1_TST_L: -- return TYPE2_MOVE_L; -+ /* Producer instruction. */ -+ rtx pro; - -- case TYPE1_MUL_W: -- case TYPE1_MUL_L: -- return TYPE2_MUL; -+ /* Consumer instruction. */ -+ rtx con; - -- case TYPE1_PEA: -- return TYPE2_PEA; -- -- case TYPE1_RTS: -- return TYPE2_RTS; -- -- case TYPE1_UNLK: -- return TYPE2_UNLK; -- -- default: -- gcc_assert (get_attr_guess (insn) == GUESS_YES); -- return TYPE2_UNKNOWN; -- } --} -+ /* Scale of indexed memory access within consumer. -+ Or zero if bypass should not be effective at the moment. */ -+ int scale; -+} sched_cfv4_bypass_data; - - /* An empty state that is used in m68k_sched_adjust_cost. */ - static state_t sched_adjust_cost_state; -@@ -5080,13 +5810,33 @@ m68k_sched_adjust_cost (rtx insn, rtx li - || recog_memoized (insn) < 0) - return cost; - -+ if (sched_cfv4_bypass_data.scale == 1) -+ /* Handle ColdFire V4 bypass for indexed address with 1x scale. */ -+ { -+ /* haifa-sched.c: insn_cost () calls bypass_p () just before -+ targetm.sched.adjust_cost (). Hence, we can be relatively sure -+ that the data in sched_cfv4_bypass_data is up to date. */ -+ gcc_assert (sched_cfv4_bypass_data.pro == def_insn -+ && sched_cfv4_bypass_data.con == insn); -+ -+ if (cost < 3) -+ cost = 3; -+ -+ sched_cfv4_bypass_data.pro = NULL; -+ sched_cfv4_bypass_data.con = NULL; -+ sched_cfv4_bypass_data.scale = 0; -+ } -+ else -+ gcc_assert (sched_cfv4_bypass_data.pro == NULL -+ && sched_cfv4_bypass_data.con == NULL -+ && sched_cfv4_bypass_data.scale == 0); -+ - /* Don't try to issue INSN earlier than DFA permits. - This is especially useful for instructions that write to memory, - as their true dependence (default) latency is better to be set to 0 - to workaround alias analysis limitations. - This is, in fact, a machine independent tweak, so, probably, - it should be moved to haifa-sched.c: insn_cost (). */ -- - delay = min_insn_conflict_delay (sched_adjust_cost_state, def_insn, insn); - if (delay > cost) - cost = delay; -@@ -5094,237 +5844,147 @@ m68k_sched_adjust_cost (rtx insn, rtx li - return cost; - } - --/* Size of the instruction buffer in words. */ --static int sched_ib_size; -- --/* Number of filled words in the instruction buffer. */ --static int sched_ib_filled; -- --/* An insn that reserves (marks empty) one word in the instruction buffer. */ --static rtx sched_ib_insn; -- --/* ID of memory unit. */ --static int sched_mem_unit_code; -- --/* Implementation of the targetm.sched.variable_issue () hook. -- It is called after INSN was issued. It returns the number of insns -- that can possibly get scheduled on the current cycle. -- It is used here to determine the effect of INSN on the instruction -- buffer. */ -+/* Return maximal number of insns that can be scheduled on a single cycle. */ - static int --m68k_sched_variable_issue (FILE *sched_dump ATTRIBUTE_UNUSED, -- int sched_verbose ATTRIBUTE_UNUSED, -- rtx insn, int can_issue_more) --{ -- int insn_size; -- -- if (recog_memoized (insn) >= 0) -- { -- insn_size = get_attr_size (insn); -- -- gcc_assert (insn_size <= sched_ib_filled); -- -- --can_issue_more; -- } -- else if (GET_CODE (PATTERN (insn)) == ASM_INPUT -- || asm_noperands (PATTERN (insn)) >= 0) -- insn_size = sched_ib_filled; -- else -- insn_size = 0; -- -- sched_ib_filled -= insn_size; -- -- return can_issue_more; --} -- --/* Statistics gatherer. */ -- --typedef enum -- { -- /* Something needs to be done for this insn. */ -- SCHED_DUMP_TODO, -- -- /* Support for this insn is complete. */ -- SCHED_DUMP_DONE, -- -- /* This insn didn't require much effort to support it. */ -- SCHED_DUMP_NOTHING -- } sched_dump_class_def; -- --/* Pointer to functions that classifies insns into 3 above classes. */ --typedef sched_dump_class_def (*sched_dump_class_func_t) (rtx); -- --/* Return statistical type of INSN regarding splits. */ --static sched_dump_class_def --sched_dump_split_class (rtx insn) -+m68k_sched_issue_rate (void) - { -- int i; -- -- i = recog_memoized (insn); -- gcc_assert (i >= 0); -- -- switch (get_attr_split (insn)) -+ switch (m68k_sched_cpu) - { -- case SPLIT_TODO: -- return SCHED_DUMP_TODO; -- -- case SPLIT_DONE: -- return SCHED_DUMP_DONE; -+ case CPU_CFV1: -+ case CPU_CFV2: -+ case CPU_CFV3: -+ return 1; - -- case SPLIT_NOTHING: -- return SCHED_DUMP_NOTHING; -+ case CPU_CFV4: -+ return 2; - - default: - gcc_unreachable (); -+ return 0; - } - } - --/* ID of the guess unit. */ --static int sched_dump_dfa_guess_unit_code; -+/* Maximal length of instruction for current CPU. -+ E.g. it is 3 for any ColdFire core. */ -+static int max_insn_size; - --/* DFA state for use in sched_dump_dfa_class (). */ --static state_t sched_dump_dfa_state; -- --/* Return statistical type of INSN regarding DFA reservations. */ --static sched_dump_class_def --sched_dump_dfa_class (rtx insn) -+/* Data to model instruction buffer of CPU. */ -+struct _sched_ib - { -- int i; -+ /* True if instruction buffer model is modeled for current CPU. */ -+ bool enabled_p; - -- i = recog_memoized (insn); -- gcc_assert (i >= 0 && insn_has_dfa_reservation_p (insn)); -+ /* Size of the instruction buffer in words. */ -+ int size; - -- if (sched_dump_split_class (insn) == SCHED_DUMP_TODO) -- /* Insn is not yet ready for reservations. */ -- return SCHED_DUMP_NOTHING; -+ /* Number of filled words in the instruction buffer. */ -+ int filled; - -- state_reset (sched_dump_dfa_state); -+ /* Additional information about instruction buffer for CPUs that have -+ a buffer of instruction records, rather then a plain buffer -+ of instruction words. */ -+ struct _sched_ib_records -+ { -+ /* Size of buffer in records. */ -+ int n_insns; - -- if (state_transition (sched_dump_dfa_state, insn) >= 0) -- gcc_unreachable (); -+ /* Array to hold data on adjustements made to the size of the buffer. */ -+ int *adjust; - -- if (cpu_unit_reservation_p (sched_dump_dfa_state, -- sched_dump_dfa_guess_unit_code)) -- return SCHED_DUMP_TODO; -+ /* Index of the above array. */ -+ int adjust_index; -+ } records; - -- return SCHED_DUMP_DONE; --} -- --/* Dump statistics on current function into file DUMP_FILENAME and prefix -- each entry with PREFIX. -- Instructions are classified with DUMP_CLASS. */ --static void --m68k_sched_dump (sched_dump_class_func_t dump_class, -- const char *prefix, FILE *dump) --{ -- sbitmap present; -- int *todos; -- int *dones; -- int *nothings; -+ /* An insn that reserves (marks empty) one word in the instruction buffer. */ - rtx insn; -+}; - -- gcc_assert (dump != NULL); -+static struct _sched_ib sched_ib; - -- present = sbitmap_alloc (CODE_FOR_nothing); -- sbitmap_zero (present); -+/* ID of memory unit. */ -+static int sched_mem_unit_code; - -- todos = xcalloc (CODE_FOR_nothing, sizeof (*todos)); -- dones = xcalloc (CODE_FOR_nothing, sizeof (*dones)); -- nothings = xcalloc (CODE_FOR_nothing, sizeof (*nothings)); -+/* Implementation of the targetm.sched.variable_issue () hook. -+ It is called after INSN was issued. It returns the number of insns -+ that can possibly get scheduled on the current cycle. -+ It is used here to determine the effect of INSN on the instruction -+ buffer. */ -+static int -+m68k_sched_variable_issue (FILE *sched_dump ATTRIBUTE_UNUSED, -+ int sched_verbose ATTRIBUTE_UNUSED, -+ rtx insn, int can_issue_more) -+{ -+ int insn_size; - -- /* Gather statistics. */ -- for (insn = get_insns (); insn != NULL_RTX; insn = NEXT_INSN (insn)) -+ if (recog_memoized (insn) >= 0 && get_attr_type (insn) != TYPE_IGNORE) - { -- if (INSN_P (insn) && recog_memoized (insn) >= 0) -+ switch (m68k_sched_cpu) - { -- enum insn_code code; -+ case CPU_CFV1: -+ case CPU_CFV2: -+ insn_size = sched_get_attr_size_int (insn); -+ break; -+ -+ case CPU_CFV3: -+ insn_size = sched_get_attr_size_int (insn); -+ -+ /* ColdFire V3 and V4 cores have instruction buffers that can -+ accumulate up to 8 instructions regardless of instructions' -+ sizes. So we should take care not to "prefetch" 24 one-word -+ or 12 two-words instructions. -+ To model this behavior we temporarily decrease size of the -+ buffer by (max_insn_size - insn_size) for next 7 instructions. */ -+ { -+ int adjust; - -- code = INSN_CODE (insn); -- gcc_assert (code < CODE_FOR_nothing); -+ adjust = max_insn_size - insn_size; -+ sched_ib.size -= adjust; - -- SET_BIT (present, code); -+ if (sched_ib.filled > sched_ib.size) -+ sched_ib.filled = sched_ib.size; - -- switch (dump_class (insn)) -- { -- case SCHED_DUMP_TODO: -- ++todos[code]; -- break; -+ sched_ib.records.adjust[sched_ib.records.adjust_index] = adjust; -+ } - -- case SCHED_DUMP_DONE: -- ++dones[code]; -- break; -+ ++sched_ib.records.adjust_index; -+ if (sched_ib.records.adjust_index == sched_ib.records.n_insns) -+ sched_ib.records.adjust_index = 0; -+ -+ /* Undo adjustement we did 7 instructions ago. */ -+ sched_ib.size -+ += sched_ib.records.adjust[sched_ib.records.adjust_index]; -+ -+ break; -+ -+ case CPU_CFV4: -+ gcc_assert (!sched_ib.enabled_p); -+ insn_size = 0; -+ break; - -- case SCHED_DUMP_NOTHING: -- ++nothings[code]; -- break; -- } -+ default: -+ gcc_unreachable (); - } -- } -- -- /* Print statisctics. */ -- { -- unsigned int i; -- sbitmap_iterator si; -- int total_todo; -- int total_done; -- int total_nothing; -- -- total_todo = 0; -- total_done = 0; -- total_nothing = 0; -- -- EXECUTE_IF_SET_IN_SBITMAP (present, 0, i, si) -- { -- int todo; -- int done; -- int nothing; -- enum insn_code code; -- -- code = (enum insn_code) i; -- -- todo = todos[code]; -- done = dones[code]; -- nothing = nothings[code]; -- -- total_todo += todo; -- total_done += done; -- total_nothing += nothing; - -- if (todo != 0) -- { -- fprintf (dump, -- "%s: %3d: %d / %d / %d ;", -- prefix, code, todo, done, nothing); -- -- { -- const char *name; -- -- name = get_insn_name (code); -- -- if (name != NULL) -- fprintf (dump, " {%s}\n", name); -- else -- fprintf (dump, " {unknown}\n"); -- } -- } -- } -- -- gcc_assert (CODE_FOR_nothing < 999); -+ gcc_assert (insn_size <= sched_ib.filled); -+ --can_issue_more; -+ } -+ else if (GET_CODE (PATTERN (insn)) == ASM_INPUT -+ || asm_noperands (PATTERN (insn)) >= 0) -+ insn_size = sched_ib.filled; -+ else -+ insn_size = 0; - -- fprintf (dump, -- "%s: 999: %d / %d / %d ; {total}\n", -- prefix, total_todo, total_done, total_nothing); -- } -+ sched_ib.filled -= insn_size; - -- free (nothings); -- nothings = NULL; -- free (dones); -- dones = NULL; -- free (todos); -- todos = NULL; -+ return can_issue_more; -+} - -- sbitmap_free (present); -- present = NULL; -+/* Return how many instructions should scheduler lookahead to choose the -+ best one. */ -+static int -+m68k_sched_first_cycle_multipass_dfa_lookahead (void) -+{ -+ return m68k_sched_issue_rate () - 1; - } - - /* Implementation of targetm.sched.md_init_global () hook. -@@ -5350,40 +6010,69 @@ m68k_sched_md_init_global (FILE *sched_d - } - } - -- if (reload_completed && sched_verbose >= 8) -- /* Dump statistics. */ -- { -- m68k_sched_dump (sched_dump_split_class, "m68k_sched_split", -- sched_dump); -+#ifdef ENABLE_CHECKING -+ /* Check that all instructions have DFA reservations and -+ that all instructions can be issued from a clean state. */ -+ { -+ rtx insn; -+ state_t state; - -- sched_dump_dfa_guess_unit_code = get_cpu_unit_code ("cf_v2_guess"); -- sched_dump_dfa_state = alloca (state_size ()); -+ state = alloca (state_size ()); - -- m68k_sched_dump (sched_dump_dfa_class, "m68k_sched_dfa", -- sched_dump); -+ for (insn = get_insns (); insn != NULL_RTX; insn = NEXT_INSN (insn)) -+ { -+ if (INSN_P (insn) && recog_memoized (insn) >= 0) -+ { -+ gcc_assert (insn_has_dfa_reservation_p (insn)); - -- sched_dump_dfa_state = NULL; -- sched_dump_dfa_guess_unit_code = 0; -- } -+ state_reset (state); -+ if (state_transition (state, insn) >= 0) -+ gcc_unreachable (); -+ } -+ } -+ } -+#endif - - /* Setup target cpu. */ -+ -+ /* ColdFire V4 has a set of features to keep its instruction buffer full -+ (e.g., a separate memory bus for instructions) and, hence, we do not model -+ buffer for this CPU. */ -+ sched_ib.enabled_p = (m68k_sched_cpu != CPU_CFV4); -+ - switch (m68k_sched_cpu) - { -- case CPU_CF_V2: -- sched_ib_size = 6; -- sched_mem_unit_code = get_cpu_unit_code ("cf_v2_mem"); -+ case CPU_CFV4: -+ sched_ib.filled = 0; -+ -+ /* FALLTHRU */ -+ -+ case CPU_CFV1: -+ case CPU_CFV2: -+ max_insn_size = 3; -+ sched_ib.records.n_insns = 0; -+ sched_ib.records.adjust = NULL; -+ break; -+ -+ case CPU_CFV3: -+ max_insn_size = 3; -+ sched_ib.records.n_insns = 8; -+ sched_ib.records.adjust = xmalloc (sched_ib.records.n_insns -+ * sizeof (*sched_ib.records.adjust)); - break; - - default: - gcc_unreachable (); - } - -+ sched_mem_unit_code = get_cpu_unit_code ("cf_mem1"); -+ - sched_adjust_cost_state = xmalloc (state_size ()); - state_reset (sched_adjust_cost_state); - - start_sequence (); - emit_insn (gen_ib ()); -- sched_ib_insn = get_insns (); -+ sched_ib.insn = get_insns (); - end_sequence (); - } - -@@ -5392,13 +6081,17 @@ static void - m68k_sched_md_finish_global (FILE *dump ATTRIBUTE_UNUSED, - int verbose ATTRIBUTE_UNUSED) - { -- sched_ib_insn = NULL; -+ sched_ib.insn = NULL; - - free (sched_adjust_cost_state); - sched_adjust_cost_state = NULL; - - sched_mem_unit_code = 0; -- sched_ib_size = 0; -+ -+ free (sched_ib.records.adjust); -+ sched_ib.records.adjust = NULL; -+ sched_ib.records.n_insns = 0; -+ max_insn_size = 0; - - free (sched_branch_type); - sched_branch_type = NULL; -@@ -5412,9 +6105,34 @@ m68k_sched_md_init (FILE *sched_dump ATT - int sched_verbose ATTRIBUTE_UNUSED, - int n_insns ATTRIBUTE_UNUSED) - { -- /* haifa-sched.c: schedule_block () calls advance_cycle () just before -- the first cycle. Workaround that. */ -- sched_ib_filled = -2; -+ switch (m68k_sched_cpu) -+ { -+ case CPU_CFV1: -+ case CPU_CFV2: -+ sched_ib.size = 6; -+ break; -+ -+ case CPU_CFV3: -+ sched_ib.size = sched_ib.records.n_insns * max_insn_size; -+ -+ memset (sched_ib.records.adjust, 0, -+ sched_ib.records.n_insns * sizeof (*sched_ib.records.adjust)); -+ sched_ib.records.adjust_index = 0; -+ break; -+ -+ case CPU_CFV4: -+ gcc_assert (!sched_ib.enabled_p); -+ sched_ib.size = 0; -+ break; -+ -+ default: -+ gcc_unreachable (); -+ } -+ -+ if (sched_ib.enabled_p) -+ /* haifa-sched.c: schedule_block () calls advance_cycle () just before -+ the first cycle. Workaround that. */ -+ sched_ib.filled = -2; - } - - /* Implementation of targetm.sched.dfa_pre_advance_cycle () hook. -@@ -5423,12 +6141,15 @@ m68k_sched_md_init (FILE *sched_dump ATT - static void - m68k_sched_dfa_pre_advance_cycle (void) - { -+ if (!sched_ib.enabled_p) -+ return; -+ - if (!cpu_unit_reservation_p (curr_state, sched_mem_unit_code)) - { -- sched_ib_filled += 2; -+ sched_ib.filled += 2; - -- if (sched_ib_filled > sched_ib_size) -- sched_ib_filled = sched_ib_size; -+ if (sched_ib.filled > sched_ib.size) -+ sched_ib.filled = sched_ib.size; - } - } - -@@ -5441,13 +6162,180 @@ static void - m68k_sched_dfa_post_advance_cycle (void) - { - int i; -- int n; -+ -+ if (!sched_ib.enabled_p) -+ return; - - /* Setup number of prefetched instruction words in the instruction - buffer. */ -- for (i = sched_ib_filled, n = sched_ib_size; i < n; ++i) -+ i = max_insn_size - sched_ib.filled; -+ -+ while (--i >= 0) - { -- if (state_transition (curr_state, sched_ib_insn) >= 0) -+ if (state_transition (curr_state, sched_ib.insn) >= 0) - gcc_unreachable (); - } - } -+ -+/* Return X or Y (depending on OPX_P) operand of INSN, -+ if it is an integer register, or NULL overwise. */ -+static rtx -+sched_get_reg_operand (rtx insn, bool opx_p) -+{ -+ rtx op = NULL; -+ -+ if (opx_p) -+ { -+ if (get_attr_opx_type (insn) == OPX_TYPE_RN) -+ { -+ op = sched_get_operand (insn, true); -+ gcc_assert (op != NULL); -+ -+ if (!reload_completed && !REG_P (op)) -+ return NULL; -+ } -+ } -+ else -+ { -+ if (get_attr_opy_type (insn) == OPY_TYPE_RN) -+ { -+ op = sched_get_operand (insn, false); -+ gcc_assert (op != NULL); -+ -+ if (!reload_completed && !REG_P (op)) -+ return NULL; -+ } -+ } -+ -+ return op; -+} -+ -+/* Return true, if X or Y (depending on OPX_P) operand of INSN -+ is a MEM. */ -+static bool -+sched_mem_operand_p (rtx insn, bool opx_p) -+{ -+ switch (sched_get_opxy_mem_type (insn, opx_p)) -+ { -+ case OP_TYPE_MEM1: -+ case OP_TYPE_MEM6: -+ return true; -+ -+ default: -+ return false; -+ } -+} -+ -+/* Return X or Y (depending on OPX_P) operand of INSN, -+ if it is a MEM, or NULL overwise. */ -+static rtx -+sched_get_mem_operand (rtx insn, bool must_read_p, bool must_write_p) -+{ -+ bool opx_p; -+ bool opy_p; -+ -+ opx_p = false; -+ opy_p = false; -+ -+ if (must_read_p) -+ { -+ opx_p = true; -+ opy_p = true; -+ } -+ -+ if (must_write_p) -+ { -+ opx_p = true; -+ opy_p = false; -+ } -+ -+ if (opy_p && sched_mem_operand_p (insn, false)) -+ return sched_get_operand (insn, false); -+ -+ if (opx_p && sched_mem_operand_p (insn, true)) -+ return sched_get_operand (insn, true); -+ -+ gcc_unreachable (); -+ return NULL; -+} -+ -+/* Return non-zero if PRO modifies register used as part of -+ address in CON. */ -+int -+m68k_sched_address_bypass_p (rtx pro, rtx con) -+{ -+ rtx pro_x; -+ rtx con_mem_read; -+ -+ pro_x = sched_get_reg_operand (pro, true); -+ if (pro_x == NULL) -+ return 0; -+ -+ con_mem_read = sched_get_mem_operand (con, true, false); -+ gcc_assert (con_mem_read != NULL); -+ -+ if (reg_mentioned_p (pro_x, con_mem_read)) -+ return 1; -+ -+ return 0; -+} -+ -+/* Helper function for m68k_sched_indexed_address_bypass_p. -+ if PRO modifies register used as index in CON, -+ return scale of indexed memory access in CON. Return zero overwise. */ -+static int -+sched_get_indexed_address_scale (rtx pro, rtx con) -+{ -+ rtx reg; -+ rtx mem; -+ struct m68k_address address; -+ -+ reg = sched_get_reg_operand (pro, true); -+ if (reg == NULL) -+ return 0; -+ -+ mem = sched_get_mem_operand (con, true, false); -+ gcc_assert (mem != NULL && MEM_P (mem)); -+ -+ if (!m68k_decompose_address (GET_MODE (mem), XEXP (mem, 0), reload_completed, -+ &address)) -+ gcc_unreachable (); -+ -+ if (REGNO (reg) == REGNO (address.index)) -+ { -+ gcc_assert (address.scale != 0); -+ return address.scale; -+ } -+ -+ return 0; -+} -+ -+/* Return non-zero if PRO modifies register used -+ as index with scale 2 or 4 in CON. */ -+int -+m68k_sched_indexed_address_bypass_p (rtx pro, rtx con) -+{ -+ gcc_assert (sched_cfv4_bypass_data.pro == NULL -+ && sched_cfv4_bypass_data.con == NULL -+ && sched_cfv4_bypass_data.scale == 0); -+ -+ switch (sched_get_indexed_address_scale (pro, con)) -+ { -+ case 1: -+ /* We can't have a variable latency bypass, so -+ remember to adjust the insn cost in adjust_cost hook. */ -+ sched_cfv4_bypass_data.pro = pro; -+ sched_cfv4_bypass_data.con = con; -+ sched_cfv4_bypass_data.scale = 1; -+ return 0; -+ -+ case 2: -+ case 4: -+ return 1; -+ -+ default: -+ 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) -@@ -266,6 +267,11 @@ along with GCC; see the file COPYING3. - #define TUNE_CPU32 (m68k_tune == ucpu32) - #define TUNE_CFV1 (m68k_tune == ucfv1) - #define TUNE_CFV2 (m68k_tune == ucfv2) -+#define TUNE_CFV3 (m68k_tune == ucfv3) -+#define TUNE_CFV4 (m68k_tune == ucfv4 || m68k_tune == ucfv4e) -+ -+#define TUNE_MAC ((m68k_tune_flags & FL_CF_MAC) != 0) -+#define TUNE_EMAC ((m68k_tune_flags & FL_CF_EMAC) != 0) - - #define OVERRIDE_OPTIONS override_options() - -@@ -496,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) \ -@@ -665,6 +672,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. */ -@@ -679,9 +690,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) \ -@@ -741,13 +753,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_mentioned_p (X)) - - #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 \ -@@ -760,52 +773,19 @@ __transfer_from_trampoline () \ - /* This address is OK as it stands. */ - #define PIC_CASE_VECTOR_ADDRESS(index) index - --/* 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). -@@ -845,6 +825,14 @@ __transfer_from_trampoline () \ - some or all of the saved cc's so they won't be used. */ - #define NOTICE_UPDATE_CC(EXP,INSN) notice_update_cc (EXP, INSN) - -+/* The shift instructions always clear the overflow bit. */ -+#define CC_OVERFLOW_UNUSABLE 01000 -+ -+/* The shift instructions use the carry bit in a way not compatible with -+ conditional branches. conditions.h uses CC_NO_OVERFLOW for this purpose. -+ Rename it to something more understandable. */ -+#define CC_NO_CARRY CC_NO_OVERFLOW -+ - #define OUTPUT_JUMP(NORMAL, FLOAT, NO_OV) \ - do { if (cc_prev_status.flags & CC_IN_68881) \ - return FLOAT; \ -@@ -1077,6 +1065,12 @@ do { if (cc_prev_status.flags & CC_IN_68 - - #define PRINT_OPERAND_ADDRESS(FILE, ADDR) print_operand_address (FILE, ADDR) - -+#define OUTPUT_ADDR_CONST_EXTRA(FILE, X, FAIL) \ -+do { \ -+ if (! m68k_output_addr_const_extra (FILE, (X))) \ -+ goto FAIL; \ -+} while (0); -+ - /* Values used in the MICROARCH argument to M68K_DEVICE. */ - enum uarch_type - { -@@ -1129,6 +1123,7 @@ extern enum target_device m68k_cpu; - extern enum uarch_type m68k_tune; - extern enum fpu_type m68k_fpu; - extern unsigned int m68k_cpu_flags; -+extern unsigned int m68k_tune_flags; - extern const char *m68k_symbolic_call; - extern const char *m68k_symbolic_jump; - -@@ -1148,4 +1143,7 @@ extern M68K_CONST_METHOD m68k_const_meth - - extern void m68k_emit_move_double (rtx [2]); - -+extern int m68k_sched_address_bypass_p (rtx, rtx); -+extern int m68k_sched_indexed_address_bypass_p (rtx, rtx); -+ - #define CPU_UNITS_QUERY 1 ---- a/gcc/config/m68k/m68k.md -+++ b/gcc/config/m68k/m68k.md -@@ -115,6 +115,9 @@ - (UNSPEC_COS 2) - (UNSPEC_GOT 3) - (UNSPEC_IB 4) -+ (UNSPEC_TIE 5) -+ (UNSPEC_RELOC16 6) -+ (UNSPEC_RELOC32 7) - ]) - - ;; UNSPEC_VOLATILE usage: -@@ -144,197 +147,104 @@ - ;; :::::::::::::::::::: - - ;; Processor type. --(define_attr "cpu" "cf_v2, unknown" (const (symbol_ref "m68k_sched_cpu"))) -+(define_attr "cpu" "cfv1, cfv2, cfv3, cfv4, unknown" -+ (const (symbol_ref "m68k_sched_cpu"))) - --;; Instruction type. --;; Basically, an asm pattern. --(define_attr "type" -- "add_l, addq_l, asr_l, bcc, bclr, bra, bset, bsr, -- clr_b, clr_w, clr_l, cmp_l, -- ext_w, extb_l, ext_l, -- fadd, fcmp, fdiv, ff1, fintrz, fmove, fmul, fsqrt, fsub, ftst, jmp, jsr, -- ib, -- lea, lsr_l, -- move_b, move_w, move_l, moveq_l, mov3q_l, mvs_b, mvs_w, mvz_b, mvz_w, -- muls_w, muls_l, mulu_w, mulu_l, -- neg_l, nop, not_l, -- pea, rts, -- scc, sub_l, subq_l, -- trap, tst_b, tst_l, tst_w, -- unlk, unknown" -- (const_string "unknown")) -+;; MAC type. -+(define_attr "mac" "no, cf_mac, cf_emac" -+ (const (symbol_ref "m68k_sched_mac"))) - - ;; Instruction type for use in scheduling description. - ;; _l and _w suffixes indicate size of the operands of instruction. - ;; alu - usual arithmetic or logic instruction. --;; alu_reg1 - arithmetic or logic instruction with one operand that is --;; a register. --;; alu_regx - arithmetic or logic instruction which has a register for its --;; X operand. - ;; aluq - arithmetic or logic instruction which has a quick immediate (the one - ;; that is encoded in the instruction word) for its Y operand. --;; - corresponding asm instructions. --(define_attr "type1" -- "alu_l, alu_reg1, alu_regx, aluq_l, bcc, bra, bsr, clr, cmp_l, jmp, jsr, lea, -- mov3q_l, move, move_l, moveq_l, mul_l, mul_w, pea, rts, tst, tst_l, unlk, -+;; alux - Arithmetic instruction that uses carry bit (e.g., addx and subx). -+;; bcc - conditional branch. -+;; bitr - bit operation that only updates flags. -+;; bitrw - bit operation that updates flags and output operand. -+;; bra, bsr, clr, cmp, div, ext - corresponding instruction. -+;; falu, fbcc, fcmp, fdiv, fmove, fmul, fneg, fsqrt, ftst - corresponding -+;; instruction. -+;; ib - fake instruction to subscribe slots in ColdFire V1,V2,V3 instruction -+;; buffer. -+;; ignore - fake instruction. -+;; jmp, jsr, lea, link, mov3q, move, moveq, mul - corresponding instruction. -+;; mvsz - mvs or mvz instruction. -+;; neg, nop, pea, rts, scc - corresponding instruction. -+;; shift - arithmetic or logical shift instruction. -+;; trap, tst, unlk - corresponding instruction. -+(define_attr "type" -+ "alu_l,aluq_l,alux_l,bcc,bitr,bitrw,bra,bsr,clr,clr_l,cmp,cmp_l, -+ div_w,div_l,ext, -+ falu,fbcc,fcmp,fdiv,fmove,fmul,fneg,fsqrt,ftst, -+ ib,ignore, -+ jmp,jsr,lea,link,mov3q_l,move,move_l,moveq_l,mul_w,mul_l,mvsz,neg_l,nop, -+ pea,rts,scc,shift, -+ trap,tst,tst_l,unlk, - unknown" -- (cond [(eq_attr "type" "add_l,sub_l") (const_string "alu_l") -- (eq_attr "type" "ext_w,extb_l,ext_l,neg_l,not_l") -- (const_string "alu_reg1") -- (eq_attr "type" "asr_l,lsr_l") (const_string "alu_regx") -- (eq_attr "type" "addq_l,subq_l") (const_string "aluq_l") -- (eq_attr "type" "bcc") (const_string "bcc") -- (eq_attr "type" "bra") (const_string "bra") -- (eq_attr "type" "bsr") (const_string "bsr") -- (eq_attr "type" "clr_b,clr_l,clr_w") (const_string "clr") -- (eq_attr "type" "cmp_l") (const_string "cmp_l") -- (eq_attr "type" "jmp") (const_string "jmp") -- (eq_attr "type" "jsr") (const_string "jsr") -- (eq_attr "type" "lea") (const_string "lea") -- (eq_attr "type" "mov3q_l") (const_string "mov3q_l") -- (eq_attr "type" "move_b,move_w") (const_string "move") -- (eq_attr "type" "move_l") (const_string "move_l") -- (eq_attr "type" "moveq_l") (const_string "moveq_l") -- (eq_attr "type" "muls_l,mulu_l") (const_string "mul_l") -- (eq_attr "type" "muls_w,mulu_w") (const_string "mul_w") -- (eq_attr "type" "pea") (const_string "pea") -- (eq_attr "type" "rts") (const_string "rts") -- (eq_attr "type" "tst_b,tst_w") (const_string "tst") -- (eq_attr "type" "tst_l") (const_string "tst_l") -- (eq_attr "type" "unlk") (const_string "unlk")] -- (const_string "unknown"))) -+ (const_string "unknown")) - - ;; Index of the X or Y operand in recog_data.operand[]. - ;; Should be used only within opx_type and opy_type. - (define_attr "opx" "" (const_int 0)) - (define_attr "opy" "" (const_int 1)) - --;; Type of the X operand. --;; See m68k.c: enum attr_op_type. --(define_attr "opx_type" -- "none, reg, mem1, mem234, mem5, mem6, mem7, imm_q, imm_w, imm_l" -- (cond [(eq_attr "type1" "rts,unlk") (const_string "none") -- (eq_attr "type1" "alu_reg1,alu_regx,lea,moveq_l,mul_l,mul_w") -- (const_string "reg") -- (eq_attr "type1" "pea") (const_string "mem1") -- (eq_attr "type1" "bcc") (const_string "imm_q") -- (eq_attr "type1" "bra,bsr") (const_string "imm_w") -- (eq_attr "type1" "jmp,jsr") -- (symbol_ref "m68k_sched_attr_opx_type (insn, 1)")] -- (symbol_ref "m68k_sched_attr_opx_type (insn, 0)"))) -- - ;; Type of the Y operand. - ;; See m68k.c: enum attr_op_type. - (define_attr "opy_type" -- "none, reg, mem1, mem234, mem5, mem6, mem7, imm_q, imm_w, imm_l" -- (cond [(eq_attr "type1" "alu_reg1,bcc,bra,bsr,clr,jmp,jsr,rts,tst,tst_l, -- unlk") (const_string "none") -- (eq_attr "type1" "mov3q_l,moveq_l,aluq_l") (const_string "imm_q") -- (eq_attr "type1" "lea,pea") -+ "none,Rn,FPn,mem1,mem234,mem5,mem6,mem7,imm_q,imm_w,imm_l" -+ (cond [(eq_attr "type" "ext,fbcc,ftst,neg_l,bcc,bra,bsr,clr,clr_l,ib,ignore, -+ jmp,jsr,nop,rts,scc,trap,tst,tst_l, -+ unlk,unknown") (const_string "none") -+ (eq_attr "type" "lea,pea") - (symbol_ref "m68k_sched_attr_opy_type (insn, 1)")] - (symbol_ref "m68k_sched_attr_opy_type (insn, 0)"))) - --;; Instruction size in words. --(define_attr "size" "" -- (cond [(eq_attr "type1" "alu_reg1,moveq_l,rts,unlk") (const_int 1)] -- (symbol_ref "m68k_sched_attr_size (insn)"))) -+;; Type of the X operand. -+;; See m68k.c: enum attr_op_type. -+(define_attr "opx_type" -+ "none,Rn,FPn,mem1,mem234,mem5,mem6,mem7,imm_q,imm_w,imm_l" -+ (cond [(eq_attr "type" "ib,ignore,nop,rts,trap,unlk, -+ unknown") (const_string "none") -+ (eq_attr "type" "pea") (const_string "mem1") -+ (eq_attr "type" "jmp,jsr") -+ (symbol_ref "m68k_sched_attr_opx_type (insn, 1)")] -+ (symbol_ref "m68k_sched_attr_opx_type (insn, 0)"))) - - ;; Access to the X operand: none, read, write, read/write, unknown. - ;; Access to the Y operand is either none (if opy_type is none) - ;; or read otherwise. --(define_attr "opx_access" "none, r, w, rw, unknown" -- (cond [(eq_attr "type1" "rts,unlk") (const_string "none") -- (eq_attr "type1" "bcc,bra,bsr,cmp_l,jmp,jsr,tst,tst_l") -- (const_string "r") -- (eq_attr "type1" "clr,lea,mov3q_l,move,move_l,moveq_l,pea") -- (const_string "w") -- (eq_attr "type1" "alu_l,alu_reg1,alu_regx,aluq_l") -- (const_string "rw")] -- (const_string "unknown"))) -- --;; Memory relation of operands: --;; r - register or immediate operand --;; m - non-indexed memory location --;; i - indexed memory location -- --(define_attr "opx_mem" "r, m, i, unknown" -- (cond [(eq_attr "opx_type" "none,reg,imm_q,imm_w,imm_l") (const_string "r") -- (eq_attr "opx_type" "mem1,mem234,mem5,mem7") (const_string "m") -- (eq_attr "opx_type" "mem6") (const_string "i")] -- (const_string "unknown"))) -- --(define_attr "opy_mem" "r, m, i, unknown" -- (cond [(eq_attr "opy_type" "none,reg,imm_q,imm_w,imm_l") (const_string "r") -- (eq_attr "opy_type" "mem1,mem234,mem5,mem7") (const_string "m") -- (eq_attr "opy_type" "mem6") (const_string "i")] -- (const_string "unknown"))) -+(define_attr "opx_access" "none, r, w, rw" -+ (cond [(eq_attr "type" "ib,ignore,nop,rts,trap,unlk, -+ unknown") (const_string "none") -+ (eq_attr "type" "bcc,bra,bsr,bitr,cmp,cmp_l,fbcc,fcmp,ftst, -+ jmp,jsr,tst,tst_l") (const_string "r") -+ (eq_attr "type" "clr,clr_l,fneg,fmove,lea, -+ mov3q_l,move,move_l,moveq_l,mvsz, -+ pea,scc") (const_string "w") -+ (eq_attr "type" "alu_l,aluq_l,alux_l,bitrw,div_w,div_l,ext, -+ falu,fdiv,fmul,fsqrt,link,mul_w,mul_l, -+ neg_l,shift") (const_string "rw")] -+ ;; Should never be used. -+ (symbol_ref "(gcc_unreachable (), OPX_ACCESS_NONE)"))) - - ;; Memory accesses of the insn. - ;; 00 - no memory references - ;; 10 - memory is read --;; i10 - indexed memory is read -+;; i0 - indexed memory is read - ;; 01 - memory is written --;; 0i1 - indexed memory is written -+;; 0i - indexed memory is written - ;; 11 - memory is read, memory is written --;; i11 - indexed memory is read, memory is written --;; 1i1 - memory is read, indexed memory is written --;; --;; unknown - should now occur on normal insn. --;; ??? This attribute is implemented in C to spare genattrtab from --;; ??? optimizing it. --(define_attr "op_mem" "00, 10, i0, 01, 0i, 11, i1, 1i, unknown" --; (cond [(and (eq_attr "opy_mem" "r") (eq_attr "opx_mem" "r")) --; (const_string "00") --; --; (and (eq_attr "opy_mem" "r") (eq_attr "opx_mem" "m")) --; (cond [(eq_attr "opx_access" "r") (const_string "10") --; (eq_attr "opx_access" "w") (const_string "01") --; (eq_attr "opx_access" "rw") (const_string "11")] --; (const_string "unknown")) --; --; (and (eq_attr "opy_mem" "r") (eq_attr "opx_mem" "i")) --; (cond [(eq_attr "opx_access" "r") (const_string "i0") --; (eq_attr "opx_access" "w") (const_string "0i") --; (eq_attr "opx_access" "rw") (const_string "i1")] --; (const_string "unknown")) --; --; (and (eq_attr "opy_mem" "m") (eq_attr "opx_mem" "r")) --; (const_string "10") --; --; (and (eq_attr "opy_mem" "m") (eq_attr "opx_mem" "m")) --; (cond [(eq_attr "opx_access" "w") (const_string "11")] --; (const_string "unknown")) --; --; (and (eq_attr "opy_mem" "m") (eq_attr "opx_mem" "i")) --; (cond [(eq_attr "opx_access" "w") (const_string "1i")] --; (const_string "unknown")) --; --; (and (eq_attr "opy_mem" "i") (eq_attr "opx_mem" "r")) --; (const_string "i0") --; --; (and (eq_attr "opy_mem" "i") (eq_attr "opx_mem" "m")) --; (cond [(eq_attr "opx_access" "w") (const_string "i1")] --; (const_string "unknown"))] --; (const_string "unknown")) -+;; i1 - indexed memory is read, memory is written -+;; 1i - memory is read, indexed memory is written -+(define_attr "op_mem" "00, 10, i0, 01, 0i, 11, i1, 1i" - (symbol_ref "m68k_sched_attr_op_mem (insn)")) - --;; Attribute to support partial automata description. --;; This attribute has value 'yes' for instructions that are not --;; fully handled yet. --(define_attr "guess" "yes, no" -- (cond [(ior (eq (symbol_ref "reload_completed") (const_int 0)) -- (eq_attr "type1" "unknown")) -- (const_string "yes")] -- (const_string "no"))) -- --;; Attribute to support statistics gathering. --;; Todo means that insn lacks something to get pipeline description. --;; Done means that insn was transformed to suit pipeline description. --;; Nothing means that insn was originally good enough for scheduling. --(define_attr "split" "todo, done, nothing" -- (if_then_else (eq_attr "type" "unknown") -- (const_string "todo") -- (const_string "nothing"))) -+;; Instruction size in words. -+(define_attr "size" "1,2,3" -+ (symbol_ref "m68k_sched_attr_size (insn)")) -+ - - ;; Mode macros for floating point operations. - ;; Valid floating point modes -@@ -364,8 +274,7 @@ - m68k_emit_move_double (operands); - DONE; - } -- [(set_attr "type" "fmove,*") -- (set_attr "split" "done,*")]) -+ [(set_attr "type" "fmove,*")]) - - (define_insn_and_split "pushdi" - [(set (match_operand:DI 0 "push_operand" "=m") -@@ -445,7 +354,7 @@ - "@ - tst%.l %0 - cmp%.w #0,%0" -- [(set_attr "type" "tst_l,*")]) -+ [(set_attr "type" "tst_l,cmp")]) - - ;; This can't use an address register, because comparisons - ;; with address registers as second operand always test the whole word. -@@ -460,7 +369,7 @@ - (match_operand:HI 0 "nonimmediate_operand" "dm"))] - "" - "tst%.w %0" -- [(set_attr "type" "tst_w")]) -+ [(set_attr "type" "tst")]) - - (define_expand "tstqi" - [(set (cc0) -@@ -473,7 +382,7 @@ - (match_operand:QI 0 "nonimmediate_operand" "dm"))] - "" - "tst%.b %0" -- [(set_attr "type" "tst_b")]) -+ [(set_attr "type" "tst")]) - - (define_expand "tst" - [(set (cc0) -@@ -492,11 +401,12 @@ - if (FP_REG_P (operands[0])) - return "ftst%.x %0"; - return "ftst%. %0"; --}) -+} -+ [(set_attr "type" "ftst")]) - - (define_insn "tst_cf" - [(set (cc0) -- (match_operand:FP 0 "general_operand" "fU"))] -+ (match_operand:FP 0 "general_operand" "fm"))] - "TARGET_COLDFIRE_FPU" - { - cc_status.flags = CC_IN_68881; -@@ -514,15 +424,15 @@ - [(set (cc0) - (compare (match_operand:DI 0 "nonimmediate_operand" "") - (match_operand:DI 1 "general_operand" ""))) -- (clobber (match_dup 2))])] -+ (clobber (match_scratch:DI 2 ""))])] - "" -- "m68k_last_compare_had_fp_operands = 0; operands[2] = gen_reg_rtx (DImode);") -+ "m68k_last_compare_had_fp_operands = 0;") - - (define_insn "" - [(set (cc0) - (compare (match_operand:DI 1 "nonimmediate_operand" "0,d") - (match_operand:DI 2 "general_operand" "d,0"))) -- (clobber (match_operand:DI 0 "register_operand" "=d,d"))] -+ (clobber (match_scratch:DI 0 "=d,d"))] - "" - { - if (rtx_equal_p (operands[0], operands[1])) -@@ -600,7 +510,7 @@ - if ((REG_P (operands[1]) && !ADDRESS_REG_P (operands[1])) - || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM)) - { -- cc_status.flags |= CC_REVERSED; -+ cc_status.flags |= CC_REVERSED; /*|*/ - return "cmp%.w %d0,%d1"; - } - return "cmp%.w %d1,%d0"; -@@ -652,8 +562,8 @@ - - (define_insn "*cmp_cf" - [(set (cc0) -- (compare (match_operand:FP 0 "fp_src_operand" "f,f,U") -- (match_operand:FP 1 "fp_src_operand" "f,U,f")))] -+ (compare (match_operand:FP 0 "fp_src_operand" "f,f,m") -+ (match_operand:FP 1 "fp_src_operand" "f,m,f")))] - "TARGET_COLDFIRE_FPU - && (register_operand (operands[0], mode) - || register_operand (operands[1], mode))" -@@ -792,8 +702,7 @@ - clr%.l %0 - mov3q%.l %1,%- - pea %a1" -- [(set_attr "type" "clr_l,mov3q_l,pea") -- (set_attr "split" "done")]) -+ [(set_attr "type" "clr_l,mov3q_l,pea")]) - - ;This is never used. - ;(define_insn "swapsi" -@@ -813,9 +722,8 @@ - moveq #0,%0 - sub%.l %0,%0 - clr%.l %0" -- [(set_attr "type" "moveq_l,sub_l,clr_l") -- (set_attr "opy_type" "imm_q,reg,*") -- (set_attr "split" "done")]) -+ [(set_attr "type" "moveq_l,alu_l,clr_l") -+ (set_attr "opy" "*,0,*")]) - - ;; Special case of fullword move when source is zero for 68040_60. - ;; On the '040, 'subl an,an' takes 2 clocks while lea takes only 1 -@@ -834,9 +742,7 @@ - return ""; - } - } -- [(set_attr "type" "lea,clr_l") -- (set_attr "opy_type" "imm_w,*") -- (set_attr "split" "done")]) -+ [(set_attr "type" "lea,clr_l")]) - - ;; Special case of fullword move when source is zero. - (define_insn "*movsi_const0" -@@ -846,9 +752,8 @@ - "@ - sub%.l %0,%0 - clr%.l %0" -- [(set_attr "type" "sub_l,clr_l") -- (set_attr "opy_type" "reg,*") -- (set_attr "split" "done")]) -+ [(set_attr "type" "alu_l,clr_l") -+ (set_attr "opy" "0,*")]) - - ;; General case of fullword move. - ;; -@@ -866,7 +771,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_referenced_p (operands[1])) -+ { -+ 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 -@@ -973,11 +912,7 @@ - return ""; - } - } -- [(set_attr "type" "mov3q_l, moveq_l,*, mvz_w, mvs_w, move_l, move_w, pea, lea, move_l, move_l, move_l") -- (set (attr "split") -- (if_then_else (eq_attr "alternative" "2") -- (const_string "*") -- (const_string "done")))]) -+ [(set_attr "type" "mov3q_l,moveq_l,*,mvsz,mvsz,move_l,move,pea,lea,move_l,move_l,move_l")]) - - ;; Special case of fullword move, where we need to get a non-GOT PIC - ;; reference into an address register. -@@ -1066,8 +1001,7 @@ - clr%.b %0 - move%.b %1,%0 - move%.b %1,%0" -- [(set_attr "type" "clr_b,clr_b,move_b,move_b") -- (set_attr "split" "done")]) -+ [(set_attr "type" "clr,clr,move,move")]) - - (define_expand "pushqi1" - [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -2))) -@@ -1162,10 +1096,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" "=rU, f, f,mr,f,r,f --,m") -- (match_operand:SF 1 "general_operand" " f, rU,f,rm,F,F, m --,f"))] -+ [(set (match_operand:SF 0 "nonimmediate_operand" "=rm,f, f,rm,f,r,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) { -@@ -1307,8 +1239,8 @@ - }) - - (define_insn "movdf_cf_hard" -- [(set (match_operand:DF 0 "nonimmediate_operand" "=f, U,r,f,r,r,m,f") -- (match_operand:DF 1 "general_operand" " fU,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]; -@@ -1688,7 +1620,7 @@ - (zero_extend:SI (match_operand:HI 1 "nonimmediate_src_operand" "rmS")))] - "ISA_HAS_MVS_MVZ" - "mvz%.w %1,%0" -- [(set_attr "type" "mvz_w")]) -+ [(set_attr "type" "mvsz")]) - - (define_insn "zero_extendhisi2" - [(set (match_operand:SI 0 "register_operand" "=d") -@@ -1713,7 +1645,7 @@ - (zero_extend:SI (match_operand:QI 1 "nonimmediate_src_operand" "dmS")))] - "ISA_HAS_MVS_MVZ" - "mvz%.b %1,%0" -- [(set_attr "type" "mvz_b")]) -+ [(set_attr "type" "mvsz")]) - - (define_insn "zero_extendqisi2" - [(set (match_operand:SI 0 "register_operand" "=d") -@@ -1794,28 +1726,73 @@ - return "move%.w %1,%2\;ext%.l %2\;smi %0\;ext%.w %0\;ext%.l %0"; - }) - --(define_insn "extendsidi2" -- [(set (match_operand:DI 0 "register_operand" "=d") -- (sign_extend:DI (match_operand:SI 1 "nonimmediate_src_operand" "rm")))] -- "" -+(define_expand "extendsidi2" -+ [(parallel -+ [(set (match_operand:DI 0 "nonimmediate_operand") -+ (sign_extend:DI (match_operand:SI 1 "nonimmediate_src_operand"))) -+ (clobber (match_scratch:SI 2 "")) -+ (clobber (match_scratch:SI 3 ""))])]) -+ -+(define_insn "*extendsidi2_m68k" -+ [(set (match_operand:DI 0 "nonimmediate_operand" "=d,<,o") -+ (sign_extend:DI -+ (match_operand:SI 1 "nonimmediate_src_operand" "rm,rm,rm"))) -+ (clobber (match_scratch:SI 2 "=X,d,d")) -+ (clobber (match_scratch:SI 3 "=X,X,X"))] -+ "!TARGET_COLDFIRE" - { - CC_STATUS_INIT; -+ -+ if (which_alternative == 0) -+ /* Handle alternative 0. */ -+ { -+ if (TARGET_68020 || TARGET_COLDFIRE) -+ return "move%.l %1,%R0\;smi %0\;extb%.l %0"; -+ else -+ return "move%.l %1,%R0\;smi %0\;ext%.w %0\;ext%.l %0"; -+ } -+ -+ /* Handle alternatives 1 and 2. We don't need to adjust address by 4 -+ in alternative 1 because autodecrement will do that for us. */ -+ operands[3] = adjust_address (operands[0], SImode, -+ which_alternative == 1 ? 0 : 4); -+ operands[0] = adjust_address (operands[0], SImode, 0); -+ - if (TARGET_68020 || TARGET_COLDFIRE) -- return "move%.l %1,%R0\;smi %0\;extb%.l %0"; -+ return "move%.l %1,%3\;smi %2\;extb%.l %2\;move%.l %2,%0"; - else -- return "move%.l %1,%R0\;smi %0\;ext%.w %0\;ext%.l %0"; -+ return "move%.l %1,%3\;smi %2\;ext%.w %2\;ext%.l %2\;move%.l %2,%0"; - }) - --(define_insn "*extendsidi2_mem" -- [(set (match_operand:DI 0 "memory_operand" "=o,<") -- (sign_extend:DI (match_operand:SI 1 "nonimmediate_src_operand" "rm,rm"))) -- (clobber (match_scratch:SI 2 "=d,d"))] -- "" -+;; This is a copy of extendsidi2_m68k except for that we can't -+;; fully handle the last alternative on ColdFire. -+;; FIXME: when 'enabled' attribute is available (in GCC 4.4) merge the -+;; two define_insns. -+(define_insn "*extendsidi2_cf" -+ [(set (match_operand:DI 0 "nonimmediate_operand" "=d,<,o") -+ (sign_extend:DI -+ (match_operand:SI 1 "nonimmediate_src_operand" "rm,rm,r"))) -+ (clobber (match_scratch:SI 2 "=X,d,d")) -+ (clobber (match_scratch:SI 3 "=X,X,X"))] -+ "TARGET_COLDFIRE" - { - CC_STATUS_INIT; -+ -+ if (which_alternative == 0) -+ /* Handle alternative 0. */ -+ { -+ if (TARGET_68020 || TARGET_COLDFIRE) -+ return "move%.l %1,%R0\;smi %0\;extb%.l %0"; -+ else -+ return "move%.l %1,%R0\;smi %0\;ext%.w %0\;ext%.l %0"; -+ } -+ -+ /* Handle alternatives 1 and 2. We don't need to adjust address by 4 -+ in alternative 1 because autodecrement will do that for us. */ - operands[3] = adjust_address (operands[0], SImode, -- which_alternative == 0 ? 4 : 0); -+ which_alternative == 1 ? 0 : 4); - operands[0] = adjust_address (operands[0], SImode, 0); -+ - if (TARGET_68020 || TARGET_COLDFIRE) - return "move%.l %1,%3\;smi %2\;extb%.l %2\;move%.l %2,%0"; - else -@@ -1866,7 +1843,7 @@ - (match_operand:HI 1 "nonimmediate_src_operand" "rmS")))] - "ISA_HAS_MVS_MVZ" - "mvs%.w %1,%0" -- [(set_attr "type" "mvs_w")]) -+ [(set_attr "type" "mvsz")]) - - (define_insn "*68k_extendhisi2" - [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,a") -@@ -1876,14 +1853,14 @@ - "@ - ext%.l %0 - move%.w %1,%0" -- [(set_attr "type" "ext_l,move_w")]) -+ [(set_attr "type" "ext,move")]) - - (define_insn "extendqihi2" - [(set (match_operand:HI 0 "nonimmediate_operand" "=d") - (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0")))] - "" - "ext%.w %0" -- [(set_attr "type" "ext_w")]) -+ [(set_attr "type" "ext")]) - - (define_expand "extendqisi2" - [(set (match_operand:SI 0 "nonimmediate_operand" "") -@@ -1896,14 +1873,14 @@ - (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "rms")))] - "ISA_HAS_MVS_MVZ" - "mvs%.b %1,%0" -- [(set_attr "type" "mvs_b")]) -+ [(set_attr "type" "mvsz")]) - - (define_insn "*68k_extendqisi2" - [(set (match_operand:SI 0 "nonimmediate_operand" "=d") - (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0")))] - "TARGET_68020 || (TARGET_COLDFIRE && !ISA_HAS_MVS_MVZ)" - "extb%.l %0" -- [(set_attr "type" "extb_l")]) -+ [(set_attr "type" "ext")]) - - ;; Conversions between float and double. - -@@ -1946,7 +1923,7 @@ - (define_insn "extendsfdf2_cf" - [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f") - (float_extend:DF -- (match_operand:SF 1 "general_operand" "f,U")))] -+ (match_operand:SF 1 "general_operand" "f,m")))] - "TARGET_COLDFIRE_FPU" - { - if (FP_REG_P (operands[0]) && FP_REG_P (operands[1])) -@@ -1986,9 +1963,9 @@ - }) - - (define_insn "truncdfsf2_cf" -- [(set (match_operand:SF 0 "nonimmediate_operand" "=f,dU") -+ [(set (match_operand:SF 0 "nonimmediate_operand" "=f,dm") - (float_truncate:SF -- (match_operand:DF 1 "general_operand" "U,f")))] -+ (match_operand:DF 1 "general_operand" "m,f")))] - "TARGET_COLDFIRE_FPU" - "@ - fsmove%.d %1,%0 -@@ -2021,7 +1998,8 @@ - [(set (match_operand:FP 0 "nonimmediate_operand" "=f") - (float:FP (match_operand:SI 1 "general_operand" "dmi")))] - "TARGET_68881" -- "fmove%.l %1,%0") -+ "fmove%.l %1,%0" -+ [(set_attr "type" "fmove")]) - - (define_insn "floatsi2_cf" - [(set (match_operand:FP 0 "nonimmediate_operand" "=f") -@@ -2128,18 +2106,19 @@ - if (FP_REG_P (operands[1])) - return "fintrz%.x %f1,%0"; - return "fintrz%. %f1,%0"; --}) -+} -+ [(set_attr "type" "falu")]) - - (define_insn "ftrunc2_cf" - [(set (match_operand:FP 0 "nonimmediate_operand" "=f") -- (fix:FP (match_operand:FP 1 "general_operand" "fU")))] -+ (fix:FP (match_operand:FP 1 "general_operand" "fm")))] - "TARGET_COLDFIRE_FPU" - { - if (FP_REG_P (operands[1])) - return "fintrz%.d %f1,%0"; - return "fintrz%. %f1,%0"; - } -- [(set_attr "type" "fintrz")]) -+ [(set_attr "type" "falu")]) - - ;; Convert a float whose value is an integer - ;; to an actual integer. Second stage of converting float to integer type. -@@ -2153,7 +2132,8 @@ - [(set (match_operand:QI 0 "nonimmediate_operand" "=dm") - (fix:QI (match_operand:FP 1 "general_operand" "f")))] - "TARGET_68881" -- "fmove%.b %1,%0") -+ "fmove%.b %1,%0" -+ [(set_attr "type" "fmove")]) - - (define_insn "fixqi2_cf" - [(set (match_operand:QI 0 "nonimmediate_operand" "=dU") -@@ -2172,7 +2152,8 @@ - [(set (match_operand:HI 0 "nonimmediate_operand" "=dm") - (fix:HI (match_operand:FP 1 "general_operand" "f")))] - "TARGET_68881" -- "fmove%.w %1,%0") -+ "fmove%.w %1,%0" -+ [(set_attr "type" "fmove")]) - - (define_insn "fixhi2_cf" - [(set (match_operand:HI 0 "nonimmediate_operand" "=dU") -@@ -2191,7 +2172,8 @@ - [(set (match_operand:SI 0 "nonimmediate_operand" "=dm") - (fix:SI (match_operand:FP 1 "general_operand" "f")))] - "TARGET_68881" -- "fmove%.l %1,%0") -+ "fmove%.l %1,%0" -+ [(set_attr "type" "fmove")]) - - (define_insn "fixsi2_cf" - [(set (match_operand:SI 0 "nonimmediate_operand" "=dU") -@@ -2297,7 +2279,7 @@ - operands[1] = adjust_address (operands[1], SImode, 4); - return "add%.l %1,%0"; - } -- [(set_attr "type" "add_l")]) -+ [(set_attr "type" "alu_l")]) - - (define_insn "adddi3" - [(set (match_operand:DI 0 "nonimmediate_operand" "=o<>,d,d,d") -@@ -2376,12 +2358,44 @@ - } - }) - --(define_insn "addsi_lshrsi_31" -+(define_expand "addsi_lshrsi_31" -+ [(set (match_operand:SI 0 "nonimmediate_operand") -+ (plus:SI (lshiftrt:SI (match_operand:SI 1 "general_operand") -+ (const_int 31)) -+ (match_dup 1)))]) -+ -+(define_insn "*addsi_lshrsi_31_m68k" - [(set (match_operand:SI 0 "nonimmediate_operand" "=dm") -- (plus:SI (lshiftrt:SI (match_operand:SI 1 "general_operand" "rm") -- (const_int 31)) -- (match_dup 1)))] -- "" -+ (plus:SI (lshiftrt:SI (match_operand:SI 1 "general_operand" "rm") -+ (const_int 31)) -+ (match_dup 1)))] -+ "!TARGET_COLDFIRE" -+{ -+ operands[2] = operands[0]; -+ operands[3] = gen_label_rtx(); -+ if (GET_CODE (operands[0]) == MEM) -+ { -+ if (GET_CODE (XEXP (operands[0], 0)) == POST_INC) -+ operands[0] = gen_rtx_MEM (SImode, XEXP (XEXP (operands[0], 0), 0)); -+ else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC) -+ operands[2] = gen_rtx_MEM (SImode, XEXP (XEXP (operands[0], 0), 0)); -+ } -+ output_asm_insn ("move%.l %1,%0", operands); -+ output_asm_insn ("jpl %l3", operands); -+ output_asm_insn ("addq%.l #1,%2", operands); -+ (*targetm.asm_out.internal_label) (asm_out_file, "L", -+ CODE_LABEL_NUMBER (operands[3])); -+ return ""; -+}) -+ -+;; FIXME: When 'enabled' attribute is available (in GCC 4.4) merge -+;; this with previous pattern. -+(define_insn "*addsi_lshrsi_31_cf" -+ [(set (match_operand:SI 0 "nonimmediate_operand" "=dm,d") -+ (plus:SI (lshiftrt:SI (match_operand:SI 1 "general_operand" "r,rm") -+ (const_int 31)) -+ (match_dup 1)))] -+ "TARGET_COLDFIRE" - { - operands[2] = operands[0]; - operands[3] = gen_label_rtx(); -@@ -2421,9 +2435,9 @@ - "* return output_addsi3 (operands);") - - (define_insn_and_split "*addsi3_5200" -- [(set (match_operand:SI 0 "nonimmediate_operand" "=mr,mr,m,r, ?a,?a,?a,?a") -- (plus:SI (match_operand:SI 1 "general_operand" "%0, 0, 0,0, a, a, r, a") -- (match_operand:SI 2 "general_src_operand" " I, L, 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) -@@ -2435,21 +2449,22 @@ - operands[2] = GEN_INT (- INTVAL (operands[2])); - return "subq%.l %2,%0"; - -- case 2: - case 3: -+ case 4: - return "add%.l %2,%0"; - -- case 4: -+ case 5: - /* move%.l %2,%0\n\tadd%.l %1,%0 */ - return "#"; - -- case 5: -+ case 6: - return MOTOROLA ? "lea (%1,%2.l),%0" : "lea %1@(0,%2:l),%0"; - -- case 6: -+ case 7: - return MOTOROLA ? "lea (%2,%1.l),%0" : "lea %2@(0,%1:l),%0"; - -- case 7: -+ case 2: -+ case 8: - return MOTOROLA ? "lea (%c2,%1),%0" : "lea %1@(%c2),%0"; - - default: -@@ -2457,17 +2472,16 @@ - return ""; - } - } -- "&& reload_completed && (extract_constrain_insn_cached (insn), which_alternative == 4) && !operands_match_p (operands[0], operands[1])" -+ "&& reload_completed && (extract_constrain_insn_cached (insn), which_alternative == 5) && !operands_match_p (operands[0], operands[1])" - [(set (match_dup 0) - (match_dup 2)) - (set (match_dup 0) - (plus:SI (match_dup 0) - (match_dup 1)))] - "" -- [(set_attr "type" "addq_l,subq_l,add_l,add_l,*,lea,lea,lea") -- (set_attr "opy" "2,2,2,2,*,*,*,*") -- (set_attr "opy_type" "*,*,*,*,*,mem6,mem6,mem5") -- (set_attr "split" "done,done,done,done,*,done,done,done")]) -+ [(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") -@@ -2711,21 +2725,27 @@ - (plus:FP (float:FP (match_operand:SI 2 "general_operand" "dmi")) - (match_operand:FP 1 "general_operand" "0")))] - "TARGET_68881" -- "fadd%.l %2,%0") -+ "fadd%.l %2,%0" -+ [(set_attr "type" "falu") -+ (set_attr "opy" "2")]) - - (define_insn "add3_floathi_68881" - [(set (match_operand:FP 0 "nonimmediate_operand" "=f") - (plus:FP (float:FP (match_operand:HI 2 "general_operand" "dmn")) - (match_operand:FP 1 "general_operand" "0")))] - "TARGET_68881" -- "fadd%.w %2,%0") -+ "fadd%.w %2,%0" -+ [(set_attr "type" "falu") -+ (set_attr "opy" "2")]) - - (define_insn "add3_floatqi_68881" - [(set (match_operand:FP 0 "nonimmediate_operand" "=f") - (plus:FP (float:FP (match_operand:QI 2 "general_operand" "dmn")) - (match_operand:FP 1 "general_operand" "0")))] - "TARGET_68881" -- "fadd%.b %2,%0") -+ "fadd%.b %2,%0" -+ [(set_attr "type" "falu") -+ (set_attr "opy" "2")]) - - (define_insn "add3_68881" - [(set (match_operand:FP 0 "nonimmediate_operand" "=f") -@@ -2736,19 +2756,22 @@ - if (FP_REG_P (operands[2])) - return "fadd%.x %2,%0"; - return "fadd%. %f2,%0"; --}) -+} -+ [(set_attr "type" "falu") -+ (set_attr "opy" "2")]) - - (define_insn "add3_cf" - [(set (match_operand:FP 0 "nonimmediate_operand" "=f") - (plus:FP (match_operand:FP 1 "general_operand" "%0") -- (match_operand:FP 2 "general_operand" "fU")))] -+ (match_operand:FP 2 "general_operand" "fm")))] - "TARGET_COLDFIRE_FPU" - { - if (FP_REG_P (operands[2])) - return "fadd%.d %2,%0"; - return "fadd%. %2,%0"; - } -- [(set_attr "type" "fadd")]) -+ [(set_attr "type" "falu") -+ (set_attr "opy" "2")]) - - ;; subtract instructions - -@@ -2783,7 +2806,7 @@ - operands[1] = adjust_address (operands[1], SImode, 4); - return "sub%.l %1,%0"; - } -- [(set_attr "type" "sub_l")]) -+ [(set_attr "type" "alu_l")]) - - (define_insn "subdi3" - [(set (match_operand:DI 0 "nonimmediate_operand" "=o<>,d,d,d") -@@ -2874,7 +2897,7 @@ - sub%.l %2,%0 - sub%.l %2,%0 - sub%.l %2,%0" -- [(set_attr "type" "subq_l,sub_l,sub_l,sub_l") -+ [(set_attr "type" "aluq_l,alu_l,alu_l,alu_l") - (set_attr "opy" "2")]) - - (define_insn "" -@@ -2925,21 +2948,27 @@ - (minus:FP (match_operand:FP 1 "general_operand" "0") - (float:FP (match_operand:SI 2 "general_operand" "dmi"))))] - "TARGET_68881" -- "fsub%.l %2,%0") -+ "fsub%.l %2,%0" -+ [(set_attr "type" "falu") -+ (set_attr "opy" "2")]) - - (define_insn "sub3_floathi_68881" - [(set (match_operand:FP 0 "nonimmediate_operand" "=f") - (minus:FP (match_operand:FP 1 "general_operand" "0") - (float:FP (match_operand:HI 2 "general_operand" "dmn"))))] - "TARGET_68881" -- "fsub%.w %2,%0") -+ "fsub%.w %2,%0" -+ [(set_attr "type" "falu") -+ (set_attr "opy" "2")]) - - (define_insn "sub3_floatqi_68881" - [(set (match_operand:FP 0 "nonimmediate_operand" "=f") - (minus:FP (match_operand:FP 1 "general_operand" "0") - (float:FP (match_operand:QI 2 "general_operand" "dmn"))))] - "TARGET_68881" -- "fsub%.b %2,%0") -+ "fsub%.b %2,%0" -+ [(set_attr "type" "falu") -+ (set_attr "opy" "2")]) - - (define_insn "sub3_68881" - [(set (match_operand:FP 0 "nonimmediate_operand" "=f") -@@ -2950,19 +2979,22 @@ - if (FP_REG_P (operands[2])) - return "fsub%.x %2,%0"; - return "fsub%. %f2,%0"; --}) -+} -+ [(set_attr "type" "falu") -+ (set_attr "opy" "2")]) - - (define_insn "sub3_cf" - [(set (match_operand:FP 0 "nonimmediate_operand" "=f") - (minus:FP (match_operand:FP 1 "general_operand" "0") -- (match_operand:FP 2 "general_operand" "fU")))] -+ (match_operand:FP 2 "general_operand" "fm")))] - "TARGET_COLDFIRE_FPU" - { - if (FP_REG_P (operands[2])) - return "fsub%.d %2,%0"; - return "fsub%. %2,%0"; - } -- [(set_attr "type" "fsub")]) -+ [(set_attr "type" "falu") -+ (set_attr "opy" "2")]) - - ;; multiply instructions - -@@ -2974,7 +3006,7 @@ - { - return MOTOROLA ? "muls%.w %2,%0" : "muls %2,%0"; - } -- [(set_attr "type" "muls_w") -+ [(set_attr "type" "mul_w") - (set_attr "opy" "2")]) - - (define_insn "mulhisi3" -@@ -2987,7 +3019,7 @@ - { - return MOTOROLA ? "muls%.w %2,%0" : "muls %2,%0"; - } -- [(set_attr "type" "muls_w") -+ [(set_attr "type" "mul_w") - (set_attr "opy" "2")]) - - (define_insn "*mulhisisi3_s" -@@ -2999,7 +3031,7 @@ - { - return MOTOROLA ? "muls%.w %2,%0" : "muls %2,%0"; - } -- [(set_attr "type" "muls_w") -+ [(set_attr "type" "mul_w") - (set_attr "opy" "2")]) - - (define_expand "mulsi3" -@@ -3016,7 +3048,7 @@ - - "TARGET_68020" - "muls%.l %2,%0" -- [(set_attr "type" "muls_l") -+ [(set_attr "type" "mul_l") - (set_attr "opy" "2")]) - - (define_insn "*mulsi3_cf" -@@ -3025,7 +3057,7 @@ - (match_operand:SI 2 "general_operand" "d")))] - "TARGET_COLDFIRE" - "muls%.l %2,%0" -- [(set_attr "type" "muls_l") -+ [(set_attr "type" "mul_l") - (set_attr "opy" "2")]) - - (define_insn "umulhisi3" -@@ -3038,7 +3070,7 @@ - { - return MOTOROLA ? "mulu%.w %2,%0" : "mulu %2,%0"; - } -- [(set_attr "type" "mulu_w") -+ [(set_attr "type" "mul_w") - (set_attr "opy" "2")]) - - (define_insn "*mulhisisi3_z" -@@ -3050,7 +3082,7 @@ - { - return MOTOROLA ? "mulu%.w %2,%0" : "mulu %2,%0"; - } -- [(set_attr "type" "mulu_w") -+ [(set_attr "type" "mul_w") - (set_attr "opy" "2")]) - - ;; We need a separate DEFINE_EXPAND for u?mulsidi3 to be able to use the -@@ -3235,7 +3267,9 @@ - return TARGET_68040 - ? "fmul%.l %2,%0" - : "fmul%.l %2,%0"; --}) -+} -+ [(set_attr "type" "fmul") -+ (set_attr "opy" "2")]) - - (define_insn "mul3_floathi_68881" - [(set (match_operand:FP 0 "nonimmediate_operand" "=f") -@@ -3246,7 +3280,9 @@ - return TARGET_68040 - ? "fmul%.w %2,%0" - : "fmul%.w %2,%0"; --}) -+} -+ [(set_attr "type" "fmul") -+ (set_attr "opy" "2")]) - - (define_insn "mul3_floatqi_68881" - [(set (match_operand:FP 0 "nonimmediate_operand" "=f") -@@ -3257,7 +3293,9 @@ - return TARGET_68040 - ? "fmul%.b %2,%0" - : "fmul%.b %2,%0"; --}) -+} -+ [(set_attr "type" "fmul") -+ (set_attr "opy" "2")]) - - (define_insn "muldf_68881" - [(set (match_operand:DF 0 "nonimmediate_operand" "=f") -@@ -3304,14 +3342,15 @@ - (define_insn "fmul3_cf" - [(set (match_operand:FP 0 "nonimmediate_operand" "=f") - (mult:FP (match_operand:FP 1 "general_operand" "%0") -- (match_operand:FP 2 "general_operand" "fU")))] -+ (match_operand:FP 2 "general_operand" "fm")))] - "TARGET_COLDFIRE_FPU" - { - if (FP_REG_P (operands[2])) - return "fmul%.d %2,%0"; - return "fmul%. %2,%0"; - } -- [(set_attr "type" "fmul")]) -+ [(set_attr "type" "fmul") -+ (set_attr "opy" "2")]) - - ;; divide instructions - -@@ -3373,14 +3412,15 @@ - (define_insn "div3_cf" - [(set (match_operand:FP 0 "nonimmediate_operand" "=f") - (div:FP (match_operand:FP 1 "general_operand" "0") -- (match_operand:FP 2 "general_operand" "fU")))] -+ (match_operand:FP 2 "general_operand" "fm")))] - "TARGET_COLDFIRE_FPU" - { - if (FP_REG_P (operands[2])) - return "fdiv%.d %2,%0"; - return "fdiv%. %2,%0"; - } -- [(set_attr "type" "fdiv")]) -+ [(set_attr "type" "fdiv") -+ (set_attr "opy" "2")]) - - ;; Remainder instructions. - -@@ -3408,7 +3448,9 @@ - return "rems%.l %2,%3:%0"; - else - return "rems%.l %2,%3:%0\;divs%.l %2,%0"; --}) -+} -+ [(set_attr "type" "div_l") -+ (set_attr "opy" "2")]) - - (define_insn "" - [(set (match_operand:SI 0 "nonimmediate_operand" "=d") -@@ -3448,7 +3490,9 @@ - return "remu%.l %2,%3:%0"; - else - return "remu%.l %2,%3:%0\;divu%.l %2,%0"; --}) -+} -+ [(set_attr "type" "div_l") -+ (set_attr "opy" "2")]) - - (define_insn "" - [(set (match_operand:SI 0 "nonimmediate_operand" "=d") -@@ -4216,7 +4260,7 @@ - - (define_insn "neg2_cf" - [(set (match_operand:FP 0 "nonimmediate_operand" "=f,d") -- (neg:FP (match_operand:FP 1 "general_operand" "fU,0")))] -+ (neg:FP (match_operand:FP 1 "general_operand" "fm,0")))] - "TARGET_COLDFIRE_FPU" - { - if (DATA_REG_P (operands[0])) -@@ -4250,13 +4294,14 @@ - - (define_insn "sqrt2_cf" - [(set (match_operand:FP 0 "nonimmediate_operand" "=f") -- (sqrt:FP (match_operand:FP 1 "general_operand" "fU")))] -+ (sqrt:FP (match_operand:FP 1 "general_operand" "fm")))] - "TARGET_COLDFIRE_FPU" - { - if (FP_REG_P (operands[1])) - return "fsqrt%.d %1,%0"; - return "fsqrt%. %1,%0"; --}) -+} -+ [(set_attr "type" "fsqrt")]) - ;; Absolute value instructions - ;; If using software floating point, just zero the sign bit. - -@@ -4368,7 +4413,7 @@ - - (define_insn "abs2_cf" - [(set (match_operand:FP 0 "nonimmediate_operand" "=f,d") -- (abs:FP (match_operand:FP 1 "general_operand" "fU,0")))] -+ (abs:FP (match_operand:FP 1 "general_operand" "fm,0")))] - "TARGET_COLDFIRE_FPU" - { - if (DATA_REG_P (operands[0])) -@@ -4379,7 +4424,8 @@ - if (FP_REG_P (operands[1])) - return "fabs%.d %1,%0"; - return "fabs%. %1,%0"; --}) -+} -+ [(set_attr "type" "bitrw,fneg")]) - - ;; bit indexing instructions - -@@ -4389,7 +4435,7 @@ - (clz:SI (match_operand:SI 1 "register_operand" "0")))] - "ISA_HAS_FF1" - "ff1 %0" -- [(set_attr "type" "ff1")]) -+ [(set_attr "type" "ext")]) - - ;; one complement instructions - -@@ -4433,7 +4479,7 @@ - (not:SI (match_operand:SI 1 "general_operand" "0")))] - "TARGET_COLDFIRE" - "not%.l %0" -- [(set_attr "type" "not_l")]) -+ [(set_attr "type" "neg_l")]) - - (define_insn "one_cmplhi2" - [(set (match_operand:HI 0 "nonimmediate_operand" "=dm") -@@ -4785,7 +4831,7 @@ - operands[1] = adjust_address (operands[1], HImode, 2); - return "move%.w %1,%0"; - } -- [(set_attr "type" "move_w")]) -+ [(set_attr "type" "move")]) - - (define_insn "subregsi1ashrdi_const32" - [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") -@@ -4965,7 +5011,7 @@ - (match_operand:SI 2 "general_operand" "dI")))] - "" - "asr%.l %2,%0" -- [(set_attr "type" "asr_l") -+ [(set_attr "type" "shift") - (set_attr "opy" "2")]) - - (define_insn "ashrhi3" -@@ -5261,7 +5307,7 @@ - (match_operand:SI 2 "general_operand" "dI")))] - "" - "lsr%.l %2,%0" -- [(set_attr "type" "lsr_l") -+ [(set_attr "type" "shift") - (set_attr "opy" "2")]) - - (define_insn "lshrhi3" -@@ -5420,7 +5466,7 @@ - CC_STATUS_INIT; - return "bset %1,%0"; - } -- [(set_attr "type" "bset")]) -+ [(set_attr "type" "bitrw")]) - - ;; set bit, bit number is (sign/zero)_extended from HImode/QImode - (define_insn "*bsetmemqi_ext" -@@ -5434,7 +5480,7 @@ - CC_STATUS_INIT; - return "bset %1,%0"; - } -- [(set_attr "type" "bset")]) -+ [(set_attr "type" "bitrw")]) - - ;; clear bit, bit number is int - (define_insn "bclrmemqi" -@@ -5448,7 +5494,7 @@ - CC_STATUS_INIT; - return "bclr %1,%0"; - } -- [(set_attr "type" "bclr")]) -+ [(set_attr "type" "bitrw")]) - - ;; clear bit, bit number is (sign/zero)_extended from HImode/QImode - (define_insn "*bclrmemqi_ext" -@@ -5463,7 +5509,7 @@ - CC_STATUS_INIT; - return "bclr %1,%0"; - } -- [(set_attr "type" "bclr")]) -+ [(set_attr "type" "bitrw")]) - - ;; Special cases of bit-field insns which we should - ;; recognize in preference to the general case. -@@ -6413,8 +6459,7 @@ - { - OUTPUT_JUMP ("jeq %l0", "fjeq %l0", "jeq %l0"); - } -- [(set (attr "type") (symbol_ref "m68k_sched_branch_type (insn)")) -- (set_attr "split" "done")]) -+ [(set (attr "type") (symbol_ref "m68k_sched_branch_type (insn)"))]) - - (define_insn "bne" - [(set (pc) -@@ -6426,8 +6471,7 @@ - { - OUTPUT_JUMP ("jne %l0", "fjne %l0", "jne %l0"); - } -- [(set (attr "type") (symbol_ref "m68k_sched_branch_type (insn)")) -- (set_attr "split" "done")]) -+ [(set (attr "type") (symbol_ref "m68k_sched_branch_type (insn)"))]) - - (define_insn "bgt" - [(set (pc) -@@ -6437,10 +6481,15 @@ - (pc)))] - "" - { -+ if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0) -+ { -+ cc_status.flags &= ~CC_OVERFLOW_UNUSABLE; -+ return 0; -+ } -+ - OUTPUT_JUMP ("jgt %l0", "fjgt %l0", 0); - } -- [(set (attr "type") (symbol_ref "m68k_sched_branch_type (insn)")) -- (set_attr "split" "done")]) -+ [(set (attr "type") (symbol_ref "m68k_sched_branch_type (insn)"))]) - - (define_insn "bgtu" - [(set (pc) -@@ -6449,7 +6498,15 @@ - (label_ref (match_operand 0 "" "")) - (pc)))] - "" -- "jhi %l0" -+{ -+ if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0) -+ { -+ cc_status.flags &= ~CC_OVERFLOW_UNUSABLE; -+ return 0; -+ } -+ -+ return "jhi %l0"; -+} - [(set_attr "type" "bcc")]) - - (define_insn "blt" -@@ -6460,10 +6517,15 @@ - (pc)))] - "" - { -+ if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0) -+ { -+ cc_status.flags &= ~CC_OVERFLOW_UNUSABLE; -+ return 0; -+ } -+ - OUTPUT_JUMP ("jlt %l0", "fjlt %l0", "jmi %l0"); - } -- [(set (attr "type") (symbol_ref "m68k_sched_branch_type (insn)")) -- (set_attr "split" "done")]) -+ [(set (attr "type") (symbol_ref "m68k_sched_branch_type (insn)"))]) - - (define_insn "bltu" - [(set (pc) -@@ -6472,7 +6534,15 @@ - (label_ref (match_operand 0 "" "")) - (pc)))] - "" -- "jcs %l0" -+{ -+ if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0) -+ { -+ cc_status.flags &= ~CC_OVERFLOW_UNUSABLE; -+ return 0; -+ } -+ -+ return "jcs %l0"; -+} - [(set_attr "type" "bcc")]) - - (define_insn "bge" -@@ -6483,6 +6553,12 @@ - (pc)))] - "" - { -+ if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0) -+ { -+ cc_status.flags &= ~CC_OVERFLOW_UNUSABLE; -+ return 0; -+ } -+ - OUTPUT_JUMP ("jge %l0", "fjge %l0", "jpl %l0"); - }) - -@@ -6493,7 +6569,15 @@ - (label_ref (match_operand 0 "" "")) - (pc)))] - "" -- "jcc %l0" -+{ -+ if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0) -+ { -+ cc_status.flags &= ~CC_OVERFLOW_UNUSABLE; -+ return 0; -+ } -+ -+ return "jcc %l0"; -+} - [(set_attr "type" "bcc")]) - - (define_insn "ble" -@@ -6504,6 +6588,12 @@ - (pc)))] - "" - { -+ if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0) -+ { -+ cc_status.flags &= ~CC_OVERFLOW_UNUSABLE; -+ return 0; -+ } -+ - OUTPUT_JUMP ("jle %l0", "fjle %l0", 0); - } - [(set_attr "type" "bcc")]) -@@ -6515,7 +6605,15 @@ - (label_ref (match_operand 0 "" "")) - (pc)))] - "" -- "jls %l0" -+{ -+ if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0) -+ { -+ cc_status.flags &= ~CC_OVERFLOW_UNUSABLE; -+ return 0; -+ } -+ -+ return "jls %l0"; -+} - [(set_attr "type" "bcc")]) - - (define_insn "bordered" -@@ -6527,7 +6625,8 @@ - { - gcc_assert (cc_prev_status.flags & CC_IN_68881); - return "fjor %l0"; --}) -+} -+ [(set_attr "type" "fbcc")]) - - (define_insn "bunordered" - [(set (pc) -@@ -6538,7 +6637,8 @@ - { - gcc_assert (cc_prev_status.flags & CC_IN_68881); - return "fjun %l0"; --}) -+} -+ [(set_attr "type" "fbcc")]) - - (define_insn "buneq" - [(set (pc) -@@ -6549,7 +6649,8 @@ - { - gcc_assert (cc_prev_status.flags & CC_IN_68881); - return "fjueq %l0"; --}) -+} -+ [(set_attr "type" "fbcc")]) - - (define_insn "bunge" - [(set (pc) -@@ -6560,7 +6661,8 @@ - { - gcc_assert (cc_prev_status.flags & CC_IN_68881); - return "fjuge %l0"; --}) -+} -+ [(set_attr "type" "fbcc")]) - - (define_insn "bungt" - [(set (pc) -@@ -6571,7 +6673,8 @@ - { - gcc_assert (cc_prev_status.flags & CC_IN_68881); - return "fjugt %l0"; --}) -+} -+ [(set_attr "type" "fbcc")]) - - (define_insn "bunle" - [(set (pc) -@@ -6582,7 +6685,8 @@ - { - gcc_assert (cc_prev_status.flags & CC_IN_68881); - return "fjule %l0"; --}) -+} -+ [(set_attr "type" "fbcc")]) - - (define_insn "bunlt" - [(set (pc) -@@ -6593,7 +6697,8 @@ - { - gcc_assert (cc_prev_status.flags & CC_IN_68881); - return "fjult %l0"; --}) -+} -+ [(set_attr "type" "fbcc")]) - - (define_insn "bltgt" - [(set (pc) -@@ -6604,7 +6709,8 @@ - { - gcc_assert (cc_prev_status.flags & CC_IN_68881); - return "fjogl %l0"; --}) -+} -+ [(set_attr "type" "fbcc")]) - - ;; Negated conditional jump instructions. - -@@ -6640,6 +6746,12 @@ - (label_ref (match_operand 0 "" ""))))] - "" - { -+ if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0) -+ { -+ cc_status.flags &= ~CC_OVERFLOW_UNUSABLE; -+ return 0; -+ } -+ - OUTPUT_JUMP ("jle %l0", "fjngt %l0", 0); - } - [(set_attr "type" "bcc")]) -@@ -6651,7 +6763,15 @@ - (pc) - (label_ref (match_operand 0 "" ""))))] - "" -- "jls %l0" -+{ -+ if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0) -+ { -+ cc_status.flags &= ~CC_OVERFLOW_UNUSABLE; -+ return 0; -+ } -+ -+ return "jls %l0"; -+} - [(set_attr "type" "bcc")]) - - (define_insn "*blt_rev" -@@ -6662,6 +6782,12 @@ - (label_ref (match_operand 0 "" ""))))] - "" - { -+ if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0) -+ { -+ cc_status.flags &= ~CC_OVERFLOW_UNUSABLE; -+ return 0; -+ } -+ - OUTPUT_JUMP ("jge %l0", "fjnlt %l0", "jpl %l0"); - } - [(set_attr "type" "bcc")]) -@@ -6673,7 +6799,15 @@ - (pc) - (label_ref (match_operand 0 "" ""))))] - "" -- "jcc %l0" -+{ -+ if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0) -+ { -+ cc_status.flags &= ~CC_OVERFLOW_UNUSABLE; -+ return 0; -+ } -+ -+ return "jcc %l0"; -+} - [(set_attr "type" "bcc")]) - - (define_insn "*bge_rev" -@@ -6684,6 +6818,12 @@ - (label_ref (match_operand 0 "" ""))))] - "" - { -+ if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0) -+ { -+ cc_status.flags &= ~CC_OVERFLOW_UNUSABLE; -+ return 0; -+ } -+ - OUTPUT_JUMP ("jlt %l0", "fjnge %l0", "jmi %l0"); - } - [(set_attr "type" "bcc")]) -@@ -6695,7 +6835,15 @@ - (pc) - (label_ref (match_operand 0 "" ""))))] - "" -- "jcs %l0" -+{ -+ if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0) -+ { -+ cc_status.flags &= ~CC_OVERFLOW_UNUSABLE; -+ return 0; -+ } -+ -+ return "jcs %l0"; -+} - [(set_attr "type" "bcc")]) - - (define_insn "*ble_rev" -@@ -6706,6 +6854,12 @@ - (label_ref (match_operand 0 "" ""))))] - "" - { -+ if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0) -+ { -+ cc_status.flags &= ~CC_OVERFLOW_UNUSABLE; -+ return 0; -+ } -+ - OUTPUT_JUMP ("jgt %l0", "fjnle %l0", 0); - } - [(set_attr "type" "bcc")]) -@@ -6717,7 +6871,15 @@ - (pc) - (label_ref (match_operand 0 "" ""))))] - "" -- "jhi %l0" -+{ -+ if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0) -+ { -+ cc_status.flags &= ~CC_OVERFLOW_UNUSABLE; -+ return 0; -+ } -+ -+ return "jhi %l0"; -+} - [(set_attr "type" "bcc")]) - - (define_insn "*bordered_rev" -@@ -6729,7 +6891,8 @@ - { - gcc_assert (cc_prev_status.flags & CC_IN_68881); - return "fjun %l0"; --}) -+} -+ [(set_attr "type" "fbcc")]) - - (define_insn "*bunordered_rev" - [(set (pc) -@@ -6740,7 +6903,8 @@ - { - gcc_assert (cc_prev_status.flags & CC_IN_68881); - return "fjor %l0"; --}) -+} -+ [(set_attr "type" "fbcc")]) - - (define_insn "*buneq_rev" - [(set (pc) -@@ -6751,7 +6915,8 @@ - { - gcc_assert (cc_prev_status.flags & CC_IN_68881); - return "fjogl %l0"; --}) -+} -+ [(set_attr "type" "fbcc")]) - - (define_insn "*bunge_rev" - [(set (pc) -@@ -6762,7 +6927,8 @@ - { - gcc_assert (cc_prev_status.flags & CC_IN_68881); - return "fjolt %l0"; --}) -+} -+ [(set_attr "type" "fbcc")]) - - (define_insn "*bungt_rev" - [(set (pc) -@@ -6773,7 +6939,8 @@ - { - gcc_assert (cc_prev_status.flags & CC_IN_68881); - return "fjole %l0"; --}) -+} -+ [(set_attr "type" "fbcc")]) - - (define_insn "*bunle_rev" - [(set (pc) -@@ -6784,7 +6951,8 @@ - { - gcc_assert (cc_prev_status.flags & CC_IN_68881); - return "fjogt %l0"; --}) -+} -+ [(set_attr "type" "fbcc")]) - - (define_insn "*bunlt_rev" - [(set (pc) -@@ -6795,7 +6963,8 @@ - { - gcc_assert (cc_prev_status.flags & CC_IN_68881); - return "fjoge %l0"; --}) -+} -+ [(set_attr "type" "fbcc")]) - - (define_insn "*bltgt_rev" - [(set (pc) -@@ -6806,7 +6975,8 @@ - { - gcc_assert (cc_prev_status.flags & CC_IN_68881); - return "fjueq %l0"; --}) -+} -+ [(set_attr "type" "fbcc")]) - - ;; Unconditional and other jump instructions - (define_insn "jump" -@@ -6835,7 +7005,7 @@ - { - return MOTOROLA ? "jmp (%0)" : "jmp %0@"; - } -- [(set_attr "type" "bra")]) -+ [(set_attr "type" "jmp")]) - - ;; Jump to variable address from dispatch table of relative addresses. - (define_insn "" -@@ -7013,7 +7183,8 @@ - "!SIBLING_CALL_P (insn)" - { - return output_call (operands[0]); --}) -+} -+ [(set_attr "type" "jsr")]) - - ;; Call subroutine, returning value in operand 0 - ;; (which must be a hard register). -@@ -7035,7 +7206,6 @@ - "!SIBLING_CALL_P (insn)" - "jsr %a1" - [(set_attr "type" "jsr") -- (set_attr "split" "done") - (set_attr "opx" "1")]) - - (define_insn "*symbolic_call_value_jsr" -@@ -7049,7 +7219,6 @@ - return m68k_symbolic_call; - } - [(set_attr "type" "jsr") -- (set_attr "split" "done") - (set_attr "opx" "1")]) - - (define_insn "*symbolic_call_value_bsr" -@@ -7065,7 +7234,6 @@ - return m68k_symbolic_call; - } - [(set_attr "type" "bsr") -- (set_attr "split" "done") - (set_attr "opx" "1")]) - - ;; Call subroutine returning any type. -@@ -7231,7 +7399,8 @@ - return "link.w %0,%1"; - else - return "link.l %0,%1"; --}) -+} -+ [(set_attr "type" "link")]) - - (define_expand "unlink" - [(parallel -@@ -7721,6 +7890,17 @@ - } - }) - -+;; These are to prevent the scheduler from moving stores to the frame -+;; before the stack adjustment. -+(define_insn "stack_tie" -+ [(set (mem:BLK (scratch)) -+ (unspec:BLK [(match_operand:SI 0 "register_operand" "r") -+ (match_operand:SI 1 "register_operand" "r")] -+ UNSPEC_TIE))] -+ "" -+ "" -+ [(set_attr "type" "ignore")]) -+ - ;; Instruction that subscribes one word in ColdFire instruction buffer. - ;; This instruction is used within scheduler only and should not appear - ;; in the instruction stream. ---- a/gcc/config/m68k/m68k.opt -+++ b/gcc/config/m68k/m68k.opt -@@ -178,3 +178,11 @@ Do not use unaligned memory references - mtune= - Target RejectNegative Joined - Tune for the specified target CPU or architecture -+ -+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-cf -+++ b/gcc/config/m68k/t-cf -@@ -2,3 +2,6 @@ - - M68K_MLIB_CPU += && (CPU ~ "^mcf") - M68K_ARCH := cf -+# Do not stamp the multilibs with a MAC type, as we never use those -+# instructions in compiler-generated code. -+MULTILIB_EXTRA_OPTS += Wa,-mno-mac ---- /dev/null -+++ b/gcc/config/m68k/t-linux -@@ -0,0 +1,11 @@ -+EXTRA_MULTILIB_PARTS=crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o -+ -+# Only include multilibs for CPUs with an MMU. -+M68K_MLIB_CPU += && match(FLAGS, "FL_MMU") -+ -+# This rule uses MULTILIB_MATCHES to generate a definition of -+# SYSROOT_SUFFIX_SPEC. -+sysroot-suffix.h: $(srcdir)/config/m68k/print-sysroot-suffix.sh -+ $(SHELL) $(srcdir)/config/m68k/print-sysroot-suffix.sh \ -+ "$(SYSTEM_HEADER_DIR)/../.." "$(MULTILIB_MATCHES)" \ -+ "$(MULTILIB_OPTIONS)" > $@ ---- 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,62 @@ -+/* -+ * Copyright (C) 2008 Free Software Foundation, Inc. -+ * -+ * This file is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 3, or (at your option) any -+ * later version. -+ * -+ * In addition to the permissions in the GNU General Public License, the -+ * Free Software Foundation gives you unlimited permission to link the -+ * compiled version of this file with other programs, and to distribute -+ * those programs without any restriction coming from the use of this -+ * file. (The General Public License restrictions do apply in other -+ * respects; for example, they cover modification of the file, and -+ * distribution when not linked into another program.) -+ * -+ * 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. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GCC; see the file COPYING3. If not see -+ * . -+ * -+ * 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. -+ */ -+ -+#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 */ ---- /dev/null -+++ b/gcc/config/mips/cs-sgxx-linux.h -@@ -0,0 +1,40 @@ -+/* MIPS SourceryG++ GNU/Linux Configuration. -+ Copyright (C) 2008 -+ 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 -+. */ -+ -+/* We do not need to provide an explicit big-endian multilib. */ -+#undef MULTILIB_DEFAULTS -+#define MULTILIB_DEFAULTS \ -+ { "EB" } -+ -+/* The various C libraries each have their own subdirectory. */ -+#undef SYSROOT_SUFFIX_SPEC -+#define SYSROOT_SUFFIX_SPEC \ -+"%{muclibc:/uclibc}\ -+%{mips2|mips3|mips4|march=mips2|march=mips3|march=mips4|march=r6000|\ -+march=r4000|march=vr4100|march=vr4111|march=vr4120|march=vr4130|\ -+march=vr4300|march=r4400|march=r4600|march=orion|march=r4650|march=r8000|\ -+march=vr5000|march=vr5400|march=vr5500|march=rm7000|\ -+march=rm9000:/mips2;\ -+mips32|march=mips32|march=4kc|march=4km|march=4kp|march=4ks:/mips32}\ -+%{msoft-float:/soft-float}%{mel|EL:/el}" -+ -+#undef SYSROOT_HEADERS_SUFFIX_SPEC -+#define SYSROOT_HEADERS_SUFFIX_SPEC \ -+ "%{muclibc:/uclibc}" ---- /dev/null -+++ b/gcc/config/mips/cs-sgxxlite-linux.h -@@ -0,0 +1,33 @@ -+/* MIPS SourceryG++ GNU/Linux Configuration. -+ Copyright (C) 2008 -+ 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 -+. */ -+ -+/* We do not need to provide an explicit big-endian multilib. */ -+#undef MULTILIB_DEFAULTS -+#define MULTILIB_DEFAULTS \ -+ { "EB" } -+ -+/* The various C libraries each have their own subdirectory. */ -+#undef SYSROOT_SUFFIX_SPEC -+#define SYSROOT_SUFFIX_SPEC \ -+"%{muclibc:/uclibc}%{msoft-float:/soft-float}%{mel|EL:/el}" -+ -+#undef SYSROOT_HEADERS_SUFFIX_SPEC -+#define SYSROOT_HEADERS_SUFFIX_SPEC \ -+ "%{muclibc:/uclibc}" ---- a/gcc/config/mips/elfoabi.h -+++ b/gcc/config/mips/elfoabi.h -@@ -19,7 +19,7 @@ You should have received a copy of the G - along with GCC; see the file COPYING3. If not see - . */ - --#define DRIVER_SELF_SPECS \ -+#define SUBTARGET_SELF_SPECS \ - /* Make sure a -mips option is present. This helps us to pick \ - the right multilib, and also makes the later specs easier \ - to write. */ \ ---- a/gcc/config/mips/iris6.h -+++ b/gcc/config/mips/iris6.h -@@ -29,7 +29,7 @@ along with GCC; see the file COPYING3. - - /* Force the default ABI onto the command line in order to make the specs - easier to write. Default to the mips2 ISA for the O32 ABI. */ --#define DRIVER_SELF_SPECS \ -+#define SUBTARGET_SELF_SPECS \ - "%{!mabi=*: -mabi=n32}", \ - "%{mabi=32: %{!mips*: %{!march*: -mips2}}}" - ---- a/gcc/config/mips/linux.h -+++ b/gcc/config/mips/linux.h -@@ -37,10 +37,6 @@ along with GCC; see the file COPYING3. - #undef MD_EXEC_PREFIX - #undef MD_STARTFILE_PREFIX - --/* If we don't set MASK_ABICALLS, we can't default to PIC. */ --#undef TARGET_DEFAULT --#define TARGET_DEFAULT MASK_ABICALLS -- - #define TARGET_OS_CPP_BUILTINS() \ - do { \ - LINUX_TARGET_OS_CPP_BUILTINS(); \ -@@ -79,7 +75,8 @@ along with GCC; see the file COPYING3. - %{static:-static}}}" - - #undef SUBTARGET_ASM_SPEC --#define SUBTARGET_ASM_SPEC "%{mabi=64: -64} %{!mno-abicalls:-KPIC}" -+#define SUBTARGET_ASM_SPEC \ -+ "%{mabi=64: -64} %{mabicalls:%{fpic|fPIC|fpie|fPIE:-KPIC;:-mnon-pic-abicalls}}" - - /* The MIPS assembler has different syntax for .set. We set it to - .dummy to trap any errors. */ -@@ -145,7 +142,15 @@ along with GCC; see the file COPYING3. - /* Default to -mno-shared for non-PIC. */ - #define NO_SHARED_SPECS \ - "%{mshared|mno-shared|fpic|fPIC|fpie|fPIE:;:-mno-shared}" --#define DRIVER_SELF_SPECS NO_SHARED_SPECS -+#undef SUBTARGET_SELF_SPECS -+#define SUBTARGET_SELF_SPECS NO_SHARED_SPECS - #else - #define NO_SHARED_SPECS - #endif -+ -+/* 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/linux64.h -+++ b/gcc/config/mips/linux64.h -@@ -20,15 +20,15 @@ along with GCC; see the file COPYING3. - - /* Force the default endianness and ABI flags onto the command line - in order to make the other specs easier to write. */ --#undef DRIVER_SELF_SPECS --#define DRIVER_SELF_SPECS \ -+#undef SUBTARGET_SELF_SPECS -+#define SUBTARGET_SELF_SPECS \ - NO_SHARED_SPECS \ - " %{!EB:%{!EL:%(endian_spec)}}" \ - " %{!mabi=*: -mabi=n32}" - - #undef SUBTARGET_ASM_SPEC - #define SUBTARGET_ASM_SPEC "\ --%{!fno-PIC:%{!fno-pic:-KPIC}} \ -+%{mabicalls:%{fpic|fPIC|fpie|fPIE:-KPIC;:-mnon-pic-abicalls}} \ - %{fno-PIC:-non_shared} %{fno-pic:-non_shared}" - - #undef LIB_SPEC -@@ -72,3 +72,9 @@ NO_SHARED_SPECS \ - 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.\t%0,%1,%2" -- [(set_attr "type" "arith") -+ [(set_attr "type" "dspalu") - (set_attr "mode" "SI")]) - - (define_insn "mips_add_s_" -@@ -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_s.\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.\t%0,%1,%2" -- [(set_attr "type" "arith") -+ [(set_attr "type" "dspalu") - (set_attr "mode" "SI")]) - - (define_insn "mips_sub_s_" -@@ -83,7 +83,7 @@ - (unspec:CCDSP [(match_dup 1) (match_dup 2)] UNSPEC_SUBQ_S))])] - "ISA_HAS_DSP" - "sub_s.\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.\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.\t%0,%1,%2"; - } -- [(set_attr "type" "shift") -+ [(set_attr "type" "dspalu") - (set_attr "mode" "SI")]) - - (define_insn "mips_shll_s_" -@@ -335,7 +335,7 @@ - } - return "shllv_s.\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_" -@@ -392,7 +392,7 @@ - } - return "shrav_r.\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.eq.\t%0,%1" -- [(set_attr "type" "arith") -+ [(set_attr "type" "dspalu") - (set_attr "mode" "SI")]) - - (define_insn "mips_cmp_lt_" -@@ -731,7 +731,7 @@ - UNSPEC_CMP_LT))] - "ISA_HAS_DSP" - "cmp.lt.\t%0,%1" -- [(set_attr "type" "arith") -+ [(set_attr "type" "dspalu") - (set_attr "mode" "SI")]) - - (define_insn "mips_cmp_le_" -@@ -742,7 +742,7 @@ - UNSPEC_CMP_LE))] - "ISA_HAS_DSP" - "cmp.le.\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.\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" -@@ -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 -@@ -177,6 +177,8 @@ extern rtx mips_emit_move (rtx, rtx); - extern bool mips_split_symbol (rtx, rtx, enum machine_mode, rtx *); - extern rtx mips_unspec_address (rtx, enum mips_symbol_type); - extern bool mips_legitimize_address (rtx *, enum machine_mode); -+extern int mask_low_and_shift_len (enum machine_mode, unsigned HOST_WIDE_INT, -+ unsigned HOST_WIDE_INT); - extern void mips_move_integer (rtx, rtx, unsigned HOST_WIDE_INT); - extern bool mips_legitimize_move (enum machine_mode, rtx, rtx); - -@@ -239,6 +241,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); -@@ -283,14 +287,18 @@ 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); - extern unsigned int current_section_flags (void); - extern bool mips_use_ins_ext_p (rtx, HOST_WIDE_INT, HOST_WIDE_INT); -+extern void mips_adjust_register_ext_operands (rtx *); - - extern const char *mips16e_output_save_restore (rtx, HOST_WIDE_INT); - extern bool mips16e_save_restore_pattern_p (rtx, HOST_WIDE_INT, - struct mips16e_save_restore_info *); -+extern void mips_expand_vector_init (rtx, rtx); - - #endif /* ! GCC_MIPS_PROTOS_H */ ---- a/gcc/config/mips/mips.c -+++ b/gcc/config/mips/mips.c -@@ -232,6 +232,8 @@ static const char *const mips_fp_conditi - MIPS_FP_CONDITIONS (STRINGIFY) - }; - -+static rtx mips_gnu_local_gp (void); -+ - /* Information about a function's frame layout. */ - struct mips_frame_info GTY(()) { - /* The size of the frame in bytes. */ -@@ -455,6 +457,10 @@ static int mips_base_align_functions; /* - /* The -mcode-readable setting. */ - enum mips_code_readable_setting mips_code_readable = CODE_READABLE_YES; - -+/* If size of stack frame exceeds this value, compiler will emit -+ warning message. */ -+static HOST_WIDE_INT mips_warn_framesize = -1; -+ - /* Index [M][R] is true if register R is allowed to hold a value of mode M. */ - bool mips_hard_regno_mode_ok[(int) MAX_MACHINE_MODE][FIRST_PSEUDO_REGISTER]; - -@@ -497,7 +503,7 @@ const enum reg_class mips_regno_to_class - MD0_REG, MD1_REG, NO_REGS, ST_REGS, - ST_REGS, ST_REGS, ST_REGS, ST_REGS, - ST_REGS, ST_REGS, ST_REGS, NO_REGS, -- NO_REGS, ALL_REGS, ALL_REGS, NO_REGS, -+ NO_REGS, FRAME_REGS, FRAME_REGS, NO_REGS, - COP0_REGS, COP0_REGS, COP0_REGS, COP0_REGS, - COP0_REGS, COP0_REGS, COP0_REGS, COP0_REGS, - COP0_REGS, COP0_REGS, COP0_REGS, COP0_REGS, -@@ -527,9 +533,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 }, -@@ -642,6 +655,9 @@ static const struct mips_cpu_info mips_c - { "sb1", PROCESSOR_SB1, 64, PTF_AVOID_BRANCHLIKELY }, - { "sb1a", PROCESSOR_SB1A, 64, PTF_AVOID_BRANCHLIKELY }, - { "sr71000", PROCESSOR_SR71000, 64, PTF_AVOID_BRANCHLIKELY }, -+ { "xlr", PROCESSOR_XLR, 64, 0 }, -+ { "octeon", PROCESSOR_OCTEON, 64, 0 }, -+ { "ice9", PROCESSOR_5KF, 64 }, /* May diverge from 5kf in future. */ - }; - - /* Default costs. If these are used for a processor we should look -@@ -1006,6 +1022,26 @@ static const struct mips_rtx_cost_data m - { /* SR71000 */ - DEFAULT_COSTS - }, -+ { /* OCTEON */ -+ SOFT_FP_COSTS, -+ /* Increase the latency values (5, 72) by 10% because MULT and -+ DIV are no fully pipelined. */ -+ COSTS_N_INSNS (6), /* int_mult_si */ -+ COSTS_N_INSNS (6), /* int_mult_di */ -+ COSTS_N_INSNS (80), /* int_div_si */ -+ COSTS_N_INSNS (80), /* int_div_di */ -+ 1, /* branch_cost */ -+ 4 /* memory_latency */ -+ }, -+ { /* XLR */ -+ SOFT_FP_COSTS, -+ COSTS_N_INSNS (8), /* int_mult_si */ -+ COSTS_N_INSNS (8), /* int_mult_di */ -+ COSTS_N_INSNS (72), /* int_div_si */ -+ COSTS_N_INSNS (72), /* int_div_di */ -+ 1, /* branch_cost */ -+ 4 /* memory_latency */ -+ } - }; - - /* This hash table keeps track of implicit "mips16" and "nomips16" attributes -@@ -1213,7 +1249,29 @@ mips_split_plus (rtx x, rtx *base_ptr, H - static unsigned int mips_build_integer (struct mips_integer_op *, - unsigned HOST_WIDE_INT); - --/* A subroutine of mips_build_integer, with the same interface. -+/* See whether: -+ -+ (and:MODE (ashift:MODE X SHIFT) MASK) -+ -+ would have the effect of masking the low N bits of X and then shifting -+ the result left SHIFT bits. Return N if so, otherwise return -1. */ -+ -+int -+mask_low_and_shift_len (enum machine_mode mode, -+ unsigned HOST_WIDE_INT shift, -+ unsigned HOST_WIDE_INT mask) -+{ -+ if (shift >= GET_MODE_BITSIZE (mode)) -+ return -1; -+ -+ /* Undo the CONST_INT sign-extension canonicalisation. */ -+ mask &= GET_MODE_MASK (mode); -+ -+ /* We don't care about the low SHIFT bits of MASK. */ -+ return exact_log2 ((mask >> shift) + 1); -+} -+ -+/* Subroutine of mips_build_integer (with the same interface). - Assume that the final action in the sequence should be a left shift. */ - - static unsigned int -@@ -1390,7 +1448,7 @@ mips_classify_symbol (const_rtx x, enum - if (TARGET_MIPS16_SHORT_JUMP_TABLES) - return SYMBOL_PC_RELATIVE; - -- if (TARGET_ABICALLS && !TARGET_ABSOLUTE_ABICALLS) -+ if (TARGET_ABICALLS && !TARGET_ABSOLUTE_ABICALLS && flag_pic) - return SYMBOL_GOT_PAGE_OFST; - - return SYMBOL_ABSOLUTE; -@@ -1413,14 +1471,16 @@ mips_classify_symbol (const_rtx x, enum - return SYMBOL_GP_RELATIVE; - } - -- /* Do not use small-data accesses for weak symbols; they may end up -- being zero. */ -- if (TARGET_GPOPT && SYMBOL_REF_SMALL_P (x) && !SYMBOL_REF_WEAK (x)) -+ /* Use a small-data access if appropriate; but do not use small-data -+ accesses for weak symbols; they may end up being zero. */ -+ if (TARGET_GPOPT -+ && SYMBOL_REF_SMALL_P (x) -+ && !SYMBOL_REF_WEAK (x)) - return SYMBOL_GP_RELATIVE; - -- /* Don't use GOT accesses for locally-binding symbols when -mno-shared -- is in effect. */ -- if (TARGET_ABICALLS -+ /* Don't use GOT accesses when compiling for the non-PIC ABI, -+ or for locally-binding symbols when -mno-shared is in effect. */ -+ if (TARGET_ABICALLS && flag_pic - && !(TARGET_ABSOLUTE_ABICALLS && mips_symbol_binds_local_p (x))) - { - /* There are three cases to consider: -@@ -1800,6 +1860,24 @@ mips_valid_base_register_p (rtx x, enum - && mips_regno_mode_ok_for_base_p (REGNO (x), mode, strict_p)); - } - -+/* Return true if, for every base register BASE_REG, (plus BASE_REG X) -+ can address a value of mode MODE. */ -+ -+static bool -+mips_valid_offset_p (rtx x, enum machine_mode mode) -+{ -+ /* Check that X is a signed 16-bit number. */ -+ if (!const_arith_operand (x, Pmode)) -+ return false; -+ -+ /* We may need to split multiword moves, so make sure that every word -+ is accessible. */ -+ if (GET_MODE_SIZE (mode) > UNITS_PER_WORD -+ && !SMALL_OPERAND (INTVAL (x) + GET_MODE_SIZE (mode) - UNITS_PER_WORD)) -+ return false; -+ -+ return true; -+} - /* Return true if X is a valid address for machine mode MODE. If it is, - fill in INFO appropriately. STRICT_P is true if REG_OK_STRICT is in - effect. */ -@@ -2175,7 +2253,9 @@ gen_load_const_gp (rtx reg) - - /* Return a pseudo register that contains the value of $gp throughout - the current function. Such registers are needed by MIPS16 functions, -- for which $gp itself is not a valid base register or addition operand. */ -+ for which $gp itself is not a valid base register or addition operand. -+ Also hold the GP in a non-PIC abicalls function which refers to TLS -+ data - such functions do not require $28 or even a hard register. */ - - static rtx - mips16_gp_pseudo_reg (void) -@@ -2191,7 +2271,11 @@ mips16_gp_pseudo_reg (void) - { - rtx insn, scan, after; - -- insn = gen_load_const_gp (cfun->machine->mips16_gp_pseudo_rtx); -+ if (TARGET_NONPIC_ABICALLS) -+ insn = gen_loadgp_nonpic (cfun->machine->mips16_gp_pseudo_rtx, -+ mips_gnu_local_gp ()); -+ else -+ insn = gen_load_const_gp (cfun->machine->mips16_gp_pseudo_rtx); - - push_topmost_sequence (); - /* We need to emit the initialization after the FUNCTION_BEG -@@ -2333,6 +2417,19 @@ mips_add_offset (rtx temp, rtx reg, HOST - return plus_constant (reg, offset); - } - -+/* Return the RTX to use for explicit GOT accesses. Uses a pseudo if -+ possible. */ -+ -+static rtx -+mips_got_base (void) -+{ -+ gcc_assert (can_create_pseudo_p ()); -+ if (TARGET_NONPIC_ABICALLS) -+ return mips16_gp_pseudo_reg (); -+ else -+ return pic_offset_table_rtx; -+} -+ - /* The __tls_get_attr symbol. */ - static GTY(()) rtx mips_tls_symbol; - -@@ -2356,7 +2453,7 @@ mips_call_tls_get_addr (rtx sym, enum mi - start_sequence (); - - emit_insn (gen_rtx_SET (Pmode, a0, -- gen_rtx_LO_SUM (Pmode, pic_offset_table_rtx, loc))); -+ gen_rtx_LO_SUM (Pmode, mips_got_base (), loc))); - insn = mips_expand_call (v0, mips_tls_symbol, const0_rtx, const0_rtx, false); - CONST_OR_PURE_CALL_P (insn) = 1; - use_reg (&CALL_INSN_FUNCTION_USAGE (insn), a0); -@@ -2435,9 +2532,9 @@ mips_legitimize_tls_address (rtx loc) - tmp1 = gen_reg_rtx (Pmode); - tmp2 = mips_unspec_address (loc, SYMBOL_GOTTPREL); - if (Pmode == DImode) -- emit_insn (gen_load_gotdi (tmp1, pic_offset_table_rtx, tmp2)); -+ emit_insn (gen_load_gotdi (tmp1, mips_got_base (), tmp2)); - else -- emit_insn (gen_load_gotsi (tmp1, pic_offset_table_rtx, tmp2)); -+ emit_insn (gen_load_gotsi (tmp1, mips_got_base (), tmp2)); - dest = gen_reg_rtx (Pmode); - emit_insn (gen_add3_insn (dest, tmp1, tp)); - break; -@@ -2464,7 +2561,7 @@ bool - mips_legitimize_address (rtx *xloc, enum machine_mode mode) - { - rtx base; -- HOST_WIDE_INT offset; -+ HOST_WIDE_INT intval, high, offset; - - if (mips_tls_symbol_p (*xloc)) - { -@@ -2485,6 +2582,32 @@ mips_legitimize_address (rtx *xloc, enum - *xloc = mips_add_offset (NULL, base, offset); - 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; - } - -@@ -3360,6 +3483,27 @@ mips_rtx_costs (rtx x, int code, int out - return false; - - case ZERO_EXTEND: -+ /* Check for BADDU patterns; see mips.md. */ -+ if (ISA_HAS_BADDU) -+ { -+ rtx op0 = XEXP (x, 0); -+ if ((GET_CODE (op0) == TRUNCATE || GET_CODE (op0) == SUBREG) -+ && GET_MODE (op0) == QImode -+ && GET_CODE (XEXP (op0, 0)) == PLUS) -+ { -+ rtx op1 = XEXP (XEXP (op0, 0), 0); -+ rtx op2 = XEXP (XEXP (op0, 0), 1); -+ if (GET_CODE (op1) == SUBREG -+ && GET_CODE (XEXP (op1, 0)) == TRUNCATE) -+ op1 = XEXP (XEXP (op1, 0), 0); -+ if (GET_CODE (op2) == SUBREG -+ && GET_CODE (XEXP (op2, 0)) == TRUNCATE) -+ op2 = XEXP (XEXP (op2, 0), 0); -+ *total = -+ COSTS_N_INSNS (1) + rtx_cost (op1, 0) + rtx_cost (op2, 0); -+ return true; -+ } -+ } - *total = mips_zero_extend_cost (mode, XEXP (x, 0)); - return false; - -@@ -3869,6 +4013,30 @@ mips_emit_compare (enum rtx_code *code, - } - } - -+/* If it is possible and profitable to use SEQ or SNE to compare a -+ register with OP, return the instruction's second source operand, -+ otherwise return null. MODE is the mode of OP. */ -+ -+static rtx -+mips_get_seq_sne_operand (enum machine_mode mode, rtx op) -+{ -+ if (!ISA_HAS_SEQ_SNE) -+ return NULL; -+ -+ if (reg_imm10_operand (op, mode)) -+ return op; -+ -+ /* If OP is in the range of either ADDIU or XORI, we could either -+ use those instructions and boolify the result, or move OP into a -+ register and use SEQ or SNE. Prefer the former, because it is -+ better than the latter when a 0/1 result is not needed. */ -+ if (uns_arith_operand (op, mode) -+ || arith_operand (op, mode)) -+ return NULL; -+ -+ return force_reg (mode, op); -+} -+ - /* Try comparing cmp_operands[0] and cmp_operands[1] using rtl code CODE. - Store the result in TARGET and return true if successful. - -@@ -3883,8 +4051,15 @@ mips_expand_scc (enum rtx_code code, rtx - target = gen_lowpart (GET_MODE (cmp_operands[0]), target); - if (code == EQ || code == NE) - { -- rtx zie = mips_zero_if_equal (cmp_operands[0], cmp_operands[1]); -- mips_emit_binary (code, target, zie, const0_rtx); -+ rtx scc_operand = mips_get_seq_sne_operand (GET_MODE (cmp_operands[0]), -+ cmp_operands[1]); -+ if (scc_operand) -+ mips_emit_binary (code, target, cmp_operands[0], scc_operand); -+ else -+ { -+ rtx zie = mips_zero_if_equal (cmp_operands[0], cmp_operands[1]); -+ mips_emit_binary (code, target, zie, const0_rtx); -+ } - } - else - mips_emit_int_order_test (code, 0, target, -@@ -5954,6 +6129,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) - { -@@ -5988,6 +6172,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)); -@@ -6398,6 +6592,27 @@ mips_print_float_branch_condition (FILE - } - } - -+/* Likewise bit branches. */ -+ -+static void -+mips_print_bit_branch_condition (FILE *file, enum rtx_code code, int letter) -+{ -+ switch (code) -+ { -+ case EQ: -+ fputs ("bit0", file); -+ break; -+ -+ case NE: -+ fputs ("bit1", file); -+ break; -+ -+ default: -+ output_operand_lossage ("'%%%c' is not a valid operand prefix", letter); -+ break; -+ } -+} -+ - /* Implement the PRINT_OPERAND macro. The MIPS-specific operand codes are: - - 'X' Print CONST_INT OP in hexadecimal format. -@@ -6419,8 +6634,11 @@ mips_print_float_branch_condition (FILE - 'D' Print the second part of a double-word register or memory operand. - 'L' Print the low-order register in a double-word register operand. - 'M' Print high-order register in a double-word register operand. -- 'z' Print $0 if OP is zero, otherwise print OP normally. */ -- -+ 'z' Print $0 if OP is zero, otherwise print OP normally. -+ 'E' substract 1 from the const_int value. -+ 'G' print part of opcode for a branch-bit condition. -+ 'H' print part of opcode for a branch-bit condition, inverted. */ -+ - void - mips_print_operand (FILE *file, rtx op, int letter) - { -@@ -6518,6 +6736,23 @@ mips_print_operand (FILE *file, rtx op, - output_operand_lossage ("invalid use of '%%%c'", letter); - break; - -+ case 'E': -+ { -+ if (code != CONST_INT) -+ output_operand_lossage ("'%%E' misused"); -+ fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (op) - 1); -+ } -+ break; -+ -+ case 'G': -+ mips_print_bit_branch_condition (file, code, letter); -+ break; -+ -+ case 'H': -+ mips_print_bit_branch_condition (file, reverse_condition (code), -+ letter); -+ break; -+ - default: - switch (code) - { -@@ -6627,7 +6862,7 @@ mips_select_rtx_section (enum machine_mo - static section * - mips_function_rodata_section (tree decl) - { -- if (!TARGET_ABICALLS || TARGET_GPWORD) -+ if (!TARGET_ABICALLS || !flag_pic || TARGET_GPWORD) - return default_function_rodata_section (decl); - - if (decl && DECL_SECTION_NAME (decl)) -@@ -6667,6 +6902,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; -@@ -6845,6 +7086,26 @@ mips_output_filename (FILE *stream, cons - } - } - -+/* Initialize vector TARGET to VALS. */ -+ -+void -+mips_expand_vector_init (rtx target, rtx vals) -+{ -+ enum machine_mode mode = GET_MODE (target); -+ enum machine_mode inner = GET_MODE_INNER (mode); -+ unsigned int i, n_elts = GET_MODE_NUNITS (mode); -+ rtx mem; -+ -+ gcc_assert (VECTOR_MODE_P (mode)); -+ -+ mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0); -+ for (i = 0; i < n_elts; i++) -+ emit_move_insn (adjust_address_nv (mem, inner, i * GET_MODE_SIZE (inner)), -+ XVECEXP (vals, 0, i)); -+ -+ emit_move_insn (target, mem); -+} -+ - /* Implement TARGET_ASM_OUTPUT_DWARF_DTPREL. */ - - static void ATTRIBUTE_UNUSED -@@ -6893,6 +7154,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 -@@ -7117,16 +7409,26 @@ 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. */ - if (TARGET_ABICALLS) - fprintf (asm_out_file, "\t.abicalls\n"); -+ if (TARGET_ABICALLS && !flag_pic) -+ fprintf (asm_out_file, "\t.option\tpic0\n"); - - if (flag_verbose_asm) - fprintf (asm_out_file, "\n%s -G value = %d, Arch = %s, ISA = %d\n", -@@ -7617,6 +7919,7 @@ mips16e_output_save_restore (rtx pattern - return buffer; - } - -+ - /* Return true if the current function has an insn that implicitly - refers to $gp. */ - -@@ -7631,6 +7934,7 @@ mips_function_has_gp_insn (void) - push_topmost_sequence (); - for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) - if (USEFUL_INSN_P (insn) -+ - && (get_attr_got (insn) != GOT_UNSET - || mips_small_data_pattern_p (PATTERN (insn)))) - { -@@ -7720,7 +8024,7 @@ mips_save_reg_p (unsigned int regno) - { - /* We only need to save $gp if TARGET_CALL_SAVED_GP and only then - if we have not chosen a call-clobbered substitute. */ -- if (regno == GLOBAL_POINTER_REGNUM) -+ if (regno == GLOBAL_POINTER_REGNUM && fixed_regs[regno]) - return TARGET_CALL_SAVED_GP && cfun->machine->global_pointer == regno; - - /* Check call-saved registers. */ -@@ -7944,7 +8248,7 @@ mips_current_loadgp_style (void) - if (TARGET_RTP_PIC) - return LOADGP_RTP; - -- if (TARGET_ABSOLUTE_ABICALLS) -+ if (TARGET_ABSOLUTE_ABICALLS || !flag_pic) - return LOADGP_ABSOLUTE; - - return TARGET_NEWABI ? LOADGP_NEWABI : LOADGP_OLDABI; -@@ -8059,9 +8363,10 @@ mips_restore_gp (void) - { - rtx base, address; - -- gcc_assert (TARGET_ABICALLS && TARGET_OLDABI); -+ gcc_assert (TARGET_ABICALLS && TARGET_OLDABI && flag_pic); - - base = frame_pointer_needed ? hard_frame_pointer_rtx : stack_pointer_rtx; -+ - address = mips_add_offset (pic_offset_table_rtx, base, - current_function_outgoing_args_size); - mips_emit_move (pic_offset_table_rtx, gen_frame_mem (Pmode, address)); -@@ -8312,7 +8617,18 @@ mips_save_reg (rtx reg, rtx mem) - - /* The __gnu_local_gp symbol. */ - --static GTY(()) rtx mips_gnu_local_gp; -+static GTY(()) rtx mips_gnu_local_gp_rtx; -+ -+static rtx -+mips_gnu_local_gp (void) -+{ -+ if (mips_gnu_local_gp_rtx == NULL) -+ { -+ mips_gnu_local_gp_rtx = gen_rtx_SYMBOL_REF (Pmode, "__gnu_local_gp"); -+ SYMBOL_REF_FLAGS (mips_gnu_local_gp_rtx) |= SYMBOL_FLAG_LOCAL; -+ } -+ return mips_gnu_local_gp_rtx; -+} - - /* If we're generating n32 or n64 abicalls, emit instructions - to set up the global pointer. */ -@@ -8326,14 +8642,9 @@ mips_emit_loadgp (void) - switch (mips_current_loadgp_style ()) - { - case LOADGP_ABSOLUTE: -- if (mips_gnu_local_gp == NULL) -- { -- mips_gnu_local_gp = gen_rtx_SYMBOL_REF (Pmode, "__gnu_local_gp"); -- SYMBOL_REF_FLAGS (mips_gnu_local_gp) |= SYMBOL_FLAG_LOCAL; -- } - emit_insn (Pmode == SImode -- ? gen_loadgp_absolute_si (pic_reg, mips_gnu_local_gp) -- : gen_loadgp_absolute_di (pic_reg, mips_gnu_local_gp)); -+ ? gen_loadgp_absolute_si (pic_reg, mips_gnu_local_gp ()) -+ : gen_loadgp_absolute_di (pic_reg, mips_gnu_local_gp ())); - break; - - case LOADGP_NEWABI: -@@ -8490,7 +8801,7 @@ mips_expand_prologue (void) - mips_emit_loadgp (); - - /* Initialize the $gp save slot. */ -- if (frame->cprestore_size > 0) -+ if (frame->cprestore_size > 0 && flag_pic ) - emit_insn (gen_cprestore (GEN_INT (current_function_outgoing_args_size))); - - /* If we are profiling, make sure no instructions are scheduled before -@@ -8549,6 +8860,11 @@ mips_expand_epilogue (bool sibcall_p) - step1 = frame->total_size; - step2 = 0; - -+ if (mips_warn_framesize >= 0 -+ && step1 > mips_warn_framesize) -+ warning (0, "frame size of %qs is " HOST_WIDE_INT_PRINT_DEC " bytes", -+ current_function_name (), step1); -+ - /* Work out which register holds the frame address. */ - if (!frame_pointer_needed) - base = stack_pointer_rtx; -@@ -9456,10 +9772,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); -@@ -9552,6 +9873,7 @@ mips_issue_rate (void) - case PROCESSOR_R5500: - case PROCESSOR_R7000: - case PROCESSOR_R9000: -+ case PROCESSOR_OCTEON: - return 2; - - case PROCESSOR_SB1: -@@ -9577,6 +9899,11 @@ mips_multipass_dfa_lookahead (void) - if (TUNE_SB1) - return 4; - -+ /* Because of the two pipelines we have at most two alternative -+ schedules on Octeon. */ -+ if (mips_tune == PROCESSOR_OCTEON) -+ return 2; -+ - return 0; - } - -@@ -9613,7 +9940,17 @@ mips_maybe_swap_ready (rtx *ready, int p - ready[pos2] = temp; - } - } -- -+ -+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; -@@ -11908,6 +12245,28 @@ mips_parse_cpu (const char *cpu_string) - return NULL; - } - -+/* Prepare the extv/extzv operands in OPERANDS for a register extraction. -+ The problem here is that the extv interface always provides word_mode -+ register operands, even if the values were originally SImode. -+ We nevertheless want to use SImode operations for naturally-SImode -+ operands because SUBREGs are harder to optimize. */ -+ -+void -+mips_adjust_register_ext_operands (rtx *operands) -+{ -+ if (GET_CODE (operands[0]) == SUBREG -+ && GET_MODE (operands[0]) == DImode -+ && GET_CODE (operands[1]) == SUBREG -+ && GET_MODE (operands[1]) == DImode -+ && GET_MODE (SUBREG_REG (operands[0])) == SImode -+ && GET_MODE (SUBREG_REG (operands[1])) == SImode -+ && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32) -+ { -+ operands[0] = SUBREG_REG (operands[0]); -+ operands[1] = SUBREG_REG (operands[1]); -+ } -+} -+ - /* Set up globals to generate code for the ISA or processor - described by INFO. */ - -@@ -11979,6 +12338,9 @@ mips_handle_option (size_t code, const c - return false; - return true; - -+ case OPT_mwarn_framesize_: -+ return sscanf (arg, HOST_WIDE_INT_PRINT_DEC, &mips_warn_framesize) == 1; -+ - default: - return true; - } -@@ -11995,10 +12357,6 @@ mips_override_options (void) - SUBTARGET_OVERRIDE_OPTIONS; - #endif - -- /* Set the small data limit. */ -- mips_small_data_threshold = (g_switch_set -- ? g_switch_value -- : MIPS_DEFAULT_GVALUE); - - /* The following code determines the architecture and register size. - Similar code was added to GAS 2.14 (see tc-mips.c:md_after_parse_args()). -@@ -12088,6 +12446,10 @@ mips_override_options (void) - - /* End of code shared with GAS. */ - -+ /* The non-PIC ABI may only be used in conjunction with the o32 ABI. */ -+ if (TARGET_ABICALLS && !flag_pic && mips_abi != ABI_32) -+ sorry ("non-PIC abicalls may only be used with the o32 ABI"); -+ - /* If no -mlong* option was given, infer it from the other options. */ - if ((target_flags_explicit & MASK_LONG64) == 0) - { -@@ -12136,23 +12498,21 @@ mips_override_options (void) - target_flags &= ~MASK_ABICALLS; - } - -- /* MIPS16 cannot generate PIC yet. */ -+ /* MIPS16 cannot generate PIC or abicalls yet. */ - if (TARGET_MIPS16 && (flag_pic || TARGET_ABICALLS)) - { -- sorry ("MIPS16 PIC"); -+ sorry ("MIPS16 PIC or abicalls are not yet implemented"); - target_flags &= ~MASK_ABICALLS; - flag_pic = flag_pie = flag_shlib = 0; - } - -- if (TARGET_ABICALLS) -- /* We need to set flag_pic for executables as well as DSOs -- because we may reference symbols that are not defined in -- the final executable. (MIPS does not use things like -- copy relocs, for example.) -- -- Also, there is a body of code that uses __PIC__ to distinguish -- between -mabicalls and -mno-abicalls code. */ -- 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 -@@ -12167,6 +12527,11 @@ mips_override_options (void) - - /* If we have a nonzero small-data limit, check that the -mgpopt - setting is consistent with the other target flags. */ -+ -+ /* Set the small data limit. */ -+ mips_small_data_threshold = (g_switch_set -+ ? g_switch_value -+ : MIPS_DEFAULT_GVALUE); - if (mips_small_data_threshold > 0) - { - if (!TARGET_GPOPT) -@@ -12262,6 +12627,10 @@ mips_override_options (void) - /* Function to allocate machine-dependent function status. */ - init_machine_status = &mips_init_machine_status; - -+ /* __thread_support is not supported by uClibc. */ -+ if (building_for_uclibc) -+ targetm.have_tls = 0; -+ - /* Default to working around R4000 errata only if the processor - was selected explicitly. */ - if ((target_flags_explicit & MASK_FIX_R4000) == 0 -@@ -12314,18 +12683,24 @@ mips_swap_registers (unsigned int i) - #undef SWAP_STRING - #undef SWAP_INT - } -- --/* Implement CONDITIONAL_REGISTER_USAGE. */ -- - void - mips_conditional_register_usage (void) - { -+ -+ /* These DSP control register fields are global. */ -+ if (ISA_HAS_DSP) -+ { -+ global_regs[CCDSP_PO_REGNUM] = 1; -+ global_regs[CCDSP_SC_REGNUM] = 1; -+ } - if (!ISA_HAS_DSP) - { - int regno; - - for (regno = DSP_ACC_REG_FIRST; regno <= DSP_ACC_REG_LAST; regno++) - fixed_regs[regno] = call_used_regs[regno] = 1; -+ for (regno = DSP_CTRL_REG_FIRST; regno <= DSP_CTRL_REG_LAST; regno++) -+ fixed_regs[regno] = call_used_regs[regno] = 1; - } - if (!TARGET_HARD_FLOAT) - { -@@ -12387,6 +12762,24 @@ mips_conditional_register_usage (void) - for (regno = DSP_ACC_REG_FIRST; regno <= DSP_ACC_REG_LAST; regno += 2) - mips_swap_registers (regno); - } -+ /* In non-PIC abicalls, $gp is completely ordinary; we can use a pseudo -+ for TLS GOT entries. */ -+ if (TARGET_NONPIC_ABICALLS) -+ { -+ call_used_regs[GLOBAL_POINTER_REGNUM] = TARGET_OLDABI; -+ call_really_used_regs[GLOBAL_POINTER_REGNUM] = TARGET_OLDABI; -+ fixed_regs[GLOBAL_POINTER_REGNUM] = 0; -+ } -+ /* $f30 is reserved for errata workarounds in ICE9A. */ -+ if (TARGET_FIX_ICE9A) -+ { -+ const int f30 = FP_REG_FIRST + 30; -+ const int f31 = FP_REG_FIRST + 31; -+ -+ fixed_regs[f30] = call_really_used_regs[f30] = call_used_regs[f30] = 1; -+ if (MAX_FPRS_PER_FMT == 2) -+ fixed_regs[f31] = call_really_used_regs[f31] = call_used_regs[f31] = 1; -+ } - } - - /* When generating MIPS16 code, we want to allocate $24 (T_REG) before -@@ -12411,6 +12804,153 @@ mips_order_regs_for_local_alloc (void) - } - } - -+#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; -+} -+ -+/* 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); -+} -+ -+/* 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); -+} -+ -+/* 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 -+ - /* Initialize the GCC target structure. */ - #undef TARGET_ASM_ALIGNED_HI_OP - #define TARGET_ASM_ALIGNED_HI_OP "\t.half\t" -@@ -12571,6 +13111,7 @@ mips_order_regs_for_local_alloc (void) - #undef TARGET_DWARF_REGISTER_SPAN - #define TARGET_DWARF_REGISTER_SPAN mips_dwarf_register_span - -+ - struct gcc_target targetm = TARGET_INITIALIZER; - - #include "gt-mips.h" ---- a/gcc/config/mips/mips.h -+++ b/gcc/config/mips/mips.h -@@ -67,6 +67,8 @@ enum processor_type { - PROCESSOR_SB1, - PROCESSOR_SB1A, - PROCESSOR_SR71000, -+ PROCESSOR_XLR, -+ PROCESSOR_OCTEON, - PROCESSOR_MAX - }; - -@@ -179,15 +181,19 @@ enum mips_code_readable_setting { - #define TARGET_SIBCALLS \ - (!TARGET_MIPS16 && (!TARGET_USE_GOT || TARGET_EXPLICIT_RELOCS)) - --/* True if we need to use a global offset table to access some symbols. */ --#define TARGET_USE_GOT (TARGET_ABICALLS || TARGET_RTP_PIC) -+/* True if we need to use a global offset table to access some symbols. -+ Small data and TLS are not counted. */ -+#define TARGET_USE_GOT ((TARGET_ABICALLS && flag_pic) || TARGET_RTP_PIC) - - /* True if TARGET_USE_GOT and if $gp is a call-clobbered register. */ --#define TARGET_CALL_CLOBBERED_GP (TARGET_ABICALLS && TARGET_OLDABI) -+#define TARGET_CALL_CLOBBERED_GP (TARGET_ABICALLS && flag_pic && TARGET_OLDABI) - - /* True if TARGET_USE_GOT and if $gp is a call-saved register. */ - #define TARGET_CALL_SAVED_GP (TARGET_USE_GOT && !TARGET_CALL_CLOBBERED_GP) - -+/* True if using abicalls, but not ourselves PIC. */ -+#define TARGET_NONPIC_ABICALLS (TARGET_ABICALLS && !flag_pic) -+ - /* True if indirect calls must use register class PIC_FN_ADDR_REG. - This is true for both the PIC and non-PIC VxWorks RTP modes. */ - #define TARGET_USE_PIC_FN_ADDR_REG (TARGET_ABICALLS || TARGET_VXWORKS_RTP) -@@ -197,7 +203,8 @@ enum mips_code_readable_setting { - Although GAS does understand .gpdword, the SGI linker mishandles - the relocations GAS generates (R_MIPS_GPREL32 followed by R_MIPS_64). - We therefore disable GP-relative switch tables for n64 on IRIX targets. */ --#define TARGET_GPWORD (TARGET_ABICALLS && !(mips_abi == ABI_64 && TARGET_IRIX)) -+#define TARGET_GPWORD (TARGET_ABICALLS && flag_pic \ -+ && !(mips_abi == ABI_64 && TARGET_IRIX)) - - /* Generate mips16 code */ - #define TARGET_MIPS16 ((target_flags & MASK_MIPS16) != 0) -@@ -237,6 +244,8 @@ enum mips_code_readable_setting { - #define TARGET_SB1 (mips_arch == PROCESSOR_SB1 \ - || mips_arch == PROCESSOR_SB1A) - #define TARGET_SR71K (mips_arch == PROCESSOR_SR71000) -+#define TARGET_OCTEON (mips_arch == PROCESSOR_OCTEON) -+#define TARGET_XLR (mips_arch == PROCESSOR_XLR) - - /* Scheduling target defines. */ - #define TUNE_MIPS3000 (mips_tune == PROCESSOR_R3000) -@@ -311,6 +320,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 -@@ -435,7 +447,10 @@ enum mips_code_readable_setting { - else if (ISA_MIPS64) \ - { \ - builtin_define ("__mips=64"); \ -- builtin_define ("__mips_isa_rev=1"); \ -+ if (TARGET_OCTEON) \ -+ builtin_define ("__mips_isa_rev=2"); \ -+ else \ -+ builtin_define ("__mips_isa_rev=1"); \ - builtin_define ("_MIPS_ISA=_MIPS_ISA_MIPS64"); \ - } \ - \ -@@ -520,6 +535,9 @@ enum mips_code_readable_setting { - \ - if (mips_abi == ABI_EABI) \ - builtin_define ("__mips_eabi"); \ -+ \ -+ if (TARGET_FIX_ICE9A) \ -+ builtin_define ("_MIPS_FIX_ICE9A"); \ - } \ - while (0) - -@@ -651,7 +669,8 @@ enum mips_code_readable_setting { - %{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=mips64|march=5k*|march=20k*|march=sb1*|march=sr71000 \ -+ |march=octeon|march=xlr: -mips64} \ - %{!march=*: -" MULTILIB_ISA_DEFAULT "}}" - - /* A spec that infers a -mhard-float or -msoft-float setting from an -@@ -664,6 +683,11 @@ enum mips_code_readable_setting { - |march=34kc|march=74kc|march=5kc: -msoft-float; \ - march=*: -mhard-float}" - -+/* A spec that infers the -mdsp setting from an -march argument. */ -+ -+#define MIPS_ARCH_DSP_SPEC \ -+ "%{!mno-dsp:%{march=24ke*|march=34k*|march=74k*: -mdsp}}" -+ - /* A spec condition that matches 32-bit options. It only works if - MIPS_ISA_LEVEL_SPEC has been applied. */ - -@@ -672,19 +696,27 @@ 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-arch32 and --with-arch64. -+ --with-tune is ignored if -mtune is specified; likewise -+ --with-tune32 and --with-tune64. - --with-abi is ignored if -mabi is specified. - --with-float is ignored if -mhard-float or -msoft-float are - specified. - --with-divide is ignored if -mdivide-traps or -mdivide-breaks are -- specified. */ -+ specified. -+ --with-fix-ice9a is ignored if -mfix-ice9a or -mno-fix-ice9a are -+ specified. */ - #define OPTION_DEFAULT_SPECS \ - {"arch", "%{" MIPS_ARCH_OPTION_SPEC ":;: -march=%(VALUE)}" }, \ -+ {"arch32", "%{!mabi=*|mabi=32:%{" MIPS_ARCH_OPTION_SPEC ":;: -march=%(VALUE)}}" }, \ -+ {"arch64", "%{mabi=n32|mabi=64:%{" MIPS_ARCH_OPTION_SPEC ":;: -march=%(VALUE)}}" }, \ - {"tune", "%{!mtune=*:-mtune=%(VALUE)}" }, \ -+ {"tune32", "%{!mabi=*|mabi=32:%{!mtune=*:-mtune=%(VALUE)}}" }, \ -+ {"tune64", "%{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)}}" }, \ -+ {"fix-ice9a", "%{!mfix-ice9a:%{!mno-fix-ice9a:-mfix-ice9a}}" }, \ - {"llsc", "%{!mllsc:%{!mno-llsc:-m%(VALUE)}}" } - - -@@ -783,6 +815,9 @@ enum mips_code_readable_setting { - || ISA_MIPS64) \ - && !TARGET_MIPS16) - -+/* ISA has Octeon specific pop instruction */ -+#define ISA_HAS_POPCOUNT (TARGET_OCTEON && !TARGET_MIPS16) -+ - /* ISA has three operand multiply instructions that put - the high part in an accumulator: mulhi or mulhiu. */ - #define ISA_HAS_MULHI ((TARGET_MIPS5400 \ -@@ -823,6 +858,7 @@ enum mips_code_readable_setting { - || TARGET_MIPS5400 \ - || TARGET_MIPS5500 \ - || TARGET_SR71K \ -+ || TARGET_OCTEON \ - || TARGET_SMARTMIPS) \ - && !TARGET_MIPS16) - -@@ -848,13 +884,33 @@ enum mips_code_readable_setting { - #define ISA_HAS_TRUNC_W (!ISA_MIPS1) - - /* ISA includes the MIPS32r2 seb and seh instructions. */ --#define ISA_HAS_SEB_SEH (ISA_MIPS32R2 \ -+#define ISA_HAS_SEB_SEH ((ISA_MIPS32R2 || TARGET_OCTEON) \ - && !TARGET_MIPS16) - - /* ISA includes the MIPS32/64 rev 2 ext and ins instructions. */ --#define ISA_HAS_EXT_INS (ISA_MIPS32R2 \ -+#define ISA_HAS_EXT_INS ((ISA_MIPS32R2 || TARGET_OCTEON) \ - && !TARGET_MIPS16) - -+/* ISA includes the exts instructions. */ -+#define ISA_HAS_EXTS (TARGET_OCTEON && !TARGET_MIPS16) -+ -+/* ISA includes the bbit* instructions. */ -+#define ISA_HAS_BBIT (TARGET_OCTEON && !TARGET_MIPS16) -+ -+/* ISA includes the seq and sne instructions. */ -+#define ISA_HAS_SEQ_SNE (TARGET_OCTEON && !TARGET_MIPS16) -+ -+/* ISA includes the baddu instruction. */ -+#define ISA_HAS_BADDU (TARGET_OCTEON && !TARGET_MIPS16) -+ -+/* ISA has single-instruction unalinged 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) -+ - /* ISA has instructions for accessing top part of 64-bit fp regs. */ - #define ISA_HAS_MXHC1 (TARGET_FLOAT64 && ISA_MIPS32R2) - -@@ -935,6 +991,49 @@ enum mips_code_readable_setting { - #endif - - -+/* Some targets (most of those with dynamic linking, e.g. Irix, -+ GNU/Linux, BSD) default to -mabicalls. They mostly default to PIC -+ also. Force the appropriate -mabicalls setting into the command -+ line for the benefit of the -fno-pic spec just below. */ -+#ifdef TARGET_ABICALLS_DEFAULT -+#define ABICALLS_SPEC "%{!mno-abicalls:%{!mabicalls:-mabicalls}}" -+#else -+#define ABICALLS_SPEC "%{!mno-abicalls:%{!mabicalls:-mno-abicalls}}" -+#endif -+ -+/* Make -mabicalls imply PIC unless the target supports non-PIC -+ abicalls. Targets which do not support non-PIC abicalls must set -+ flag_pic for executables as well as DSOs -+ because we may reference symbols that are not defined in -+ the final executable - these targets do not have copy relocs. -+ -+ All 64-bit targets are assumed to not support PIC abicalls. -+ CSL NOTE: It would be nice to remove this restriction before -+ contributing upstream; 64-bit support should be a small project. -+ -+ Also, there is a body of code that uses __PIC__ to distinguish -+ between -mabicalls and -mno-abicalls code. For targets with -+ non-PIC abicalls support any such code will have to be corrected. -+ All you need to do if !__PIC__ is use $t9 for indirect calls -+ and be careful about assuming $gp is set up in inline asm. */ -+#ifdef TARGET_ABICALLS_NONPIC -+#define ABICALLS_SELF_SPECS ABICALLS_SPEC, \ -+ "%{mabicalls:%{!fno-pic:%{mabi=o64|mabi=64|mabi=n32:-fpic}}}" -+#else -+#define ABICALLS_SELF_SPECS ABICALLS_SPEC, \ -+ "%{mabicalls:%{!fno-pic:-fpic}}" -+#endif -+ -+/* Any additional self specs defined by the subtarget. */ -+#ifndef SUBTARGET_SELF_SPECS -+#define SUBTARGET_SELF_SPECS "" -+#endif -+ -+#define DRIVER_SELF_SPECS \ -+ SUBTARGET_SELF_SPECS, \ -+ ABICALLS_SELF_SPECS -+ -+ - #ifndef MIPS_ABI_DEFAULT - #define MIPS_ABI_DEFAULT ABI_32 - #endif -@@ -1003,7 +1102,7 @@ enum mips_code_readable_setting { - %{mdspr2} %{mno-dspr2} \ - %{msmartmips} %{mno-smartmips} \ - %{mmt} %{mno-mt} \ --%{mfix-vr4120} %{mfix-vr4130} \ -+%{mfix-vr4120} %{mfix-vr4130} %{mfix-ice9a} %{mno-fix-ice9a} \ - %(subtarget_asm_optimizing_spec) \ - %(subtarget_asm_debugging_spec) \ - %{mabi=*} %{!mabi*: %(asm_abi_default_spec)} \ -@@ -1012,6 +1111,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. */ -@@ -1515,9 +1615,24 @@ enum mips_code_readable_setting { - #define DSP_ACC_REG_LAST 181 - #define DSP_ACC_REG_NUM (DSP_ACC_REG_LAST - DSP_ACC_REG_FIRST + 1) - -+#define DSP_CTRL_REG_FIRST 182 -+#define DSP_CTRL_REG_LAST 187 -+ - #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) - - /* 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 -@@ -1673,6 +1788,7 @@ enum reg_class - ST_REGS, /* status registers (fp status) */ - DSP_ACC_REGS, /* DSP accumulator registers */ - ACC_REGS, /* Hi/Lo and DSP accumulator registers */ -+ FRAME_REGS, /* $arg and $frame */ - ALL_REGS, /* all registers */ - LIM_REG_CLASSES /* max value + 1 */ - }; -@@ -1715,6 +1831,7 @@ enum reg_class - "ST_REGS", \ - "DSP_ACC_REGS", \ - "ACC_REGS", \ -+ "FRAME_REGS", \ - "ALL_REGS" \ - } - -@@ -1758,7 +1875,8 @@ enum reg_class - { 0x00000000, 0x00000000, 0x000007f8, 0x00000000, 0x00000000, 0x00000000 }, /* status registers */ \ - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x003f0000 }, /* dsp accumulator registers */ \ - { 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x003f0000 }, /* hi/lo and dsp accumulator registers */ \ -- { 0xffffffff, 0xffffffff, 0xffff07ff, 0xffffffff, 0xffffffff, 0x0fffffff } /* all registers */ \ -+ { 0x00000000, 0x00000000, 0x00006000, 0x00000000, 0x00000000, 0x00000000 }, /* frame registers */ \ -+ { 0xffffffff, 0xffffffff, 0xffff67ff, 0xffffffff, 0xffffffff, 0x0fffffff } /* all registers */ \ - } - - -@@ -2446,7 +2564,7 @@ typedef struct mips_args { - ? "%*" INSN "\t%" #OPNO "%/" \ - : REG_P (OPERANDS[OPNO]) \ - ? "%*" INSN "r\t%" #OPNO "%/" \ -- : TARGET_ABICALLS \ -+ : TARGET_ABICALLS && flag_pic \ - ? (".option\tpic0\n\t" \ - "%*" INSN "\t%" #OPNO "%/\n\t" \ - ".option\tpic2") \ ---- a/gcc/config/mips/mips.md -+++ b/gcc/config/mips/mips.md -@@ -60,7 +60,10 @@ - (UNSPEC_MEMORY_BARRIER 41) - (UNSPEC_SET_GOT_VERSION 42) - (UNSPEC_UPDATE_GOT_VERSION 43) -- -+ -+ (UNSPEC_UNALIGNED_LOAD 50) -+ (UNSPEC_UNALIGNED_STORE 51) -+ - (UNSPEC_ADDRESS_FIRST 100) - - (TLS_GET_TP_REGNUM 3) -@@ -269,6 +272,7 @@ - ;; slt set less than instructions - ;; signext sign extend instructions - ;; clz the clz and clo instructions -+;; pop pop and dpop - ;; trap trap if instructions - ;; imul integer multiply 2 operands - ;; imul3 integer multiply 3 operands -@@ -291,11 +295,17 @@ - ;; 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 - (define_attr "type" -- "unknown,branch,jump,call,load,fpload,fpidxload,store,fpstore,fpidxstore,prefetch,prefetchx,condmove,mfc,mtc,mthilo,mfhilo,const,arith,logical,shift,slt,signext,clz,trap,imul,imul3,imadd,idiv,move,fmove,fadd,fmul,fmadd,fdiv,frdiv,frdiv1,frdiv2,fabs,fneg,fcmp,fcvt,fsqrt,frsqrt,frsqrt1,frsqrt2,multi,nop,ghost" -+ "unknown,branch,jump,call,load,fpload,fpidxload,store,fpstore,fpidxstore,prefetch,prefetchx,condmove,mfc,mtc,mthilo,mfhilo,const,arith,logical,shift,slt,signext,clz,pop,trap,imul,imul3,imadd,idiv,move,fmove,fadd,fmul,fmadd,fdiv,frdiv,frdiv1,frdiv2,fabs,fneg,fcmp,fcvt,fsqrt,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")] - (const_string "unknown"))) -@@ -412,7 +422,7 @@ - ;; Attribute describing the processor. This attribute must match exactly - ;; with the processor_type enumeration in mips.h. - (define_attr "cpu" -- "r3000,4kc,4kp,5kc,5kf,20kc,24kc,24kf2_1,24kf1_1,74kc,74kf2_1,74kf1_1,74kf3_2,m4k,r3900,r6000,r4000,r4100,r4111,r4120,r4130,r4300,r4600,r4650,r5000,r5400,r5500,r7000,r8000,r9000,sb1,sb1a,sr71000" -+ "r3000,4kc,4kp,5kc,5kf,20kc,24kc,24kf2_1,24kf1_1,74kc,74kf2_1,74kf1_1,74kf3_2,m4k,r3900,r6000,r4000,r4100,r4111,r4120,r4130,r4300,r4600,r4650,r5000,r5400,r5500,r7000,r8000,r9000,sb1,sb1a,sr71000,xlr,octeon" - (const (symbol_ref "mips_tune"))) - - ;; The type of hardware hazard associated with this instruction. -@@ -461,6 +471,16 @@ - (const_string "yes") - (const_string "no")))) - -+;; Attributes defining whether a branch has a branch-likely variant. -+(define_attr "branch_without_likely" "no,yes" (const_string "no")) -+ -+(define_attr "branch_with_likely" "no,yes" -+ (if_then_else -+ (and (eq_attr "type" "branch") -+ (eq_attr "branch_without_likely" "no")) -+ (const_string "yes") -+ (const_string "no"))) -+ - ;; True if an instruction might assign to hi or lo when reloaded. - ;; This is used by the TUNE_MACC_CHAINS code. - (define_attr "may_clobber_hilo" "no,yes" -@@ -513,6 +533,30 @@ - (V2SF "!TARGET_64BIT && TARGET_PAIRED_SINGLE_FLOAT") - (TF "TARGET_64BIT && TARGET_FLOAT64")]) - -+;; The attributes for the ICE9A fix. -+(define_mode_attr ice9a_stallnops [(SF "") (V2SF "") -+ (DF "movn.d\t$f30, $f28, $0\;movn.d\t$f30, $f28, $0\;movn.d\t$f30, $f28, $0\;movn.d\t$f30, $f28, $0\;movn.d\t$f30, $f28, $0\;")]) -+(define_mode_attr ice9a_round [(SF "") (V2SF "") -+ (DF "\;movn.d\t$f30, %0, $0")]) -+ -+ -+ -+;; stall workaround = 5 insns, => length = 4 * (1+5) = 24 -+(define_mode_attr ice9a_length_stall [(SF "4") (V2SF "4") -+ (DF "24")]) -+ -+;; round workaround = 1 insn, => length = 4 * (1+1) = 8 -+(define_mode_attr ice9a_length_round [(SF "4") (V2SF "4") -+ (DF "8")]) -+ -+;; both workarounds = 5+1 insn, => length = 4 * (1+5+1) = 28 -+(define_mode_attr ice9a_length_both [(SF "4") (V2SF "4") -+ (DF "28")]) -+ -+ -+ -+ -+ - ;; In GPR templates, a string like "subu" will expand to "subu" in the - ;; 32-bit version and "dsubu" in the 64-bit version. - (define_mode_attr d [(SI "") (DI "d") -@@ -525,9 +569,12 @@ - ;; instruction. - (define_mode_attr size [(QI "b") (HI "h")]) - --;; This attributes gives the mode mask of a SHORT. -+;; This attribute gives the mode mask of a SHORT. - (define_mode_attr mask [(QI "0x00ff") (HI "0xffff")]) - -+;; This attribute gives the number of the topmost bit of a SUBDI. -+(define_mode_attr topbit [(QI "7") (HI "15") (SI "31")]) -+ - ;; Mode attributes for GPR loads and stores. - (define_mode_attr load [(SI "lw") (DI "ld")]) - (define_mode_attr store [(SI "sw") (DI "sd")]) -@@ -599,14 +646,23 @@ - ;; to use the same template. - (define_code_iterator any_extend [sign_extend zero_extend]) - -+;; This code iterator allows both sorts of extraction to be treated alike. -+(define_code_iterator any_extract [sign_extract zero_extract]) -+ - ;; This code iterator allows the three shift instructions to be generated - ;; from the same template. - (define_code_iterator any_shift [ashift ashiftrt lshiftrt]) - -+;; This code iterator allows both of the right shift codes to be treated alike. -+(define_code_iterator any_shiftrt [ashiftrt lshiftrt]) -+ - ;; This code iterator allows all native floating-point comparisons to be - ;; generated from the same template. - (define_code_iterator fcond [unordered uneq unlt unle eq lt le]) - -+;; This code iterator allows both equality operators to be treated alike. -+(define_code_iterator equality_op [eq ne]) -+ - ;; This code iterator is used for comparisons that can be implemented - ;; by swapping the operands. - (define_code_iterator swapped_fcond [ge gt unge ungt]) -@@ -663,13 +719,19 @@ - ;; - ;; ......................... - --(define_delay (and (eq_attr "type" "branch") -+(define_delay (and (eq_attr "branch_with_likely" "yes") - (eq (symbol_ref "TARGET_MIPS16") (const_int 0))) - [(eq_attr "can_delay" "yes") - (nil) - (and (eq_attr "branch_likely" "yes") - (eq_attr "can_delay" "yes"))]) - -+(define_delay (and (eq_attr "branch_without_likely" "yes") -+ (eq (symbol_ref "TARGET_MIPS16") (const_int 0))) -+ [(eq_attr "can_delay" "yes") -+ (nil) -+ (nil)]) -+ - (define_delay (eq_attr "type" "jump") - [(eq_attr "can_delay" "yes") - (nil) -@@ -720,7 +782,9 @@ - (include "7000.md") - (include "9000.md") - (include "sb1.md") -+(include "octeon.md") - (include "sr71k.md") -+(include "xlr.md") - (include "generic.md") - - ;; -@@ -985,6 +1049,51 @@ - [(set_attr "type" "arith") - (set_attr "mode" "SI") - (set_attr "extended_mips16" "yes")]) -+ -+;; Combiner patterns for unsigned byte-add. -+ -+(define_insn "*baddu_si" -+ [(set (match_operand:SI 0 "register_operand" "=d") -+ (zero_extend:SI -+ (subreg:QI -+ (plus:SI (match_operand:SI 1 "register_operand" "d") -+ (match_operand:SI 2 "register_operand" "d")) 3)))] -+ "ISA_HAS_BADDU && TARGET_BIG_ENDIAN" -+ "baddu\\t%0,%1,%2" -+ [(set_attr "type" "arith")]) -+ -+(define_insn "*baddu_disi" -+ [(set (match_operand:SI 0 "register_operand" "=d") -+ (zero_extend:SI -+ (truncate:QI -+ (plus:DI (match_operand:DI 1 "register_operand" "d") -+ (match_operand:DI 2 "register_operand" "d")))))] -+ "TARGET_64BIT && ISA_HAS_BADDU" -+ "baddu\\t%0,%1,%2" -+ [(set_attr "type" "arith")]) -+ -+(define_insn "*baddu_didi" -+ [(set (match_operand:DI 0 "register_operand" "=d") -+ (zero_extend:DI -+ (truncate:QI -+ (plus:DI -+ (subreg:DI -+ (truncate:QI (match_operand:DI 1 "register_operand" "d")) 0) -+ (subreg:DI -+ (truncate:QI (match_operand:DI 2 "register_operand" "d")) 0)))))] -+ "TARGET_64BIT && ISA_HAS_BADDU" -+ "baddu\\t%0,%1,%2" -+ [(set_attr "type" "arith")]) -+ -+(define_insn "*baddu_didi2" -+ [(set (match_operand:DI 0 "register_operand" "=d") -+ (zero_extend:DI -+ (truncate:QI -+ (plus:DI (match_operand:DI 1 "register_operand" "d") -+ (match_operand:DI 2 "register_operand" "d")))))] -+ "TARGET_64BIT && ISA_HAS_BADDU" -+ "baddu\\t%0,%1,%2" -+ [(set_attr "type" "arith")]) - - ;; - ;; .................... -@@ -1041,7 +1150,7 @@ - [(set (match_operand:SCALARF 0 "register_operand" "=f") - (mult:SCALARF (match_operand:SCALARF 1 "register_operand" "f") - (match_operand:SCALARF 2 "register_operand" "f")))] -- "!TARGET_4300_MUL_FIX" -+ "!TARGET_4300_MUL_FIX && !TARGET_FIX_ICE9A" - "mul.\t%0,%1,%2" - [(set_attr "type" "fmul") - (set_attr "mode" "")]) -@@ -1054,12 +1163,22 @@ - [(set (match_operand:SCALARF 0 "register_operand" "=f") - (mult:SCALARF (match_operand:SCALARF 1 "register_operand" "f") - (match_operand:SCALARF 2 "register_operand" "f")))] -- "TARGET_4300_MUL_FIX" -+ "TARGET_4300_MUL_FIX && !TARGET_FIX_ICE9A" - "mul.\t%0,%1,%2\;nop" - [(set_attr "type" "fmul") - (set_attr "mode" "") - (set_attr "length" "8")]) - -+(define_insn "*mul3_fix_ice9a" -+ [(set (match_operand:SCALARF 0 "register_operand" "=f") -+ (mult:SCALARF (match_operand:SCALARF 1 "register_operand" "f") -+ (match_operand:SCALARF 2 "register_operand" "f")))] -+ "TARGET_FIX_ICE9A && !TARGET_4300_MUL_FIX" -+ "mul.\t%0,%1,%2" -+ [(set_attr "type" "fmul") -+ (set_attr "mode" "") -+ (set_attr "length" "")]) -+ - (define_insn "mulv2sf3" - [(set (match_operand:V2SF 0 "register_operand" "=f") - (mult:V2SF (match_operand:V2SF 1 "register_operand" "f") -@@ -1849,21 +1968,43 @@ - (plus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f") - (match_operand:ANYF 2 "register_operand" "f")) - (match_operand:ANYF 3 "register_operand" "f")))] -- "ISA_HAS_FP4 && TARGET_FUSED_MADD" -+ "ISA_HAS_FP4 && TARGET_FUSED_MADD && !TARGET_FIX_ICE9A" - "madd.\t%0,%3,%1,%2" - [(set_attr "type" "fmadd") - (set_attr "mode" "")]) - -+(define_insn "*madd_ice9a" -+ [(set (match_operand:ANYF 0 "register_operand" "=f") -+ (plus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f") -+ (match_operand:ANYF 2 "register_operand" "f")) -+ (match_operand:ANYF 3 "register_operand" "f")))] -+ "ISA_HAS_FP4 && TARGET_FUSED_MADD && TARGET_FIX_ICE9A" -+ "madd.\t%0,%3,%1,%2" -+ [(set_attr "type" "fmadd") -+ (set_attr "mode" "") -+ (set_attr "length" "")]) -+ - (define_insn "*msub" - [(set (match_operand:ANYF 0 "register_operand" "=f") - (minus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f") - (match_operand:ANYF 2 "register_operand" "f")) - (match_operand:ANYF 3 "register_operand" "f")))] -- "ISA_HAS_FP4 && TARGET_FUSED_MADD" -+ "ISA_HAS_FP4 && TARGET_FUSED_MADD && !TARGET_FIX_ICE9A" - "msub.\t%0,%3,%1,%2" - [(set_attr "type" "fmadd") - (set_attr "mode" "")]) - -+(define_insn "*msub_ice9a" -+ [(set (match_operand:ANYF 0 "register_operand" "=f") -+ (minus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f") -+ (match_operand:ANYF 2 "register_operand" "f")) -+ (match_operand:ANYF 3 "register_operand" "f")))] -+ "ISA_HAS_FP4 && TARGET_FUSED_MADD && TARGET_FIX_ICE9A" -+ "msub.\t%0,%3,%1,%2" -+ [(set_attr "type" "fmadd") -+ (set_attr "mode" "") -+ (set_attr "length" "")]) -+ - (define_insn "*nmadd" - [(set (match_operand:ANYF 0 "register_operand" "=f") - (neg:ANYF (plus:ANYF -@@ -1873,7 +2014,8 @@ - "ISA_HAS_NMADD_NMSUB (mode) - && TARGET_FUSED_MADD - && HONOR_SIGNED_ZEROS (mode) -- && !HONOR_NANS (mode)" -+ && !HONOR_NANS (mode) -+ && !TARGET_FIX_ICE9A" - "nmadd.\t%0,%3,%1,%2" - [(set_attr "type" "fmadd") - (set_attr "mode" "")]) -@@ -1887,11 +2029,44 @@ - "ISA_HAS_NMADD_NMSUB (mode) - && TARGET_FUSED_MADD - && !HONOR_SIGNED_ZEROS (mode) -- && !HONOR_NANS (mode)" -+ && !HONOR_NANS (mode) -+ && !TARGET_FIX_ICE9A" - "nmadd.\t%0,%3,%1,%2" - [(set_attr "type" "fmadd") - (set_attr "mode" "")]) - -+(define_insn "*nmadd_ice9a" -+ [(set (match_operand:ANYF 0 "register_operand" "=f") -+ (neg:ANYF (plus:ANYF -+ (mult:ANYF (match_operand:ANYF 1 "register_operand" "f") -+ (match_operand:ANYF 2 "register_operand" "f")) -+ (match_operand:ANYF 3 "register_operand" "f"))))] -+ "ISA_HAS_NMADD_NMSUB (mode) -+ && TARGET_FUSED_MADD -+ && HONOR_SIGNED_ZEROS (mode) -+ && !HONOR_NANS (mode) -+ && TARGET_FIX_ICE9A" -+ "nmadd.\t%0,%3,%1,%2" -+ [(set_attr "type" "fmadd") -+ (set_attr "length" "") -+ (set_attr "mode" "")]) -+ -+(define_insn "*nmadd_fastmath_ice9a" -+ [(set (match_operand:ANYF 0 "register_operand" "=f") -+ (minus:ANYF -+ (mult:ANYF (neg:ANYF (match_operand:ANYF 1 "register_operand" "f")) -+ (match_operand:ANYF 2 "register_operand" "f")) -+ (match_operand:ANYF 3 "register_operand" "f")))] -+ "ISA_HAS_NMADD_NMSUB (mode) -+ && TARGET_FUSED_MADD -+ && !HONOR_SIGNED_ZEROS (mode) -+ && !HONOR_NANS (mode) -+ && TARGET_FIX_ICE9A" -+ "nmadd.\t%0,%3,%1,%2" -+ [(set_attr "type" "fmadd") -+ (set_attr "length" "") -+ (set_attr "mode" "")]) -+ - (define_insn "*nmsub" - [(set (match_operand:ANYF 0 "register_operand" "=f") - (neg:ANYF (minus:ANYF -@@ -1901,7 +2076,8 @@ - "ISA_HAS_NMADD_NMSUB (mode) - && TARGET_FUSED_MADD - && HONOR_SIGNED_ZEROS (mode) -- && !HONOR_NANS (mode)" -+ && !HONOR_NANS (mode) -+ && !TARGET_FIX_ICE9A" - "nmsub.\t%0,%1,%2,%3" - [(set_attr "type" "fmadd") - (set_attr "mode" "")]) -@@ -1915,10 +2091,43 @@ - "ISA_HAS_NMADD_NMSUB (mode) - && TARGET_FUSED_MADD - && !HONOR_SIGNED_ZEROS (mode) -- && !HONOR_NANS (mode)" -+ && !HONOR_NANS (mode) -+ && !TARGET_FIX_ICE9A" - "nmsub.\t%0,%1,%2,%3" - [(set_attr "type" "fmadd") - (set_attr "mode" "")]) -+ -+(define_insn "*nmsub_ice9a" -+ [(set (match_operand:ANYF 0 "register_operand" "=f") -+ (neg:ANYF (minus:ANYF -+ (mult:ANYF (match_operand:ANYF 2 "register_operand" "f") -+ (match_operand:ANYF 3 "register_operand" "f")) -+ (match_operand:ANYF 1 "register_operand" "f"))))] -+ "ISA_HAS_NMADD_NMSUB (mode) -+ && TARGET_FUSED_MADD -+ && HONOR_SIGNED_ZEROS (mode) -+ && !HONOR_NANS (mode) -+ && TARGET_FIX_ICE9A" -+ "nmsub.\t%0,%1,%2,%3" -+ [(set_attr "type" "fmadd") -+ (set_attr "length" "") -+ (set_attr "mode" "")]) -+ -+(define_insn "*nmsub_fastmath_ice9a" -+ [(set (match_operand:ANYF 0 "register_operand" "=f") -+ (minus:ANYF -+ (match_operand:ANYF 1 "register_operand" "f") -+ (mult:ANYF (match_operand:ANYF 2 "register_operand" "f") -+ (match_operand:ANYF 3 "register_operand" "f"))))] -+ "ISA_HAS_NMADD_NMSUB (mode) -+ && TARGET_FUSED_MADD -+ && !HONOR_SIGNED_ZEROS (mode) -+ && !HONOR_NANS (mode) -+ && TARGET_FIX_ICE9A" -+ "nmsub.\t%0,%1,%2,%3" -+ [(set_attr "type" "fmadd") -+ (set_attr "length" "") -+ (set_attr "mode" "")]) - - ;; - ;; .................... -@@ -1973,19 +2182,40 @@ - [(set (match_operand:ANYF 0 "register_operand" "=f") - (div:ANYF (match_operand:ANYF 1 "const_1_operand" "") - (match_operand:ANYF 2 "register_operand" "f")))] -- " && flag_unsafe_math_optimizations" --{ -- if (TARGET_FIX_SB1) -- return "recip.\t%0,%2\;mov.\t%0,%0"; -- else -- return "recip.\t%0,%2"; --} -+ " && -+ flag_unsafe_math_optimizations && -+ !TARGET_FIX_SB1 && -+ !TARGET_FIX_ICE9A" -+ "recip.\t%0,%2" -+ [(set_attr "type" "frdiv") -+ (set_attr "mode" "")]) -+ -+(define_insn "*recip3_fix_sb1" -+ [(set (match_operand:ANYF 0 "register_operand" "=f") -+ (div:ANYF (match_operand:ANYF 1 "const_1_operand" "") -+ (match_operand:ANYF 2 "register_operand" "f")))] -+ " && -+ flag_unsafe_math_optimizations && -+ TARGET_FIX_SB1 && -+ !TARGET_FIX_ICE9A" -+ "recip.\t%0,%2\;mov.\t%0,%0" - [(set_attr "type" "frdiv") - (set_attr "mode" "") -- (set (attr "length") -- (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0)) -- (const_int 8) -- (const_int 4)))]) -+ (set_attr "length" "8")]) -+ -+(define_insn "*recip3_fix_ice9a" -+ [(set (match_operand:ANYF 0 "register_operand" "=f") -+ (div:ANYF (match_operand:ANYF 1 "const_1_operand" "") -+ (match_operand:ANYF 2 "register_operand" "f")))] -+ " && -+ flag_unsafe_math_optimizations && -+ !TARGET_FIX_SB1 && -+ TARGET_FIX_ICE9A" -+ "recip.\t%0,%2" -+ [(set_attr "type" "frdiv") -+ (set_attr "mode" "") -+ (set_attr "length" "")]) -+ - - ;; VR4120 errata MD(A1): signed division instructions do not work correctly - ;; with negative operands. We use special libgcc functions instead. -@@ -2021,60 +2251,117 @@ - ;; .................... - - ;; These patterns work around the early SB-1 rev2 core "F1" erratum (see --;; "*div[sd]f3" comment for details). -+;; "*div[sd]f3" comment for details), and ICE9A errata. - --(define_insn "sqrt2" -+(define_expand "sqrt2" - [(set (match_operand:ANYF 0 "register_operand" "=f") - (sqrt:ANYF (match_operand:ANYF 1 "register_operand" "f")))] - "" --{ -- if (TARGET_FIX_SB1) -- return "sqrt.\t%0,%1\;mov.\t%0,%0"; -- else -- return "sqrt.\t%0,%1"; --} -+ "") -+ -+(define_insn "*sqrt2" -+ [(set (match_operand:ANYF 0 "register_operand" "=f") -+ (sqrt:ANYF (match_operand:ANYF 1 "register_operand" "f")))] -+ " && -+ !TARGET_FIX_SB1 && -+ !TARGET_FIX_ICE9A" -+ "sqrt.\t%0,%1" -+ [(set_attr "type" "fsqrt") -+ (set_attr "mode" "")]) -+ -+(define_insn "*sqrt2_fix_sb1" -+ [(set (match_operand:ANYF 0 "register_operand" "=f") -+ (sqrt:ANYF (match_operand:ANYF 1 "register_operand" "f")))] -+ " && -+ TARGET_FIX_SB1 && -+ !TARGET_FIX_ICE9A" -+ "sqrt.\t%0,%1\;mov.\t%0,%0" - [(set_attr "type" "fsqrt") - (set_attr "mode" "") -- (set (attr "length") -- (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0)) -- (const_int 8) -- (const_int 4)))]) -+ (set_attr "length" "8")]) -+ -+(define_insn "*sqrt2_fix_ice9a" -+ [(set (match_operand:ANYF 0 "register_operand" "=f") -+ (sqrt:ANYF (match_operand:ANYF 1 "register_operand" "f")))] -+ " && -+ !TARGET_FIX_SB1 && -+ TARGET_FIX_ICE9A" -+ "sqrt.\t%0,%1" -+ [(set_attr "type" "fsqrt") -+ (set_attr "mode" "") -+ (set_attr "length" "")]) - - (define_insn "*rsqrta" - [(set (match_operand:ANYF 0 "register_operand" "=f") - (div:ANYF (match_operand:ANYF 1 "const_1_operand" "") - (sqrt:ANYF (match_operand:ANYF 2 "register_operand" "f"))))] -- " && flag_unsafe_math_optimizations" --{ -- if (TARGET_FIX_SB1) -- return "rsqrt.\t%0,%2\;mov.\t%0,%0"; -- else -- return "rsqrt.\t%0,%2"; --} -+ " && -+ flag_unsafe_math_optimizations && -+ !TARGET_FIX_SB1 && -+ !TARGET_FIX_ICE9A" -+ "rsqrt.\t%0,%2" -+ [(set_attr "type" "frsqrt") -+ (set_attr "mode" "")]) -+ -+(define_insn "*rsqrta_fix_sb1" -+ [(set (match_operand:ANYF 0 "register_operand" "=f") -+ (div:ANYF (match_operand:ANYF 1 "const_1_operand" "") -+ (sqrt:ANYF (match_operand:ANYF 2 "register_operand" "f"))))] -+ " && -+ flag_unsafe_math_optimizations && -+ TARGET_FIX_SB1" -+ "rsqrt.\t%0,%2\;mov.\t%0,%0" - [(set_attr "type" "frsqrt") - (set_attr "mode" "") -- (set (attr "length") -- (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0)) -- (const_int 8) -- (const_int 4)))]) -+ (set_attr "length" "8")]) -+ -+(define_insn "*rsqrta_fix_ice9a" -+ [(set (match_operand:ANYF 0 "register_operand" "=f") -+ (div:ANYF (match_operand:ANYF 1 "const_1_operand" "") -+ (sqrt:ANYF (match_operand:ANYF 2 "register_operand" "f"))))] -+ " && -+ flag_unsafe_math_optimizations && -+ TARGET_FIX_ICE9A" -+ "rsqrt.\t%0,%2" -+ [(set_attr "type" "frsqrt") -+ (set_attr "mode" "") -+ (set_attr "length" "")]) - - (define_insn "*rsqrtb" - [(set (match_operand:ANYF 0 "register_operand" "=f") - (sqrt:ANYF (div:ANYF (match_operand:ANYF 1 "const_1_operand" "") - (match_operand:ANYF 2 "register_operand" "f"))))] -- " && flag_unsafe_math_optimizations" --{ -- if (TARGET_FIX_SB1) -- return "rsqrt.\t%0,%2\;mov.\t%0,%0"; -- else -- return "rsqrt.\t%0,%2"; --} -+ " && -+ flag_unsafe_math_optimizations && -+ !TARGET_FIX_SB1 && -+ !TARGET_FIX_ICE9A" -+ "rsqrt.\t%0,%2" -+ [(set_attr "type" "frsqrt") -+ (set_attr "mode" "")]) -+ -+(define_insn "*rsqrtb_fix_sb1" -+ [(set (match_operand:ANYF 0 "register_operand" "=f") -+ (sqrt:ANYF (div:ANYF (match_operand:ANYF 1 "const_1_operand" "") -+ (match_operand:ANYF 2 "register_operand" "f"))))] -+ " && -+ flag_unsafe_math_optimizations && -+ TARGET_FIX_SB1" -+ "rsqrt.\t%0,%2\;mov.\t%0,%0" - [(set_attr "type" "frsqrt") - (set_attr "mode" "") -- (set (attr "length") -- (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0)) -- (const_int 8) -- (const_int 4)))]) -+ (set_attr "length" "8")]) -+ -+(define_insn "*rsqrtb_fix_ice9a" -+ [(set (match_operand:ANYF 0 "register_operand" "=f") -+ (sqrt:ANYF (div:ANYF (match_operand:ANYF 1 "const_1_operand" "") -+ (match_operand:ANYF 2 "register_operand" "f"))))] -+ " && -+ flag_unsafe_math_optimizations && -+ TARGET_FIX_ICE9A" -+ "rsqrt.\t%0,%2\;mov.\t%0,%0" -+ [(set_attr "type" "frsqrt") -+ (set_attr "mode" "") -+ (set_attr "length" "")]) - - ;; - ;; .................... -@@ -2093,7 +2380,9 @@ - (define_insn "abs2" - [(set (match_operand:ANYF 0 "register_operand" "=f") - (abs:ANYF (match_operand:ANYF 1 "register_operand" "f")))] -- "!HONOR_NANS (mode)" -+ "!HONOR_NANS (mode) -+ || (TARGET_MIPS_SDE -+ && TARGET_HARD_FLOAT)" - "abs.\t%0,%1" - [(set_attr "type" "fabs") - (set_attr "mode" "")]) -@@ -2115,6 +2404,22 @@ - (set_attr "mode" "")]) - - ;; -+;; ................... -+;; -+;; Count number of 1-bits. -+;; -+;; ................... -+;; -+ -+(define_insn "popcount2" -+ [(set (match_operand:GPR 0 "register_operand" "=d") -+ (popcount:GPR (match_operand:GPR 1 "register_operand" "d")))] -+ "ISA_HAS_POPCOUNT" -+ "pop\t%0,%1" -+ [(set_attr "type" "pop") -+ (set_attr "mode" "")]) -+ -+;; - ;; .................... - ;; - ;; NEGATION and ONE'S COMPLEMENT -@@ -2347,6 +2652,16 @@ - (set_attr "mode" "SI") - (set_attr "extended_mips16" "yes,*")]) - -+(define_insn "*_trunc_exts" -+ [(set (match_operand:SUBDI 0 "register_operand" "=d") -+ (truncate:SUBDI -+ (any_shiftrt:DI (match_operand:DI 1 "register_operand" "d") -+ (match_operand:DI 2 "const_int_operand" ""))))] -+ "TARGET_64BIT && ISA_HAS_EXTS && INTVAL (operands[2]) < 32" -+ "exts\t%0,%1,%2,31" -+ [(set_attr "type" "shift") -+ (set_attr "mode" "SI")]) -+ - ;; Combiner patterns to optimize shift/truncate combinations. - - (define_insn "" -@@ -2447,10 +2762,15 @@ - - ;; Extension insns. - --(define_insn_and_split "zero_extendsidi2" -+(define_expand "zero_extendsidi2" -+ [(set (match_operand:DI 0 "register_operand") -+ (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))] -+ "TARGET_64BIT") -+ -+(define_insn_and_split "*zero_extendsidi2" - [(set (match_operand:DI 0 "register_operand" "=d,d") - (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,W")))] -- "TARGET_64BIT" -+ "TARGET_64BIT && !ISA_HAS_EXT_INS" - "@ - # - lwu\t%0,%1" -@@ -2471,7 +2791,7 @@ - [(set (match_operand:DI 0 "register_operand" "=d,d") - (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,W") - (const_int 4294967295)))] -- "TARGET_64BIT" -+ "TARGET_64BIT && !ISA_HAS_EXT_INS" - { - if (which_alternative == 0) - return "#"; -@@ -2489,6 +2809,31 @@ - (set_attr "mode" "DI") - (set_attr "length" "8,*")]) - -+(define_insn "*zero_extendsidi2_dext" -+ [(set (match_operand:DI 0 "register_operand" "=d,d") -+ (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,W")))] -+ "TARGET_64BIT && ISA_HAS_EXT_INS" -+ "@ -+ dext\t%0,%1,0,32 -+ lwu\t%0,%1" -+ [(set_attr "type" "shift,load") -+ (set_attr "mode" "DI")]) -+ -+(define_insn "*clear_upper32_dext" -+ [(set (match_operand:DI 0 "register_operand" "=d,d") -+ (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,o") -+ (const_int 4294967295)))] -+ "TARGET_64BIT && ISA_HAS_EXT_INS" -+{ -+ if (which_alternative == 0) -+ return "dext\t%0,%1,0,32"; -+ -+ operands[1] = gen_lowpart (SImode, operands[1]); -+ return "lwu\t%0,%1"; -+} -+ [(set_attr "type" "shift,load") -+ (set_attr "mode" "DI")]) -+ - (define_expand "zero_extend2" - [(set (match_operand:GPR 0 "register_operand") - (zero_extend:GPR (match_operand:SHORT 1 "nonimmediate_operand")))] -@@ -3026,11 +3371,18 @@ - ;; - ;; .................... - --;; Bit field extract patterns which use lwl/lwr or ldl/ldr. -+;; Bit field extract patterns which use lwl/lwr or ldl/ldr or -+;; exts/ext/dext. -+ -+;; ??? Using nonimmediate_operand for operand 1 will cause mode_for_extraction -+;; to return word_mode rather than QImode for memories. That's probably -+;; harmless given the current middle-end code; the RTL expander will only -+;; pass QImode references in any case, and any attempt to recog() a memory -+;; extraction will fail whatever mode the memory has. - - (define_expand "extv" - [(set (match_operand 0 "register_operand") -- (sign_extract (match_operand:QI 1 "memory_operand") -+ (sign_extract (match_operand 1 "nonimmediate_operand") - (match_operand 2 "immediate_operand") - (match_operand 3 "immediate_operand")))] - "!TARGET_MIPS16" -@@ -3039,10 +3391,52 @@ - INTVAL (operands[2]), - INTVAL (operands[3]))) - DONE; -+ else if (ISA_HAS_EXTS -+ && register_operand (operands[1], VOIDmode) -+ && INTVAL (operands[2]) <= 32) -+ { -+ mips_adjust_register_ext_operands (operands); -+ if (GET_MODE (operands[0]) == SImode) -+ { -+ emit_insn (gen_extvsi (operands[0], operands[1], operands[2], -+ operands[3])); -+ DONE; -+ } -+ else if (TARGET_64BIT && GET_MODE (operands[0]) == DImode) -+ { -+ emit_insn (gen_extvdi (operands[0], operands[1], operands[2], -+ operands[3])); -+ DONE; -+ } -+ } - else - FAIL; - }) - -+(define_insn "extv" -+ [(set (match_operand:GPR 0 "register_operand" "=d") -+ (sign_extract:GPR (match_operand:GPR 1 "register_operand" "d") -+ (match_operand 2 "const_int_operand" "") -+ (match_operand 3 "const_int_operand" "")))] -+ "ISA_HAS_EXTS && INTVAL (operands[2]) <= 32" -+ "exts\t%0,%1,%3,%E2" -+ [(set_attr "type" "shift") -+ (set_attr "mode" "")]) -+ -+;; If we are extracting something no bigger than 32 bits, the destination -+;; register will be a properly sign-extended SImode value. Truncation -+;; is therefore a no-op in this case. -+(define_insn "*extv_truncdi" -+ [(set (match_operand:SUBDI 0 "register_operand" "=d") -+ (truncate:SUBDI -+ (sign_extract:DI (match_operand:DI 1 "register_operand" "d") -+ (match_operand 2 "const_int_operand" "") -+ (match_operand 3 "const_int_operand" ""))))] -+ "TARGET_64BIT && ISA_HAS_EXTS && INTVAL (operands[2]) <= 32" -+ "exts\t%0,%1,%3,%E2" -+ [(set_attr "type" "shift") -+ (set_attr "mode" "")]) -+ - (define_expand "extzv" - [(set (match_operand 0 "register_operand") - (zero_extract (match_operand 1 "nonimmediate_operand") -@@ -3055,8 +3449,17 @@ - INTVAL (operands[3]))) - DONE; - else if (mips_use_ins_ext_p (operands[1], INTVAL (operands[2]), -- INTVAL (operands[3]))) -+ INTVAL (operands[3])) -+ /* extract_bit_field can invoke us with (subreg:DI (reg:SI)) -+ as the output and size more than 31 bits. We would -+ create incorrect SI values. Instead, just FAIL. */ -+ && (GET_MODE (operands[0]) != DImode -+ || !(GET_CODE (operands[0]) == SUBREG -+ && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (operands[0]))) -+ < (GET_MODE_SIZE (GET_MODE (operands[0])))) -+ && INTVAL (operands[2]) >= 32))) - { -+ mips_adjust_register_ext_operands (operands); - if (GET_MODE (operands[0]) == DImode) - emit_insn (gen_extzvdi (operands[0], operands[1], operands[2], - operands[3])); -@@ -3080,6 +3483,32 @@ - [(set_attr "type" "arith") - (set_attr "mode" "")]) - -+;; If we're extracting fewer than 32 bits, the upper 33 bits of the -+;; destination will be zero, and thus truncation will be a no-op. -+(define_insn "*extzv_truncdi" -+ [(set (match_operand:SUBDI 0 "register_operand" "=d") -+ (truncate:SUBDI -+ (zero_extract:DI (match_operand:DI 1 "register_operand" "d") -+ (match_operand 2 "const_int_operand" "") -+ (match_operand 3 "const_int_operand" ""))))] -+ "TARGET_64BIT && ISA_HAS_EXT_INS && INTVAL (operands[2]) < 32" -+ "dext\t%0,%1,%3,%2" -+ [(set_attr "type" "shift") -+ (set_attr "mode" "")]) -+ -+;; If we're truncating an extraction that is at least big as the truncation -+;; mode, we can simply extract the useful bits and sign-extend the rest. -+;; The result will be a properly sign-extended value. -+(define_insn "*extz_truncdi_exts" -+ [(set (match_operand:SUBDI 0 "register_operand" "=d") -+ (truncate:SUBDI -+ (zero_extract:DI (match_operand:DI 1 "register_operand" "d") -+ (match_operand 2 "const_int_operand" "") -+ (match_operand 3 "const_int_operand" ""))))] -+ "TARGET_64BIT && ISA_HAS_EXTS && INTVAL (operands[2]) > " -+ "exts\t%0,%1,%3," -+ [(set_attr "type" "shift") -+ (set_attr "mode" "")]) - - (define_expand "insv" - [(set (zero_extract (match_operand 0 "nonimmediate_operand") -@@ -3102,9 +3531,9 @@ - emit_insn (gen_insvsi (operands[0], operands[1], operands[2], - operands[3])); - DONE; -- } -- else -- FAIL; -+ } -+ else -+ FAIL; - }) - - (define_insn "insv" -@@ -3118,6 +3547,62 @@ - [(set_attr "type" "arith") - (set_attr "mode" "")]) - -+(define_insn "*insvdi" -+ [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+d") -+ (match_operand 1 "const_int_operand" "") -+ (match_operand 2 "const_int_operand" "")) -+ (subreg:DI -+ (truncate:SUBDI (match_operand:DI 3 "register_operand" "d")) 0))] -+ "TARGET_64BIT && mips_use_ins_ext_p (operands[0], INTVAL (operands[1]), -+ INTVAL (operands[2]))" -+ "dins\t%0,%3,%2,%1" -+ [(set_attr "type" "shift") -+ (set_attr "mode" "DI")]) -+ -+;; Combine does not notice that zero- and sign-extensions have no -+;; effect here. -+;; ??? Should ideally be done in combine instead. -+ -+(define_insn "*insv__di" -+ [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+d") -+ (match_operand 1 "const_int_operand" "") -+ (match_operand 2 "const_int_operand" "")) -+ (any_extend:DI (match_operand:SUBDI 3 "register_operand" "d")))] -+ "TARGET_64BIT && ISA_HAS_EXT_INS && INTVAL (operands[1]) <= + 1" -+ "dins\t%0,%3,%2,%1" -+ [(set_attr "type" "shift") -+ (set_attr "mode" "DI")]) -+ -+(define_insn "*insvdi_clear_upper32" -+ [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+d") -+ (match_operand 1 "const_int_operand" "") -+ (match_operand 2 "const_int_operand" "")) -+ (subreg:DI -+ (truncate:SUBDI -+ (and:DI (match_operand:DI 3 "register_operand" "d") -+ (const_int 4294967295))) 0))] -+ "TARGET_64BIT && ISA_HAS_EXT_INS && INTVAL (operands[1]) <= 32" -+ "dins\t%0,%3,%2,%1" -+ [(set_attr "type" "shift") -+ (set_attr "mode" "DI")]) -+ -+;; Combiner pattern for cins. -+ -+(define_insn "*cins" -+ [(set (match_operand:DI 0 "register_operand" "=d") -+ (match_operator:DI 1 "mask_low_and_shift_operator" -+ [(ashift:DI -+ (match_operand:DI 2 "register_operand" "d") -+ (match_operand:DI 3 "const_int_operand" "")) -+ (match_operand:DI 4 "const_int_operand" "")]))] -+ "TARGET_64BIT && ISA_HAS_CINS" -+{ -+ operands[4] -+ = GEN_INT (mask_low_and_shift_len (DImode, INTVAL (operands[3]), -+ INTVAL (operands[4]))); -+ return "cins\t%0,%2,%3,%E4"; -+}) -+ - ;; Unaligned word moves generated by the bit field patterns. - ;; - ;; As far as the rtl is concerned, both the left-part and right-part -@@ -3135,7 +3620,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, operands[1])" -+ "!TARGET_MIPS16 -+ && !ISA_HAS_UL_US -+ && mips_mem_fits_mode_p (mode, operands[1])" - "l\t%0,%2" - [(set_attr "type" "load") - (set_attr "mode" "")]) -@@ -3146,7 +3633,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, operands[1])" -+ "!TARGET_MIPS16 -+ && !ISA_HAS_UL_US -+ && mips_mem_fits_mode_p (mode, operands[1])" - "r\t%0,%2" - [(set_attr "type" "load") - (set_attr "mode" "")]) -@@ -3156,7 +3645,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, operands[0])" -+ "!TARGET_MIPS16 -+ && !ISA_HAS_UL_US -+ && mips_mem_fits_mode_p (mode, operands[0])" - "l\t%z1,%2" - [(set_attr "type" "store") - (set_attr "mode" "")]) -@@ -3172,6 +3663,28 @@ - [(set_attr "type" "store") - (set_attr "mode" "")]) - -+;; Unaligned load and store patterns. -+ -+(define_insn "mov_u" -+ [(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, operands[1])" -+ "u\t%0,%2" -+ [(set_attr "type" "load") -+ (set_attr "mode" "")]) -+ -+(define_insn "mov_u" -+ [(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, operands[0])" -+ "u\t%z1,%2" -+ [(set_attr "type" "store") -+ (set_attr "mode" "")]) -+ - ;; An instruction to calculate the high part of a 64-bit SYMBOL_ABSOLUTE. - ;; The required value is: - ;; -@@ -3497,6 +4010,26 @@ - (const_string "*") - (const_string "*")])]) - -+;; Truncate to QI in two steps. Combine should probably canonicalize -+;; this to just one truncate:QI. -+ -+(define_insn "*truncsi_storeqi" -+ [(set (match_operand:QI 0 "memory_operand" "=m") -+ (subreg:QI -+ (truncate:SI (match_operand:DI 1 "register_operand" "d")) 3))] -+ "TARGET_64BIT && !TARGET_MIPS16 && TARGET_BIG_ENDIAN" -+ "sb\t%z1,%0" -+ [(set_attr "type" "store") -+ (set_attr "mode" "QI")]) -+ -+(define_insn "*truncsi_storehi" -+ [(set (match_operand:HI 0 "memory_operand" "=m") -+ (subreg:HI -+ (truncate:SI (match_operand:DI 1 "register_operand" "d")) 2))] -+ "TARGET_64BIT && !TARGET_MIPS16 && TARGET_BIG_ENDIAN" -+ "sh\t%z1,%0" -+ [(set_attr "type" "store") -+ (set_attr "mode" "HI")]) - - ;; On the mips16, we can split ld $r,N($r) into an add and a load, - ;; when the original load is a 4 byte instruction but the add and the -@@ -4270,6 +4803,22 @@ - [(set (match_operand:P 0 "register_operand" "=d") - (const:P (unspec:P [(const_int 0)] UNSPEC_GP)))]) - -+;; Move the constant value of __gnu_local_gp (operand 1) into -+;; operand 0, for non-PIC abicalls code. All uses of the result -+;; are explicit, so there's no need for unspec_volatile here. -+(define_insn_and_split "loadgp_nonpic" -+ [(set (match_operand 0 "register_operand" "=d") -+ (const (unspec [(match_operand 1 "" "")] UNSPEC_LOADGP)))] -+ "TARGET_ABICALLS && !flag_pic" -+ "#" -+ "" -+ [(const_int 0)] -+{ -+ mips_emit_move (operands[0], operands[1]); -+ DONE; -+} -+ [(set_attr "length" "8")]) -+ - ;; Insn to initialize $gp for n32/n64 abicalls. Operand 0 is the offset - ;; of _gp from the start of this function. Operand 1 is the incoming - ;; function address. -@@ -4820,7 +5369,7 @@ - (define_insn_and_split "" - [(set (match_operand:SI 0 "register_operand" "=d") - (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m") -- (match_operand:SI 2 "immediate_operand" "I")))] -+ (match_operand:SI 2 "const_int_operand" "")))] - "TARGET_MIPS16" - "#" - "" -@@ -4997,6 +5546,96 @@ - [(set_attr "type" "branch") - (set_attr "mode" "none")]) - -+;; Conditional branch on whether a bit is set or clear. -+ -+(define_insn "*branch_bit" -+ [(set (pc) -+ (if_then_else -+ (match_operator 0 "equality_operator" -+ [(zero_extract:GPR -+ (match_operand:GPR 2 "register_operand" "d") -+ (const_int 1) -+ (match_operand 3 "const_int_operand" "")) -+ (const_int 0)]) -+ (label_ref (match_operand 1 "" "")) -+ (pc)))] -+ "ISA_HAS_BBIT" -+{ -+ return mips_output_conditional_branch (insn, operands, -+ MIPS_BRANCH ("b%G0", "%2,%3,%1"), -+ MIPS_BRANCH ("b%H0", "%2,%3,%1")); -+} -+ [(set_attr "type" "branch") -+ (set_attr "branch_without_likely" "yes") -+ (set_attr "mode" "none")]) -+ -+(define_insn "*branch_bit_truncdi" -+ [(set (pc) -+ (if_then_else -+ (match_operator 0 "equality_operator" -+ [(zero_extract:DI -+ (subreg:DI -+ (truncate:SUBDI -+ (match_operand:DI 2 "register_operand" "d")) 0) -+ (const_int 1) -+ (match_operand 3 "const_int_operand" "")) -+ (const_int 0)]) -+ (label_ref (match_operand 1 "" "")) -+ (pc)))] -+ "TARGET_64BIT && ISA_HAS_BBIT" -+{ -+ return mips_output_conditional_branch (insn, operands, -+ MIPS_BRANCH ("b%G0", "%2,%3,%1"), -+ MIPS_BRANCH ("b%H0", "%2,%3,%1")); -+} -+ [(set_attr "type" "branch") -+ (set_attr "branch_without_likely" "yes") -+ (set_attr "mode" "none")]) -+ -+(define_insn "*branch_bit_inverted" -+ [(set (pc) -+ (if_then_else -+ (match_operator 0 "equality_operator" -+ [(zero_extract:GPR -+ (match_operand:GPR 2 "register_operand" "d") -+ (const_int 1) -+ (match_operand 3 "const_int_operand" "")) -+ (const_int 0)]) -+ (pc) -+ (label_ref (match_operand 1 "" ""))))] -+ "ISA_HAS_BBIT" -+{ -+ return mips_output_conditional_branch (insn, operands, -+ MIPS_BRANCH ("b%H0", "%2,%3,%1"), -+ MIPS_BRANCH ("b%G0", "%2,%3,%1")); -+} -+ [(set_attr "type" "branch") -+ (set_attr "branch_without_likely" "yes") -+ (set_attr "mode" "none")]) -+ -+(define_insn "*branch_bit_truncdi_inverted" -+ [(set (pc) -+ (if_then_else -+ (match_operator 0 "equality_operator" -+ [(zero_extract:DI -+ (subreg:DI -+ (truncate:SUBDI -+ (match_operand:DI 2 "register_operand" "d")) 0) -+ (const_int 1) -+ (match_operand 3 "const_int_operand" "")) -+ (const_int 0)]) -+ (pc) -+ (label_ref (match_operand 1 "" ""))))] -+ "TARGET_64BIT && ISA_HAS_BBIT" -+{ -+ return mips_output_conditional_branch (insn, operands, -+ MIPS_BRANCH ("b%H0", "%2,%3,%1"), -+ MIPS_BRANCH ("b%G0", "%2,%3,%1")); -+} -+ [(set_attr "type" "branch") -+ (set_attr "branch_without_likely" "yes") -+ (set_attr "mode" "none")]) -+ - ;; MIPS16 branches - - (define_insn "*branch_equality_mips16" -@@ -5065,11 +5704,42 @@ - [(set (match_operand:GPR 0 "register_operand" "=d") - (eq:GPR (match_operand:GPR 1 "register_operand" "d") - (const_int 0)))] -- "!TARGET_MIPS16" -+ "!TARGET_MIPS16 && !ISA_HAS_SEQ_SNE" - "sltu\t%0,%1,1" - [(set_attr "type" "slt") - (set_attr "mode" "")]) - -+(define_insn "*seq_si_to_di" -+ [(set (match_operand:DI 0 "register_operand" "=d") -+ (eq:DI (match_operand:SI 1 "register_operand" "d") -+ (const_int 0)))] -+ "TARGET_64BIT && !TARGET_MIPS16 && !ISA_HAS_SEQ_SNE" -+ "sltu\t%0,%1,1" -+ [(set_attr "type" "slt") -+ (set_attr "mode" "DI")]) -+ -+(define_insn "*s__s" -+ [(set (match_operand:GPR 0 "register_operand" "=d,d") -+ (equality_op:GPR (match_operand:GPR 1 "register_operand" "%d,d") -+ (match_operand:GPR 2 "reg_imm10_operand" "d,YB")))] -+ "ISA_HAS_SEQ_SNE" -+ "@ -+ s\\t%0,%1,%2 -+ si\\t%0,%1,%2" -+ [(set_attr "type" "arith") -+ (set_attr "mode" "")]) -+ -+(define_insn "*s_si_to_di_s" -+ [(set (match_operand:DI 0 "register_operand" "=d,d") -+ (equality_op:DI (match_operand:SI 1 "register_operand" "%d,d") -+ (match_operand:SI 2 "reg_imm10_operand" "d,YB")))] -+ "TARGET_64BIT && ISA_HAS_SEQ_SNE" -+ "@ -+ s\\t%0,%1,%2 -+ si\\t%0,%1,%2" -+ [(set_attr "type" "arith") -+ (set_attr "mode" "SI")]) -+ - (define_insn "*seq__mips16" - [(set (match_operand:GPR 0 "register_operand" "=t") - (eq:GPR (match_operand:GPR 1 "register_operand" "d") -@@ -5079,6 +5749,15 @@ - [(set_attr "type" "slt") - (set_attr "mode" "")]) - -+(define_insn "*seq_si_to_di_mips16" -+ [(set (match_operand:DI 0 "register_operand" "=d") -+ (eq:DI (match_operand:SI 1 "register_operand" "d") -+ (const_int 0)))] -+ "TARGET_64BIT && TARGET_MIPS16" -+ "sltu\t%1,1" -+ [(set_attr "type" "slt") -+ (set_attr "mode" "DI")]) -+ - ;; "sne" uses sltu instructions in which the first operand is $0. - ;; This isn't possible in mips16 code. - -@@ -5093,11 +5772,20 @@ - [(set (match_operand:GPR 0 "register_operand" "=d") - (ne:GPR (match_operand:GPR 1 "register_operand" "d") - (const_int 0)))] -- "!TARGET_MIPS16" -+ "!TARGET_MIPS16 && !ISA_HAS_SEQ_SNE" - "sltu\t%0,%.,%1" - [(set_attr "type" "slt") - (set_attr "mode" "")]) - -+(define_insn "*sne_si_to_di" -+ [(set (match_operand:DI 0 "register_operand" "=d") -+ (ne:DI (match_operand:SI 1 "register_operand" "d") -+ (const_int 0)))] -+ "TARGET_64BIT && !TARGET_MIPS16 && !ISA_HAS_SEQ_SNE" -+ "sltu\t%0,%.,%1" -+ [(set_attr "type" "slt") -+ (set_attr "mode" "DI")]) -+ - (define_expand "sgt" - [(set (match_operand:SI 0 "register_operand") - (gt:SI (match_dup 1) -@@ -5353,6 +6041,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%@%/%]"; - } -@@ -5371,7 +6079,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. -@@ -5462,11 +6176,12 @@ - - ;; Restore the gp that we saved above. Despite the earlier comment, it seems - ;; that older code did recalculate the gp from $25. Continue to jump through --;; $25 for compatibility (we lose nothing by doing so). -+;; $25 for compatibility (we lose nothing by doing so). Similarly restore -+;; $gp if we might be jumping to code which expects that. - - (define_expand "builtin_longjmp" - [(use (match_operand 0 "register_operand"))] -- "TARGET_USE_GOT" -+ "TARGET_USE_GOT || TARGET_ABICALLS" - { - /* The elements of the buffer are, in order: */ - int W = GET_MODE_SIZE (Pmode); ---- a/gcc/config/mips/mips.opt -+++ b/gcc/config/mips/mips.opt -@@ -124,6 +124,10 @@ mfix-vr4130 - Target Report Var(TARGET_FIX_VR4130) - Work around VR4130 mflo/mfhi errata - -+mfix-ice9a -+Target Report Var(TARGET_FIX_ICE9A) -+Work around SiCortex ICE9A errata -+ - mfix4300 - Target Report Var(TARGET_4300_MUL_FIX) - Work around an early 4300 hardware bug -@@ -176,6 +180,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 -@@ -228,6 +236,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 -@@ -260,6 +272,10 @@ mtune= - Target RejectNegative Joined Var(mips_tune_string) - -mtune=PROCESSOR Optimize the output for PROCESSOR - -+muclibc -+Target RejectNegative Var(building_for_uclibc) -+Building with -muclibc -+ - muninit-const-in-rodata - Target Report Var(TARGET_UNINIT_CONST_IN_RODATA) - Put uninitialized constants in ROM (needs -membedded-data) -@@ -268,6 +284,10 @@ mvr4130-align - Target Report Mask(VR4130_ALIGN) - Perform VR4130-specific alignment optimizations - -+mwarn-framesize= -+Target RejectNegative Joined -+Warn if a single function's framesize exceeds the given framesize -+ - mxgot - Target Report Var(TARGET_XGOT) - Lift restrictions on GOT size ---- /dev/null -+++ b/gcc/config/mips/montavista-linux.h -@@ -0,0 +1,54 @@ -+/* MontaVista GNU/Linux Configuration. -+ 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 -+. */ -+ -+/* Override linux64.h to default to O32. */ -+#undef SUBTARGET_SELF_SPECS -+#define SUBTARGET_SELF_SPECS \ -+NO_SHARED_SPECS, \ -+"%{!EB:%{!EL:%(endian_spec)}}", \ -+"%{!mabi=*: -mabi=32}" -+ -+/* We do not need to provide an explicit big-endian multilib. */ -+#undef MULTILIB_DEFAULTS -+#define MULTILIB_DEFAULTS \ -+ { "meb", "mabi=32" } -+ -+/* The various C libraries each have their own subdirectory. */ -+#undef SYSROOT_SUFFIX_SPEC -+#define SYSROOT_SUFFIX_SPEC \ -+ "%{mel:%{msoft-float:/mel/soft-float ; \ -+ :/mel} ; \ -+ msoft-float:/soft-float}" -+ -+/* MULTILIB_OSDIRNAMES provides directory names used in two ways: -+ relative to $target/lib/ in the GCC installation, and relative to -+ lib/ and usr/lib/ in a sysroot. For the latter, we want names such -+ as plain ../lib64, but these cannot be used outside the sysroot -+ because different multilibs would be mapped to the same directory. -+ Directories are searched both with and without the multilib suffix, -+ so it suffices if the directory without the suffix is correct -+ within the sysroot while the directory with the suffix doesn't -+ exist. We use STARTFILE_PREFIX_SPEC to achieve the desired -+ effect. */ -+#undef STARTFILE_PREFIX_SPEC -+#define STARTFILE_PREFIX_SPEC \ -+ "%{mabi=32: /usr/local/lib/ /lib/ /usr/lib/} \ -+ %{mabi=n32: /usr/local/lib32/ /lib32/ /usr/lib32/} \ -+ %{mabi=64: /usr/local/lib64/ /lib64/ /usr/lib64/}" ---- /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) -+ -+ -+/* 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)); \ -+ } ---- /dev/null -+++ b/gcc/config/mips/octeon.md -@@ -0,0 +1,85 @@ -+;; Octeon pipeline description. -+;; 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. -+ -+;; The OCTEON is a dual-issue processor that can bundle instructions as: -+;; {arith|imul(3)|idiv|*hilo|condmove|load|store|branch|jump|xfer} -+;; {arith|imul(3)|idiv|*hilo|condmove} -+ -+(define_automaton "octeon") -+ -+(define_cpu_unit "octeon_pipe0" "octeon") -+(define_cpu_unit "octeon_pipe1" "octeon") -+(define_cpu_unit "octeon_mult" "octeon") -+ -+(define_insn_reservation "octeon_arith" 1 -+ (and (eq_attr "cpu" "octeon") -+ (eq_attr "type" "arith,const,shift,slt,nop,logical,signext,move")) -+ "octeon_pipe0 | octeon_pipe1") -+ -+(define_insn_reservation "octeon_condmove" 2 -+ (and (eq_attr "cpu" "octeon") -+ (eq_attr "type" "condmove")) -+ "octeon_pipe0 | octeon_pipe1") -+ -+;; ??? Unaligned accesses take longer. We will need to differentiate -+;; between the two. -+ -+(define_insn_reservation "octeon_pipe0" 2 -+ (and (eq_attr "cpu" "octeon") -+ (eq_attr "type" "load,store,prefetch,mfc,mtc")) -+ "octeon_pipe0") -+ -+(define_insn_reservation "octeon_brj" 1 -+ (and (eq_attr "cpu" "octeon") -+ (eq_attr "type" "branch,jump,call,trap")) -+ "octeon_pipe0") -+ -+(define_insn_reservation "octeon_imul3" 5 -+ (and (eq_attr "cpu" "octeon") -+ (eq_attr "type" "imul3,pop,clz")) -+ "(octeon_pipe0 | octeon_pipe1) + octeon_mult") -+ -+(define_insn_reservation "octeon_imul" 2 -+ (and (eq_attr "cpu" "octeon") -+ (eq_attr "type" "imul,mthilo")) -+ "(octeon_pipe0 | octeon_pipe1) + octeon_mult, octeon_mult") -+ -+(define_insn_reservation "octeon_mfhilo" 5 -+ (and (eq_attr "cpu" "octeon") -+ (eq_attr "type" "mfhilo")) -+ "(octeon_pipe0 | octeon_pipe1) + octeon_mult") -+ -+(define_insn_reservation "octeon_imadd" 4 -+ (and (eq_attr "cpu" "octeon") -+ (eq_attr "type" "imadd")) -+ "(octeon_pipe0 | octeon_pipe1) + octeon_mult, (octeon_mult * 3)") -+ -+(define_insn_reservation "octeon_idiv" 72 -+ (and (eq_attr "cpu" "octeon") -+ (eq_attr "type" "idiv")) -+ "(octeon_pipe0 | octeon_pipe1) + octeon_mult, (octeon_mult * 71)") -+ -+;; Assume both pipes are needed for unknown and multiple-instruction -+;; patterns. -+ -+(define_insn_reservation "octeon_unknown" 1 -+ (and (eq_attr "cpu" "octeon") -+ (eq_attr "type" "unknown,multi")) -+ "octeon_pipe0 + octeon_pipe1") ---- a/gcc/config/mips/predicates.md -+++ b/gcc/config/mips/predicates.md -@@ -105,11 +105,15 @@ - /* We can only use direct calls for TARGET_ABSOLUTE_ABICALLS if we - are sure that the target function does not need $25 to be live - on entry. This is true for any locally-defined function because -- any such function will use %hi/%lo accesses to set up $gp. */ -+ any such function will use %hi/%lo accesses to set up $gp. -+ Alternatively, if PLTs and copy relocations are available, the -+ static linker will make sure that $25 is valid on entry to the -+ target function. */ - if (TARGET_ABSOLUTE_ABICALLS - && !(GET_CODE (op) == SYMBOL_REF - && SYMBOL_REF_DECL (op) -- && !DECL_EXTERNAL (SYMBOL_REF_DECL (op)))) -+ && !DECL_EXTERNAL (SYMBOL_REF_DECL (op))) -+ && flag_pic) - return false; - - /* If -mlong-calls or if this function has an explicit long_call -@@ -209,6 +213,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,7 +19,11 @@ You should have received a copy of the G - along with GCC; see the file COPYING3. If not see - . */ - --#define DRIVER_SELF_SPECS \ -+#undef TARGET_MIPS_SDE -+#define TARGET_MIPS_SDE 1 -+ -+#undef SUBTARGET_SELF_SPECS -+#define SUBTARGET_SELF_SPECS \ - /* Make sure a -mips option is present. This helps us to pick \ - the right multilib, and also makes the later specs easier \ - to write. */ \ -@@ -28,6 +32,9 @@ along with GCC; see the file COPYING3. - /* Infer the default float setting from -march. */ \ - MIPS_ARCH_FLOAT_SPEC, \ - \ -+ /* Infer the default dsp setting from -march. */ \ -+ MIPS_ARCH_DSP_SPEC, \ -+ \ - /* If no ABI option is specified, infer one from the ISA level \ - or -mgp setting. */ \ - "%{!mabi=*: %{" MIPS_32BIT_OPTION_SPEC ": -mabi=32;: -mabi=n32}}", \ -@@ -56,7 +63,6 @@ along with GCC; see the file COPYING3. - #undef SUBTARGET_ASM_SPEC - #define SUBTARGET_ASM_SPEC "\ - %{!mips1:--trap} \ --%{fPIC|fpic|fPIE|fpie:%{!mips16*:-KPIC}} \ - %{mips16:-no-mips16}" - - #undef LINK_SPEC ---- 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 - . */ - -+#define TARGET_MIPS_SDEMTK 1 -+ - #define TARGET_OS_CPP_BUILTINS() \ - do \ - { \ -@@ -105,3 +107,13 @@ 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=5kc: -msoft-float; \ -+ march=*: -mhard-float}" -+ ---- /dev/null -+++ b/gcc/config/mips/sicortex.h -@@ -0,0 +1,30 @@ -+/* SiCortex GNU/Linux Configuration. -+ Copyright (C) 2008 -+ 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 -+. */ -+ -+/* Override linux.h default to add __SICORTEX__ define. */ -+#undef TARGET_OS_CPP_BUILTINS -+#define TARGET_OS_CPP_BUILTINS() \ -+ do { \ -+ LINUX_TARGET_OS_CPP_BUILTINS(); \ -+ builtin_define ("__SICORTEX__"); \ -+ /* The GNU C++ standard library requires this. */ \ -+ if (c_dialect_cxx ()) \ -+ builtin_define ("_GNU_SOURCE"); \ -+ } while (0) ---- /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-montavista-elf -@@ -0,0 +1,22 @@ -+# MontaVista ELF Configuration. -+# 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 -+# . -+ -+MULTILIB_OPTIONS = -+MULTILIB_DIRNAMES = ---- /dev/null -+++ b/gcc/config/mips/t-montavista-linux -@@ -0,0 +1,43 @@ -+# MontaVista GNU/Linux Configuration. -+# 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 -+# . -+ -+# Build big-endian and little-endian support libraries. -+MULTILIB_OPTIONS = mel msoft-float march=octeon mabi=n32/mabi=64 -+MULTILIB_DIRNAMES = mel soft-float octeon n32 64 -+MULTILIB_EXCEPTIONS = *mel*/*mabi=n32* *mel*/*mabi=64* -+MULTILIB_EXCEPTIONS += *mel*/*march=octeon* march=octeon march=octeon/mabi=n32 -+MULTILIB_EXCEPTIONS += march=octeon/mabi=64 msoft-float/march=octeon -+ -+# These files must be built for each multilib. -+EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o -+ -+# See comment in montavista-linux.h on STARTFILE_PREFIX_SPEC for how the real -+# directories used in the sysroots are determined. These directories -+# are specified so that (a) they are distinct and (b) removing the -+# components that form part of the sysroot suffix leaves the real -+# directory within the sysroot. -+MULTILIB_OSDIRNAMES = msoft-float/mabi.n32=../lib32/soft-float -+MULTILIB_OSDIRNAMES += msoft-float/mabi.64=../lib64/soft-float -+MULTILIB_OSDIRNAMES += msoft-float/march.octeon/mabi.n32=../lib32/soft-float/octeon -+MULTILIB_OSDIRNAMES += msoft-float/march.octeon/mabi.64=../lib64/soft-float/octeon -+MULTILIB_OSDIRNAMES += mel/msoft-float=!mel/soft-float -+MULTILIB_OSDIRNAMES += msoft-float=!soft-float -+MULTILIB_OSDIRNAMES += mabi.64=../lib64 -+MULTILIB_OSDIRNAMES += mabi.n32=../lib32 ---- /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/t-sde -+++ b/gcc/config/mips/t-sde -@@ -10,9 +10,17 @@ $(T)crtn.o: $(srcdir)/config/mips/crtn.a - $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) \ - -c -o $(T)crtn.o -x assembler-with-cpp $(srcdir)/config/mips/crtn.asm - --MULTILIB_OPTIONS = EL/EB mips32/mips32r2/mips64 mips16 msoft-float/mfp64 mcode-readable=no -+# We must build libgcc2.a with -G 0, in case the user wants to link -+# without the $gp register. Use -fno-optimize-sibling-calls in case -+# we have a mixed mips16/non-mips16 environment where a plain "jump" -+# instuction won't work across the divide (no jx instruction). -+# Compile libraries with -mcode-xonly, so that they are link-compatible -+# with both -mcode-readable=pcrel and -mcode-readable=yes. -+TARGET_LIBGCC2_CFLAGS = -G 0 -fno-optimize-sibling-calls -mcode-xonly -+ -+MULTILIB_OPTIONS = EL/EB mips32/mips32r2/mips64 mips16 msoft-float/mfp64 mno-data-in-code - MULTILIB_DIRNAMES = el eb mips32 mips32r2 mips64 mips16 sof f64 spram --MULTILIB_MATCHES = EL=mel EB=meb -+MULTILIB_MATCHES = EL=mel EB=meb mips16=mips16e - - # The -mfp64 option is only valid in conjunction with -mips32r2. - ifneq ($(filter MIPS_ISA_DEFAULT=33,$(tm_defines)),) ---- /dev/null -+++ b/gcc/config/mips/t-sdelib -@@ -0,0 +1,23 @@ -+# Override newlib settings in t-sde and set up for building -+# against SDE header files and libraries. -+ -+# Remove stdarg.h and stddef.h from USER_H. -+USER_H = $(srcdir)/ginclude/float.h \ -+ $(srcdir)/ginclude/iso646.h \ -+ $(srcdir)/ginclude/stdbool.h \ -+ $(srcdir)/ginclude/varargs.h \ -+ $(EXTRA_HEADERS) -+ -+# Don't run fixinclude -+STMP_FIXINC = stmp-sdefixinc -+stmp-sdefixinc: gsyslimits.h -+ rm -rf include; mkdir include -+ chmod a+rx include -+ rm -f include/syslimits.h -+ cp $(srcdir)/gsyslimits.h include/syslimits.h -+ chmod a+r include/syslimits.h -+ $(STAMP) stmp-sdefixinc -+ -+# Don't build FPBIT and DPBIT; we'll be using the SDE soft-float library. -+FPBIT = -+DPBIT = ---- a/gcc/config/mips/t-sdemtk -+++ b/gcc/config/mips/t-sdemtk -@@ -1,26 +1,7 @@ --# Override newlib settings in t-sde and set up for building --# against SDE header files and libraries. - --MULTILIB_OPTIONS = EL/EB mips32/mips32r2/mips64 mips16 msoft-float/mno-float/mfp64 --MULTILIB_DIRNAMES = el eb mips32 mips32r2 mips64 mips16 sof nof f64 -+MULTILIB_OPTIONS = EL/EB mips32/mips32r2/mips64 mips16 fp64/msoft-float/mno-float -+MULTILIB_DIRNAMES = el eb mips32 mips32r2 mips64 mips16 f64 sof nof -+MULTILIB_MATCHES = EL=mel EB=meb -+MULTILIB_EXCLUSIONS = mfp64/!mips32r2 mips16/mips64 mcode-readable=no/!mips16 -+MULTILIB_EXCEPTIONS = - --# Remove stdarg.h and stddef.h from USER_H. --USER_H = $(srcdir)/ginclude/float.h \ -- $(srcdir)/ginclude/iso646.h \ -- $(srcdir)/ginclude/stdbool.h \ -- $(srcdir)/ginclude/varargs.h \ -- $(EXTRA_HEADERS) -- --# Don't run fixinclude --STMP_FIXINC = stmp-sdefixinc --stmp-sdefixinc: gsyslimits.h -- rm -rf include; mkdir include -- chmod a+rx include -- rm -f include/syslimits.h -- cp $(srcdir)/gsyslimits.h include/syslimits.h -- chmod a+r include/syslimits.h -- $(STAMP) stmp-sdefixinc -- --# Don't build FPBIT and DPBIT; we'll be using the SDE soft-float library. --FPBIT = --DPBIT = ---- /dev/null -+++ b/gcc/config/mips/t-sgxx-linux -@@ -0,0 +1,11 @@ -+MULTILIB_OPTIONS = muclibc march=mips2/march=mips32 msoft-float EL/EB -+MULTILIB_DIRNAMES = uclibc mips2 mips32 soft-float el eb -+MULTILIB_MATCHES := EL=mel EB=meb \ -+ march?mips2=mips2 march?mips2=mips3 march?mips2=mips4 \ -+ $(foreach cpu,mips3 mips4 r6000 r4000 vr4100 vr4111 vr4120 vr4130 vr4300 \ -+ r4400 r4600 orion r4650 r8000 vr5000 vr5400 vr5500 rm7000 \ -+ rm9000,march?mips2=march?$(cpu)) \ -+ march?mips32=mips32 \ -+ $(foreach cpu,4kc 4km 4kp 4ks,march?mips32=march?$(cpu)) -+MULTILIB_EXCEPTIONS = *muclibc*/*march?mips2* *muclibc*/*march?mips32* -+EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o ---- /dev/null -+++ b/gcc/config/mips/t-sgxx-sde -@@ -0,0 +1,7 @@ -+# SourceryG++ overrides for SDE builds -+ -+MULTILIB_OPTIONS = EL/EB mips16 mfp64/msoft-float/mno-float mcode-readable=no -+MULTILIB_DIRNAMES = el eb mips16 fp64 sof nof spram -+MULTILIB_MATCHES = EL=mel EB=meb mips16=mips16e -+MULTILIB_EXCLUSIONS = mcode-readable=no/!mips16 -+MULTILIB_EXCEPTIONS = ---- /dev/null -+++ b/gcc/config/mips/t-sgxxlite-linux -@@ -0,0 +1,5 @@ -+MULTILIB_OPTIONS = muclibc msoft-float EL/EB -+MULTILIB_DIRNAMES = uclibc soft-float el eb -+MULTILIB_MATCHES := EL=mel EB=meb -+EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o -+ ---- /dev/null -+++ b/gcc/config/mips/t-sicortex -@@ -0,0 +1,24 @@ -+# SiCortex GNU/Linux Configuration. -+# Copyright (C) 2008 -+# 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 -+# . -+ -+# No O32 libraries for SiCortex. -+MULTILIB_OPTIONS = mabi=n32/mabi=64 -+MULTILIB_DIRNAMES = n32 64 -+MULTILIB_OSDIRNAMES = ../lib32 ../lib64 ---- /dev/null -+++ b/gcc/config/mips/t-wrs-linux -@@ -0,0 +1,50 @@ -+# Wind River GNU/Linux Configuration. -+# Copyright (C) 2006, 2007 -+# 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 -+# . -+ -+# Build big-endian and little-endian support libraries. -+MULTILIB_OPTIONS = muclibc mel mhard-float march=octeon mabi=n32/mabi=64 -+MULTILIB_DIRNAMES = uclibc mel hard-float octeon n32 64 -+MULTILIB_EXCEPTIONS = *muclibc*/*mhard-float* -+MULTILIB_EXCEPTIONS += *muclibc*/*mabi=n32* -+MULTILIB_EXCEPTIONS += *muclibc*/*mabi=64* -+MULTILIB_EXCEPTIONS += */march=octeon* -+MULTILIB_EXCEPTIONS += march=octeon march=octeon/mabi=32 -+MULTILIB_EXCEPTIONS += mel/mabi=n32 mel/mabi=64 -+MULTILIB_EXCEPTIONS += mabi=n32 -+# These files must be built for each multilib. -+EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o -+ -+# See comment in wrs-linux.h on STARTFILE_PREFIX_SPEC for how the real -+# directories used in the sysroots are determined. These directories -+# are specified so that (a) they are distinct and (b) removing the -+# components that form part of the sysroot suffix leaves the real -+# directory within the sysroot. -+MULTILIB_OSDIRNAMES = mel/mhard-float/mabi.n32=../lib32/mel/hard-float -+MULTILIB_OSDIRNAMES += mel/mhard-float/mabi.64=../lib64/mel/hard-float -+MULTILIB_OSDIRNAMES += mhard-float/mabi.n32=../lib32/hard-float -+MULTILIB_OSDIRNAMES += mhard-float/mabi.64=../lib64/hard-float -+MULTILIB_OSDIRNAMES += mel/mhard-float=!mel/hard-float -+MULTILIB_OSDIRNAMES += mhard-float=!hard-float -+MULTILIB_OSDIRNAMES += mabi.64=../lib64 -+MULTILIB_OSDIRNAMES += march.octeon/mabi.n32=../lib32/octeon -+MULTILIB_OSDIRNAMES += march.octeon/mabi.64=../lib64/octeon -+MULTILIB_OSDIRNAMES += muclibc/mel=!uclibc/mel -+MULTILIB_OSDIRNAMES += muclibc=!uclibc -+ ---- a/gcc/config/mips/vr.h -+++ b/gcc/config/mips/vr.h -@@ -26,7 +26,7 @@ along with GCC; see the file COPYING3. - MULTILIB_ABI_DEFAULT, \ - DEFAULT_VR_ARCH } - --#define DRIVER_SELF_SPECS \ -+#define SUBTARGET_SELF_SPECS \ - /* Enforce the default architecture. This is mostly for \ - the assembler's benefit. */ \ - "%{!march=*:%{!mfix-vr4120:%{!mfix-vr4130:" \ ---- /dev/null -+++ b/gcc/config/mips/wrs-linux.h -@@ -0,0 +1,63 @@ -+/* Wind River GNU/Linux Configuration. -+ Copyright (C) 2006, 2007 -+ 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 -+. */ -+ -+/* Override linux64.h to default to O32. */ -+#undef SUBTARGET_SELF_SPECS -+#define SUBTARGET_SELF_SPECS \ -+NO_SHARED_SPECS, \ -+"%{!EB:%{!EL:%(endian_spec)}}", \ -+"%{!mabi=*: -mabi=32}" -+ -+/* We do not need to provide an explicit big-endian multilib. */ -+#undef MULTILIB_DEFAULTS -+#define MULTILIB_DEFAULTS \ -+ { "meb", "mabi=32" } -+ -+/* The GLIBC headers are in /usr/include, relative to the sysroot; the -+ uClibc headers are in /uclibc/usr/include. */ -+#undef SYSROOT_HEADERS_SUFFIX_SPEC -+#define SYSROOT_HEADERS_SUFFIX_SPEC \ -+ "%{muclibc:/uclibc}" -+ -+/* The various C libraries each have their own subdirectory. */ -+#undef SYSROOT_SUFFIX_SPEC -+#define SYSROOT_SUFFIX_SPEC \ -+ "%{muclibc:%{mel:/uclibc/mel ; \ -+ :/uclibc} ; \ -+ mel:%{mhard-float:/mel/hard-float ; \ -+ :/mel} ; \ -+ march=octeon:/octeon ; \ -+ mhard-float:/hard-float}" -+ -+/* MULTILIB_OSDIRNAMES provides directory names used in two ways: -+ relative to $target/lib/ in the GCC installation, and relative to -+ lib/ and usr/lib/ in a sysroot. For the latter, we want names such -+ as plain ../lib64, but these cannot be used outside the sysroot -+ because different multilibs would be mapped to the same directory. -+ Directories are searched both with and without the multilib suffix, -+ so it suffices if the directory without the suffix is correct -+ within the sysroot while the directory with the suffix doesn't -+ exist. We use STARTFILE_PREFIX_SPEC to achieve the desired -+ effect. */ -+#undef STARTFILE_PREFIX_SPEC -+#define STARTFILE_PREFIX_SPEC \ -+ "%{mabi=32: /usr/local/lib/ /lib/ /usr/lib/} \ -+ %{mabi=n32: /usr/local/lib32/ /lib32/ /usr/lib32/} \ -+ %{mabi=64: /usr/local/lib64/ /lib64/ /usr/lib64/}" ---- /dev/null -+++ b/gcc/config/mips/xlr.md -@@ -0,0 +1,89 @@ -+;; DFA-based pipeline description for the XLR. -+;; Copyright (C) 2008 Free Software Foundation, Inc. -+;; -+;; xlr.md Machine Description for the RMI XLR Microprocessor -+;; 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 -+;; . -+ -+(define_automaton "xlr_main,xlr_muldiv") -+ -+;; Definitions for xlr_main automaton. -+(define_cpu_unit "xlr_main_pipe" "xlr_main") -+ -+(define_insn_reservation "ir_xlr_alu_slt" 2 -+ (and (eq_attr "cpu" "xlr") -+ (eq_attr "type" "slt")) -+ "xlr_main_pipe") -+ -+;; Integer arithmetic instructions. -+(define_insn_reservation "ir_xlr_alu" 1 -+ (and (eq_attr "cpu" "xlr") -+ (eq_attr "type" "move,arith,shift,clz,logical,signext,const,unknown,multi,nop,trap")) -+ "xlr_main_pipe") -+ -+;; Integer arithmetic instructions. -+(define_insn_reservation "ir_xlr_condmove" 2 -+ (and (eq_attr "cpu" "xlr") -+ (eq_attr "type" "condmove")) -+ "xlr_main_pipe") -+ -+;; Load/store instructions. -+(define_insn_reservation "ir_xlr_load" 4 -+ (and (eq_attr "cpu" "xlr") -+ (eq_attr "type" "load")) -+ "xlr_main_pipe") -+ -+(define_insn_reservation "ir_xlr_store" 1 -+ (and (eq_attr "cpu" "xlr") -+ (eq_attr "type" "store")) -+ "xlr_main_pipe") -+ -+(define_insn_reservation "ir_xlr_prefetch_x" 1 -+ (and (eq_attr "cpu" "xlr") -+ (eq_attr "type" "prefetch,prefetchx")) -+ "xlr_main_pipe") -+ -+;; Branch instructions - use branch misprediction latency. -+(define_insn_reservation "ir_xlr_branch" 1 -+ (and (eq_attr "cpu" "xlr") -+ (eq_attr "type" "branch,jump,call")) -+ "xlr_main_pipe") -+ -+;; Coprocessor move instructions. -+(define_insn_reservation "ir_xlr_xfer" 2 -+ (and (eq_attr "cpu" "xlr") -+ (eq_attr "type" "mtc,mfc")) -+ "xlr_main_pipe") -+ -+(define_bypass 5 "ir_xlr_xfer" "ir_xlr_xfer") -+ -+;; Definitions for the xlr_muldiv automaton. -+(define_cpu_unit "xlr_imuldiv_nopipe" "xlr_muldiv") -+ -+(define_insn_reservation "ir_xlr_imul" 8 -+ (and (eq_attr "cpu" "xlr") -+ (eq_attr "type" "imul,imul3,imadd")) -+ "xlr_main_pipe,xlr_imuldiv_nopipe*6") -+ -+(define_insn_reservation "ir_xlr_div" 68 -+ (and (eq_attr "cpu" "xlr") -+ (eq_attr "type" "idiv")) -+ "xlr_main_pipe,xlr_imuldiv_nopipe*67") -+ -+(define_insn_reservation "xlr_hilo" 2 -+ (and (eq_attr "cpu" "xlr") -+ (eq_attr "type" "mfhilo,mthilo")) -+ "xlr_imuldiv_nopipe") ---- /dev/null -+++ b/gcc/config/print-sysroot-suffix.sh -@@ -0,0 +1,107 @@ -+#! /bin/sh -+# Script to generate SYSROOT_SUFFIX equivalent to MULTILIB_OSDIRNAMES -+# Arguments are MULTILIB_OSDIRNAMES, MULTILIB_OPTIONS, MULTILIB_MATCHES -+# and MULTILIB_ALIASES. -+ -+set -e -+ -+dirnames="$1" -+options="$2" -+matches="$3" -+aliases="$4" -+ -+cat > print-sysroot-suffix3.sh <<\EOF -+#! /bin/sh -+# Print all the multilib matches for this option -+result="$1" -+EOF -+for x in $matches; do -+ l=`echo $x | sed -e 's/=.*$//' -e 's/?/=/g'` -+ r=`echo $x | sed -e 's/^.*=//' -e 's/?/=/g'` -+ echo "[ \"\$1\" = \"$l\" ] && result=\"\$result|$r\"" >> print-sysroot-suffix3.sh -+done -+echo 'echo $result' >> print-sysroot-suffix3.sh -+chmod +x print-sysroot-suffix3.sh -+ -+cat > print-sysroot-suffix2.sh <<\EOF -+#! /bin/sh -+# Recursive script to enumerate all multilib combinations, match against -+# multilib directories and optut a spec string of the result. -+# Will fold identical trees. -+ -+padding="$1" -+optstring="$2" -+shift 2 -+n="\" \\ -+$padding\"" -+if [ $# = 0 ]; then -+ case $optstring in -+EOF -+for x in $aliases; do -+ l=`echo $x | sed -e 's/=.*$//' -e 's/?/=/g'` -+ r=`echo $x | sed -e 's/^.*=//' -e 's/?/=/g'` -+ echo "/$r/) optstring=\"/$l/\" ;;" >> print-sysroot-suffix2.sh -+done -+echo " esac" >> print-sysroot-suffix2.sh -+ -+pat= -+for x in $dirnames; do -+ p=`echo $x | sed -e 's,=!,/$=/,'` -+ pat="$pat -e 's=^//$p='" -+done -+echo ' optstring=`echo "/$optstring" | sed '"$pat\`" >> print-sysroot-suffix2.sh -+cat >> print-sysroot-suffix2.sh <<\EOF -+ case $optstring in -+ //*) -+ ;; -+ *) -+ echo "$optstring" -+ ;; -+ esac -+else -+ thisopt="$1" -+ shift -+ bit= -+ lastcond= -+ result= -+ for x in `echo "$thisopt" | sed -e 's,/, ,g'`; do -+ case $x in -+EOF -+for x in `echo "$options" | sed -e 's,/, ,g'`; do -+ match=`./print-sysroot-suffix3.sh "$x"` -+ echo "$x) optmatch=\"$match\" ;;" >> print-sysroot-suffix2.sh -+done -+cat >> print-sysroot-suffix2.sh <<\EOF -+ esac -+ bit=`"$0" "$padding " "$optstring$x/" "$@"` -+ if [ -z "$lastopt" ]; then -+ lastopt="$optmatch" -+ else -+ if [ "$lastbit" = "$bit" ]; then -+ lastopt="$lastopt|$optmatch" -+ else -+ result="$result$lastopt:$lastbit;$n" -+ lastopt="$optmatch" -+ fi -+ fi -+ lastbit="$bit" -+ done -+ bit=`"$0" "$padding " "$optstring" "$@"` -+ if [ "$bit" = "$lastbit" ]; then -+ if [ -z "$result" ]; then -+ echo "$bit" -+ else -+ echo "$n%{$result:$bit}" -+ fi -+ else -+ echo "$n%{$result$lastopt:$lastbit;$n:$bit}" -+ fi -+fi -+EOF -+ -+chmod +x ./print-sysroot-suffix2.sh -+result=`./print-sysroot-suffix2.sh "" "/" $options` -+echo "#undef SYSROOT_SUFFIX_SPEC" -+echo "#define SYSROOT_SUFFIX_SPEC \"$result\"" -+rm print-sysroot-suffix2.sh -+rm print-sysroot-suffix3.sh ---- a/gcc/config/rs6000/aix.h -+++ b/gcc/config/rs6000/aix.h -@@ -202,6 +202,8 @@ - - /* Define cutoff for using external functions to save floating point. */ - #define FP_SAVE_INLINE(FIRST_REG) ((FIRST_REG) == 62 || (FIRST_REG) == 63) -+/* And similarly for general purpose registers. */ -+#define GP_SAVE_INLINE(FIRST_REG) ((FIRST_REG) < 32) - - /* __throw will restore its own return address to be the same as the - return address of the function that the throw is being made to. ---- a/gcc/config/rs6000/altivec.md -+++ b/gcc/config/rs6000/altivec.md -@@ -64,7 +64,6 @@ - (UNSPEC_VPKUWUS 102) - (UNSPEC_VPKSWUS 103) - (UNSPEC_VRL 104) -- (UNSPEC_VSL 107) - (UNSPEC_VSLV4SI 110) - (UNSPEC_VSLO 111) - (UNSPEC_VSR 118) -@@ -582,7 +581,7 @@ - /* Generate [-0.0, -0.0, -0.0, -0.0]. */ - neg0 = gen_reg_rtx (V4SImode); - emit_insn (gen_altivec_vspltisw (neg0, constm1_rtx)); -- emit_insn (gen_altivec_vslw (neg0, neg0, neg0)); -+ emit_insn (gen_ashlv4si3 (neg0, neg0, neg0)); - - /* Use the multiply-add. */ - emit_insn (gen_altivec_vmaddfp (operands[0], operands[1], operands[2], -@@ -641,7 +640,7 @@ - high_product = gen_reg_rtx (V4SImode); - emit_insn (gen_altivec_vmsumuhm (high_product, one, small_swap, zero)); - -- emit_insn (gen_altivec_vslw (high_product, high_product, sixteen)); -+ emit_insn (gen_ashlv4si3 (high_product, high_product, sixteen)); - - emit_insn (gen_addv4si3 (operands[0], high_product, low_product)); - -@@ -1227,15 +1226,6 @@ - "vrl %0,%1,%2" - [(set_attr "type" "vecsimple")]) - --(define_insn "altivec_vsl" -- [(set (match_operand:VI 0 "register_operand" "=v") -- (unspec:VI [(match_operand:VI 1 "register_operand" "v") -- (match_operand:VI 2 "register_operand" "v")] -- UNSPEC_VSL))] -- "TARGET_ALTIVEC" -- "vsl %0,%1,%2" -- [(set_attr "type" "vecsimple")]) -- - (define_insn "altivec_vsl" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") -@@ -1254,6 +1244,14 @@ - "vslo %0,%1,%2" - [(set_attr "type" "vecperm")]) - -+(define_insn "ashl3" -+ [(set (match_operand:VI 0 "register_operand" "=v") -+ (ashift:VI (match_operand:VI 1 "register_operand" "v") -+ (match_operand:VI 2 "register_operand" "v") ))] -+ "TARGET_ALTIVEC" -+ "vsl %0,%1,%2" -+ [(set_attr "type" "vecsimple")]) -+ - (define_insn "lshr3" - [(set (match_operand:VI 0 "register_operand" "=v") - (lshiftrt:VI (match_operand:VI 1 "register_operand" "v") -@@ -2045,7 +2043,7 @@ - [(set (match_dup 2) - (vec_duplicate:V4SI (const_int -1))) - (set (match_dup 3) -- (unspec:V4SI [(match_dup 2) (match_dup 2)] UNSPEC_VSL)) -+ (ashift:V4SI (match_dup 2) (match_dup 2))) - (set (match_operand:V4SF 0 "register_operand" "=v") - (and:V4SF (not:V4SF (subreg:V4SF (match_dup 3) 0)) - (match_operand:V4SF 1 "register_operand" "v")))] -@@ -2648,7 +2646,7 @@ - /* Generate [-0.0, -0.0, -0.0, -0.0]. */ - neg0 = gen_reg_rtx (V4SImode); - emit_insn (gen_altivec_vspltisw (neg0, constm1_rtx)); -- emit_insn (gen_altivec_vslw (neg0, neg0, neg0)); -+ emit_insn (gen_ashlv4si3 (neg0, neg0, neg0)); - - /* XOR */ - emit_insn (gen_xorv4sf3 (operands[0], ---- /dev/null -+++ b/gcc/config/rs6000/crtresfpr.asm -@@ -0,0 +1,90 @@ -+/* -+ * Special support for eabi and SVR4 -+ * -+ * Copyright (C) 1995, 1996, 1998, 2000, 2001, 2008 -+ * Free Software Foundation, Inc. -+ * Written By Michael Meissner -+ * 64-bit support written by David Edelsohn -+ * -+ * 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 2, or (at your option) any -+ * later version. -+ * -+ * In addition to the permissions in the GNU General Public License, the -+ * Free Software Foundation gives you unlimited permission to link the -+ * compiled version of this file with other programs, and to distribute -+ * those programs without any restriction coming from the use of this -+ * file. (The General Public License restrictions do apply in other -+ * respects; for example, they cover modification of the file, and -+ * distribution when not linked into another program.) -+ * -+ * 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. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; see the file COPYING. If not, write to -+ * the Free Software Foundation, 51 Franklin Street, Fifth Floor, -+ * Boston, MA 02110-1301, 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. -+ */ -+ -+/* Do any initializations needed for the eabi environment */ -+ -+ .file "crtresfpr.asm" -+ .section ".text" -+ #include "ppc-asm.h" -+ -+/* On PowerPC64 Linux, these functions are provided by the linker. */ -+#ifndef __powerpc64__ -+ -+/* Routines for restoring floating point registers, called by the compiler. */ -+/* Called with r11 pointing to the stack header word of the caller of the */ -+/* function, just beyond the end of the floating point save area. */ -+ -+HIDDEN_FUNC(_restfpr_14) lfd 14,-144(11) /* restore fp registers */ -+HIDDEN_FUNC(_restfpr_15) lfd 15,-136(11) -+HIDDEN_FUNC(_restfpr_16) lfd 16,-128(11) -+HIDDEN_FUNC(_restfpr_17) lfd 17,-120(11) -+HIDDEN_FUNC(_restfpr_18) lfd 18,-112(11) -+HIDDEN_FUNC(_restfpr_19) lfd 19,-104(11) -+HIDDEN_FUNC(_restfpr_20) lfd 20,-96(11) -+HIDDEN_FUNC(_restfpr_21) lfd 21,-88(11) -+HIDDEN_FUNC(_restfpr_22) lfd 22,-80(11) -+HIDDEN_FUNC(_restfpr_23) lfd 23,-72(11) -+HIDDEN_FUNC(_restfpr_24) lfd 24,-64(11) -+HIDDEN_FUNC(_restfpr_25) lfd 25,-56(11) -+HIDDEN_FUNC(_restfpr_26) lfd 26,-48(11) -+HIDDEN_FUNC(_restfpr_27) lfd 27,-40(11) -+HIDDEN_FUNC(_restfpr_28) lfd 28,-32(11) -+HIDDEN_FUNC(_restfpr_29) lfd 29,-24(11) -+HIDDEN_FUNC(_restfpr_30) lfd 30,-16(11) -+HIDDEN_FUNC(_restfpr_31) lfd 31,-8(11) -+ blr -+FUNC_END(_restfpr_31) -+FUNC_END(_restfpr_30) -+FUNC_END(_restfpr_29) -+FUNC_END(_restfpr_28) -+FUNC_END(_restfpr_27) -+FUNC_END(_restfpr_26) -+FUNC_END(_restfpr_25) -+FUNC_END(_restfpr_24) -+FUNC_END(_restfpr_23) -+FUNC_END(_restfpr_22) -+FUNC_END(_restfpr_21) -+FUNC_END(_restfpr_20) -+FUNC_END(_restfpr_19) -+FUNC_END(_restfpr_18) -+FUNC_END(_restfpr_17) -+FUNC_END(_restfpr_16) -+FUNC_END(_restfpr_15) -+FUNC_END(_restfpr_14) -+ -+#endif ---- /dev/null -+++ b/gcc/config/rs6000/crtresgpr.asm -@@ -0,0 +1,90 @@ -+/* -+ * Special support for eabi and SVR4 -+ * -+ * Copyright (C) 1995, 1996, 1998, 2000, 2001, 2008 -+ * Free Software Foundation, Inc. -+ * Written By Michael Meissner -+ * 64-bit support written by David Edelsohn -+ * -+ * 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 2, or (at your option) any -+ * later version. -+ * -+ * In addition to the permissions in the GNU General Public License, the -+ * Free Software Foundation gives you unlimited permission to link the -+ * compiled version of this file with other programs, and to distribute -+ * those programs without any restriction coming from the use of this -+ * file. (The General Public License restrictions do apply in other -+ * respects; for example, they cover modification of the file, and -+ * distribution when not linked into another program.) -+ * -+ * 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. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; see the file COPYING. If not, write to -+ * the Free Software Foundation, 51 Franklin Street, Fifth Floor, -+ * Boston, MA 02110-1301, 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. -+ */ -+ -+/* Do any initializations needed for the eabi environment */ -+ -+ .file "crtresgpr.asm" -+ .section ".text" -+ #include "ppc-asm.h" -+ -+/* On PowerPC64 Linux, these functions are provided by the linker. */ -+#ifndef __powerpc64__ -+ -+/* Routines for restoring integer registers, called by the compiler. */ -+/* Called with r11 pointing to the stack header word of the caller of the */ -+/* function, just beyond the end of the integer restore area. */ -+ -+HIDDEN_FUNC(_restgpr_14) lwz 14,-72(11) /* restore gp registers */ -+HIDDEN_FUNC(_restgpr_15) lwz 15,-68(11) -+HIDDEN_FUNC(_restgpr_16) lwz 16,-64(11) -+HIDDEN_FUNC(_restgpr_17) lwz 17,-60(11) -+HIDDEN_FUNC(_restgpr_18) lwz 18,-56(11) -+HIDDEN_FUNC(_restgpr_19) lwz 19,-52(11) -+HIDDEN_FUNC(_restgpr_20) lwz 20,-48(11) -+HIDDEN_FUNC(_restgpr_21) lwz 21,-44(11) -+HIDDEN_FUNC(_restgpr_22) lwz 22,-40(11) -+HIDDEN_FUNC(_restgpr_23) lwz 23,-36(11) -+HIDDEN_FUNC(_restgpr_24) lwz 24,-32(11) -+HIDDEN_FUNC(_restgpr_25) lwz 25,-28(11) -+HIDDEN_FUNC(_restgpr_26) lwz 26,-24(11) -+HIDDEN_FUNC(_restgpr_27) lwz 27,-20(11) -+HIDDEN_FUNC(_restgpr_28) lwz 28,-16(11) -+HIDDEN_FUNC(_restgpr_29) lwz 29,-12(11) -+HIDDEN_FUNC(_restgpr_30) lwz 30,-8(11) -+HIDDEN_FUNC(_restgpr_31) lwz 31,-4(11) -+ blr -+FUNC_END(_restgpr_31) -+FUNC_END(_restgpr_30) -+FUNC_END(_restgpr_29) -+FUNC_END(_restgpr_28) -+FUNC_END(_restgpr_27) -+FUNC_END(_restgpr_26) -+FUNC_END(_restgpr_25) -+FUNC_END(_restgpr_24) -+FUNC_END(_restgpr_23) -+FUNC_END(_restgpr_22) -+FUNC_END(_restgpr_21) -+FUNC_END(_restgpr_20) -+FUNC_END(_restgpr_19) -+FUNC_END(_restgpr_18) -+FUNC_END(_restgpr_17) -+FUNC_END(_restgpr_16) -+FUNC_END(_restgpr_15) -+FUNC_END(_restgpr_14) -+ -+#endif ---- /dev/null -+++ b/gcc/config/rs6000/crtresxfpr.asm -@@ -0,0 +1,95 @@ -+/* -+ * Special support for eabi and SVR4 -+ * -+ * Copyright (C) 1995, 1996, 1998, 2000, 2001, 2008 -+ * Free Software Foundation, Inc. -+ * Written By Michael Meissner -+ * 64-bit support written by David Edelsohn -+ * -+ * 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 2, or (at your option) any -+ * later version. -+ * -+ * In addition to the permissions in the GNU General Public License, the -+ * Free Software Foundation gives you unlimited permission to link the -+ * compiled version of this file with other programs, and to distribute -+ * those programs without any restriction coming from the use of this -+ * file. (The General Public License restrictions do apply in other -+ * respects; for example, they cover modification of the file, and -+ * distribution when not linked into another program.) -+ * -+ * 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. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; see the file COPYING. If not, write to -+ * the Free Software Foundation, 51 Franklin Street, Fifth Floor, -+ * Boston, MA 02110-1301, 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. -+ */ -+ -+/* Do any initializations needed for the eabi environment */ -+ -+ .file "crtresxfpr.asm" -+ .section ".text" -+ #include "ppc-asm.h" -+ -+/* On PowerPC64 Linux, these functions are provided by the linker. */ -+#ifndef __powerpc64__ -+ -+/* Routines for restoring floating point registers, called by the compiler. */ -+/* Called with r11 pointing to the stack header word of the caller of the */ -+/* function, just beyond the end of the floating point save area. */ -+/* In addition to restoring the fp registers, it will return to the caller's */ -+/* caller */ -+ -+HIDDEN_FUNC(_restfpr_14_x) lfd 14,-144(11) /* restore fp registers */ -+HIDDEN_FUNC(_restfpr_15_x) lfd 15,-136(11) -+HIDDEN_FUNC(_restfpr_16_x) lfd 16,-128(11) -+HIDDEN_FUNC(_restfpr_17_x) lfd 17,-120(11) -+HIDDEN_FUNC(_restfpr_18_x) lfd 18,-112(11) -+HIDDEN_FUNC(_restfpr_19_x) lfd 19,-104(11) -+HIDDEN_FUNC(_restfpr_20_x) lfd 20,-96(11) -+HIDDEN_FUNC(_restfpr_21_x) lfd 21,-88(11) -+HIDDEN_FUNC(_restfpr_22_x) lfd 22,-80(11) -+HIDDEN_FUNC(_restfpr_23_x) lfd 23,-72(11) -+HIDDEN_FUNC(_restfpr_24_x) lfd 24,-64(11) -+HIDDEN_FUNC(_restfpr_25_x) lfd 25,-56(11) -+HIDDEN_FUNC(_restfpr_26_x) lfd 26,-48(11) -+HIDDEN_FUNC(_restfpr_27_x) lfd 27,-40(11) -+HIDDEN_FUNC(_restfpr_28_x) lfd 28,-32(11) -+HIDDEN_FUNC(_restfpr_29_x) lfd 29,-24(11) -+HIDDEN_FUNC(_restfpr_30_x) lfd 30,-16(11) -+HIDDEN_FUNC(_restfpr_31_x) lwz 0,4(11) -+ lfd 31,-8(11) -+ mtlr 0 -+ mr 1,11 -+ blr -+FUNC_END(_restfpr_31_x) -+FUNC_END(_restfpr_30_x) -+FUNC_END(_restfpr_29_x) -+FUNC_END(_restfpr_28_x) -+FUNC_END(_restfpr_27_x) -+FUNC_END(_restfpr_26_x) -+FUNC_END(_restfpr_25_x) -+FUNC_END(_restfpr_24_x) -+FUNC_END(_restfpr_23_x) -+FUNC_END(_restfpr_22_x) -+FUNC_END(_restfpr_21_x) -+FUNC_END(_restfpr_20_x) -+FUNC_END(_restfpr_19_x) -+FUNC_END(_restfpr_18_x) -+FUNC_END(_restfpr_17_x) -+FUNC_END(_restfpr_16_x) -+FUNC_END(_restfpr_15_x) -+FUNC_END(_restfpr_14_x) -+ -+#endif ---- /dev/null -+++ b/gcc/config/rs6000/crtresxgpr.asm -@@ -0,0 +1,93 @@ -+/* -+ * Special support for eabi and SVR4 -+ * -+ * Copyright (C) 1995, 1996, 1998, 2000, 2001, 2008 -+ * Free Software Foundation, Inc. -+ * Written By Michael Meissner -+ * 64-bit support written by David Edelsohn -+ * -+ * 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 2, or (at your option) any -+ * later version. -+ * -+ * In addition to the permissions in the GNU General Public License, the -+ * Free Software Foundation gives you unlimited permission to link the -+ * compiled version of this file with other programs, and to distribute -+ * those programs without any restriction coming from the use of this -+ * file. (The General Public License restrictions do apply in other -+ * respects; for example, they cover modification of the file, and -+ * distribution when not linked into another program.) -+ * -+ * 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. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; see the file COPYING. If not, write to -+ * the Free Software Foundation, 51 Franklin Street, Fifth Floor, -+ * Boston, MA 02110-1301, 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. -+ */ -+ -+/* Do any initializations needed for the eabi environment */ -+ -+ .file "crtresxgpr.asm" -+ .section ".text" -+ #include "ppc-asm.h" -+ -+/* On PowerPC64 Linux, these functions are provided by the linker. */ -+#ifndef __powerpc64__ -+ -+/* Routines for restoring integer registers, called by the compiler. */ -+/* Called with r11 pointing to the stack header word of the caller of the */ -+/* function, just beyond the end of the integer restore area. */ -+ -+HIDDEN_FUNC(_restgpr_14_x) lwz 14,-72(11) /* restore gp registers */ -+HIDDEN_FUNC(_restgpr_15_x) lwz 15,-68(11) -+HIDDEN_FUNC(_restgpr_16_x) lwz 16,-64(11) -+HIDDEN_FUNC(_restgpr_17_x) lwz 17,-60(11) -+HIDDEN_FUNC(_restgpr_18_x) lwz 18,-56(11) -+HIDDEN_FUNC(_restgpr_19_x) lwz 19,-52(11) -+HIDDEN_FUNC(_restgpr_20_x) lwz 20,-48(11) -+HIDDEN_FUNC(_restgpr_21_x) lwz 21,-44(11) -+HIDDEN_FUNC(_restgpr_22_x) lwz 22,-40(11) -+HIDDEN_FUNC(_restgpr_23_x) lwz 23,-36(11) -+HIDDEN_FUNC(_restgpr_24_x) lwz 24,-32(11) -+HIDDEN_FUNC(_restgpr_25_x) lwz 25,-28(11) -+HIDDEN_FUNC(_restgpr_26_x) lwz 26,-24(11) -+HIDDEN_FUNC(_restgpr_27_x) lwz 27,-20(11) -+HIDDEN_FUNC(_restgpr_28_x) lwz 28,-16(11) -+HIDDEN_FUNC(_restgpr_29_x) lwz 29,-12(11) -+HIDDEN_FUNC(_restgpr_30_x) lwz 30,-8(11) -+HIDDEN_FUNC(_restgpr_31_x) lwz 0,4(11) -+ lwz 31,-4(11) -+ mtlr 0 -+ mr 1,11 -+ blr -+FUNC_END(_restgpr_31_x) -+FUNC_END(_restgpr_30_x) -+FUNC_END(_restgpr_29_x) -+FUNC_END(_restgpr_28_x) -+FUNC_END(_restgpr_27_x) -+FUNC_END(_restgpr_26_x) -+FUNC_END(_restgpr_25_x) -+FUNC_END(_restgpr_24_x) -+FUNC_END(_restgpr_23_x) -+FUNC_END(_restgpr_22_x) -+FUNC_END(_restgpr_21_x) -+FUNC_END(_restgpr_20_x) -+FUNC_END(_restgpr_19_x) -+FUNC_END(_restgpr_18_x) -+FUNC_END(_restgpr_17_x) -+FUNC_END(_restgpr_16_x) -+FUNC_END(_restgpr_15_x) -+FUNC_END(_restgpr_14_x) -+ -+#endif ---- /dev/null -+++ b/gcc/config/rs6000/crtsavfpr.asm -@@ -0,0 +1,90 @@ -+/* -+ * Special support for eabi and SVR4 -+ * -+ * Copyright (C) 1995, 1996, 1998, 2000, 2001, 2008 -+ * Free Software Foundation, Inc. -+ * Written By Michael Meissner -+ * 64-bit support written by David Edelsohn -+ * -+ * 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 2, or (at your option) any -+ * later version. -+ * -+ * In addition to the permissions in the GNU General Public License, the -+ * Free Software Foundation gives you unlimited permission to link the -+ * compiled version of this file with other programs, and to distribute -+ * those programs without any restriction coming from the use of this -+ * file. (The General Public License restrictions do apply in other -+ * respects; for example, they cover modification of the file, and -+ * distribution when not linked into another program.) -+ * -+ * 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. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; see the file COPYING. If not, write to -+ * the Free Software Foundation, 51 Franklin Street, Fifth Floor, -+ * Boston, MA 02110-1301, 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. -+ */ -+ -+/* Do any initializations needed for the eabi environment */ -+ -+ .file "crtsavfpr.asm" -+ .section ".text" -+ #include "ppc-asm.h" -+ -+/* On PowerPC64 Linux, these functions are provided by the linker. */ -+#ifndef __powerpc64__ -+ -+/* Routines for saving floating point registers, called by the compiler. */ -+/* Called with r11 pointing to the stack header word of the caller of the */ -+/* function, just beyond the end of the floating point save area. */ -+ -+HIDDEN_FUNC(_savefpr_14) stfd 14,-144(11) /* save fp registers */ -+HIDDEN_FUNC(_savefpr_15) stfd 15,-136(11) -+HIDDEN_FUNC(_savefpr_16) stfd 16,-128(11) -+HIDDEN_FUNC(_savefpr_17) stfd 17,-120(11) -+HIDDEN_FUNC(_savefpr_18) stfd 18,-112(11) -+HIDDEN_FUNC(_savefpr_19) stfd 19,-104(11) -+HIDDEN_FUNC(_savefpr_20) stfd 20,-96(11) -+HIDDEN_FUNC(_savefpr_21) stfd 21,-88(11) -+HIDDEN_FUNC(_savefpr_22) stfd 22,-80(11) -+HIDDEN_FUNC(_savefpr_23) stfd 23,-72(11) -+HIDDEN_FUNC(_savefpr_24) stfd 24,-64(11) -+HIDDEN_FUNC(_savefpr_25) stfd 25,-56(11) -+HIDDEN_FUNC(_savefpr_26) stfd 26,-48(11) -+HIDDEN_FUNC(_savefpr_27) stfd 27,-40(11) -+HIDDEN_FUNC(_savefpr_28) stfd 28,-32(11) -+HIDDEN_FUNC(_savefpr_29) stfd 29,-24(11) -+HIDDEN_FUNC(_savefpr_30) stfd 30,-16(11) -+HIDDEN_FUNC(_savefpr_31) stfd 31,-8(11) -+ blr -+FUNC_END(_savefpr_31) -+FUNC_END(_savefpr_30) -+FUNC_END(_savefpr_29) -+FUNC_END(_savefpr_28) -+FUNC_END(_savefpr_27) -+FUNC_END(_savefpr_26) -+FUNC_END(_savefpr_25) -+FUNC_END(_savefpr_24) -+FUNC_END(_savefpr_23) -+FUNC_END(_savefpr_22) -+FUNC_END(_savefpr_21) -+FUNC_END(_savefpr_20) -+FUNC_END(_savefpr_19) -+FUNC_END(_savefpr_18) -+FUNC_END(_savefpr_17) -+FUNC_END(_savefpr_16) -+FUNC_END(_savefpr_15) -+FUNC_END(_savefpr_14) -+ -+#endif ---- /dev/null -+++ b/gcc/config/rs6000/crtsavgpr.asm -@@ -0,0 +1,90 @@ -+/* -+ * Special support for eabi and SVR4 -+ * -+ * Copyright (C) 1995, 1996, 1998, 2000, 2001, 2008 -+ * Free Software Foundation, Inc. -+ * Written By Michael Meissner -+ * 64-bit support written by David Edelsohn -+ * -+ * 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 2, or (at your option) any -+ * later version. -+ * -+ * In addition to the permissions in the GNU General Public License, the -+ * Free Software Foundation gives you unlimited permission to link the -+ * compiled version of this file with other programs, and to distribute -+ * those programs without any restriction coming from the use of this -+ * file. (The General Public License restrictions do apply in other -+ * respects; for example, they cover modification of the file, and -+ * distribution when not linked into another program.) -+ * -+ * 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. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; see the file COPYING. If not, write to -+ * the Free Software Foundation, 51 Franklin Street, Fifth Floor, -+ * Boston, MA 02110-1301, 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. -+ */ -+ -+/* Do any initializations needed for the eabi environment */ -+ -+ .file "crtsavgpr.asm" -+ .section ".text" -+ #include "ppc-asm.h" -+ -+/* On PowerPC64 Linux, these functions are provided by the linker. */ -+#ifndef __powerpc64__ -+ -+/* Routines for saving integer registers, called by the compiler. */ -+/* Called with r11 pointing to the stack header word of the caller of the */ -+/* function, just beyond the end of the integer save area. */ -+ -+HIDDEN_FUNC(_savegpr_14) stw 14,-72(11) /* save gp registers */ -+HIDDEN_FUNC(_savegpr_15) stw 15,-68(11) -+HIDDEN_FUNC(_savegpr_16) stw 16,-64(11) -+HIDDEN_FUNC(_savegpr_17) stw 17,-60(11) -+HIDDEN_FUNC(_savegpr_18) stw 18,-56(11) -+HIDDEN_FUNC(_savegpr_19) stw 19,-52(11) -+HIDDEN_FUNC(_savegpr_20) stw 20,-48(11) -+HIDDEN_FUNC(_savegpr_21) stw 21,-44(11) -+HIDDEN_FUNC(_savegpr_22) stw 22,-40(11) -+HIDDEN_FUNC(_savegpr_23) stw 23,-36(11) -+HIDDEN_FUNC(_savegpr_24) stw 24,-32(11) -+HIDDEN_FUNC(_savegpr_25) stw 25,-28(11) -+HIDDEN_FUNC(_savegpr_26) stw 26,-24(11) -+HIDDEN_FUNC(_savegpr_27) stw 27,-20(11) -+HIDDEN_FUNC(_savegpr_28) stw 28,-16(11) -+HIDDEN_FUNC(_savegpr_29) stw 29,-12(11) -+HIDDEN_FUNC(_savegpr_30) stw 30,-8(11) -+HIDDEN_FUNC(_savegpr_31) stw 31,-4(11) -+ blr -+FUNC_END(_savegpr_31) -+FUNC_END(_savegpr_30) -+FUNC_END(_savegpr_29) -+FUNC_END(_savegpr_28) -+FUNC_END(_savegpr_27) -+FUNC_END(_savegpr_26) -+FUNC_END(_savegpr_25) -+FUNC_END(_savegpr_24) -+FUNC_END(_savegpr_23) -+FUNC_END(_savegpr_22) -+FUNC_END(_savegpr_21) -+FUNC_END(_savegpr_20) -+FUNC_END(_savegpr_19) -+FUNC_END(_savegpr_18) -+FUNC_END(_savegpr_17) -+FUNC_END(_savegpr_16) -+FUNC_END(_savegpr_15) -+FUNC_END(_savegpr_14) -+ -+#endif ---- a/gcc/config/rs6000/crtsavres.asm -+++ /dev/null -@@ -1,307 +0,0 @@ --/* -- * Special support for eabi and SVR4 -- * -- * Copyright (C) 1995, 1996, 1998, 2000, 2001 Free Software Foundation, Inc. -- * Written By Michael Meissner -- * 64-bit support written by David Edelsohn -- * -- * 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 2, or (at your option) any -- * later version. -- * -- * In addition to the permissions in the GNU General Public License, the -- * Free Software Foundation gives you unlimited permission to link the -- * compiled version of this file with other programs, and to distribute -- * those programs without any restriction coming from the use of this -- * file. (The General Public License restrictions do apply in other -- * respects; for example, they cover modification of the file, and -- * distribution when not linked into another program.) -- * -- * 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. -- * -- * You should have received a copy of the GNU General Public License -- * along with this program; see the file COPYING. If not, write to -- * the Free Software Foundation, 51 Franklin Street, Fifth Floor, -- * Boston, MA 02110-1301, 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. -- */ -- --/* Do any initializations needed for the eabi environment */ -- -- .file "crtsavres.asm" -- .section ".text" -- #include "ppc-asm.h" -- --/* On PowerPC64 Linux, these functions are provided by the linker. */ --#ifndef __powerpc64__ -- --/* Routines for saving floating point registers, called by the compiler. */ --/* Called with r11 pointing to the stack header word of the caller of the */ --/* function, just beyond the end of the floating point save area. */ -- --FUNC_START(_savefpr_14) stfd 14,-144(11) /* save fp registers */ --FUNC_START(_savefpr_15) stfd 15,-136(11) --FUNC_START(_savefpr_16) stfd 16,-128(11) --FUNC_START(_savefpr_17) stfd 17,-120(11) --FUNC_START(_savefpr_18) stfd 18,-112(11) --FUNC_START(_savefpr_19) stfd 19,-104(11) --FUNC_START(_savefpr_20) stfd 20,-96(11) --FUNC_START(_savefpr_21) stfd 21,-88(11) --FUNC_START(_savefpr_22) stfd 22,-80(11) --FUNC_START(_savefpr_23) stfd 23,-72(11) --FUNC_START(_savefpr_24) stfd 24,-64(11) --FUNC_START(_savefpr_25) stfd 25,-56(11) --FUNC_START(_savefpr_26) stfd 26,-48(11) --FUNC_START(_savefpr_27) stfd 27,-40(11) --FUNC_START(_savefpr_28) stfd 28,-32(11) --FUNC_START(_savefpr_29) stfd 29,-24(11) --FUNC_START(_savefpr_30) stfd 30,-16(11) --FUNC_START(_savefpr_31) stfd 31,-8(11) -- blr --FUNC_END(_savefpr_31) --FUNC_END(_savefpr_30) --FUNC_END(_savefpr_29) --FUNC_END(_savefpr_28) --FUNC_END(_savefpr_27) --FUNC_END(_savefpr_26) --FUNC_END(_savefpr_25) --FUNC_END(_savefpr_24) --FUNC_END(_savefpr_23) --FUNC_END(_savefpr_22) --FUNC_END(_savefpr_21) --FUNC_END(_savefpr_20) --FUNC_END(_savefpr_19) --FUNC_END(_savefpr_18) --FUNC_END(_savefpr_17) --FUNC_END(_savefpr_16) --FUNC_END(_savefpr_15) --FUNC_END(_savefpr_14) -- --/* Routines for saving integer registers, called by the compiler. */ --/* Called with r11 pointing to the stack header word of the caller of the */ --/* function, just beyond the end of the integer save area. */ -- --FUNC_START(_savegpr_14) stw 14,-72(11) /* save gp registers */ --FUNC_START(_savegpr_15) stw 15,-68(11) --FUNC_START(_savegpr_16) stw 16,-64(11) --FUNC_START(_savegpr_17) stw 17,-60(11) --FUNC_START(_savegpr_18) stw 18,-56(11) --FUNC_START(_savegpr_19) stw 19,-52(11) --FUNC_START(_savegpr_20) stw 20,-48(11) --FUNC_START(_savegpr_21) stw 21,-44(11) --FUNC_START(_savegpr_22) stw 22,-40(11) --FUNC_START(_savegpr_23) stw 23,-36(11) --FUNC_START(_savegpr_24) stw 24,-32(11) --FUNC_START(_savegpr_25) stw 25,-28(11) --FUNC_START(_savegpr_26) stw 26,-24(11) --FUNC_START(_savegpr_27) stw 27,-20(11) --FUNC_START(_savegpr_28) stw 28,-16(11) --FUNC_START(_savegpr_29) stw 29,-12(11) --FUNC_START(_savegpr_30) stw 30,-8(11) --FUNC_START(_savegpr_31) stw 31,-4(11) -- blr --FUNC_END(_savegpr_31) --FUNC_END(_savegpr_30) --FUNC_END(_savegpr_29) --FUNC_END(_savegpr_28) --FUNC_END(_savegpr_27) --FUNC_END(_savegpr_26) --FUNC_END(_savegpr_25) --FUNC_END(_savegpr_24) --FUNC_END(_savegpr_23) --FUNC_END(_savegpr_22) --FUNC_END(_savegpr_21) --FUNC_END(_savegpr_20) --FUNC_END(_savegpr_19) --FUNC_END(_savegpr_18) --FUNC_END(_savegpr_17) --FUNC_END(_savegpr_16) --FUNC_END(_savegpr_15) --FUNC_END(_savegpr_14) -- --/* Routines for restoring floating point registers, called by the compiler. */ --/* Called with r11 pointing to the stack header word of the caller of the */ --/* function, just beyond the end of the floating point save area. */ -- --FUNC_START(_restfpr_14) lfd 14,-144(11) /* restore fp registers */ --FUNC_START(_restfpr_15) lfd 15,-136(11) --FUNC_START(_restfpr_16) lfd 16,-128(11) --FUNC_START(_restfpr_17) lfd 17,-120(11) --FUNC_START(_restfpr_18) lfd 18,-112(11) --FUNC_START(_restfpr_19) lfd 19,-104(11) --FUNC_START(_restfpr_20) lfd 20,-96(11) --FUNC_START(_restfpr_21) lfd 21,-88(11) --FUNC_START(_restfpr_22) lfd 22,-80(11) --FUNC_START(_restfpr_23) lfd 23,-72(11) --FUNC_START(_restfpr_24) lfd 24,-64(11) --FUNC_START(_restfpr_25) lfd 25,-56(11) --FUNC_START(_restfpr_26) lfd 26,-48(11) --FUNC_START(_restfpr_27) lfd 27,-40(11) --FUNC_START(_restfpr_28) lfd 28,-32(11) --FUNC_START(_restfpr_29) lfd 29,-24(11) --FUNC_START(_restfpr_30) lfd 30,-16(11) --FUNC_START(_restfpr_31) lfd 31,-8(11) -- blr --FUNC_END(_restfpr_31) --FUNC_END(_restfpr_30) --FUNC_END(_restfpr_29) --FUNC_END(_restfpr_28) --FUNC_END(_restfpr_27) --FUNC_END(_restfpr_26) --FUNC_END(_restfpr_25) --FUNC_END(_restfpr_24) --FUNC_END(_restfpr_23) --FUNC_END(_restfpr_22) --FUNC_END(_restfpr_21) --FUNC_END(_restfpr_20) --FUNC_END(_restfpr_19) --FUNC_END(_restfpr_18) --FUNC_END(_restfpr_17) --FUNC_END(_restfpr_16) --FUNC_END(_restfpr_15) --FUNC_END(_restfpr_14) -- --/* Routines for restoring integer registers, called by the compiler. */ --/* Called with r11 pointing to the stack header word of the caller of the */ --/* function, just beyond the end of the integer restore area. */ -- --FUNC_START(_restgpr_14) lwz 14,-72(11) /* restore gp registers */ --FUNC_START(_restgpr_15) lwz 15,-68(11) --FUNC_START(_restgpr_16) lwz 16,-64(11) --FUNC_START(_restgpr_17) lwz 17,-60(11) --FUNC_START(_restgpr_18) lwz 18,-56(11) --FUNC_START(_restgpr_19) lwz 19,-52(11) --FUNC_START(_restgpr_20) lwz 20,-48(11) --FUNC_START(_restgpr_21) lwz 21,-44(11) --FUNC_START(_restgpr_22) lwz 22,-40(11) --FUNC_START(_restgpr_23) lwz 23,-36(11) --FUNC_START(_restgpr_24) lwz 24,-32(11) --FUNC_START(_restgpr_25) lwz 25,-28(11) --FUNC_START(_restgpr_26) lwz 26,-24(11) --FUNC_START(_restgpr_27) lwz 27,-20(11) --FUNC_START(_restgpr_28) lwz 28,-16(11) --FUNC_START(_restgpr_29) lwz 29,-12(11) --FUNC_START(_restgpr_30) lwz 30,-8(11) --FUNC_START(_restgpr_31) lwz 31,-4(11) -- blr --FUNC_END(_restgpr_31) --FUNC_END(_restgpr_30) --FUNC_END(_restgpr_29) --FUNC_END(_restgpr_28) --FUNC_END(_restgpr_27) --FUNC_END(_restgpr_26) --FUNC_END(_restgpr_25) --FUNC_END(_restgpr_24) --FUNC_END(_restgpr_23) --FUNC_END(_restgpr_22) --FUNC_END(_restgpr_21) --FUNC_END(_restgpr_20) --FUNC_END(_restgpr_19) --FUNC_END(_restgpr_18) --FUNC_END(_restgpr_17) --FUNC_END(_restgpr_16) --FUNC_END(_restgpr_15) --FUNC_END(_restgpr_14) -- --/* Routines for restoring floating point registers, called by the compiler. */ --/* Called with r11 pointing to the stack header word of the caller of the */ --/* function, just beyond the end of the floating point save area. */ --/* In addition to restoring the fp registers, it will return to the caller's */ --/* caller */ -- --FUNC_START(_restfpr_14_x) lfd 14,-144(11) /* restore fp registers */ --FUNC_START(_restfpr_15_x) lfd 15,-136(11) --FUNC_START(_restfpr_16_x) lfd 16,-128(11) --FUNC_START(_restfpr_17_x) lfd 17,-120(11) --FUNC_START(_restfpr_18_x) lfd 18,-112(11) --FUNC_START(_restfpr_19_x) lfd 19,-104(11) --FUNC_START(_restfpr_20_x) lfd 20,-96(11) --FUNC_START(_restfpr_21_x) lfd 21,-88(11) --FUNC_START(_restfpr_22_x) lfd 22,-80(11) --FUNC_START(_restfpr_23_x) lfd 23,-72(11) --FUNC_START(_restfpr_24_x) lfd 24,-64(11) --FUNC_START(_restfpr_25_x) lfd 25,-56(11) --FUNC_START(_restfpr_26_x) lfd 26,-48(11) --FUNC_START(_restfpr_27_x) lfd 27,-40(11) --FUNC_START(_restfpr_28_x) lfd 28,-32(11) --FUNC_START(_restfpr_29_x) lfd 29,-24(11) --FUNC_START(_restfpr_30_x) lfd 30,-16(11) --FUNC_START(_restfpr_31_x) lwz 0,4(11) -- lfd 31,-8(11) -- mtlr 0 -- mr 1,11 -- blr --FUNC_END(_restfpr_31_x) --FUNC_END(_restfpr_30_x) --FUNC_END(_restfpr_29_x) --FUNC_END(_restfpr_28_x) --FUNC_END(_restfpr_27_x) --FUNC_END(_restfpr_26_x) --FUNC_END(_restfpr_25_x) --FUNC_END(_restfpr_24_x) --FUNC_END(_restfpr_23_x) --FUNC_END(_restfpr_22_x) --FUNC_END(_restfpr_21_x) --FUNC_END(_restfpr_20_x) --FUNC_END(_restfpr_19_x) --FUNC_END(_restfpr_18_x) --FUNC_END(_restfpr_17_x) --FUNC_END(_restfpr_16_x) --FUNC_END(_restfpr_15_x) --FUNC_END(_restfpr_14_x) -- --/* Routines for restoring integer registers, called by the compiler. */ --/* Called with r11 pointing to the stack header word of the caller of the */ --/* function, just beyond the end of the integer restore area. */ -- --FUNC_START(_restgpr_14_x) lwz 14,-72(11) /* restore gp registers */ --FUNC_START(_restgpr_15_x) lwz 15,-68(11) --FUNC_START(_restgpr_16_x) lwz 16,-64(11) --FUNC_START(_restgpr_17_x) lwz 17,-60(11) --FUNC_START(_restgpr_18_x) lwz 18,-56(11) --FUNC_START(_restgpr_19_x) lwz 19,-52(11) --FUNC_START(_restgpr_20_x) lwz 20,-48(11) --FUNC_START(_restgpr_21_x) lwz 21,-44(11) --FUNC_START(_restgpr_22_x) lwz 22,-40(11) --FUNC_START(_restgpr_23_x) lwz 23,-36(11) --FUNC_START(_restgpr_24_x) lwz 24,-32(11) --FUNC_START(_restgpr_25_x) lwz 25,-28(11) --FUNC_START(_restgpr_26_x) lwz 26,-24(11) --FUNC_START(_restgpr_27_x) lwz 27,-20(11) --FUNC_START(_restgpr_28_x) lwz 28,-16(11) --FUNC_START(_restgpr_29_x) lwz 29,-12(11) --FUNC_START(_restgpr_30_x) lwz 30,-8(11) --FUNC_START(_restgpr_31_x) lwz 0,4(11) -- lwz 31,-4(11) -- mtlr 0 -- mr 1,11 -- blr --FUNC_END(_restgpr_31_x) --FUNC_END(_restgpr_30_x) --FUNC_END(_restgpr_29_x) --FUNC_END(_restgpr_28_x) --FUNC_END(_restgpr_27_x) --FUNC_END(_restgpr_26_x) --FUNC_END(_restgpr_25_x) --FUNC_END(_restgpr_24_x) --FUNC_END(_restgpr_23_x) --FUNC_END(_restgpr_22_x) --FUNC_END(_restgpr_21_x) --FUNC_END(_restgpr_20_x) --FUNC_END(_restgpr_19_x) --FUNC_END(_restgpr_18_x) --FUNC_END(_restgpr_17_x) --FUNC_END(_restgpr_16_x) --FUNC_END(_restgpr_15_x) --FUNC_END(_restgpr_14_x) -- --#endif ---- a/gcc/config/rs6000/darwin-ldouble.c -+++ b/gcc/config/rs6000/darwin-ldouble.c -@@ -422,15 +422,13 @@ fmsub (double a, double b, double c) - FP_UNPACK_SEMIRAW_Q(U,u); - FP_UNPACK_SEMIRAW_Q(Z,z); - FP_SUB_Q(V,U,Z); -- FP_PACK_SEMIRAW_Q(v,V); -- FP_HANDLE_EXCEPTIONS; - - /* Truncate quad to double. */ -- FP_INIT_ROUNDMODE; -- FP_UNPACK_SEMIRAW_Q(V,v); - #if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q -+ V_f[3] &= 0x0007ffff; - FP_TRUNC(D,Q,2,4,R,V); - #else -+ V_f1 &= 0x0007ffffffffffffL; - FP_TRUNC(D,Q,1,2,R,V); - #endif - FP_PACK_SEMIRAW_D(r,R); ---- a/gcc/config/rs6000/darwin.h -+++ b/gcc/config/rs6000/darwin.h -@@ -191,6 +191,8 @@ - - #undef FP_SAVE_INLINE - #define FP_SAVE_INLINE(FIRST_REG) ((FIRST_REG) < 64) -+#undef GP_SAVE_INLINE -+#define GP_SAVE_INLINE(FIRST_REG) ((FIRST_REG) < 32) - - /* Darwin uses a function call if everything needs to be saved/restored. */ - #undef WORLD_SAVE_P ---- a/gcc/config/rs6000/dfp.md -+++ b/gcc/config/rs6000/dfp.md -@@ -155,7 +155,7 @@ - (define_expand "negdd2" - [(set (match_operand:DD 0 "gpc_reg_operand" "") - (neg:DD (match_operand:DD 1 "gpc_reg_operand" "")))] -- "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)" -+ "TARGET_HARD_FLOAT && TARGET_FPRS" - "") - - (define_insn "*negdd2_fpr" -@@ -168,7 +168,7 @@ - (define_expand "absdd2" - [(set (match_operand:DD 0 "gpc_reg_operand" "") - (abs:DD (match_operand:DD 1 "gpc_reg_operand" "")))] -- "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)" -+ "TARGET_HARD_FLOAT && TARGET_FPRS" - "") - - (define_insn "*absdd2_fpr" -@@ -376,7 +376,7 @@ - (define_insn "*movdd_softfloat32" - [(set (match_operand:DD 0 "nonimmediate_operand" "=r,r,m,r,r,r") - (match_operand:DD 1 "input_operand" "r,m,r,G,H,F"))] -- "! TARGET_POWERPC64 && TARGET_SOFT_FLOAT -+ "! TARGET_POWERPC64 && (TARGET_SOFT_FLOAT || !TARGET_FPRS) - && (gpc_reg_operand (operands[0], DDmode) - || gpc_reg_operand (operands[1], DDmode))" - "* -@@ -486,7 +486,7 @@ - (define_expand "negtd2" - [(set (match_operand:TD 0 "gpc_reg_operand" "") - (neg:TD (match_operand:TD 1 "gpc_reg_operand" "")))] -- "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)" -+ "TARGET_HARD_FLOAT && TARGET_FPRS" - "") - - (define_insn "*negtd2_fpr" -@@ -499,7 +499,7 @@ - (define_expand "abstd2" - [(set (match_operand:TD 0 "gpc_reg_operand" "") - (abs:TD (match_operand:TD 1 "gpc_reg_operand" "")))] -- "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)" -+ "TARGET_HARD_FLOAT && TARGET_FPRS" - "") - - (define_insn "*abstd2_fpr" ---- /dev/null -+++ b/gcc/config/rs6000/e300c2c3.md -@@ -0,0 +1,189 @@ -+;; Pipeline description for Motorola PowerPC e300c3 core. -+;; Copyright (C) 2008 Free Software Foundation, Inc. -+;; Contributed by Edmar Wienskoski (edmar@freescale.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 -+;; . -+ -+(define_automaton "ppce300c3_most,ppce300c3_long,ppce300c3_retire") -+(define_cpu_unit "ppce300c3_decode_0,ppce300c3_decode_1" "ppce300c3_most") -+ -+;; We don't simulate general issue queue (GIC). If we have SU insn -+;; and then SU1 insn, they can not be issued on the same cycle -+;; (although SU1 insn and then SU insn can be issued) because the SU -+;; insn will go to SU1 from GIC0 entry. Fortunately, the first cycle -+;; multipass insn scheduling will find the situation and issue the SU1 -+;; insn and then the SU insn. -+(define_cpu_unit "ppce300c3_issue_0,ppce300c3_issue_1" "ppce300c3_most") -+ -+;; We could describe completion buffers slots in combination with the -+;; retirement units and the order of completion but the result -+;; automaton would behave in the same way because we can not describe -+;; real latency time with taking in order completion into account. -+;; Actually we could define the real latency time by querying reserved -+;; automaton units but the current scheduler uses latency time before -+;; issuing insns and making any reservations. -+;; -+;; So our description is aimed to achieve a insn schedule in which the -+;; insns would not wait in the completion buffer. -+(define_cpu_unit "ppce300c3_retire_0,ppce300c3_retire_1" "ppce300c3_retire") -+ -+;; Branch unit: -+(define_cpu_unit "ppce300c3_bu" "ppce300c3_most") -+ -+;; IU: -+(define_cpu_unit "ppce300c3_iu0_stage0,ppce300c3_iu1_stage0" "ppce300c3_most") -+ -+;; IU: This used to describe non-pipelined division. -+(define_cpu_unit "ppce300c3_mu_div" "ppce300c3_long") -+ -+;; SRU: -+(define_cpu_unit "ppce300c3_sru_stage0" "ppce300c3_most") -+ -+;; Here we simplified LSU unit description not describing the stages. -+(define_cpu_unit "ppce300c3_lsu" "ppce300c3_most") -+ -+;; FPU: -+(define_cpu_unit "ppce300c3_fpu" "ppce300c3_most") -+ -+;; The following units are used to make automata deterministic -+(define_cpu_unit "present_ppce300c3_decode_0" "ppce300c3_most") -+(define_cpu_unit "present_ppce300c3_issue_0" "ppce300c3_most") -+(define_cpu_unit "present_ppce300c3_retire_0" "ppce300c3_retire") -+(define_cpu_unit "present_ppce300c3_iu0_stage0" "ppce300c3_most") -+ -+;; The following sets to make automata deterministic when option ndfa is used. -+(presence_set "present_ppce300c3_decode_0" "ppce300c3_decode_0") -+(presence_set "present_ppce300c3_issue_0" "ppce300c3_issue_0") -+(presence_set "present_ppce300c3_retire_0" "ppce300c3_retire_0") -+(presence_set "present_ppce300c3_iu0_stage0" "ppce300c3_iu0_stage0") -+ -+;; Some useful abbreviations. -+(define_reservation "ppce300c3_decode" -+ "ppce300c3_decode_0|ppce300c3_decode_1+present_ppce300c3_decode_0") -+(define_reservation "ppce300c3_issue" -+ "ppce300c3_issue_0|ppce300c3_issue_1+present_ppce300c3_issue_0") -+(define_reservation "ppce300c3_retire" -+ "ppce300c3_retire_0|ppce300c3_retire_1+present_ppce300c3_retire_0") -+(define_reservation "ppce300c3_iu_stage0" -+ "ppce300c3_iu0_stage0|ppce300c3_iu1_stage0+present_ppce300c3_iu0_stage0") -+ -+;; Compares can be executed either one of the IU or SRU -+(define_insn_reservation "ppce300c3_cmp" 1 -+ (and (eq_attr "type" "cmp,compare,delayed_compare,fast_compare") -+ (ior (eq_attr "cpu" "ppce300c2") (eq_attr "cpu" "ppce300c3"))) -+ "ppce300c3_decode,ppce300c3_issue+(ppce300c3_iu_stage0|ppce300c3_sru_stage0) \ -+ +ppce300c3_retire") -+ -+;; Other one cycle IU insns -+(define_insn_reservation "ppce300c3_iu" 1 -+ (and (eq_attr "type" "integer,insert_word") -+ (ior (eq_attr "cpu" "ppce300c2") (eq_attr "cpu" "ppce300c3"))) -+ "ppce300c3_decode,ppce300c3_issue+ppce300c3_iu_stage0+ppce300c3_retire") -+ -+;; Branch. Actually this latency time is not used by the scheduler. -+(define_insn_reservation "ppce300c3_branch" 1 -+ (and (eq_attr "type" "jmpreg,branch") -+ (ior (eq_attr "cpu" "ppce300c2") (eq_attr "cpu" "ppce300c3"))) -+ "ppce300c3_decode,ppce300c3_bu,ppce300c3_retire") -+ -+;; Multiply is non-pipelined but can be executed in any IU -+(define_insn_reservation "ppce300c3_multiply" 2 -+ (and (eq_attr "type" "imul,imul2,imul3,imul_compare") -+ (ior (eq_attr "cpu" "ppce300c2") (eq_attr "cpu" "ppce300c3"))) -+ "ppce300c3_decode,ppce300c3_issue+ppce300c3_iu_stage0, \ -+ ppce300c3_iu_stage0+ppce300c3_retire") -+ -+;; Divide. We use the average latency time here. We omit reserving a -+;; retire unit because of the result automata will be huge. -+(define_insn_reservation "ppce300c3_divide" 20 -+ (and (eq_attr "type" "idiv") -+ (ior (eq_attr "cpu" "ppce300c2") (eq_attr "cpu" "ppce300c3"))) -+ "ppce300c3_decode,ppce300c3_issue+ppce300c3_iu_stage0+ppce300c3_mu_div,\ -+ ppce300c3_mu_div*19") -+ -+;; CR logical -+(define_insn_reservation "ppce300c3_cr_logical" 1 -+ (and (eq_attr "type" "cr_logical,delayed_cr") -+ (ior (eq_attr "cpu" "ppce300c2") (eq_attr "cpu" "ppce300c3"))) -+ "ppce300c3_decode,ppce300c3_issue+ppce300c3_sru_stage0+ppce300c3_retire") -+ -+;; Mfcr -+(define_insn_reservation "ppce300c3_mfcr" 1 -+ (and (eq_attr "type" "mfcr") -+ (ior (eq_attr "cpu" "ppce300c2") (eq_attr "cpu" "ppce300c3"))) -+ "ppce300c3_decode,ppce300c3_issue+ppce300c3_sru_stage0+ppce300c3_retire") -+ -+;; Mtcrf -+(define_insn_reservation "ppce300c3_mtcrf" 1 -+ (and (eq_attr "type" "mtcr") -+ (ior (eq_attr "cpu" "ppce300c2") (eq_attr "cpu" "ppce300c3"))) -+ "ppce300c3_decode,ppce300c3_issue+ppce300c3_sru_stage0+ppce300c3_retire") -+ -+;; Mtjmpr -+(define_insn_reservation "ppce300c3_mtjmpr" 1 -+ (and (eq_attr "type" "mtjmpr,mfjmpr") -+ (ior (eq_attr "cpu" "ppce300c2") (eq_attr "cpu" "ppce300c3"))) -+ "ppce300c3_decode,ppce300c3_issue+ppce300c3_sru_stage0+ppce300c3_retire") -+ -+;; Float point instructions -+(define_insn_reservation "ppce300c3_fpcompare" 3 -+ (and (eq_attr "type" "fpcompare") -+ (eq_attr "cpu" "ppce300c3")) -+ "ppce300c3_decode,ppce300c3_issue+ppce300c3_fpu,nothing,ppce300c3_retire") -+ -+(define_insn_reservation "ppce300c3_fp" 3 -+ (and (eq_attr "type" "fp") -+ (eq_attr "cpu" "ppce300c3")) -+ "ppce300c3_decode,ppce300c3_issue+ppce300c3_fpu,nothing,ppce300c3_retire") -+ -+(define_insn_reservation "ppce300c3_dmul" 4 -+ (and (eq_attr "type" "dmul") -+ (eq_attr "cpu" "ppce300c3")) -+ "ppce300c3_decode,ppce300c3_issue+ppce300c3_fpu,ppce300c3_fpu,nothing,ppce300c3_retire") -+ -+; Divides are not pipelined -+(define_insn_reservation "ppce300c3_sdiv" 18 -+ (and (eq_attr "type" "sdiv") -+ (eq_attr "cpu" "ppce300c3")) -+ "ppce300c3_decode,ppce300c3_issue+ppce300c3_fpu,ppce300c3_fpu*17") -+ -+(define_insn_reservation "ppce300c3_ddiv" 33 -+ (and (eq_attr "type" "ddiv") -+ (eq_attr "cpu" "ppce300c3")) -+ "ppce300c3_decode,ppce300c3_issue+ppce300c3_fpu,ppce300c3_fpu*32") -+ -+;; Loads -+(define_insn_reservation "ppce300c3_load" 2 -+ (and (eq_attr "type" "load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u") -+ (ior (eq_attr "cpu" "ppce300c2") (eq_attr "cpu" "ppce300c3"))) -+ "ppce300c3_decode,ppce300c3_issue+ppce300c3_lsu,ppce300c3_retire") -+ -+(define_insn_reservation "ppce300c3_fpload" 2 -+ (and (eq_attr "type" "fpload,fpload_ux,fpload_u") -+ (eq_attr "cpu" "ppce300c3")) -+ "ppce300c3_decode,ppce300c3_issue+ppce300c3_lsu,ppce300c3_retire") -+ -+;; Stores. -+(define_insn_reservation "ppce300c3_store" 2 -+ (and (eq_attr "type" "store,store_ux,store_u") -+ (ior (eq_attr "cpu" "ppce300c2") (eq_attr "cpu" "ppce300c3"))) -+ "ppce300c3_decode,ppce300c3_issue+ppce300c3_lsu,ppce300c3_retire") -+ -+(define_insn_reservation "ppce300c3_fpstore" 2 -+ (and (eq_attr "type" "fpstore,fpstore_ux,fpstore_u") -+ (eq_attr "cpu" "ppce300c3")) -+ "ppce300c3_decode,ppce300c3_issue+ppce300c3_lsu,ppce300c3_retire") ---- a/gcc/config/rs6000/e500.h -+++ b/gcc/config/rs6000/e500.h -@@ -19,7 +19,6 @@ - #undef TARGET_SPE_ABI - #undef TARGET_SPE - #undef TARGET_E500 --#undef TARGET_ISEL - #undef TARGET_FPRS - #undef TARGET_E500_SINGLE - #undef TARGET_E500_DOUBLE -@@ -28,13 +27,12 @@ - #define TARGET_SPE_ABI rs6000_spe_abi - #define TARGET_SPE rs6000_spe - #define TARGET_E500 (rs6000_cpu == PROCESSOR_PPC8540) --#define TARGET_ISEL rs6000_isel - #define TARGET_FPRS (rs6000_float_gprs == 0) - #define TARGET_E500_SINGLE (TARGET_HARD_FLOAT && rs6000_float_gprs == 1) - #define TARGET_E500_DOUBLE (TARGET_HARD_FLOAT && rs6000_float_gprs == 2) - #define CHECK_E500_OPTIONS \ - do { \ -- if (TARGET_E500 || TARGET_SPE || TARGET_SPE_ABI || TARGET_ISEL \ -+ if (TARGET_E500 || TARGET_SPE || TARGET_SPE_ABI \ - || TARGET_E500_SINGLE || TARGET_E500_DOUBLE) \ - { \ - if (TARGET_ALTIVEC) \ ---- /dev/null -+++ b/gcc/config/rs6000/e500crtres32gpr.asm -@@ -0,0 +1,84 @@ -+/* -+ * Special support for e500 eabi and SVR4 -+ * -+ * Copyright (C) 2008 Free Software Foundation, Inc. -+ * Written by Nathan Froyd -+ * -+ * 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 2, or (at your option) any -+ * later version. -+ * -+ * In addition to the permissions in the GNU General Public License, the -+ * Free Software Foundation gives you unlimited permission to link the -+ * compiled version of this file with other programs, and to distribute -+ * those programs without any restriction coming from the use of this -+ * file. (The General Public License restrictions do apply in other -+ * respects; for example, they cover modification of the file, and -+ * distribution when not linked into another program.) -+ * -+ * 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. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; see the file COPYING. If not, write to -+ * the Free Software Foundation, 51 Franklin Street, Fifth Floor, -+ * Boston, MA 02110-1301, 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. -+ */ -+ -+ .file "e500crtres32gpr.asm" -+ .section ".text" -+ #include "ppc-asm.h" -+ -+#ifdef __SPE__ -+ -+/* Routines for restoring 32-bit integer registers, called by the compiler. */ -+/* "Bare" versions that simply return to their caller. */ -+ -+HIDDEN_FUNC(_rest32gpr_14) lwz 14,-72(11) -+HIDDEN_FUNC(_rest32gpr_15) lwz 15,-68(11) -+HIDDEN_FUNC(_rest32gpr_16) lwz 16,-64(11) -+HIDDEN_FUNC(_rest32gpr_17) lwz 17,-60(11) -+HIDDEN_FUNC(_rest32gpr_18) lwz 18,-56(11) -+HIDDEN_FUNC(_rest32gpr_19) lwz 19,-52(11) -+HIDDEN_FUNC(_rest32gpr_20) lwz 20,-48(11) -+HIDDEN_FUNC(_rest32gpr_21) lwz 21,-44(11) -+HIDDEN_FUNC(_rest32gpr_22) lwz 22,-40(11) -+HIDDEN_FUNC(_rest32gpr_23) lwz 23,-36(11) -+HIDDEN_FUNC(_rest32gpr_24) lwz 24,-32(11) -+HIDDEN_FUNC(_rest32gpr_25) lwz 25,-28(11) -+HIDDEN_FUNC(_rest32gpr_26) lwz 26,-24(11) -+HIDDEN_FUNC(_rest32gpr_27) lwz 27,-20(11) -+HIDDEN_FUNC(_rest32gpr_28) lwz 28,-16(11) -+HIDDEN_FUNC(_rest32gpr_29) lwz 29,-12(11) -+HIDDEN_FUNC(_rest32gpr_30) lwz 30,-8(11) -+HIDDEN_FUNC(_rest32gpr_31) lwz 31,-4(11) -+ blr -+FUNC_END(_rest32gpr_31) -+FUNC_END(_rest32gpr_30) -+FUNC_END(_rest32gpr_29) -+FUNC_END(_rest32gpr_28) -+FUNC_END(_rest32gpr_27) -+FUNC_END(_rest32gpr_26) -+FUNC_END(_rest32gpr_25) -+FUNC_END(_rest32gpr_24) -+FUNC_END(_rest32gpr_23) -+FUNC_END(_rest32gpr_22) -+FUNC_END(_rest32gpr_21) -+FUNC_END(_rest32gpr_20) -+FUNC_END(_rest32gpr_19) -+FUNC_END(_rest32gpr_18) -+FUNC_END(_rest32gpr_17) -+FUNC_END(_rest32gpr_16) -+FUNC_END(_rest32gpr_15) -+FUNC_END(_rest32gpr_14) -+ -+#endif ---- /dev/null -+++ b/gcc/config/rs6000/e500crtres64gpr.asm -@@ -0,0 +1,84 @@ -+/* -+ * Special support for e500 eabi and SVR4 -+ * -+ * Copyright (C) 2008 Free Software Foundation, Inc. -+ * Written by Nathan Froyd -+ * -+ * 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 2, or (at your option) any -+ * later version. -+ * -+ * In addition to the permissions in the GNU General Public License, the -+ * Free Software Foundation gives you unlimited permission to link the -+ * compiled version of this file with other programs, and to distribute -+ * those programs without any restriction coming from the use of this -+ * file. (The General Public License restrictions do apply in other -+ * respects; for example, they cover modification of the file, and -+ * distribution when not linked into another program.) -+ * -+ * 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. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; see the file COPYING. If not, write to -+ * the Free Software Foundation, 51 Franklin Street, Fifth Floor, -+ * Boston, MA 02110-1301, 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. -+ */ -+ -+ .file "e500crtres64gpr.asm" -+ .section ".text" -+ #include "ppc-asm.h" -+ -+#ifdef __SPE__ -+ -+/* Routines for restoring 64-bit integer registers, called by the compiler. */ -+/* "Bare" versions that return to their caller. */ -+ -+HIDDEN_FUNC(_rest64gpr_14) evldd 14,0(11) -+HIDDEN_FUNC(_rest64gpr_15) evldd 15,8(11) -+HIDDEN_FUNC(_rest64gpr_16) evldd 16,16(11) -+HIDDEN_FUNC(_rest64gpr_17) evldd 17,24(11) -+HIDDEN_FUNC(_rest64gpr_18) evldd 18,32(11) -+HIDDEN_FUNC(_rest64gpr_19) evldd 19,40(11) -+HIDDEN_FUNC(_rest64gpr_20) evldd 20,48(11) -+HIDDEN_FUNC(_rest64gpr_21) evldd 21,56(11) -+HIDDEN_FUNC(_rest64gpr_22) evldd 22,64(11) -+HIDDEN_FUNC(_rest64gpr_23) evldd 23,72(11) -+HIDDEN_FUNC(_rest64gpr_24) evldd 24,80(11) -+HIDDEN_FUNC(_rest64gpr_25) evldd 25,88(11) -+HIDDEN_FUNC(_rest64gpr_26) evldd 26,96(11) -+HIDDEN_FUNC(_rest64gpr_27) evldd 27,104(11) -+HIDDEN_FUNC(_rest64gpr_28) evldd 28,112(11) -+HIDDEN_FUNC(_rest64gpr_29) evldd 29,120(11) -+HIDDEN_FUNC(_rest64gpr_30) evldd 30,128(11) -+HIDDEN_FUNC(_rest64gpr_31) evldd 31,136(11) -+ blr -+FUNC_END(_rest64gpr_31) -+FUNC_END(_rest64gpr_30) -+FUNC_END(_rest64gpr_29) -+FUNC_END(_rest64gpr_28) -+FUNC_END(_rest64gpr_27) -+FUNC_END(_rest64gpr_26) -+FUNC_END(_rest64gpr_25) -+FUNC_END(_rest64gpr_24) -+FUNC_END(_rest64gpr_23) -+FUNC_END(_rest64gpr_22) -+FUNC_END(_rest64gpr_21) -+FUNC_END(_rest64gpr_20) -+FUNC_END(_rest64gpr_19) -+FUNC_END(_rest64gpr_18) -+FUNC_END(_rest64gpr_17) -+FUNC_END(_rest64gpr_16) -+FUNC_END(_rest64gpr_15) -+FUNC_END(_rest64gpr_14) -+ -+#endif ---- /dev/null -+++ b/gcc/config/rs6000/e500crtres64gprctr.asm -@@ -0,0 +1,83 @@ -+/* -+ * Special support for e500 eabi and SVR4 -+ * -+ * Copyright (C) 2008 Free Software Foundation, Inc. -+ * Written by Nathan Froyd -+ * -+ * 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 2, or (at your option) any -+ * later version. -+ * -+ * In addition to the permissions in the GNU General Public License, the -+ * Free Software Foundation gives you unlimited permission to link the -+ * compiled version of this file with other programs, and to distribute -+ * those programs without any restriction coming from the use of this -+ * file. (The General Public License restrictions do apply in other -+ * respects; for example, they cover modification of the file, and -+ * distribution when not linked into another program.) -+ * -+ * 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. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; see the file COPYING. If not, write to -+ * the Free Software Foundation, 51 Franklin Street, Fifth Floor, -+ * Boston, MA 02110-1301, 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. -+ */ -+ -+ .file "e500crtres64gprctr.asm" -+ .section ".text" -+ #include "ppc-asm.h" -+ -+#ifdef __SPE__ -+ -+/* Routines for restoring 64-bit integer registers where the number of -+ registers to be restored is passed in CTR, called by the compiler. */ -+ -+HIDDEN_FUNC(_rest64gpr_ctr_14) evldd 14,0(11) -+ bdz _rest64_gpr_ctr_done -+HIDDEN_FUNC(_rest64gpr_ctr_15) evldd 15,8(11) -+ bdz _rest64_gpr_ctr_done -+HIDDEN_FUNC(_rest64gpr_ctr_16) evldd 16,16(11) -+ bdz _rest64_gpr_ctr_done -+HIDDEN_FUNC(_rest64gpr_ctr_17) evldd 17,24(11) -+ bdz _rest64_gpr_ctr_done -+HIDDEN_FUNC(_rest64gpr_ctr_18) evldd 18,32(11) -+ bdz _rest64_gpr_ctr_done -+HIDDEN_FUNC(_rest64gpr_ctr_19) evldd 19,40(11) -+ bdz _rest64_gpr_ctr_done -+HIDDEN_FUNC(_rest64gpr_ctr_20) evldd 20,48(11) -+ bdz _rest64_gpr_ctr_done -+HIDDEN_FUNC(_rest64gpr_ctr_21) evldd 21,56(11) -+ bdz _rest64_gpr_ctr_done -+HIDDEN_FUNC(_rest64gpr_ctr_22) evldd 22,64(11) -+ bdz _rest64_gpr_ctr_done -+HIDDEN_FUNC(_rest64gpr_ctr_23) evldd 23,72(11) -+ bdz _rest64_gpr_ctr_done -+HIDDEN_FUNC(_rest64gpr_ctr_24) evldd 24,80(11) -+ bdz _rest64_gpr_ctr_done -+HIDDEN_FUNC(_rest64gpr_ctr_25) evldd 25,88(11) -+ bdz _rest64_gpr_ctr_done -+HIDDEN_FUNC(_rest64gpr_ctr_26) evldd 26,96(11) -+ bdz _rest64_gpr_ctr_done -+HIDDEN_FUNC(_rest64gpr_ctr_27) evldd 27,104(11) -+ bdz _rest64_gpr_ctr_done -+HIDDEN_FUNC(_rest64gpr_ctr_28) evldd 28,112(11) -+ bdz _rest64_gpr_ctr_done -+HIDDEN_FUNC(_rest64gpr_ctr_29) evldd 29,120(11) -+ bdz _rest64_gpr_ctr_done -+HIDDEN_FUNC(_rest64gpr_ctr_30) evldd 30,128(11) -+ bdz _rest64_gpr_ctr_done -+HIDDEN_FUNC(_rest64gpr_ctr_31) evldd 31,136(11) -+_rest64gpr_ctr_done: blr -+ -+#endif ---- /dev/null -+++ b/gcc/config/rs6000/e500crtrest32gpr.asm -@@ -0,0 +1,86 @@ -+/* -+ * Special support for e500 eabi and SVR4 -+ * -+ * Copyright (C) 2008 Free Software Foundation, Inc. -+ * Written by Nathan Froyd -+ * -+ * 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 2, or (at your option) any -+ * later version. -+ * -+ * In addition to the permissions in the GNU General Public License, the -+ * Free Software Foundation gives you unlimited permission to link the -+ * compiled version of this file with other programs, and to distribute -+ * those programs without any restriction coming from the use of this -+ * file. (The General Public License restrictions do apply in other -+ * respects; for example, they cover modification of the file, and -+ * distribution when not linked into another program.) -+ * -+ * 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. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; see the file COPYING. If not, write to -+ * the Free Software Foundation, 51 Franklin Street, Fifth Floor, -+ * Boston, MA 02110-1301, 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. -+ */ -+ -+ .file "e500crtrest32gpr.asm" -+ .section ".text" -+ #include "ppc-asm.h" -+ -+#ifdef __SPE__ -+ -+/* Routines for restoring 32-bit integer registers, called by the compiler. */ -+/* "Tail" versions that perform a tail call. */ -+ -+HIDDEN_FUNC(_rest32gpr_14_t) lwz 14,-72(11) -+HIDDEN_FUNC(_rest32gpr_15_t) lwz 15,-68(11) -+HIDDEN_FUNC(_rest32gpr_16_t) lwz 16,-64(11) -+HIDDEN_FUNC(_rest32gpr_17_t) lwz 17,-60(11) -+HIDDEN_FUNC(_rest32gpr_18_t) lwz 18,-56(11) -+HIDDEN_FUNC(_rest32gpr_19_t) lwz 19,-52(11) -+HIDDEN_FUNC(_rest32gpr_20_t) lwz 20,-48(11) -+HIDDEN_FUNC(_rest32gpr_21_t) lwz 21,-44(11) -+HIDDEN_FUNC(_rest32gpr_22_t) lwz 22,-40(11) -+HIDDEN_FUNC(_rest32gpr_23_t) lwz 23,-36(11) -+HIDDEN_FUNC(_rest32gpr_24_t) lwz 24,-32(11) -+HIDDEN_FUNC(_rest32gpr_25_t) lwz 25,-28(11) -+HIDDEN_FUNC(_rest32gpr_26_t) lwz 26,-24(11) -+HIDDEN_FUNC(_rest32gpr_27_t) lwz 27,-20(11) -+HIDDEN_FUNC(_rest32gpr_28_t) lwz 28,-16(11) -+HIDDEN_FUNC(_rest32gpr_29_t) lwz 29,-12(11) -+HIDDEN_FUNC(_rest32gpr_30_t) lwz 30,-8(11) -+HIDDEN_FUNC(_rest32gpr_31_t) lwz 31,-4(11) -+ lwz 0,4(11) -+ mr 1,11 -+ blr -+FUNC_END(_rest32gpr_31_t) -+FUNC_END(_rest32gpr_30_t) -+FUNC_END(_rest32gpr_29_t) -+FUNC_END(_rest32gpr_28_t) -+FUNC_END(_rest32gpr_27_t) -+FUNC_END(_rest32gpr_26_t) -+FUNC_END(_rest32gpr_25_t) -+FUNC_END(_rest32gpr_24_t) -+FUNC_END(_rest32gpr_23_t) -+FUNC_END(_rest32gpr_22_t) -+FUNC_END(_rest32gpr_21_t) -+FUNC_END(_rest32gpr_20_t) -+FUNC_END(_rest32gpr_19_t) -+FUNC_END(_rest32gpr_18_t) -+FUNC_END(_rest32gpr_17_t) -+FUNC_END(_rest32gpr_16_t) -+FUNC_END(_rest32gpr_15_t) -+FUNC_END(_rest32gpr_14_t) -+ -+#endif ---- /dev/null -+++ b/gcc/config/rs6000/e500crtrest64gpr.asm -@@ -0,0 +1,85 @@ -+/* -+ * Special support for e500 eabi and SVR4 -+ * -+ * Copyright (C) 2008 Free Software Foundation, Inc. -+ * Written by Nathan Froyd -+ * -+ * 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 2, or (at your option) any -+ * later version. -+ * -+ * In addition to the permissions in the GNU General Public License, the -+ * Free Software Foundation gives you unlimited permission to link the -+ * compiled version of this file with other programs, and to distribute -+ * those programs without any restriction coming from the use of this -+ * file. (The General Public License restrictions do apply in other -+ * respects; for example, they cover modification of the file, and -+ * distribution when not linked into another program.) -+ * -+ * 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. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; see the file COPYING. If not, write to -+ * the Free Software Foundation, 51 Franklin Street, Fifth Floor, -+ * Boston, MA 02110-1301, 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. -+ */ -+ -+ .file "e500crtrest64gpr.asm" -+ .section ".text" -+ #include "ppc-asm.h" -+ -+#ifdef __SPE__ -+ -+/* "Tail" versions that perform a tail call. */ -+ -+HIDDEN_FUNC(_rest64gpr_14_t) evldd 14,0(11) -+HIDDEN_FUNC(_rest64gpr_15_t) evldd 15,8(11) -+HIDDEN_FUNC(_rest64gpr_16_t) evldd 16,16(11) -+HIDDEN_FUNC(_rest64gpr_17_t) evldd 17,24(11) -+HIDDEN_FUNC(_rest64gpr_18_t) evldd 18,32(11) -+HIDDEN_FUNC(_rest64gpr_19_t) evldd 19,40(11) -+HIDDEN_FUNC(_rest64gpr_20_t) evldd 20,48(11) -+HIDDEN_FUNC(_rest64gpr_21_t) evldd 21,56(11) -+HIDDEN_FUNC(_rest64gpr_22_t) evldd 22,64(11) -+HIDDEN_FUNC(_rest64gpr_23_t) evldd 23,72(11) -+HIDDEN_FUNC(_rest64gpr_24_t) evldd 24,80(11) -+HIDDEN_FUNC(_rest64gpr_25_t) evldd 25,88(11) -+HIDDEN_FUNC(_rest64gpr_26_t) evldd 26,96(11) -+HIDDEN_FUNC(_rest64gpr_27_t) evldd 27,104(11) -+HIDDEN_FUNC(_rest64gpr_28_t) evldd 28,112(11) -+HIDDEN_FUNC(_rest64gpr_29_t) evldd 29,120(11) -+HIDDEN_FUNC(_rest64gpr_30_t) evldd 30,128(11) -+HIDDEN_FUNC(_rest64gpr_31_t) lwz 0,148(11) -+ evldd 31,136(11) -+ addi 1,11,144 -+ blr -+FUNC_END(_rest64gpr_31_t) -+FUNC_END(_rest64gpr_30_t) -+FUNC_END(_rest64gpr_29_t) -+FUNC_END(_rest64gpr_28_t) -+FUNC_END(_rest64gpr_27_t) -+FUNC_END(_rest64gpr_26_t) -+FUNC_END(_rest64gpr_25_t) -+FUNC_END(_rest64gpr_24_t) -+FUNC_END(_rest64gpr_23_t) -+FUNC_END(_rest64gpr_22_t) -+FUNC_END(_rest64gpr_21_t) -+FUNC_END(_rest64gpr_20_t) -+FUNC_END(_rest64gpr_19_t) -+FUNC_END(_rest64gpr_18_t) -+FUNC_END(_rest64gpr_17_t) -+FUNC_END(_rest64gpr_16_t) -+FUNC_END(_rest64gpr_15_t) -+FUNC_END(_rest64gpr_14_t) -+ -+#endif ---- /dev/null -+++ b/gcc/config/rs6000/e500crtresx32gpr.asm -@@ -0,0 +1,87 @@ -+/* -+ * Special support for e500 eabi and SVR4 -+ * -+ * Copyright (C) 2008 Free Software Foundation, Inc. -+ * Written by Nathan Froyd -+ * -+ * 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 2, or (at your option) any -+ * later version. -+ * -+ * In addition to the permissions in the GNU General Public License, the -+ * Free Software Foundation gives you unlimited permission to link the -+ * compiled version of this file with other programs, and to distribute -+ * those programs without any restriction coming from the use of this -+ * file. (The General Public License restrictions do apply in other -+ * respects; for example, they cover modification of the file, and -+ * distribution when not linked into another program.) -+ * -+ * 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. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; see the file COPYING. If not, write to -+ * the Free Software Foundation, 51 Franklin Street, Fifth Floor, -+ * Boston, MA 02110-1301, 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. -+ */ -+ -+ .file "e500crtresx32gpr.asm" -+ .section ".text" -+ #include "ppc-asm.h" -+ -+#ifdef __SPE__ -+ -+/* Routines for restoring 32-bit integer registers, called by the compiler. */ -+/* "Exit" versions that return to the caller's caller. */ -+ -+HIDDEN_FUNC(_rest32gpr_14_x) lwz 14,-72(11) -+HIDDEN_FUNC(_rest32gpr_15_x) lwz 15,-68(11) -+HIDDEN_FUNC(_rest32gpr_16_x) lwz 16,-64(11) -+HIDDEN_FUNC(_rest32gpr_17_x) lwz 17,-60(11) -+HIDDEN_FUNC(_rest32gpr_18_x) lwz 18,-56(11) -+HIDDEN_FUNC(_rest32gpr_19_x) lwz 19,-52(11) -+HIDDEN_FUNC(_rest32gpr_20_x) lwz 20,-48(11) -+HIDDEN_FUNC(_rest32gpr_21_x) lwz 21,-44(11) -+HIDDEN_FUNC(_rest32gpr_22_x) lwz 22,-40(11) -+HIDDEN_FUNC(_rest32gpr_23_x) lwz 23,-36(11) -+HIDDEN_FUNC(_rest32gpr_24_x) lwz 24,-32(11) -+HIDDEN_FUNC(_rest32gpr_25_x) lwz 25,-28(11) -+HIDDEN_FUNC(_rest32gpr_26_x) lwz 26,-24(11) -+HIDDEN_FUNC(_rest32gpr_27_x) lwz 27,-20(11) -+HIDDEN_FUNC(_rest32gpr_28_x) lwz 28,-16(11) -+HIDDEN_FUNC(_rest32gpr_29_x) lwz 29,-12(11) -+HIDDEN_FUNC(_rest32gpr_30_x) lwz 30,-8(11) -+HIDDEN_FUNC(_rest32gpr_31_x) lwz 0,4(11) -+ lwz 31,-4(11) -+ mr 1,11 -+ mtlr 0 -+ blr -+FUNC_END(_rest32gpr_31_x) -+FUNC_END(_rest32gpr_30_x) -+FUNC_END(_rest32gpr_29_x) -+FUNC_END(_rest32gpr_28_x) -+FUNC_END(_rest32gpr_27_x) -+FUNC_END(_rest32gpr_26_x) -+FUNC_END(_rest32gpr_25_x) -+FUNC_END(_rest32gpr_24_x) -+FUNC_END(_rest32gpr_23_x) -+FUNC_END(_rest32gpr_22_x) -+FUNC_END(_rest32gpr_21_x) -+FUNC_END(_rest32gpr_20_x) -+FUNC_END(_rest32gpr_19_x) -+FUNC_END(_rest32gpr_18_x) -+FUNC_END(_rest32gpr_17_x) -+FUNC_END(_rest32gpr_16_x) -+FUNC_END(_rest32gpr_15_x) -+FUNC_END(_rest32gpr_14_x) -+ -+#endif ---- /dev/null -+++ b/gcc/config/rs6000/e500crtresx64gpr.asm -@@ -0,0 +1,86 @@ -+/* -+ * Special support for e500 eabi and SVR4 -+ * -+ * Copyright (C) 2008 Free Software Foundation, Inc. -+ * Written by Nathan Froyd -+ * -+ * 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 2, or (at your option) any -+ * later version. -+ * -+ * In addition to the permissions in the GNU General Public License, the -+ * Free Software Foundation gives you unlimited permission to link the -+ * compiled version of this file with other programs, and to distribute -+ * those programs without any restriction coming from the use of this -+ * file. (The General Public License restrictions do apply in other -+ * respects; for example, they cover modification of the file, and -+ * distribution when not linked into another program.) -+ * -+ * 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. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; see the file COPYING. If not, write to -+ * the Free Software Foundation, 51 Franklin Street, Fifth Floor, -+ * Boston, MA 02110-1301, 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. -+ */ -+ -+ .file "e500crtresx64gpr.asm" -+ .section ".text" -+ #include "ppc-asm.h" -+ -+#ifdef __SPE__ -+ -+/* "Exit" versions that return to their caller's caller. */ -+ -+HIDDEN_FUNC(_rest64gpr_14_x) evldd 14,0(11) -+HIDDEN_FUNC(_rest64gpr_15_x) evldd 15,8(11) -+HIDDEN_FUNC(_rest64gpr_16_x) evldd 16,16(11) -+HIDDEN_FUNC(_rest64gpr_17_x) evldd 17,24(11) -+HIDDEN_FUNC(_rest64gpr_18_x) evldd 18,32(11) -+HIDDEN_FUNC(_rest64gpr_19_x) evldd 19,40(11) -+HIDDEN_FUNC(_rest64gpr_20_x) evldd 20,48(11) -+HIDDEN_FUNC(_rest64gpr_21_x) evldd 21,56(11) -+HIDDEN_FUNC(_rest64gpr_22_x) evldd 22,64(11) -+HIDDEN_FUNC(_rest64gpr_23_x) evldd 23,72(11) -+HIDDEN_FUNC(_rest64gpr_24_x) evldd 24,80(11) -+HIDDEN_FUNC(_rest64gpr_25_x) evldd 25,88(11) -+HIDDEN_FUNC(_rest64gpr_26_x) evldd 26,96(11) -+HIDDEN_FUNC(_rest64gpr_27_x) evldd 27,104(11) -+HIDDEN_FUNC(_rest64gpr_28_x) evldd 28,112(11) -+HIDDEN_FUNC(_rest64gpr_29_x) evldd 29,120(11) -+HIDDEN_FUNC(_rest64gpr_30_x) evldd 30,128(11) -+HIDDEN_FUNC(_rest64gpr_31_x) lwz 0,148(11) -+ evldd 31,136(11) -+ addi 1,11,144 -+ mtlr 0 -+ blr -+FUNC_END(_rest64gpr_31_x) -+FUNC_END(_rest64gpr_30_x) -+FUNC_END(_rest64gpr_29_x) -+FUNC_END(_rest64gpr_28_x) -+FUNC_END(_rest64gpr_27_x) -+FUNC_END(_rest64gpr_26_x) -+FUNC_END(_rest64gpr_25_x) -+FUNC_END(_rest64gpr_24_x) -+FUNC_END(_rest64gpr_23_x) -+FUNC_END(_rest64gpr_22_x) -+FUNC_END(_rest64gpr_21_x) -+FUNC_END(_rest64gpr_20_x) -+FUNC_END(_rest64gpr_19_x) -+FUNC_END(_rest64gpr_18_x) -+FUNC_END(_rest64gpr_17_x) -+FUNC_END(_rest64gpr_16_x) -+FUNC_END(_rest64gpr_15_x) -+FUNC_END(_rest64gpr_14_x) -+ -+#endif ---- /dev/null -+++ b/gcc/config/rs6000/e500crtsav32gpr.asm -@@ -0,0 +1,84 @@ -+/* -+ * Special support for e500 eabi and SVR4 -+ * -+ * Copyright (C) 2008 Free Software Foundation, Inc. -+ * Written by Nathan Froyd -+ * -+ * 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 2, or (at your option) any -+ * later version. -+ * -+ * In addition to the permissions in the GNU General Public License, the -+ * Free Software Foundation gives you unlimited permission to link the -+ * compiled version of this file with other programs, and to distribute -+ * those programs without any restriction coming from the use of this -+ * file. (The General Public License restrictions do apply in other -+ * respects; for example, they cover modification of the file, and -+ * distribution when not linked into another program.) -+ * -+ * 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. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; see the file COPYING. If not, write to -+ * the Free Software Foundation, 51 Franklin Street, Fifth Floor, -+ * Boston, MA 02110-1301, 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. -+ */ -+ -+ .file "e500crtsav32gpr.asm" -+ .section ".text" -+ #include "ppc-asm.h" -+ -+#ifdef __SPE__ -+ -+/* Routines for saving 32-bit integer registers, called by the compiler. */ -+/* "Bare" versions that simply return to their caller. */ -+ -+HIDDEN_FUNC(_save32gpr_14) stw 14,-72(11) -+HIDDEN_FUNC(_save32gpr_15) stw 15,-68(11) -+HIDDEN_FUNC(_save32gpr_16) stw 16,-64(11) -+HIDDEN_FUNC(_save32gpr_17) stw 17,-60(11) -+HIDDEN_FUNC(_save32gpr_18) stw 18,-56(11) -+HIDDEN_FUNC(_save32gpr_19) stw 19,-52(11) -+HIDDEN_FUNC(_save32gpr_20) stw 20,-48(11) -+HIDDEN_FUNC(_save32gpr_21) stw 21,-44(11) -+HIDDEN_FUNC(_save32gpr_22) stw 22,-40(11) -+HIDDEN_FUNC(_save32gpr_23) stw 23,-36(11) -+HIDDEN_FUNC(_save32gpr_24) stw 24,-32(11) -+HIDDEN_FUNC(_save32gpr_25) stw 25,-28(11) -+HIDDEN_FUNC(_save32gpr_26) stw 26,-24(11) -+HIDDEN_FUNC(_save32gpr_27) stw 27,-20(11) -+HIDDEN_FUNC(_save32gpr_28) stw 28,-16(11) -+HIDDEN_FUNC(_save32gpr_29) stw 29,-12(11) -+HIDDEN_FUNC(_save32gpr_30) stw 30,-8(11) -+HIDDEN_FUNC(_save32gpr_31) stw 31,-4(11) -+ blr -+FUNC_END(_save32gpr_31) -+FUNC_END(_save32gpr_30) -+FUNC_END(_save32gpr_29) -+FUNC_END(_save32gpr_28) -+FUNC_END(_save32gpr_27) -+FUNC_END(_save32gpr_26) -+FUNC_END(_save32gpr_25) -+FUNC_END(_save32gpr_24) -+FUNC_END(_save32gpr_23) -+FUNC_END(_save32gpr_22) -+FUNC_END(_save32gpr_21) -+FUNC_END(_save32gpr_20) -+FUNC_END(_save32gpr_19) -+FUNC_END(_save32gpr_18) -+FUNC_END(_save32gpr_17) -+FUNC_END(_save32gpr_16) -+FUNC_END(_save32gpr_15) -+FUNC_END(_save32gpr_14) -+ -+#endif ---- /dev/null -+++ b/gcc/config/rs6000/e500crtsav64gpr.asm -@@ -0,0 +1,83 @@ -+/* -+ * Special support for e500 eabi and SVR4 -+ * -+ * Copyright (C) 2008 Free Software Foundation, Inc. -+ * Written by Nathan Froyd -+ * -+ * 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 2, or (at your option) any -+ * later version. -+ * -+ * In addition to the permissions in the GNU General Public License, the -+ * Free Software Foundation gives you unlimited permission to link the -+ * compiled version of this file with other programs, and to distribute -+ * those programs without any restriction coming from the use of this -+ * file. (The General Public License restrictions do apply in other -+ * respects; for example, they cover modification of the file, and -+ * distribution when not linked into another program.) -+ * -+ * 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. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; see the file COPYING. If not, write to -+ * the Free Software Foundation, 51 Franklin Street, Fifth Floor, -+ * Boston, MA 02110-1301, 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. -+ */ -+ -+ .file "e500crtsav64gpr.asm" -+ .section ".text" -+ #include "ppc-asm.h" -+ -+#ifdef __SPE__ -+ -+/* Routines for saving 64-bit integer registers, called by the compiler. */ -+ -+HIDDEN_FUNC(_save64gpr_14) evstdd 14,0(11) -+HIDDEN_FUNC(_save64gpr_15) evstdd 15,8(11) -+HIDDEN_FUNC(_save64gpr_16) evstdd 16,16(11) -+HIDDEN_FUNC(_save64gpr_17) evstdd 17,24(11) -+HIDDEN_FUNC(_save64gpr_18) evstdd 18,32(11) -+HIDDEN_FUNC(_save64gpr_19) evstdd 19,40(11) -+HIDDEN_FUNC(_save64gpr_20) evstdd 20,48(11) -+HIDDEN_FUNC(_save64gpr_21) evstdd 21,56(11) -+HIDDEN_FUNC(_save64gpr_22) evstdd 22,64(11) -+HIDDEN_FUNC(_save64gpr_23) evstdd 23,72(11) -+HIDDEN_FUNC(_save64gpr_24) evstdd 24,80(11) -+HIDDEN_FUNC(_save64gpr_25) evstdd 25,88(11) -+HIDDEN_FUNC(_save64gpr_26) evstdd 26,96(11) -+HIDDEN_FUNC(_save64gpr_27) evstdd 27,104(11) -+HIDDEN_FUNC(_save64gpr_28) evstdd 28,112(11) -+HIDDEN_FUNC(_save64gpr_29) evstdd 29,120(11) -+HIDDEN_FUNC(_save64gpr_30) evstdd 30,128(11) -+HIDDEN_FUNC(_save64gpr_31) evstdd 31,136(11) -+ blr -+FUNC_END(_save64gpr_31) -+FUNC_END(_save64gpr_30) -+FUNC_END(_save64gpr_29) -+FUNC_END(_save64gpr_28) -+FUNC_END(_save64gpr_27) -+FUNC_END(_save64gpr_26) -+FUNC_END(_save64gpr_25) -+FUNC_END(_save64gpr_24) -+FUNC_END(_save64gpr_23) -+FUNC_END(_save64gpr_22) -+FUNC_END(_save64gpr_21) -+FUNC_END(_save64gpr_20) -+FUNC_END(_save64gpr_19) -+FUNC_END(_save64gpr_18) -+FUNC_END(_save64gpr_17) -+FUNC_END(_save64gpr_16) -+FUNC_END(_save64gpr_15) -+FUNC_END(_save64gpr_14) -+ -+#endif ---- /dev/null -+++ b/gcc/config/rs6000/e500crtsav64gprctr.asm -@@ -0,0 +1,102 @@ -+/* -+ * Special support for e500 eabi and SVR4 -+ * -+ * Copyright (C) 2008 Free Software Foundation, Inc. -+ * Written by Nathan Froyd -+ * -+ * 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 2, or (at your option) any -+ * later version. -+ * -+ * In addition to the permissions in the GNU General Public License, the -+ * Free Software Foundation gives you unlimited permission to link the -+ * compiled version of this file with other programs, and to distribute -+ * those programs without any restriction coming from the use of this -+ * file. (The General Public License restrictions do apply in other -+ * respects; for example, they cover modification of the file, and -+ * distribution when not linked into another program.) -+ * -+ * 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. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; see the file COPYING. If not, write to -+ * the Free Software Foundation, 51 Franklin Street, Fifth Floor, -+ * Boston, MA 02110-1301, 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. -+ */ -+ -+ .file "e500crtsav64gprctr.asm" -+ .section ".text" -+ #include "ppc-asm.h" -+ -+#ifdef __SPE__ -+ -+/* Routines for saving 64-bit integer registers where the number of -+ registers to be saved is passed in CTR, called by the compiler. */ -+/* "Bare" versions that return to their caller. */ -+ -+HIDDEN_FUNC(_save64gpr_ctr_14) evstdd 14,0(11) -+ bdz _save64_gpr_ctr_done -+HIDDEN_FUNC(_save64gpr_ctr_15) evstdd 15,8(11) -+ bdz _save64_gpr_ctr_done -+HIDDEN_FUNC(_save64gpr_ctr_16) evstdd 16,16(11) -+ bdz _save64_gpr_ctr_done -+HIDDEN_FUNC(_save64gpr_ctr_17) evstdd 17,24(11) -+ bdz _save64_gpr_ctr_done -+HIDDEN_FUNC(_save64gpr_ctr_18) evstdd 18,32(11) -+ bdz _save64_gpr_ctr_done -+HIDDEN_FUNC(_save64gpr_ctr_19) evstdd 19,40(11) -+ bdz _save64_gpr_ctr_done -+HIDDEN_FUNC(_save64gpr_ctr_20) evstdd 20,48(11) -+ bdz _save64_gpr_ctr_done -+HIDDEN_FUNC(_save64gpr_ctr_21) evstdd 21,56(11) -+ bdz _save64_gpr_ctr_done -+HIDDEN_FUNC(_save64gpr_ctr_22) evstdd 22,64(11) -+ bdz _save64_gpr_ctr_done -+HIDDEN_FUNC(_save64gpr_ctr_23) evstdd 23,72(11) -+ bdz _save64_gpr_ctr_done -+HIDDEN_FUNC(_save64gpr_ctr_24) evstdd 24,80(11) -+ bdz _save64_gpr_ctr_done -+HIDDEN_FUNC(_save64gpr_ctr_25) evstdd 25,88(11) -+ bdz _save64_gpr_ctr_done -+HIDDEN_FUNC(_save64gpr_ctr_26) evstdd 26,96(11) -+ bdz _save64_gpr_ctr_done -+HIDDEN_FUNC(_save64gpr_ctr_27) evstdd 27,104(11) -+ bdz _save64_gpr_ctr_done -+HIDDEN_FUNC(_save64gpr_ctr_28) evstdd 28,112(11) -+ bdz _save64_gpr_ctr_done -+HIDDEN_FUNC(_save64gpr_ctr_29) evstdd 29,120(11) -+ bdz _save64_gpr_ctr_done -+HIDDEN_FUNC(_save64gpr_ctr_30) evstdd 30,128(11) -+ bdz _save64_gpr_ctr_done -+HIDDEN_FUNC(_save64gpr_ctr_31) evstdd 31,136(11) -+_save64gpr_ctr_done: blr -+FUNC_END(_save64gpr_ctr_31) -+FUNC_END(_save64gpr_ctr_30) -+FUNC_END(_save64gpr_ctr_29) -+FUNC_END(_save64gpr_ctr_28) -+FUNC_END(_save64gpr_ctr_27) -+FUNC_END(_save64gpr_ctr_26) -+FUNC_END(_save64gpr_ctr_25) -+FUNC_END(_save64gpr_ctr_24) -+FUNC_END(_save64gpr_ctr_23) -+FUNC_END(_save64gpr_ctr_22) -+FUNC_END(_save64gpr_ctr_21) -+FUNC_END(_save64gpr_ctr_20) -+FUNC_END(_save64gpr_ctr_19) -+FUNC_END(_save64gpr_ctr_18) -+FUNC_END(_save64gpr_ctr_17) -+FUNC_END(_save64gpr_ctr_16) -+FUNC_END(_save64gpr_ctr_15) -+FUNC_END(_save64gpr_ctr_14) -+ -+#endif ---- /dev/null -+++ b/gcc/config/rs6000/e500crtsavg32gpr.asm -@@ -0,0 +1,84 @@ -+/* -+ * Special support for e500 eabi and SVR4 -+ * -+ * Copyright (C) 2008 Free Software Foundation, Inc. -+ * Written by Nathan Froyd -+ * -+ * 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 2, or (at your option) any -+ * later version. -+ * -+ * In addition to the permissions in the GNU General Public License, the -+ * Free Software Foundation gives you unlimited permission to link the -+ * compiled version of this file with other programs, and to distribute -+ * those programs without any restriction coming from the use of this -+ * file. (The General Public License restrictions do apply in other -+ * respects; for example, they cover modification of the file, and -+ * distribution when not linked into another program.) -+ * -+ * 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. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; see the file COPYING. If not, write to -+ * the Free Software Foundation, 51 Franklin Street, Fifth Floor, -+ * Boston, MA 02110-1301, 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. -+ */ -+ -+ .file "e500crtsavg32gpr.asm" -+ .section ".text" -+ #include "ppc-asm.h" -+ -+#ifdef __SPE__ -+ -+/* Routines for saving 32-bit integer registers, called by the compiler. */ -+/* "GOT" versions that load the address of the GOT into lr before returning. */ -+ -+HIDDEN_FUNC(_save32gpr_14_g) stw 14,-72(11) -+HIDDEN_FUNC(_save32gpr_15_g) stw 15,-68(11) -+HIDDEN_FUNC(_save32gpr_16_g) stw 16,-64(11) -+HIDDEN_FUNC(_save32gpr_17_g) stw 17,-60(11) -+HIDDEN_FUNC(_save32gpr_18_g) stw 18,-56(11) -+HIDDEN_FUNC(_save32gpr_19_g) stw 19,-52(11) -+HIDDEN_FUNC(_save32gpr_20_g) stw 20,-48(11) -+HIDDEN_FUNC(_save32gpr_21_g) stw 21,-44(11) -+HIDDEN_FUNC(_save32gpr_22_g) stw 22,-40(11) -+HIDDEN_FUNC(_save32gpr_23_g) stw 23,-36(11) -+HIDDEN_FUNC(_save32gpr_24_g) stw 24,-32(11) -+HIDDEN_FUNC(_save32gpr_25_g) stw 25,-28(11) -+HIDDEN_FUNC(_save32gpr_26_g) stw 26,-24(11) -+HIDDEN_FUNC(_save32gpr_27_g) stw 27,-20(11) -+HIDDEN_FUNC(_save32gpr_28_g) stw 28,-16(11) -+HIDDEN_FUNC(_save32gpr_29_g) stw 29,-12(11) -+HIDDEN_FUNC(_save32gpr_30_g) stw 30,-8(11) -+HIDDEN_FUNC(_save32gpr_31_g) stw 31,-4(11) -+ b _GLOBAL_OFFSET_TABLE_-4 -+FUNC_END(_save32gpr_31_g) -+FUNC_END(_save32gpr_30_g) -+FUNC_END(_save32gpr_29_g) -+FUNC_END(_save32gpr_28_g) -+FUNC_END(_save32gpr_27_g) -+FUNC_END(_save32gpr_26_g) -+FUNC_END(_save32gpr_25_g) -+FUNC_END(_save32gpr_24_g) -+FUNC_END(_save32gpr_23_g) -+FUNC_END(_save32gpr_22_g) -+FUNC_END(_save32gpr_21_g) -+FUNC_END(_save32gpr_20_g) -+FUNC_END(_save32gpr_19_g) -+FUNC_END(_save32gpr_18_g) -+FUNC_END(_save32gpr_17_g) -+FUNC_END(_save32gpr_16_g) -+FUNC_END(_save32gpr_15_g) -+FUNC_END(_save32gpr_14_g) -+ -+#endif ---- /dev/null -+++ b/gcc/config/rs6000/e500crtsavg64gpr.asm -@@ -0,0 +1,84 @@ -+/* -+ * Special support for e500 eabi and SVR4 -+ * -+ * Copyright (C) 2008 Free Software Foundation, Inc. -+ * Written by Nathan Froyd -+ * -+ * 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 2, or (at your option) any -+ * later version. -+ * -+ * In addition to the permissions in the GNU General Public License, the -+ * Free Software Foundation gives you unlimited permission to link the -+ * compiled version of this file with other programs, and to distribute -+ * those programs without any restriction coming from the use of this -+ * file. (The General Public License restrictions do apply in other -+ * respects; for example, they cover modification of the file, and -+ * distribution when not linked into another program.) -+ * -+ * 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. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; see the file COPYING. If not, write to -+ * the Free Software Foundation, 51 Franklin Street, Fifth Floor, -+ * Boston, MA 02110-1301, 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. -+ */ -+ -+ .file "e500crtsavg64gpr.asm" -+ .section ".text" -+ #include "ppc-asm.h" -+ -+#ifdef __SPE__ -+ -+/* Routines for saving 64-bit integer registers, called by the compiler. */ -+/* "GOT" versions that load the address of the GOT into lr before returning. */ -+ -+HIDDEN_FUNC(_save64gpr_14_g) evstdd 14,0(11) -+HIDDEN_FUNC(_save64gpr_15_g) evstdd 15,8(11) -+HIDDEN_FUNC(_save64gpr_16_g) evstdd 16,16(11) -+HIDDEN_FUNC(_save64gpr_17_g) evstdd 17,24(11) -+HIDDEN_FUNC(_save64gpr_18_g) evstdd 18,32(11) -+HIDDEN_FUNC(_save64gpr_19_g) evstdd 19,40(11) -+HIDDEN_FUNC(_save64gpr_20_g) evstdd 20,48(11) -+HIDDEN_FUNC(_save64gpr_21_g) evstdd 21,56(11) -+HIDDEN_FUNC(_save64gpr_22_g) evstdd 22,64(11) -+HIDDEN_FUNC(_save64gpr_23_g) evstdd 23,72(11) -+HIDDEN_FUNC(_save64gpr_24_g) evstdd 24,80(11) -+HIDDEN_FUNC(_save64gpr_25_g) evstdd 25,88(11) -+HIDDEN_FUNC(_save64gpr_26_g) evstdd 26,96(11) -+HIDDEN_FUNC(_save64gpr_27_g) evstdd 27,104(11) -+HIDDEN_FUNC(_save64gpr_28_g) evstdd 28,112(11) -+HIDDEN_FUNC(_save64gpr_29_g) evstdd 29,120(11) -+HIDDEN_FUNC(_save64gpr_30_g) evstdd 30,128(11) -+HIDDEN_FUNC(_save64gpr_31_g) evstdd 31,136(11) -+ b _GLOBAL_OFFSET_TABLE_-4 -+FUNC_END(_save64gpr_31_g) -+FUNC_END(_save64gpr_30_g) -+FUNC_END(_save64gpr_29_g) -+FUNC_END(_save64gpr_28_g) -+FUNC_END(_save64gpr_27_g) -+FUNC_END(_save64gpr_26_g) -+FUNC_END(_save64gpr_25_g) -+FUNC_END(_save64gpr_24_g) -+FUNC_END(_save64gpr_23_g) -+FUNC_END(_save64gpr_22_g) -+FUNC_END(_save64gpr_21_g) -+FUNC_END(_save64gpr_20_g) -+FUNC_END(_save64gpr_19_g) -+FUNC_END(_save64gpr_18_g) -+FUNC_END(_save64gpr_17_g) -+FUNC_END(_save64gpr_16_g) -+FUNC_END(_save64gpr_15_g) -+FUNC_END(_save64gpr_14_g) -+ -+#endif ---- /dev/null -+++ b/gcc/config/rs6000/e500crtsavg64gprctr.asm -@@ -0,0 +1,101 @@ -+/* -+ * Special support for e500 eabi and SVR4 -+ * -+ * Copyright (C) 2008 Free Software Foundation, Inc. -+ * Written by Nathan Froyd -+ * -+ * 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 2, or (at your option) any -+ * later version. -+ * -+ * In addition to the permissions in the GNU General Public License, the -+ * Free Software Foundation gives you unlimited permission to link the -+ * compiled version of this file with other programs, and to distribute -+ * those programs without any restriction coming from the use of this -+ * file. (The General Public License restrictions do apply in other -+ * respects; for example, they cover modification of the file, and -+ * distribution when not linked into another program.) -+ * -+ * 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. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; see the file COPYING. If not, write to -+ * the Free Software Foundation, 51 Franklin Street, Fifth Floor, -+ * Boston, MA 02110-1301, 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. -+ */ -+ -+ .file "e500crtsavg64gprctr.asm" -+ .section ".text" -+ #include "ppc-asm.h" -+ -+#ifdef __SPE__ -+ -+/* Routines for saving 64-bit integer registers, called by the compiler. */ -+/* "GOT" versions that load the address of the GOT into lr before returning. */ -+ -+HIDDEN_FUNC(_save64gpr_ctr_14_g) evstdd 14,0(11) -+ bdz _save64_gpr_ctr_g_done -+HIDDEN_FUNC(_save64gpr_ctr_15_g) evstdd 15,8(11) -+ bdz _save64_gpr_ctr_g_done -+HIDDEN_FUNC(_save64gpr_ctr_16_g) evstdd 16,16(11) -+ bdz _save64_gpr_ctr_g_done -+HIDDEN_FUNC(_save64gpr_ctr_17_g) evstdd 17,24(11) -+ bdz _save64_gpr_ctr_g_done -+HIDDEN_FUNC(_save64gpr_ctr_18_g) evstdd 18,32(11) -+ bdz _save64_gpr_ctr_g_done -+HIDDEN_FUNC(_save64gpr_ctr_19_g) evstdd 19,40(11) -+ bdz _save64_gpr_ctr_g_done -+HIDDEN_FUNC(_save64gpr_ctr_20_g) evstdd 20,48(11) -+ bdz _save64_gpr_ctr_g_done -+HIDDEN_FUNC(_save64gpr_ctr_21_g) evstdd 21,56(11) -+ bdz _save64_gpr_ctr_g_done -+HIDDEN_FUNC(_save64gpr_ctr_22_g) evstdd 22,64(11) -+ bdz _save64_gpr_ctr_g_done -+HIDDEN_FUNC(_save64gpr_ctr_23_g) evstdd 23,72(11) -+ bdz _save64_gpr_ctr_g_done -+HIDDEN_FUNC(_save64gpr_ctr_24_g) evstdd 24,80(11) -+ bdz _save64_gpr_ctr_g_done -+HIDDEN_FUNC(_save64gpr_ctr_25_g) evstdd 25,88(11) -+ bdz _save64_gpr_ctr_g_done -+HIDDEN_FUNC(_save64gpr_ctr_26_g) evstdd 26,96(11) -+ bdz _save64_gpr_ctr_g_done -+HIDDEN_FUNC(_save64gpr_ctr_27_g) evstdd 27,104(11) -+ bdz _save64_gpr_ctr_g_done -+HIDDEN_FUNC(_save64gpr_ctr_28_g) evstdd 28,112(11) -+ bdz _save64_gpr_ctr_g_done -+HIDDEN_FUNC(_save64gpr_ctr_29_g) evstdd 29,120(11) -+ bdz _save64_gpr_ctr_g_done -+HIDDEN_FUNC(_save64gpr_ctr_30_g) evstdd 30,128(11) -+ bdz _save64_gpr_ctr_g_done -+HIDDEN_FUNC(_save64gpr_ctr_31_g) evstdd 31,136(11) -+_save64gpr_ctr_g_done: b _GLOBAL_OFFSET_TABLE_-4 -+FUNC_END(_save64gpr_ctr_31_g) -+FUNC_END(_save64gpr_ctr_30_g) -+FUNC_END(_save64gpr_ctr_29_g) -+FUNC_END(_save64gpr_ctr_28_g) -+FUNC_END(_save64gpr_ctr_27_g) -+FUNC_END(_save64gpr_ctr_26_g) -+FUNC_END(_save64gpr_ctr_25_g) -+FUNC_END(_save64gpr_ctr_24_g) -+FUNC_END(_save64gpr_ctr_23_g) -+FUNC_END(_save64gpr_ctr_22_g) -+FUNC_END(_save64gpr_ctr_21_g) -+FUNC_END(_save64gpr_ctr_20_g) -+FUNC_END(_save64gpr_ctr_19_g) -+FUNC_END(_save64gpr_ctr_18_g) -+FUNC_END(_save64gpr_ctr_17_g) -+FUNC_END(_save64gpr_ctr_16_g) -+FUNC_END(_save64gpr_ctr_15_g) -+FUNC_END(_save64gpr_ctr_14_g) -+ -+#endif ---- /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 -+ . */ -+ -+/* 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" ---- /dev/null -+++ b/gcc/config/rs6000/e500mc.md -@@ -0,0 +1,198 @@ -+;; Pipeline description for Motorola PowerPC e500mc core. -+;; Copyright (C) 2008 Free Software Foundation, Inc. -+;; Contributed by Edmar Wienskoski (edmar@freescale.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 -+;; . -+;; -+;; e500mc 32-bit SU(2), LSU, FPU, BPU -+;; Max issue 3 insns/clock cycle (includes 1 branch) -+;; FP is half clocked, timings of other instructions are as in the e500v2. -+ -+(define_automaton "e500mc_most,e500mc_long,e500mc_retire") -+(define_cpu_unit "e500mc_decode_0,e500mc_decode_1" "e500mc_most") -+(define_cpu_unit "e500mc_issue_0,e500mc_issue_1" "e500mc_most") -+(define_cpu_unit "e500mc_retire_0,e500mc_retire_1" "e500mc_retire") -+ -+;; SU. -+(define_cpu_unit "e500mc_su0_stage0,e500mc_su1_stage0" "e500mc_most") -+ -+;; MU. -+(define_cpu_unit "e500mc_mu_stage0,e500mc_mu_stage1" "e500mc_most") -+(define_cpu_unit "e500mc_mu_stage2,e500mc_mu_stage3" "e500mc_most") -+ -+;; Non-pipelined division. -+(define_cpu_unit "e500mc_mu_div" "e500mc_long") -+ -+;; LSU. -+(define_cpu_unit "e500mc_lsu" "e500mc_most") -+ -+;; FPU. -+(define_cpu_unit "e500mc_fpu" "e500mc_most") -+ -+;; Branch unit. -+(define_cpu_unit "e500mc_bu" "e500mc_most") -+ -+;; The following units are used to make the automata deterministic. -+(define_cpu_unit "present_e500mc_decode_0" "e500mc_most") -+(define_cpu_unit "present_e500mc_issue_0" "e500mc_most") -+(define_cpu_unit "present_e500mc_retire_0" "e500mc_retire") -+(define_cpu_unit "present_e500mc_su0_stage0" "e500mc_most") -+ -+;; The following sets to make automata deterministic when option ndfa is used. -+(presence_set "present_e500mc_decode_0" "e500mc_decode_0") -+(presence_set "present_e500mc_issue_0" "e500mc_issue_0") -+(presence_set "present_e500mc_retire_0" "e500mc_retire_0") -+(presence_set "present_e500mc_su0_stage0" "e500mc_su0_stage0") -+ -+;; Some useful abbreviations. -+(define_reservation "e500mc_decode" -+ "e500mc_decode_0|e500mc_decode_1+present_e500mc_decode_0") -+(define_reservation "e500mc_issue" -+ "e500mc_issue_0|e500mc_issue_1+present_e500mc_issue_0") -+(define_reservation "e500mc_retire" -+ "e500mc_retire_0|e500mc_retire_1+present_e500mc_retire_0") -+(define_reservation "e500mc_su_stage0" -+ "e500mc_su0_stage0|e500mc_su1_stage0+present_e500mc_su0_stage0") -+ -+;; Simple SU insns. -+(define_insn_reservation "e500mc_su" 1 -+ (and (eq_attr "type" "integer,insert_word,insert_dword,cmp,compare,\ -+ delayed_compare,var_delayed_compare,fast_compare,\ -+ shift,trap,var_shift_rotate,cntlz,exts") -+ (eq_attr "cpu" "ppce500mc")) -+ "e500mc_decode,e500mc_issue+e500mc_su_stage0+e500mc_retire") -+ -+(define_insn_reservation "e500mc_two" 1 -+ (and (eq_attr "type" "two") -+ (eq_attr "cpu" "ppce500mc")) -+ "e500mc_decode,e500mc_issue+e500mc_su_stage0+e500mc_retire,\ -+ e500mc_issue+e500mc_su_stage0+e500mc_retire") -+ -+(define_insn_reservation "e500mc_three" 1 -+ (and (eq_attr "type" "three") -+ (eq_attr "cpu" "ppce500mc")) -+ "e500mc_decode,e500mc_issue+e500mc_su_stage0+e500mc_retire,\ -+ e500mc_issue+e500mc_su_stage0+e500mc_retire,\ -+ e500mc_issue+e500mc_su_stage0+e500mc_retire") -+ -+;; Multiply. -+(define_insn_reservation "e500mc_multiply" 4 -+ (and (eq_attr "type" "imul,imul2,imul3,imul_compare") -+ (eq_attr "cpu" "ppce500mc")) -+ "e500mc_decode,e500mc_issue+e500mc_mu_stage0,e500mc_mu_stage1,\ -+ e500mc_mu_stage2,e500mc_mu_stage3+e500mc_retire") -+ -+;; Divide. We use the average latency time here. -+(define_insn_reservation "e500mc_divide" 14 -+ (and (eq_attr "type" "idiv") -+ (eq_attr "cpu" "ppce500mc")) -+ "e500mc_decode,e500mc_issue+e500mc_mu_stage0+e500mc_mu_div,\ -+ e500mc_mu_div*13") -+ -+;; Branch. -+(define_insn_reservation "e500mc_branch" 1 -+ (and (eq_attr "type" "jmpreg,branch,isync") -+ (eq_attr "cpu" "ppce500mc")) -+ "e500mc_decode,e500mc_bu,e500mc_retire") -+ -+;; CR logical. -+(define_insn_reservation "e500mc_cr_logical" 1 -+ (and (eq_attr "type" "cr_logical,delayed_cr") -+ (eq_attr "cpu" "ppce500mc")) -+ "e500mc_decode,e500mc_bu,e500mc_retire") -+ -+;; Mfcr. -+(define_insn_reservation "e500mc_mfcr" 1 -+ (and (eq_attr "type" "mfcr") -+ (eq_attr "cpu" "ppce500mc")) -+ "e500mc_decode,e500mc_issue+e500mc_su1_stage0+e500mc_retire") -+ -+;; Mtcrf. -+(define_insn_reservation "e500mc_mtcrf" 1 -+ (and (eq_attr "type" "mtcr") -+ (eq_attr "cpu" "ppce500mc")) -+ "e500mc_decode,e500mc_issue+e500mc_su1_stage0+e500mc_retire") -+ -+;; Mtjmpr. -+(define_insn_reservation "e500mc_mtjmpr" 1 -+ (and (eq_attr "type" "mtjmpr,mfjmpr") -+ (eq_attr "cpu" "ppce500mc")) -+ "e500mc_decode,e500mc_issue+e500mc_su_stage0+e500mc_retire") -+ -+;; Brinc. -+(define_insn_reservation "e500mc_brinc" 1 -+ (and (eq_attr "type" "brinc") -+ (eq_attr "cpu" "ppce500mc")) -+ "e500mc_decode,e500mc_issue+e500mc_su_stage0+e500mc_retire") -+ -+;; Loads. -+(define_insn_reservation "e500mc_load" 3 -+ (and (eq_attr "type" "load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u,\ -+ load_l,sync") -+ (eq_attr "cpu" "ppce500mc")) -+ "e500mc_decode,e500mc_issue+e500mc_lsu,nothing,e500mc_retire") -+ -+(define_insn_reservation "e500mc_fpload" 4 -+ (and (eq_attr "type" "fpload,fpload_ux,fpload_u") -+ (eq_attr "cpu" "ppce500mc")) -+ "e500mc_decode,e500mc_issue+e500mc_lsu,nothing*2,e500mc_retire") -+ -+;; Stores. -+(define_insn_reservation "e500mc_store" 3 -+ (and (eq_attr "type" "store,store_ux,store_u,store_c") -+ (eq_attr "cpu" "ppce500mc")) -+ "e500mc_decode,e500mc_issue+e500mc_lsu,nothing,e500mc_retire") -+ -+(define_insn_reservation "e500mc_fpstore" 3 -+ (and (eq_attr "type" "fpstore,fpstore_ux,fpstore_u") -+ (eq_attr "cpu" "ppce500mc")) -+ "e500mc_decode,e500mc_issue+e500mc_lsu,nothing,e500mc_retire") -+ -+;; Simple FP. -+(define_insn_reservation "e500mc_simple_float" 8 -+ (and (eq_attr "type" "fpsimple") -+ (eq_attr "cpu" "ppce500mc")) -+ "e500mc_decode,e500mc_issue+e500mc_fpu,nothing*6,e500mc_retire") -+ -+;; FP. -+(define_insn_reservation "e500mc_float" 8 -+ (and (eq_attr "type" "fp") -+ (eq_attr "cpu" "ppce500mc")) -+ "e500mc_decode,e500mc_issue+e500mc_fpu,nothing*6,e500mc_retire") -+ -+(define_insn_reservation "e500mc_fpcompare" 8 -+ (and (eq_attr "type" "fpcompare") -+ (eq_attr "cpu" "ppce500mc")) -+ "e500mc_decode,e500mc_issue+e500mc_fpu,nothing*6,e500mc_retire") -+ -+;; The following ignores the retire unit to avoid a large automata. -+ -+(define_insn_reservation "e500mc_dmul" 10 -+ (and (eq_attr "type" "dmul") -+ (eq_attr "cpu" "ppce500mc")) -+ "e500mc_decode,e500mc_issue+e500mc_fpu") -+ -+;; FP divides are not pipelined. -+(define_insn_reservation "e500mc_sdiv" 36 -+ (and (eq_attr "type" "sdiv") -+ (eq_attr "cpu" "ppce500mc")) -+ "e500mc_decode,e500mc_issue+e500mc_fpu,e500mc_fpu*35") -+ -+(define_insn_reservation "e500mc_ddiv" 66 -+ (and (eq_attr "type" "ddiv") -+ (eq_attr "cpu" "ppce500mc")) -+ "e500mc_decode,e500mc_issue+e500mc_fpu,e500mc_fpu*65") ---- a/gcc/config/rs6000/eabi-ci.asm -+++ b/gcc/config/rs6000/eabi-ci.asm -@@ -111,6 +111,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 -@@ -119,6 +120,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-cn.asm -+++ b/gcc/config/rs6000/eabi-cn.asm -@@ -36,7 +36,6 @@ Boston, MA 02110-1301, USA. - /* This file just supplies labeled ending points for the .got* and other - special sections. It is linked in last after other modules. */ - -- .file "crtn.s" - .ident "GNU C crtn.s" - - #ifndef __powerpc64__ ---- a/gcc/config/rs6000/eabi.asm -+++ b/gcc/config/rs6000/eabi.asm -@@ -114,6 +114,9 @@ - .Linit = .-.LCTOC1 - .long .Linit_p /* address of variable to say we've been called */ - -+.Lfini = .-.LCTOC1 -+ .long __fini /* global destructors in .fini */ -+ - .text - .align 2 - .Lptr: -@@ -226,10 +229,12 @@ FUNC_START(__eabi) - - lwz 2,.Lsda2(11) /* load r2 with _SDA2_BASE_ address */ - --/* Done adjusting pointers, return by way of doing the C++ global constructors. */ -+/* Done adjusting pointers. We used to return here by way of doing the -+ C++ global constructors, but we currently let newlib take care of -+ running them and registering finalizers. */ - - .Ldone: -- b FUNC_NAME(__init) /* do any C++ global constructors (which returns to caller) */ -+ blr - FUNC_END(__eabi) - - /* Special subroutine to convert a bunch of pointers directly. -@@ -240,7 +245,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 */ -@@ -295,5 +300,6 @@ FUNC_START(__eabi_uconvert) - blr - - FUNC_END(__eabi_uconvert) -+#endif /* _RELOCATABLE */ - - #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/montavista-linux.h -@@ -0,0 +1,41 @@ -+/* MontaVista GNU/Linux Configuration. -+ 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 -+. */ -+ -+/* Add -te500v2 option for convenience in generating multilibs. */ -+#undef CC1_EXTRA_SPEC -+#define CC1_EXTRA_SPEC \ -+ "%{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 \ -+ "%{te500v2:-mppc -mspe -me500 ; \ -+ te600:-mppc -maltivec ; \ -+ te500mc:-me500mc ; \ -+ :-mppc}" -+ -+/* The various C libraries each have their own subdirectory. */ -+#undef SYSROOT_SUFFIX_SPEC -+#define SYSROOT_SUFFIX_SPEC \ -+ "%{msoft-float:/soft-float ; \ -+ te600:/te600 ; \ -+ te500v2:/te500v2 ; \ -+ te500mc:/te500mc}" ---- a/gcc/config/rs6000/netbsd.h -+++ b/gcc/config/rs6000/netbsd.h -@@ -75,8 +75,7 @@ - #define STARTFILE_SPEC NETBSD_STARTFILE_SPEC - - #undef ENDFILE_SPEC --#define ENDFILE_SPEC \ -- "crtsavres%O%s %(netbsd_endfile_spec)" -+#define ENDFILE_SPEC "%(netbsd_endfile_spec)" - - #undef LIB_SPEC - #define LIB_SPEC NETBSD_LIB_SPEC ---- a/gcc/config/rs6000/paired.md -+++ b/gcc/config/rs6000/paired.md -@@ -28,7 +28,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" -@@ -42,7 +42,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" -@@ -56,7 +56,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")))] -@@ -64,7 +64,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")))] -@@ -72,7 +72,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")))] -@@ -87,7 +87,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/ppc-asm.h -+++ b/gcc/config/rs6000/ppc-asm.h -@@ -110,6 +110,11 @@ name: \ - .globl GLUE(.,name); \ - GLUE(.,name): - -+#define HIDDEN_FUNC(name) \ -+ FUNC_START(name) \ -+ .hidden name; \ -+ .hidden GLUE(.,name); -+ - #define FUNC_END(name) \ - GLUE(.L,name): \ - .size GLUE(.,name),GLUE(.L,name)-GLUE(.,name) -@@ -136,6 +141,11 @@ name: \ - .globl GLUE(.,name); \ - GLUE(.,name): - -+#define HIDDEN_FUNC(name) \ -+ FUNC_START(name) \ -+ .hidden name; \ -+ .hidden GLUE(.,name); -+ - #define FUNC_END(name) \ - GLUE(.L,name): \ - .size GLUE(.,name),GLUE(.L,name)-GLUE(.,name) -@@ -153,6 +163,10 @@ GLUE(.L,name): \ - .globl FUNC_NAME(name); \ - FUNC_NAME(name): - -+#define HIDDEN_FUNC(name) \ -+ FUNC_START(name) \ -+ .hidden FUNC_NAME(name); -+ - #define FUNC_END(name) \ - GLUE(.L,name): \ - .size FUNC_NAME(name),GLUE(.L,name)-FUNC_NAME(name) ---- a/gcc/config/rs6000/predicates.md -+++ b/gcc/config/rs6000/predicates.md -@@ -915,7 +915,7 @@ - rtx elt; - int count = XVECLEN (op, 0); - -- if (count != 55) -+ if (count != 54) - return 0; - - index = 0; -@@ -964,9 +964,8 @@ - || GET_MODE (SET_SRC (elt)) != Pmode) - return 0; - -- if (GET_CODE (XVECEXP (op, 0, index++)) != USE -- || GET_CODE (XVECEXP (op, 0, index++)) != USE -- || GET_CODE (XVECEXP (op, 0, index++)) != CLOBBER) -+ if (GET_CODE (XVECEXP (op, 0, index++)) != SET -+ || GET_CODE (XVECEXP (op, 0, index++)) != SET) - return 0; - return 1; - }) ---- a/gcc/config/rs6000/rs6000.c -+++ b/gcc/config/rs6000/rs6000.c -@@ -174,9 +174,15 @@ int rs6000_ieeequad; - /* Nonzero to use AltiVec ABI. */ - int rs6000_altivec_abi; - -+/* Nonzero if we want SPE SIMD instructions. */ -+int rs6000_spe; -+ - /* Nonzero if we want SPE ABI extensions. */ - int rs6000_spe_abi; - -+/* Nonzero to use isel instructions. */ -+int rs6000_isel; -+ - /* Nonzero if floating point operations are done in the GPRs. */ - int rs6000_float_gprs = 0; - -@@ -669,6 +675,44 @@ struct processor_costs ppc8540_cost = { - 1, /* prefetch streams /*/ - }; - -+/* Instruction costs on E300C2 and E300C3 cores. */ -+static const -+struct processor_costs ppce300c2c3_cost = { -+ COSTS_N_INSNS (4), /* mulsi */ -+ COSTS_N_INSNS (4), /* mulsi_const */ -+ COSTS_N_INSNS (4), /* mulsi_const9 */ -+ COSTS_N_INSNS (4), /* muldi */ -+ COSTS_N_INSNS (19), /* divsi */ -+ COSTS_N_INSNS (19), /* divdi */ -+ COSTS_N_INSNS (3), /* fp */ -+ COSTS_N_INSNS (4), /* dmul */ -+ COSTS_N_INSNS (18), /* sdiv */ -+ COSTS_N_INSNS (33), /* ddiv */ -+ 32, -+ 16, /* l1 cache */ -+ 16, /* l2 cache */ -+ 1, /* prefetch streams /*/ -+}; -+ -+/* Instruction costs on PPCE500MC processors. */ -+static const -+struct processor_costs ppce500mc_cost = { -+ COSTS_N_INSNS (4), /* mulsi */ -+ COSTS_N_INSNS (4), /* mulsi_const */ -+ COSTS_N_INSNS (4), /* mulsi_const9 */ -+ COSTS_N_INSNS (4), /* muldi */ -+ COSTS_N_INSNS (14), /* divsi */ -+ COSTS_N_INSNS (14), /* divdi */ -+ COSTS_N_INSNS (8), /* fp */ -+ COSTS_N_INSNS (10), /* dmul */ -+ COSTS_N_INSNS (36), /* sdiv */ -+ COSTS_N_INSNS (66), /* ddiv */ -+ 64, /* cache line size */ -+ 32, /* l1 cache */ -+ 128, /* l2 cache */ -+ 1, /* prefetch streams /*/ -+}; -+ - /* Instruction costs on POWER4 and POWER5 processors. */ - static const - struct processor_costs power4_cost = { -@@ -713,12 +757,11 @@ static const char *rs6000_invalid_within - static rtx rs6000_generate_compare (enum rtx_code); - static void rs6000_emit_stack_tie (void); - static void rs6000_frame_related (rtx, rtx, HOST_WIDE_INT, rtx, rtx); --static rtx spe_synthesize_frame_save (rtx); - static bool spe_func_has_64bit_regs_p (void); - static void emit_frame_save (rtx, rtx, enum machine_mode, unsigned int, - int, HOST_WIDE_INT); - static rtx gen_frame_mem_offset (enum machine_mode, rtx, int); --static void rs6000_emit_allocate_stack (HOST_WIDE_INT, int); -+static void rs6000_emit_allocate_stack (HOST_WIDE_INT, int, int); - static unsigned rs6000_hash_constant (rtx); - static unsigned toc_hash_function (const void *); - static int toc_hash_eq (const void *, const void *); -@@ -728,7 +771,7 @@ static bool legitimate_small_data_p (enu - static bool legitimate_lo_sum_address_p (enum machine_mode, rtx, int); - static struct machine_function * rs6000_init_machine_status (void); - static bool rs6000_assemble_integer (rtx, unsigned int, int); --static bool no_global_regs_above (int); -+static bool no_global_regs_above (int, bool); - #ifdef HAVE_GAS_HIDDEN - static void rs6000_assemble_visibility (tree, int); - #endif -@@ -741,7 +784,13 @@ static void rs6000_eliminate_indexed_mem - static const char *rs6000_mangle_type (const_tree); - extern const struct attribute_spec rs6000_attribute_table[]; - static void rs6000_set_default_type_attributes (tree); -+static rtx rs6000_savres_routine_sym (rs6000_stack_t *, bool, bool, bool); -+static void rs6000_emit_stack_reset (rs6000_stack_t *, rtx, rtx, int, bool); -+static rtx rs6000_make_savres_rtx (rs6000_stack_t *, rtx, int, -+ enum machine_mode, bool, bool, bool); - static bool rs6000_reg_live_or_pic_offset_p (int); -+static int rs6000_savres_strategy (rs6000_stack_t *, bool, int, int); -+static void rs6000_restore_saved_cr (rtx, int); - static void rs6000_output_function_prologue (FILE *, HOST_WIDE_INT); - static void rs6000_output_function_epilogue (FILE *, HOST_WIDE_INT); - static void rs6000_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT, -@@ -1420,6 +1469,9 @@ rs6000_override_options (const char *def - {"8540", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN}, - /* 8548 has a dummy entry for now. */ - {"8548", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN}, -+ {"e300c2", PROCESSOR_PPCE300C2, POWERPC_BASE_MASK | MASK_SOFT_FLOAT}, -+ {"e300c3", PROCESSOR_PPCE300C3, POWERPC_BASE_MASK}, -+ {"e500mc", PROCESSOR_PPCE500MC, POWERPC_BASE_MASK | MASK_PPC_GFXOPT}, - {"860", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT}, - {"970", PROCESSOR_POWER4, - POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64}, -@@ -1523,9 +1575,20 @@ rs6000_override_options (const char *def - } - } - -- if (TARGET_E500) -+ if ((TARGET_E500 || rs6000_cpu == PROCESSOR_PPCE500MC) -+ && !rs6000_explicit_options.isel) - rs6000_isel = 1; - -+ if (rs6000_cpu == PROCESSOR_PPCE300C2 -+ || rs6000_cpu == PROCESSOR_PPCE300C3 -+ || rs6000_cpu == PROCESSOR_PPCE500MC) -+ { -+ if (TARGET_ALTIVEC) -+ error ("AltiVec not supported in this target"); -+ if (TARGET_SPE) -+ error ("Spe not supported in this target"); -+ } -+ - /* If we are optimizing big endian systems for space, use the load/store - multiple and string instructions. */ - if (BYTES_BIG_ENDIAN && optimize_size) -@@ -1635,9 +1698,9 @@ rs6000_override_options (const char *def - SUB3TARGET_OVERRIDE_OPTIONS; - #endif - -- if (TARGET_E500) -+ if (TARGET_E500 || rs6000_cpu == PROCESSOR_PPCE500MC) - { -- /* The e500 does not have string instructions, and we set -+ /* The e500 and e500mc do not have string instructions, and we set - MASK_STRING above when optimizing for size. */ - if ((target_flags & MASK_STRING) != 0) - target_flags = target_flags & ~MASK_STRING; -@@ -1845,6 +1908,15 @@ rs6000_override_options (const char *def - rs6000_cost = &ppc8540_cost; - break; - -+ case PROCESSOR_PPCE300C2: -+ case PROCESSOR_PPCE300C3: -+ rs6000_cost = &ppce300c2c3_cost; -+ break; -+ -+ case PROCESSOR_PPCE500MC: -+ rs6000_cost = &ppce500mc_cost; -+ break; -+ - case PROCESSOR_POWER4: - case PROCESSOR_POWER5: - rs6000_cost = &power4_cost; -@@ -2144,11 +2216,21 @@ rs6000_handle_option (size_t code, const - rs6000_parse_yes_no_option ("vrsave", arg, &(TARGET_ALTIVEC_VRSAVE)); - break; - -+ case OPT_misel: -+ rs6000_explicit_options.isel = true; -+ rs6000_isel = value; -+ break; -+ - case OPT_misel_: - rs6000_explicit_options.isel = true; - rs6000_parse_yes_no_option ("isel", arg, &(rs6000_isel)); - break; - -+ case OPT_mspe: -+ rs6000_explicit_options.spe = true; -+ rs6000_spe = value; -+ break; -+ - case OPT_mspe_: - rs6000_explicit_options.spe = true; - rs6000_parse_yes_no_option ("spe", arg, &(rs6000_spe)); -@@ -2395,6 +2477,8 @@ rs6000_file_start (void) - (TARGET_ALTIVEC_ABI ? 2 - : TARGET_SPE_ABI ? 3 - : 1)); -+ fprintf (file, "\t.gnu_attribute 12, %d\n", -+ aix_struct_return ? 2 : 1); - } - #endif - -@@ -3145,24 +3229,26 @@ invalid_e500_subreg (rtx op, enum machin - if (TARGET_E500_DOUBLE) - { - /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or -- subreg:TI and reg:TF. */ -+ subreg:TI and reg:TF. Decimal float modes are like integer -+ modes (only low part of each register used) for this -+ purpose. */ - if (GET_CODE (op) == SUBREG -- && (mode == SImode || mode == DImode || mode == TImode) -+ && (mode == SImode || mode == DImode || mode == TImode -+ || mode == DDmode || mode == TDmode) - && REG_P (SUBREG_REG (op)) - && (GET_MODE (SUBREG_REG (op)) == DFmode -- || GET_MODE (SUBREG_REG (op)) == TFmode -- || GET_MODE (SUBREG_REG (op)) == DDmode -- || GET_MODE (SUBREG_REG (op)) == TDmode)) -+ || GET_MODE (SUBREG_REG (op)) == TFmode)) - return true; - - /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and - reg:TI. */ - if (GET_CODE (op) == SUBREG -- && (mode == DFmode || mode == TFmode -- || mode == DDmode || mode == TDmode) -+ && (mode == DFmode || mode == TFmode) - && REG_P (SUBREG_REG (op)) - && (GET_MODE (SUBREG_REG (op)) == DImode -- || GET_MODE (SUBREG_REG (op)) == TImode)) -+ || GET_MODE (SUBREG_REG (op)) == TImode -+ || GET_MODE (SUBREG_REG (op)) == DDmode -+ || GET_MODE (SUBREG_REG (op)) == TDmode)) - return true; - } - -@@ -3413,10 +3499,10 @@ rs6000_legitimate_offset_address_p (enum - return SPE_CONST_OFFSET_OK (offset); - - case DFmode: -- case DDmode: - if (TARGET_E500_DOUBLE) - return SPE_CONST_OFFSET_OK (offset); - -+ case DDmode: - case DImode: - /* On e500v2, we may have: - -@@ -3433,11 +3519,11 @@ rs6000_legitimate_offset_address_p (enum - break; - - case TFmode: -- case TDmode: - if (TARGET_E500_DOUBLE) - return (SPE_CONST_OFFSET_OK (offset) - && SPE_CONST_OFFSET_OK (offset + 8)); - -+ case TDmode: - case TImode: - if (mode == TFmode || mode == TDmode || !TARGET_POWERPC64) - extra = 12; -@@ -3582,8 +3668,10 @@ rs6000_legitimize_address (rtx x, rtx ol - && GET_CODE (XEXP (x, 1)) == CONST_INT - && (unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000) >= 0x10000 - && !(SPE_VECTOR_MODE (mode) -+ || ALTIVEC_VECTOR_MODE (mode) - || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode -- || mode == DImode)))) -+ || mode == DImode || mode == DDmode -+ || mode == TDmode)))) - { - HOST_WIDE_INT high_int, low_int; - rtx sum; -@@ -3591,7 +3679,14 @@ rs6000_legitimize_address (rtx x, rtx ol - high_int = INTVAL (XEXP (x, 1)) - low_int; - sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0), - GEN_INT (high_int)), 0); -- return gen_rtx_PLUS (Pmode, sum, GEN_INT (low_int)); -+ /* Using a REG+CONST 64-bit integer load on 64-bit platforms -+ requires that CONST be word-aligned. */ -+ if (TARGET_POWERPC64 -+ && (mode == DImode || mode == DDmode) -+ && (low_int & 0x3)) -+ return gen_rtx_PLUS (Pmode, sum, force_reg (Pmode, GEN_INT (low_int))); -+ else -+ return gen_rtx_PLUS (Pmode, sum, GEN_INT (low_int)); - } - else if (GET_CODE (x) == PLUS - && GET_CODE (XEXP (x, 0)) == REG -@@ -3599,11 +3694,12 @@ rs6000_legitimize_address (rtx x, rtx ol - && GET_MODE_NUNITS (mode) == 1 - && ((TARGET_HARD_FLOAT && TARGET_FPRS) - || TARGET_POWERPC64 -- || (((mode != DImode && mode != DFmode && mode != DDmode) -- || TARGET_E500_DOUBLE) -- && mode != TFmode && mode != TDmode)) -+ || ((mode != DImode && mode != DFmode && mode != DDmode) -+ || (TARGET_E500_DOUBLE && mode != DDmode))) - && (TARGET_POWERPC64 || mode != DImode) -- && mode != TImode) -+ && mode != TImode -+ && mode != TFmode -+ && mode != TDmode) - { - return gen_rtx_PLUS (Pmode, XEXP (x, 0), - force_reg (Pmode, force_operand (XEXP (x, 1), 0))); -@@ -3630,19 +3726,29 @@ rs6000_legitimize_address (rtx x, rtx ol - /* We accept [reg + reg] and [reg + OFFSET]. */ - - if (GET_CODE (x) == PLUS) -- { -- rtx op1 = XEXP (x, 0); -- rtx op2 = XEXP (x, 1); -- -- op1 = force_reg (Pmode, op1); -- -- if (GET_CODE (op2) != REG -- && (GET_CODE (op2) != CONST_INT -- || !SPE_CONST_OFFSET_OK (INTVAL (op2)))) -- op2 = force_reg (Pmode, op2); -- -- return gen_rtx_PLUS (Pmode, op1, op2); -- } -+ { -+ rtx op1 = XEXP (x, 0); -+ rtx op2 = XEXP (x, 1); -+ rtx y; -+ -+ op1 = force_reg (Pmode, op1); -+ -+ if (GET_CODE (op2) != REG -+ && (GET_CODE (op2) != CONST_INT -+ || !SPE_CONST_OFFSET_OK (INTVAL (op2)) -+ || (GET_MODE_SIZE (mode) > 8 -+ && !SPE_CONST_OFFSET_OK (INTVAL (op2) + 8)))) -+ op2 = force_reg (Pmode, op2); -+ -+ /* We can't always do [reg + reg] for these, because [reg + -+ reg + offset] is not a legitimate addressing mode. */ -+ y = gen_rtx_PLUS (Pmode, op1, op2); -+ -+ if ((GET_MODE_SIZE (mode) > 8 || mode == DDmode) && REG_P (op2)) -+ return force_reg (Pmode, y); -+ else -+ return y; -+ } - - return force_reg (Pmode, x); - } -@@ -4190,7 +4296,8 @@ rs6000_legitimate_address (enum machine_ - && mode != TDmode - && ((TARGET_HARD_FLOAT && TARGET_FPRS) - || TARGET_POWERPC64 -- || ((mode != DFmode && mode != DDmode) || TARGET_E500_DOUBLE)) -+ || (mode != DFmode && mode != DDmode) -+ || (TARGET_E500_DOUBLE && mode != DDmode)) - && (TARGET_POWERPC64 || mode != DImode) - && legitimate_indexed_address_p (x, reg_ok_strict)) - return 1; -@@ -4314,7 +4421,8 @@ rs6000_hard_regno_nregs (int regno, enum - would require function_arg and rs6000_spe_function_arg to handle - SCmode so as to pass the value correctly in a pair of - registers. */ -- if (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode) && mode != SCmode) -+ if (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode) && mode != SCmode -+ && !DECIMAL_FLOAT_MODE_P (mode)) - return (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD; - - return (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD; -@@ -4394,16 +4502,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; - } - - /* Try to output insns to set TARGET equal to the constant C if it can -@@ -5588,14 +5699,12 @@ spe_build_register_parallel (enum machin - switch (mode) - { - case DFmode: -- case DDmode: - r1 = gen_rtx_REG (DImode, gregno); - r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx); - return gen_rtx_PARALLEL (mode, gen_rtvec (1, r1)); - - case DCmode: - case TFmode: -- case TDmode: - r1 = gen_rtx_REG (DImode, gregno); - r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx); - r3 = gen_rtx_REG (DImode, gregno + 2); -@@ -5628,13 +5737,12 @@ rs6000_spe_function_arg (CUMULATIVE_ARGS - /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but - are passed and returned in a pair of GPRs for ABI compatibility. */ - if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode -- || mode == DDmode || mode == TDmode - || mode == DCmode || mode == TCmode)) - { - int n_words = rs6000_arg_size (mode, type); - - /* Doubles go in an odd/even register pair (r5/r6, etc). */ -- if (mode == DFmode || mode == DDmode) -+ if (mode == DFmode) - gregno += (1 - gregno) & 1; - - /* Multi-reg args are not split between registers and stack. */ -@@ -6047,10 +6155,8 @@ function_arg (CUMULATIVE_ARGS *cum, enum - else if (TARGET_SPE_ABI && TARGET_SPE - && (SPE_VECTOR_MODE (mode) - || (TARGET_E500_DOUBLE && (mode == DFmode -- || mode == DDmode - || mode == DCmode - || mode == TFmode -- || mode == TDmode - || mode == TCmode)))) - return rs6000_spe_function_arg (cum, mode, type); - -@@ -7049,9 +7155,9 @@ static struct builtin_description bdesc_ - { MASK_ALTIVEC, CODE_FOR_altivec_vrlb, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB }, - { MASK_ALTIVEC, CODE_FOR_altivec_vrlh, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH }, - { MASK_ALTIVEC, CODE_FOR_altivec_vrlw, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW }, -- { MASK_ALTIVEC, CODE_FOR_altivec_vslb, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB }, -- { MASK_ALTIVEC, CODE_FOR_altivec_vslh, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH }, -- { MASK_ALTIVEC, CODE_FOR_altivec_vslw, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW }, -+ { MASK_ALTIVEC, CODE_FOR_ashlv16qi3, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB }, -+ { MASK_ALTIVEC, CODE_FOR_ashlv8hi3, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH }, -+ { MASK_ALTIVEC, CODE_FOR_ashlv4si3, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW }, - { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL }, - { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO }, - { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB }, -@@ -7211,10 +7317,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 }, -@@ -7223,10 +7329,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 }, -@@ -7502,7 +7608,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 }, -@@ -7534,9 +7640,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 } - }; -@@ -9051,6 +9157,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); -@@ -9088,60 +9196,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 (); -@@ -12472,7 +12595,7 @@ rs6000_generate_compare (enum rtx_code c - switch (op_mode) - { - case SFmode: -- cmp = flag_unsafe_math_optimizations -+ cmp = (flag_finite_math_only && !flag_trapping_math) - ? gen_tstsfeq_gpr (compare_result, rs6000_compare_op0, - rs6000_compare_op1) - : gen_cmpsfeq_gpr (compare_result, rs6000_compare_op0, -@@ -12480,7 +12603,7 @@ rs6000_generate_compare (enum rtx_code c - break; - - case DFmode: -- cmp = flag_unsafe_math_optimizations -+ cmp = (flag_finite_math_only && !flag_trapping_math) - ? gen_tstdfeq_gpr (compare_result, rs6000_compare_op0, - rs6000_compare_op1) - : gen_cmpdfeq_gpr (compare_result, rs6000_compare_op0, -@@ -12488,7 +12611,7 @@ rs6000_generate_compare (enum rtx_code c - break; - - case TFmode: -- cmp = flag_unsafe_math_optimizations -+ cmp = (flag_finite_math_only && !flag_trapping_math) - ? gen_tsttfeq_gpr (compare_result, rs6000_compare_op0, - rs6000_compare_op1) - : gen_cmptfeq_gpr (compare_result, rs6000_compare_op0, -@@ -12504,7 +12627,7 @@ rs6000_generate_compare (enum rtx_code c - switch (op_mode) - { - case SFmode: -- cmp = flag_unsafe_math_optimizations -+ cmp = (flag_finite_math_only && !flag_trapping_math) - ? gen_tstsfgt_gpr (compare_result, rs6000_compare_op0, - rs6000_compare_op1) - : gen_cmpsfgt_gpr (compare_result, rs6000_compare_op0, -@@ -12512,7 +12635,7 @@ rs6000_generate_compare (enum rtx_code c - break; - - case DFmode: -- cmp = flag_unsafe_math_optimizations -+ cmp = (flag_finite_math_only && !flag_trapping_math) - ? gen_tstdfgt_gpr (compare_result, rs6000_compare_op0, - rs6000_compare_op1) - : gen_cmpdfgt_gpr (compare_result, rs6000_compare_op0, -@@ -12520,7 +12643,7 @@ rs6000_generate_compare (enum rtx_code c - break; - - case TFmode: -- cmp = flag_unsafe_math_optimizations -+ cmp = (flag_finite_math_only && !flag_trapping_math) - ? gen_tsttfgt_gpr (compare_result, rs6000_compare_op0, - rs6000_compare_op1) - : gen_cmptfgt_gpr (compare_result, rs6000_compare_op0, -@@ -12536,7 +12659,7 @@ rs6000_generate_compare (enum rtx_code c - switch (op_mode) - { - case SFmode: -- cmp = flag_unsafe_math_optimizations -+ cmp = (flag_finite_math_only && !flag_trapping_math) - ? gen_tstsflt_gpr (compare_result, rs6000_compare_op0, - rs6000_compare_op1) - : gen_cmpsflt_gpr (compare_result, rs6000_compare_op0, -@@ -12544,7 +12667,7 @@ rs6000_generate_compare (enum rtx_code c - break; - - case DFmode: -- cmp = flag_unsafe_math_optimizations -+ cmp = (flag_finite_math_only && !flag_trapping_math) - ? gen_tstdflt_gpr (compare_result, rs6000_compare_op0, - rs6000_compare_op1) - : gen_cmpdflt_gpr (compare_result, rs6000_compare_op0, -@@ -12552,7 +12675,7 @@ rs6000_generate_compare (enum rtx_code c - break; - - case TFmode: -- cmp = flag_unsafe_math_optimizations -+ cmp = (flag_finite_math_only && !flag_trapping_math) - ? gen_tsttflt_gpr (compare_result, rs6000_compare_op0, - rs6000_compare_op1) - : gen_cmptflt_gpr (compare_result, rs6000_compare_op0, -@@ -12587,7 +12710,7 @@ rs6000_generate_compare (enum rtx_code c - switch (op_mode) - { - case SFmode: -- cmp = flag_unsafe_math_optimizations -+ cmp = (flag_finite_math_only && !flag_trapping_math) - ? gen_tstsfeq_gpr (compare_result2, rs6000_compare_op0, - rs6000_compare_op1) - : gen_cmpsfeq_gpr (compare_result2, rs6000_compare_op0, -@@ -12595,7 +12718,7 @@ rs6000_generate_compare (enum rtx_code c - break; - - case DFmode: -- cmp = flag_unsafe_math_optimizations -+ cmp = (flag_finite_math_only && !flag_trapping_math) - ? gen_tstdfeq_gpr (compare_result2, rs6000_compare_op0, - rs6000_compare_op1) - : gen_cmpdfeq_gpr (compare_result2, rs6000_compare_op0, -@@ -12603,7 +12726,7 @@ rs6000_generate_compare (enum rtx_code c - break; - - case TFmode: -- cmp = flag_unsafe_math_optimizations -+ cmp = (flag_finite_math_only && !flag_trapping_math) - ? gen_tsttfeq_gpr (compare_result2, rs6000_compare_op0, - rs6000_compare_op1) - : gen_cmptfeq_gpr (compare_result2, rs6000_compare_op0, -@@ -13946,8 +14069,8 @@ rs6000_split_multireg_move (rtx dst, rtx - reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode : DFmode; - else if (ALTIVEC_REGNO_P (reg)) - reg_mode = V16QImode; -- else if (TARGET_E500_DOUBLE && (mode == TFmode || mode == TDmode)) -- reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode : DFmode; -+ else if (TARGET_E500_DOUBLE && mode == TFmode) -+ reg_mode = DFmode; - else - reg_mode = word_mode; - reg_mode_size = GET_MODE_SIZE (reg_mode); -@@ -14535,7 +14658,7 @@ rs6000_stack_info (void) - { - /* Align stack so SPE GPR save area is aligned on a - double-word boundary. */ -- if (info_ptr->spe_gp_size != 0) -+ if (info_ptr->spe_gp_size != 0 && info_ptr->cr_save_offset != 0) - info_ptr->spe_padding_size - = 8 - (-info_ptr->cr_save_offset % 8); - else -@@ -14686,8 +14809,7 @@ spe_func_has_64bit_regs_p (void) - - if (SPE_VECTOR_MODE (mode)) - return true; -- if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode -- || mode == DDmode || mode == TDmode)) -+ if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode)) - return true; - } - } -@@ -15191,10 +15313,12 @@ rs6000_emit_stack_tie (void) - - /* Emit the correct code for allocating stack space, as insns. - If COPY_R12, make sure a copy of the old frame is left in r12. -+ If COPY_R11, make sure a copy of the old frame is left in r11, -+ in preference to r12 if COPY_R12. - The generated code may use hard register 0 as a temporary. */ - - static void --rs6000_emit_allocate_stack (HOST_WIDE_INT size, int copy_r12) -+rs6000_emit_allocate_stack (HOST_WIDE_INT size, int copy_r12, int copy_r11) - { - rtx insn; - rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM); -@@ -15243,8 +15367,11 @@ rs6000_emit_allocate_stack (HOST_WIDE_IN - warning (0, "stack limit expression is not supported"); - } - -- if (copy_r12 || ! TARGET_UPDATE) -- emit_move_insn (gen_rtx_REG (Pmode, 12), stack_reg); -+ if (copy_r12 || copy_r11 || ! TARGET_UPDATE) -+ emit_move_insn (copy_r11 -+ ? gen_rtx_REG (Pmode, 11) -+ : gen_rtx_REG (Pmode, 12), -+ stack_reg); - - if (TARGET_UPDATE) - { -@@ -15270,7 +15397,9 @@ rs6000_emit_allocate_stack (HOST_WIDE_IN - ? gen_addsi3 (stack_reg, stack_reg, todec) - : gen_adddi3 (stack_reg, stack_reg, todec)); - emit_move_insn (gen_rtx_MEM (Pmode, stack_reg), -- gen_rtx_REG (Pmode, 12)); -+ copy_r11 -+ ? gen_rtx_REG (Pmode, 11) -+ : gen_rtx_REG (Pmode, 12)); - } - - RTX_FRAME_RELATED_P (insn) = 1; -@@ -15359,77 +15488,12 @@ rs6000_frame_related (rtx insn, rtx reg, - } - } - -- if (TARGET_SPE) -- real = spe_synthesize_frame_save (real); -- - RTX_FRAME_RELATED_P (insn) = 1; - REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, - real, - REG_NOTES (insn)); - } - --/* Given an SPE frame note, return a PARALLEL of SETs with the -- original note, plus a synthetic register save. */ -- --static rtx --spe_synthesize_frame_save (rtx real) --{ -- rtx synth, offset, reg, real2; -- -- if (GET_CODE (real) != SET -- || GET_MODE (SET_SRC (real)) != V2SImode) -- return real; -- -- /* For the SPE, registers saved in 64-bits, get a PARALLEL for their -- frame related note. The parallel contains a set of the register -- being saved, and another set to a synthetic register (n+1200). -- This is so we can differentiate between 64-bit and 32-bit saves. -- Words cannot describe this nastiness. */ -- -- gcc_assert (GET_CODE (SET_DEST (real)) == MEM -- && GET_CODE (XEXP (SET_DEST (real), 0)) == PLUS -- && GET_CODE (SET_SRC (real)) == REG); -- -- /* Transform: -- (set (mem (plus (reg x) (const y))) -- (reg z)) -- into: -- (set (mem (plus (reg x) (const y+4))) -- (reg z+1200)) -- */ -- -- real2 = copy_rtx (real); -- PUT_MODE (SET_DEST (real2), SImode); -- reg = SET_SRC (real2); -- real2 = replace_rtx (real2, reg, gen_rtx_REG (SImode, REGNO (reg))); -- synth = copy_rtx (real2); -- -- if (BYTES_BIG_ENDIAN) -- { -- offset = XEXP (XEXP (SET_DEST (real2), 0), 1); -- real2 = replace_rtx (real2, offset, GEN_INT (INTVAL (offset) + 4)); -- } -- -- reg = SET_SRC (synth); -- -- synth = replace_rtx (synth, reg, -- gen_rtx_REG (SImode, REGNO (reg) + 1200)); -- -- offset = XEXP (XEXP (SET_DEST (synth), 0), 1); -- synth = replace_rtx (synth, offset, -- GEN_INT (INTVAL (offset) -- + (BYTES_BIG_ENDIAN ? 0 : 4))); -- -- RTX_FRAME_RELATED_P (synth) = 1; -- RTX_FRAME_RELATED_P (real2) = 1; -- if (BYTES_BIG_ENDIAN) -- real = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, synth, real2)); -- else -- real = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, real2, synth)); -- -- return real; --} -- - /* Returns an insn that has a vrsave set operation with the - appropriate CLOBBERs. */ - -@@ -15503,7 +15567,7 @@ emit_frame_save (rtx frame_reg, rtx fram - - /* Some cases that need register indexed addressing. */ - if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode)) -- || (TARGET_E500_DOUBLE && (mode == DFmode || mode == DDmode)) -+ || (TARGET_E500_DOUBLE && mode == DFmode) - || (TARGET_SPE_ABI - && SPE_VECTOR_MODE (mode) - && !SPE_CONST_OFFSET_OK (offset))) -@@ -15543,7 +15607,7 @@ gen_frame_mem_offset (enum machine_mode - int_rtx = GEN_INT (offset); - - if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode)) -- || (TARGET_E500_DOUBLE && (mode == DFmode || mode == DDmode))) -+ || (TARGET_E500_DOUBLE && mode == DFmode)) - { - offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH); - emit_move_insn (offset_rtx, int_rtx); -@@ -15558,11 +15622,11 @@ gen_frame_mem_offset (enum machine_mode - and cannot use stmw/lmw if there are any in its range. */ - - static bool --no_global_regs_above (int first_greg) -+no_global_regs_above (int first, bool gpr) - { - int i; -- for (i = 0; i < 32 - first_greg; i++) -- if (global_regs[first_greg + i]) -+ for (i = first; i < (gpr ? 32 : 64); i++) -+ if (global_regs[i]) - return false; - return true; - } -@@ -15571,6 +15635,164 @@ no_global_regs_above (int first_greg) - #define TARGET_FIX_AND_CONTINUE 0 - #endif - -+/* It's really GPR 13 and FPR 14, but we need the smaller of the two. */ -+#define FIRST_SAVRES_REGISTER FIRST_SAVED_GP_REGNO -+#define LAST_SAVRES_REGISTER 31 -+#define N_SAVRES_REGISTERS (LAST_SAVRES_REGISTER - FIRST_SAVRES_REGISTER + 1) -+ -+static GTY(()) rtx savres_routine_syms[N_SAVRES_REGISTERS][8]; -+ -+/* Return the symbol for an out-of-line register save/restore routine. -+ We are saving/restoring GPRs if GPR is true. */ -+ -+static rtx -+rs6000_savres_routine_sym (rs6000_stack_t *info, bool savep, bool gpr, bool exitp) -+{ -+ int regno = gpr ? info->first_gp_reg_save : (info->first_fp_reg_save - 32); -+ rtx sym; -+ int select = ((savep ? 1 : 0) << 2 -+ | (TARGET_SPE_ABI -+ /* On the SPE, we never have any FPRs, but we do have -+ 32/64-bit versions of the routines. */ -+ ? (info->spe_64bit_regs_used ? 1 : 0) -+ : (gpr ? 1 : 0)) << 1 -+ | (exitp ? 1: 0)); -+ -+ /* Don't generate bogus routine names. */ -+ gcc_assert (FIRST_SAVRES_REGISTER <= regno && regno <= LAST_SAVRES_REGISTER); -+ -+ sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select]; -+ -+ if (sym == NULL) -+ { -+ char name[30]; -+ const char *action; -+ const char *regkind; -+ const char *exit_suffix; -+ -+ action = savep ? "save" : "rest"; -+ -+ /* SPE has slightly different names for its routines depending on -+ whether we are saving 32-bit or 64-bit registers. */ -+ if (TARGET_SPE_ABI) -+ { -+ /* No floating point saves on the SPE. */ -+ gcc_assert (gpr); -+ -+ regkind = info->spe_64bit_regs_used ? "64gpr" : "32gpr"; -+ } -+ else -+ regkind = gpr ? "gpr" : "fpr"; -+ -+ exit_suffix = exitp ? "_x" : ""; -+ -+ sprintf (name, "_%s%s_%d%s", action, regkind, regno, exit_suffix); -+ -+ 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; -+} -+ -+/* Emit a sequence of insns, including a stack tie if needed, for -+ resetting the stack pointer. If SAVRES is true, then don't reset the -+ stack pointer, but move the base of the frame into r11 for use by -+ out-of-line register restore routines. */ -+ -+static void -+rs6000_emit_stack_reset (rs6000_stack_t *info, -+ rtx sp_reg_rtx, rtx frame_reg_rtx, -+ int sp_offset, bool savres) -+{ -+ /* This blockage is needed so that sched doesn't decide to move -+ the sp change before the register restores. */ -+ if (frame_reg_rtx != sp_reg_rtx -+ || (TARGET_SPE_ABI -+ && info->spe_64bit_regs_used != 0 -+ && info->first_gp_reg_save != 32)) -+ rs6000_emit_stack_tie (); -+ -+ if (frame_reg_rtx != sp_reg_rtx) -+ { -+ rs6000_emit_stack_tie (); -+ if (sp_offset != 0) -+ emit_insn (gen_addsi3 (sp_reg_rtx, frame_reg_rtx, -+ GEN_INT (sp_offset))); -+ else if (!savres) -+ emit_move_insn (sp_reg_rtx, frame_reg_rtx); -+ } -+ else if (sp_offset != 0) -+ { -+ /* If we are restoring registers out-of-line, we will be using the -+ "exit" variants of the restore routines, which will reset the -+ stack for us. But we do need to point r11 into the right place -+ for those routines. */ -+ rtx dest_reg = (savres -+ ? gen_rtx_REG (Pmode, 11) -+ : sp_reg_rtx); -+ -+ emit_insn (TARGET_32BIT -+ ? gen_addsi3 (dest_reg, sp_reg_rtx, -+ GEN_INT (sp_offset)) -+ : gen_adddi3 (dest_reg, sp_reg_rtx, -+ GEN_INT (sp_offset))); -+ } -+} -+ -+/* Construct a parallel rtx describing the effect of a call to an -+ out-of-line register save/restore routine. */ -+ -+static rtx -+rs6000_make_savres_rtx (rs6000_stack_t *info, -+ rtx frame_reg_rtx, int save_area_offset, -+ enum machine_mode reg_mode, -+ bool savep, bool gpr, bool exitp) -+{ -+ int i; -+ int offset, start_reg, end_reg, n_regs; -+ int reg_size = GET_MODE_SIZE (reg_mode); -+ rtx sym; -+ rtvec p; -+ -+ offset = 0; -+ start_reg = (gpr -+ ? info->first_gp_reg_save -+ : info->first_fp_reg_save); -+ end_reg = gpr ? 32 : 64; -+ n_regs = end_reg - start_reg; -+ p = rtvec_alloc ((exitp ? 4 : 3) + n_regs); -+ -+ /* If we're saving registers, then we should never say we're exiting. */ -+ gcc_assert ((savep && !exitp) || !savep); -+ -+ if (exitp) -+ RTVEC_ELT (p, offset++) = gen_rtx_RETURN (VOIDmode); -+ -+ RTVEC_ELT (p, offset++) -+ = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 65)); -+ -+ sym = rs6000_savres_routine_sym (info, savep, gpr, exitp); -+ RTVEC_ELT (p, offset++) = gen_rtx_USE (VOIDmode, sym); -+ RTVEC_ELT (p, offset++) = gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 11)); -+ -+ for (i = 0; i < end_reg - start_reg; i++) -+ { -+ rtx addr, reg, mem; -+ reg = gen_rtx_REG (reg_mode, start_reg + i); -+ addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, -+ GEN_INT (save_area_offset + reg_size*i)); -+ mem = gen_frame_mem (reg_mode, addr); -+ -+ RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode, -+ savep ? mem : reg, -+ savep ? reg : mem); -+ } -+ -+ return gen_rtx_PARALLEL (VOIDmode, p); -+} -+ - /* Determine whether the gp REG is really used. */ - - static bool -@@ -15585,6 +15807,93 @@ rs6000_reg_live_or_pic_offset_p (int reg - || (DEFAULT_ABI == ABI_DARWIN && flag_pic)))); - } - -+enum { -+ SAVRES_MULTIPLE = 0x1, -+ SAVRES_INLINE_FPRS = 0x2, -+ SAVRES_INLINE_GPRS = 0x4 -+}; -+ -+/* Determine the strategy for savings/restoring registers. */ -+ -+static int -+rs6000_savres_strategy (rs6000_stack_t *info, bool savep, -+ int using_static_chain_p, int sibcall) -+{ -+ bool using_multiple_p; -+ bool common; -+ bool savres_fprs_inline; -+ bool savres_gprs_inline; -+ bool noclobber_global_gprs -+ = no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true); -+ -+ using_multiple_p = (TARGET_MULTIPLE && ! TARGET_POWERPC64 -+ && (!TARGET_SPE_ABI -+ || info->spe_64bit_regs_used == 0) -+ && info->first_gp_reg_save < 31 -+ && noclobber_global_gprs); -+ /* Don't bother to try to save things out-of-line if r11 is occupied -+ by the static chain. It would require too much fiddling and the -+ static chain is rarely used anyway. */ -+ common = (using_static_chain_p -+ || sibcall -+ || current_function_calls_eh_return -+ || !info->lr_save_p -+ || cfun->machine->ra_need_lr -+ || info->total_size > 32767); -+ savres_fprs_inline = (common -+ || info->first_fp_reg_save == 64 -+ || !no_global_regs_above (info->first_fp_reg_save, -+ /*gpr=*/false) -+ || FP_SAVE_INLINE (info->first_fp_reg_save)); -+ savres_gprs_inline = (common -+ /* Saving CR interferes with the exit routines -+ used on the SPE, so just punt here. */ -+ || (!savep -+ && TARGET_SPE_ABI -+ && info->spe_64bit_regs_used != 0 -+ && info->cr_save_p != 0) -+ || info->first_gp_reg_save == 32 -+ || !noclobber_global_gprs -+ || GP_SAVE_INLINE (info->first_gp_reg_save)); -+ -+ if (savep) -+ /* If we are going to use store multiple, then don't even bother -+ with the out-of-line routines, since the store-multiple instruction -+ will always be smaller. */ -+ savres_gprs_inline = savres_gprs_inline || using_multiple_p; -+ else -+ { -+ /* The situation is more complicated with load multiple. We'd -+ prefer to use the out-of-line routines for restores, since the -+ "exit" out-of-line routines can handle the restore of LR and -+ the frame teardown. But we can only use the out-of-line -+ routines if we know that we've used store multiple or -+ out-of-line routines in the prologue, i.e. if we've saved all -+ the registers from first_gp_reg_save. Otherwise, we risk -+ loading garbage from the stack. Furthermore, we can only use -+ the "exit" out-of-line gpr restore if we haven't saved any -+ fprs. */ -+ bool saved_all = !savres_gprs_inline || using_multiple_p; -+ -+ if (saved_all && info->first_fp_reg_save != 64) -+ /* We can't use the exit routine; use load multiple if it's -+ available. */ -+ 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)); -+} -+ - /* Emit function prologue as insns. */ - - void -@@ -15598,8 +15907,13 @@ rs6000_emit_prologue (void) - rtx frame_reg_rtx = sp_reg_rtx; - rtx cr_save_rtx = NULL_RTX; - rtx insn; -+ int strategy; - int saving_FPRs_inline; -+ int saving_GPRs_inline; - 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]); - HOST_WIDE_INT sp_offset = 0; - - if (TARGET_FIX_AND_CONTINUE) -@@ -15622,15 +15936,12 @@ rs6000_emit_prologue (void) - reg_size = 8; - } - -- using_store_multiple = (TARGET_MULTIPLE && ! TARGET_POWERPC64 -- && (!TARGET_SPE_ABI -- || info->spe_64bit_regs_used == 0) -- && info->first_gp_reg_save < 31 -- && no_global_regs_above (info->first_gp_reg_save)); -- saving_FPRs_inline = (info->first_fp_reg_save == 64 -- || FP_SAVE_INLINE (info->first_fp_reg_save) -- || current_function_calls_eh_return -- || cfun->machine->ra_need_lr); -+ strategy = rs6000_savres_strategy (info, /*savep=*/true, -+ /*static_chain_p=*/using_static_chain_p, -+ /*sibcall=*/0); -+ using_store_multiple = strategy & SAVRES_MULTIPLE; -+ saving_FPRs_inline = strategy & SAVRES_INLINE_FPRS; -+ saving_GPRs_inline = strategy & SAVRES_INLINE_GPRS; - - /* For V.4, update stack before we do any saving and set back pointer. */ - if (! WORLD_SAVE_P (info) -@@ -15638,17 +15949,24 @@ rs6000_emit_prologue (void) - && (DEFAULT_ABI == ABI_V4 - || current_function_calls_eh_return)) - { -+ bool need_r11 = (TARGET_SPE -+ ? (!saving_GPRs_inline -+ && info->spe_64bit_regs_used == 0) -+ : (!saving_FPRs_inline || !saving_GPRs_inline)); - if (info->total_size < 32767) - sp_offset = info->total_size; - else -- frame_reg_rtx = frame_ptr_rtx; -+ frame_reg_rtx = (need_r11 -+ ? gen_rtx_REG (Pmode, 11) -+ : frame_ptr_rtx); - rs6000_emit_allocate_stack (info->total_size, - (frame_reg_rtx != sp_reg_rtx - && (info->cr_save_p - || info->lr_save_p - || info->first_fp_reg_save < 64 - || info->first_gp_reg_save < 32 -- ))); -+ )), -+ need_r11); - if (frame_reg_rtx != sp_reg_rtx) - rs6000_emit_stack_tie (); - } -@@ -15825,40 +16143,147 @@ rs6000_emit_prologue (void) - } - else if (!WORLD_SAVE_P (info) && info->first_fp_reg_save != 64) - { -+ rtx par; -+ -+ par = rs6000_make_savres_rtx (info, frame_reg_rtx, -+ info->fp_save_offset + sp_offset, -+ DFmode, -+ /*savep=*/true, /*gpr=*/false, -+ /*exitp=*/false); -+ insn = emit_insn (par); -+ rs6000_frame_related (insn, frame_ptr_rtx, info->total_size, -+ NULL_RTX, NULL_RTX); -+ } -+ -+ /* Save GPRs. This is done as a PARALLEL if we are using -+ the store-multiple instructions. */ -+ if (!WORLD_SAVE_P (info) -+ && TARGET_SPE_ABI -+ && info->spe_64bit_regs_used != 0 -+ && info->first_gp_reg_save != 32) -+ { - int i; -- char rname[30]; -- const char *alloc_rname; -- rtvec p; -- p = rtvec_alloc (2 + 64 - info->first_fp_reg_save); -+ rtx spe_save_area_ptr; -+ -+ /* Determine whether we can address all of the registers that need -+ to be saved with an offset from the stack pointer that fits in -+ the small const field for SPE memory instructions. */ -+ int spe_regs_addressable_via_sp -+ = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset -+ + (32 - info->first_gp_reg_save - 1) * reg_size) -+ && saving_GPRs_inline); -+ int spe_offset; -+ -+ if (spe_regs_addressable_via_sp) -+ { -+ spe_save_area_ptr = frame_reg_rtx; -+ spe_offset = info->spe_gp_save_offset + sp_offset; -+ } -+ else -+ { -+ /* Make r11 point to the start of the SPE save area. We need -+ to be careful here if r11 is holding the static chain. If -+ it is, then temporarily save it in r0. We would use r0 as -+ our base register here, but using r0 as a base register in -+ loads and stores means something different from what we -+ would like. */ -+ int ool_adjust = (saving_GPRs_inline -+ ? 0 -+ : (info->first_gp_reg_save -+ - (FIRST_SAVRES_REGISTER+1))*8); -+ HOST_WIDE_INT offset = (info->spe_gp_save_offset -+ + sp_offset - ool_adjust); - -- RTVEC_ELT (p, 0) = gen_rtx_CLOBBER (VOIDmode, -- gen_rtx_REG (Pmode, -- LR_REGNO)); -- sprintf (rname, "%s%d%s", SAVE_FP_PREFIX, -- info->first_fp_reg_save - 32, SAVE_FP_SUFFIX); -- alloc_rname = ggc_strdup (rname); -- RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode, -- gen_rtx_SYMBOL_REF (Pmode, -- alloc_rname)); -- for (i = 0; i < 64 - info->first_fp_reg_save; i++) -+ if (using_static_chain_p) -+ { -+ rtx r0 = gen_rtx_REG (Pmode, 0); -+ gcc_assert (info->first_gp_reg_save > 11); -+ -+ emit_move_insn (r0, gen_rtx_REG (Pmode, 11)); -+ } -+ -+ spe_save_area_ptr = gen_rtx_REG (Pmode, 11); -+ insn = emit_insn (gen_addsi3 (spe_save_area_ptr, -+ frame_reg_rtx, -+ GEN_INT (offset))); -+ /* We need to make sure the move to r11 gets noted for -+ properly outputting unwind information. */ -+ if (!saving_GPRs_inline) -+ rs6000_frame_related (insn, frame_reg_rtx, offset, -+ NULL_RTX, NULL_RTX); -+ spe_offset = 0; -+ } -+ -+ if (saving_GPRs_inline) - { -- rtx addr, reg, mem; -- reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i); -- addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, -- GEN_INT (info->fp_save_offset -- + sp_offset + 8*i)); -- mem = gen_frame_mem (DFmode, addr); -+ for (i = 0; i < 32 - info->first_gp_reg_save; i++) -+ if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i)) -+ { -+ rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i); -+ rtx offset, addr, mem; -+ -+ /* We're doing all this to ensure that the offset fits into -+ the immediate offset of 'evstdd'. */ -+ gcc_assert (SPE_CONST_OFFSET_OK (reg_size * i + spe_offset)); -+ -+ offset = GEN_INT (reg_size * i + spe_offset); -+ addr = gen_rtx_PLUS (Pmode, spe_save_area_ptr, offset); -+ mem = gen_rtx_MEM (V2SImode, addr); -+ -+ insn = emit_move_insn (mem, reg); -+ -+ rs6000_frame_related (insn, spe_save_area_ptr, -+ info->spe_gp_save_offset -+ + sp_offset + reg_size * i, -+ offset, const0_rtx); -+ } -+ } -+ else -+ { -+ rtx par; - -- RTVEC_ELT (p, i + 2) = gen_rtx_SET (VOIDmode, mem, reg); -+ par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11), -+ 0, reg_mode, -+ /*savep=*/true, /*gpr=*/true, -+ /*exitp=*/false); -+ insn = emit_insn (par); -+ rs6000_frame_related (insn, frame_ptr_rtx, info->total_size, -+ NULL_RTX, NULL_RTX); - } -- insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p)); -+ -+ -+ /* Move the static chain pointer back. */ -+ if (using_static_chain_p && !spe_regs_addressable_via_sp) -+ emit_move_insn (gen_rtx_REG (Pmode, 11), gen_rtx_REG (Pmode, 0)); -+ } -+ else if (!WORLD_SAVE_P (info) && !saving_GPRs_inline) -+ { -+ rtx par; -+ -+ /* Need to adjust r11 if we saved any FPRs. */ -+ if (info->first_fp_reg_save != 64) -+ { -+ rtx r11 = gen_rtx_REG (reg_mode, 11); -+ rtx offset = GEN_INT (info->total_size -+ + (-8 * (64-info->first_fp_reg_save))); -+ rtx ptr_reg = (sp_reg_rtx == frame_reg_rtx -+ ? sp_reg_rtx : r11); -+ -+ emit_insn (TARGET_32BIT -+ ? gen_addsi3 (r11, ptr_reg, offset) -+ : gen_adddi3 (r11, ptr_reg, offset)); -+ } -+ -+ par = rs6000_make_savres_rtx (info, frame_reg_rtx, -+ info->gp_save_offset + sp_offset, -+ reg_mode, -+ /*savep=*/true, /*gpr=*/true, -+ /*exitp=*/false); -+ insn = emit_insn (par); - rs6000_frame_related (insn, frame_ptr_rtx, info->total_size, - NULL_RTX, NULL_RTX); - } -- -- /* Save GPRs. This is done as a PARALLEL if we are using -- the store-multiple instructions. */ -- if (!WORLD_SAVE_P (info) && using_store_multiple) -+ else if (!WORLD_SAVE_P (info) && using_store_multiple) - { - rtvec p; - int i; -@@ -15879,80 +16304,6 @@ rs6000_emit_prologue (void) - rs6000_frame_related (insn, frame_ptr_rtx, info->total_size, - NULL_RTX, NULL_RTX); - } -- else if (!WORLD_SAVE_P (info) -- && TARGET_SPE_ABI -- && info->spe_64bit_regs_used != 0 -- && info->first_gp_reg_save != 32) -- { -- int i; -- rtx spe_save_area_ptr; -- 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]); -- -- /* Determine whether we can address all of the registers that need -- to be saved with an offset from the stack pointer that fits in -- the small const field for SPE memory instructions. */ -- int spe_regs_addressable_via_sp -- = SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset -- + (32 - info->first_gp_reg_save - 1) * reg_size); -- int spe_offset; -- -- if (spe_regs_addressable_via_sp) -- { -- spe_save_area_ptr = frame_reg_rtx; -- spe_offset = info->spe_gp_save_offset + sp_offset; -- } -- else -- { -- /* Make r11 point to the start of the SPE save area. We need -- to be careful here if r11 is holding the static chain. If -- it is, then temporarily save it in r0. We would use r0 as -- our base register here, but using r0 as a base register in -- loads and stores means something different from what we -- would like. */ -- if (using_static_chain_p) -- { -- rtx r0 = gen_rtx_REG (Pmode, 0); -- -- gcc_assert (info->first_gp_reg_save > 11); -- -- emit_move_insn (r0, gen_rtx_REG (Pmode, 11)); -- } -- -- spe_save_area_ptr = gen_rtx_REG (Pmode, 11); -- emit_insn (gen_addsi3 (spe_save_area_ptr, frame_reg_rtx, -- GEN_INT (info->spe_gp_save_offset + sp_offset))); -- -- spe_offset = 0; -- } -- -- for (i = 0; i < 32 - info->first_gp_reg_save; i++) -- if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i)) -- { -- rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i); -- rtx offset, addr, mem; -- -- /* We're doing all this to ensure that the offset fits into -- the immediate offset of 'evstdd'. */ -- gcc_assert (SPE_CONST_OFFSET_OK (reg_size * i + spe_offset)); -- -- offset = GEN_INT (reg_size * i + spe_offset); -- addr = gen_rtx_PLUS (Pmode, spe_save_area_ptr, offset); -- mem = gen_rtx_MEM (V2SImode, addr); -- -- insn = emit_move_insn (mem, reg); -- -- rs6000_frame_related (insn, spe_save_area_ptr, -- info->spe_gp_save_offset -- + sp_offset + reg_size * i, -- offset, const0_rtx); -- } -- -- /* Move the static chain pointer back. */ -- if (using_static_chain_p && !spe_regs_addressable_via_sp) -- emit_move_insn (gen_rtx_REG (Pmode, 11), gen_rtx_REG (Pmode, 0)); -- } - else if (!WORLD_SAVE_P (info)) - { - int i; -@@ -16052,7 +16403,8 @@ rs6000_emit_prologue (void) - (frame_reg_rtx != sp_reg_rtx - && ((info->altivec_size != 0) - || (info->vrsave_mask != 0) -- ))); -+ )), -+ FALSE); - if (frame_reg_rtx != sp_reg_rtx) - rs6000_emit_stack_tie (); - } -@@ -16208,8 +16560,7 @@ rs6000_output_function_prologue (FILE *f - && !FP_SAVE_INLINE (info->first_fp_reg_save)) - fprintf (file, "\t.extern %s%d%s\n\t.extern %s%d%s\n", - SAVE_FP_PREFIX, info->first_fp_reg_save - 32, SAVE_FP_SUFFIX, -- RESTORE_FP_PREFIX, info->first_fp_reg_save - 32, -- RESTORE_FP_SUFFIX); -+ RESTORE_FP_PREFIX, info->first_fp_reg_save - 32, RESTORE_FP_SUFFIX); - - /* Write .extern for AIX common mode routines, if needed. */ - if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined) -@@ -16253,6 +16604,54 @@ rs6000_output_function_prologue (FILE *f - rs6000_pic_labelno++; - } - -+/* Reload CR from REG. */ -+ -+static void -+rs6000_restore_saved_cr (rtx reg, int using_mfcr_multiple) -+{ -+ int count = 0; -+ int i; -+ -+ if (using_mfcr_multiple) -+ { -+ for (i = 0; i < 8; i++) -+ if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i]) -+ count++; -+ gcc_assert (count); -+ } -+ -+ if (using_mfcr_multiple && count > 1) -+ { -+ rtvec p; -+ int ndx; -+ -+ p = rtvec_alloc (count); -+ -+ ndx = 0; -+ for (i = 0; i < 8; i++) -+ if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i]) -+ { -+ rtvec r = rtvec_alloc (2); -+ RTVEC_ELT (r, 0) = reg; -+ RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i)); -+ RTVEC_ELT (p, ndx) = -+ gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i), -+ gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR)); -+ ndx++; -+ } -+ emit_insn (gen_rtx_PARALLEL (VOIDmode, p)); -+ gcc_assert (ndx == count); -+ } -+ else -+ for (i = 0; i < 8; i++) -+ if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i]) -+ { -+ emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode, -+ CR0_REGNO+i), -+ reg)); -+ } -+} -+ - /* Emit function epilogue as insns. - - At present, dwarf2out_frame_debug_expr doesn't understand -@@ -16264,10 +16663,13 @@ void - rs6000_emit_epilogue (int sibcall) - { - rs6000_stack_t *info; -+ int restoring_GPRs_inline; - int restoring_FPRs_inline; - int using_load_multiple; - int using_mtcr_multiple; - int use_backchain_to_restore_sp; -+ int restore_lr; -+ int strategy; - int sp_offset = 0; - rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1); - rtx frame_reg_rtx = sp_reg_rtx; -@@ -16283,15 +16685,11 @@ rs6000_emit_epilogue (int sibcall) - reg_size = 8; - } - -- using_load_multiple = (TARGET_MULTIPLE && ! TARGET_POWERPC64 -- && (!TARGET_SPE_ABI -- || info->spe_64bit_regs_used == 0) -- && info->first_gp_reg_save < 31 -- && no_global_regs_above (info->first_gp_reg_save)); -- restoring_FPRs_inline = (sibcall -- || current_function_calls_eh_return -- || info->first_fp_reg_save == 64 -- || FP_SAVE_INLINE (info->first_fp_reg_save)); -+ strategy = rs6000_savres_strategy (info, /*savep=*/false, -+ /*static_chain_p=*/0, sibcall); -+ using_load_multiple = strategy & SAVRES_MULTIPLE; -+ restoring_FPRs_inline = strategy & SAVRES_INLINE_FPRS; -+ restoring_GPRs_inline = strategy & SAVRES_INLINE_GPRS; - use_backchain_to_restore_sp = (frame_pointer_needed - || current_function_calls_alloca - || info->total_size > 32767); -@@ -16299,6 +16697,10 @@ rs6000_emit_epilogue (int sibcall) - || rs6000_cpu == PROCESSOR_PPC603 - || rs6000_cpu == PROCESSOR_PPC750 - || optimize_size); -+ restore_lr = (info->lr_save_p -+ && (restoring_GPRs_inline -+ || (restoring_FPRs_inline -+ && info->first_fp_reg_save < 64))); - - if (WORLD_SAVE_P (info)) - { -@@ -16537,8 +16939,9 @@ rs6000_emit_epilogue (int sibcall) - emit_insn (generate_set_vrsave (reg, info, 1)); - } - -- /* Get the old lr if we saved it. */ -- if (info->lr_save_p) -+ /* 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 && restoring_GPRs_inline) - { - rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx, - info->lr_save_offset + sp_offset); -@@ -16557,7 +16960,7 @@ rs6000_emit_epilogue (int sibcall) - } - - /* Set LR here to try to overlap restores below. */ -- if (info->lr_save_p) -+ if (restore_lr && restoring_GPRs_inline) - emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO), - gen_rtx_REG (Pmode, 0)); - -@@ -16593,35 +16996,17 @@ rs6000_emit_epilogue (int sibcall) - - /* Restore GPRs. This is done as a PARALLEL if we are using - the load-multiple instructions. */ -- if (using_load_multiple) -- { -- rtvec p; -- p = rtvec_alloc (32 - info->first_gp_reg_save); -- for (i = 0; i < 32 - info->first_gp_reg_save; i++) -- { -- rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, -- GEN_INT (info->gp_save_offset -- + sp_offset -- + reg_size * i)); -- rtx mem = gen_frame_mem (reg_mode, addr); -- -- RTVEC_ELT (p, i) = -- gen_rtx_SET (VOIDmode, -- gen_rtx_REG (reg_mode, info->first_gp_reg_save + i), -- mem); -- } -- emit_insn (gen_rtx_PARALLEL (VOIDmode, p)); -- } -- else if (TARGET_SPE_ABI -- && info->spe_64bit_regs_used != 0 -- && info->first_gp_reg_save != 32) -+ if (TARGET_SPE_ABI -+ && info->spe_64bit_regs_used != 0 -+ && info->first_gp_reg_save != 32) - { - /* Determine whether we can address all of the registers that need - to be saved with an offset from the stack pointer that fits in - the small const field for SPE memory instructions. */ - int spe_regs_addressable_via_sp -- = SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset -- + (32 - info->first_gp_reg_save - 1) * reg_size); -+ = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset -+ + (32 - info->first_gp_reg_save - 1) * reg_size) -+ && restoring_GPRs_inline); - int spe_offset; - - if (spe_regs_addressable_via_sp) -@@ -16633,10 +17018,17 @@ rs6000_emit_epilogue (int sibcall) - not clobbering it when we were saving registers in the prologue. - There's no need to worry here because the static chain is passed - anew to every function. */ -+ int ool_adjust = (restoring_GPRs_inline -+ ? 0 -+ : (info->first_gp_reg_save -+ - (FIRST_SAVRES_REGISTER+1))*8); -+ - if (frame_reg_rtx == sp_reg_rtx) - frame_reg_rtx = gen_rtx_REG (Pmode, 11); - emit_insn (gen_addsi3 (frame_reg_rtx, old_frame_reg_rtx, -- GEN_INT (info->spe_gp_save_offset + sp_offset))); -+ GEN_INT (info->spe_gp_save_offset -+ + sp_offset -+ - ool_adjust))); - /* Keep the invariant that frame_reg_rtx + sp_offset points - at the top of the stack frame. */ - sp_offset = -info->spe_gp_save_offset; -@@ -16644,26 +17036,80 @@ rs6000_emit_epilogue (int sibcall) - spe_offset = 0; - } - -- for (i = 0; i < 32 - info->first_gp_reg_save; i++) -- if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i)) -- { -- rtx offset, addr, mem; -+ if (restoring_GPRs_inline) -+ { -+ for (i = 0; i < 32 - info->first_gp_reg_save; i++) -+ if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i)) -+ { -+ rtx offset, addr, mem; - -- /* We're doing all this to ensure that the immediate offset -- fits into the immediate field of 'evldd'. */ -- gcc_assert (SPE_CONST_OFFSET_OK (spe_offset + reg_size * i)); -- -- offset = GEN_INT (spe_offset + reg_size * i); -- addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, offset); -- mem = gen_rtx_MEM (V2SImode, addr); -+ /* We're doing all this to ensure that the immediate offset -+ fits into the immediate field of 'evldd'. */ -+ gcc_assert (SPE_CONST_OFFSET_OK (spe_offset + reg_size * i)); -+ -+ offset = GEN_INT (spe_offset + reg_size * i); -+ addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, offset); -+ mem = gen_rtx_MEM (V2SImode, addr); - -- emit_move_insn (gen_rtx_REG (reg_mode, info->first_gp_reg_save + i), -- mem); -- } -+ emit_move_insn (gen_rtx_REG (reg_mode, info->first_gp_reg_save + i), -+ mem); -+ } -+ } -+ else -+ { -+ rtx par; -+ -+ par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11), -+ 0, reg_mode, -+ /*savep=*/false, /*gpr=*/true, -+ /*exitp=*/true); -+ emit_jump_insn (par); -+ -+ /* We don't want anybody else emitting things after we jumped -+ back. */ -+ return; -+ } - } -- else -- for (i = 0; i < 32 - info->first_gp_reg_save; i++) -- if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i)) -+ else if (!restoring_GPRs_inline) -+ { -+ /* We are jumping to an out-of-line function. */ -+ bool can_use_exit = info->first_fp_reg_save == 64; -+ rtx par; -+ -+ /* Emit stack reset code if we need it. */ -+ if (can_use_exit) -+ rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx, -+ sp_offset, can_use_exit); -+ else -+ emit_insn (gen_addsi3 (gen_rtx_REG (Pmode, 11), -+ sp_reg_rtx, -+ GEN_INT (sp_offset - info->fp_size))); -+ -+ par = rs6000_make_savres_rtx (info, frame_reg_rtx, -+ info->gp_save_offset, reg_mode, -+ /*savep=*/false, /*gpr=*/true, -+ /*exitp=*/can_use_exit); -+ -+ if (can_use_exit) -+ { -+ if (info->cr_save_p) -+ rs6000_restore_saved_cr (gen_rtx_REG (SImode, 12), -+ using_mtcr_multiple); -+ -+ emit_jump_insn (par); -+ -+ /* We don't want anybody else emitting things after we jumped -+ back. */ -+ return; -+ } -+ else -+ emit_insn (par); -+ } -+ else if (using_load_multiple) -+ { -+ rtvec p; -+ p = rtvec_alloc (32 - info->first_gp_reg_save); -+ for (i = 0; i < 32 - info->first_gp_reg_save; i++) - { - rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, - GEN_INT (info->gp_save_offset -@@ -16671,9 +17117,40 @@ rs6000_emit_epilogue (int sibcall) - + reg_size * i)); - rtx mem = gen_frame_mem (reg_mode, addr); - -- emit_move_insn (gen_rtx_REG (reg_mode, -- info->first_gp_reg_save + i), mem); -+ RTVEC_ELT (p, i) = -+ gen_rtx_SET (VOIDmode, -+ gen_rtx_REG (reg_mode, info->first_gp_reg_save + i), -+ mem); - } -+ emit_insn (gen_rtx_PARALLEL (VOIDmode, p)); -+ } -+ else -+ { -+ for (i = 0; i < 32 - info->first_gp_reg_save; i++) -+ if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i)) -+ { -+ rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, -+ GEN_INT (info->gp_save_offset -+ + sp_offset -+ + reg_size * i)); -+ rtx mem = gen_frame_mem (reg_mode, addr); -+ -+ emit_move_insn (gen_rtx_REG (reg_mode, -+ info->first_gp_reg_save + i), mem); -+ } -+ } -+ -+ 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) -@@ -16695,69 +17172,12 @@ rs6000_emit_epilogue (int sibcall) - - /* If we saved cr, restore it here. Just those that were used. */ - if (info->cr_save_p) -- { -- rtx r12_rtx = gen_rtx_REG (SImode, 12); -- int count = 0; -- -- if (using_mtcr_multiple) -- { -- for (i = 0; i < 8; i++) -- if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i]) -- count++; -- gcc_assert (count); -- } -- -- if (using_mtcr_multiple && count > 1) -- { -- rtvec p; -- int ndx; -- -- p = rtvec_alloc (count); -- -- ndx = 0; -- for (i = 0; i < 8; i++) -- if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i]) -- { -- rtvec r = rtvec_alloc (2); -- RTVEC_ELT (r, 0) = r12_rtx; -- RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i)); -- RTVEC_ELT (p, ndx) = -- gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i), -- gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR)); -- ndx++; -- } -- emit_insn (gen_rtx_PARALLEL (VOIDmode, p)); -- gcc_assert (ndx == count); -- } -- else -- for (i = 0; i < 8; i++) -- if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i]) -- { -- emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode, -- CR0_REGNO+i), -- r12_rtx)); -- } -- } -+ rs6000_restore_saved_cr (gen_rtx_REG (SImode, 12), using_mtcr_multiple); - - /* If this is V.4, unwind the stack pointer after all of the loads - have been done. */ -- if (frame_reg_rtx != sp_reg_rtx) -- { -- /* This blockage is needed so that sched doesn't decide to move -- the sp change before the register restores. */ -- rs6000_emit_stack_tie (); -- if (sp_offset != 0) -- emit_insn (gen_addsi3 (sp_reg_rtx, frame_reg_rtx, -- GEN_INT (sp_offset))); -- else -- emit_move_insn (sp_reg_rtx, frame_reg_rtx); -- } -- else if (sp_offset != 0) -- emit_insn (TARGET_32BIT -- ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx, -- GEN_INT (sp_offset)) -- : gen_adddi3 (sp_reg_rtx, sp_reg_rtx, -- GEN_INT (sp_offset))); -+ rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx, -+ sp_offset, !restoring_FPRs_inline); - - if (current_function_calls_eh_return) - { -@@ -16771,30 +17191,30 @@ rs6000_emit_epilogue (int sibcall) - { - rtvec p; - if (! restoring_FPRs_inline) -- p = rtvec_alloc (3 + 64 - info->first_fp_reg_save); -+ p = rtvec_alloc (4 + 64 - info->first_fp_reg_save); - else - p = rtvec_alloc (2); - - RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode); -- RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode, -- gen_rtx_REG (Pmode, -- LR_REGNO)); -+ RTVEC_ELT (p, 1) = (restoring_FPRs_inline -+ ? gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 65)) -+ : gen_rtx_CLOBBER (VOIDmode, -+ gen_rtx_REG (Pmode, 65))); - - /* If we have to restore more than two FP registers, branch to the - restore function. It will return to our caller. */ - if (! restoring_FPRs_inline) - { - int i; -- char rname[30]; -- const char *alloc_rname; -- -- sprintf (rname, "%s%d%s", RESTORE_FP_PREFIX, -- info->first_fp_reg_save - 32, RESTORE_FP_SUFFIX); -- alloc_rname = ggc_strdup (rname); -- RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode, -- gen_rtx_SYMBOL_REF (Pmode, -- alloc_rname)); -+ rtx sym; - -+ sym = rs6000_savres_routine_sym (info, -+ /*savep=*/false, -+ /*gpr=*/false, -+ /*exitp=*/true); -+ RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode, sym); -+ RTVEC_ELT (p, 3) = gen_rtx_USE (VOIDmode, -+ gen_rtx_REG (Pmode, 11)); - for (i = 0; i < 64 - info->first_fp_reg_save; i++) - { - rtx addr, mem; -@@ -16802,7 +17222,7 @@ rs6000_emit_epilogue (int sibcall) - GEN_INT (info->fp_save_offset + 8*i)); - mem = gen_frame_mem (DFmode, addr); - -- RTVEC_ELT (p, i+3) = -+ RTVEC_ELT (p, i+4) = - gen_rtx_SET (VOIDmode, - gen_rtx_REG (DFmode, info->first_fp_reg_save + i), - mem); -@@ -18611,6 +19031,9 @@ rs6000_issue_rate (void) - case CPU_PPC7400: - case CPU_PPC8540: - case CPU_CELL: -+ case CPU_PPCE300C2: -+ case CPU_PPCE300C3: -+ case CPU_PPCE500MC: - return 2; - case CPU_RIOS2: - case CPU_PPC604: -@@ -21814,8 +22237,8 @@ rs6000_function_value (const_tree valtyp - && ALTIVEC_VECTOR_MODE (mode)) - regno = ALTIVEC_ARG_RETURN; - else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT -- && (mode == DFmode || mode == DDmode || mode == DCmode -- || mode == TFmode || mode == TDmode || mode == TCmode)) -+ && (mode == DFmode || mode == DCmode -+ || mode == TFmode || mode == TCmode)) - return spe_build_register_parallel (mode, GP_ARG_RETURN); - else - regno = GP_ARG_RETURN; -@@ -21856,8 +22279,8 @@ rs6000_libcall_value (enum machine_mode - else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg) - return rs6000_complex_function_value (mode); - else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT -- && (mode == DFmode || mode == DDmode || mode == DCmode -- || mode == TFmode || mode == TDmode || mode == TCmode)) -+ && (mode == DFmode || mode == DCmode -+ || mode == TFmode || mode == TCmode)) - return spe_build_register_parallel (mode, GP_ARG_RETURN); - else - regno = GP_ARG_RETURN; -@@ -21904,19 +22327,22 @@ rs6000_is_opaque_type (const_tree type) - { - return (type == opaque_V2SI_type_node - || type == opaque_V2SF_type_node -- || type == opaque_p_V2SI_type_node - || type == opaque_V4SI_type_node); - } - - 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; -@@ -21926,15 +22352,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 -@@ -117,6 +117,9 @@ - %{mcpu=G5: -mpower4 -maltivec} \ - %{mcpu=8540: -me500} \ - %{mcpu=8548: -me500} \ -+%{mcpu=e300c2: -mppc} \ -+%{mcpu=e300c3: -mppc -mpmr} \ -+%{mcpu=e500mc: -me500mc} \ - %{maltivec: -maltivec} \ - -many" - -@@ -262,6 +265,9 @@ enum processor_type - PROCESSOR_PPC7400, - PROCESSOR_PPC7450, - PROCESSOR_PPC8540, -+ PROCESSOR_PPCE300C2, -+ PROCESSOR_PPCE300C3, -+ PROCESSOR_PPCE500MC, - PROCESSOR_POWER4, - PROCESSOR_POWER5, - PROCESSOR_POWER6, -@@ -313,12 +319,15 @@ enum group_termination - }; - - /* Support for a compile-time default CPU, et cetera. The rules are: -- --with-cpu is ignored if -mcpu is specified. -+ --with-cpu is ignored if -mcpu is specified; likewise --with-cpu32 -+ and --with-cpu64. - --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)}" }, \ -+ {"cpu", "%{mcpu=*|te500mc|te500v1|te500v2|te600:;:-mcpu=%(VALUE)}" }, \ -+ {"cpu32", "%{m64|mcpu=*|te500mc|te500v1|te500v2|te600:;:-mcpu=%(VALUE)}" }, \ -+ {"cpu64", "%{m32|mcpu=*|te500mc|te500v1|te500v2|te600:;:-mcpu=%(VALUE)}" }, \ - {"tune", "%{!mtune=*:-mtune=%(VALUE)}" }, \ - {"float", "%{!msoft-float:%{!mhard-float:-m%(VALUE)-float}}" } - -@@ -349,6 +358,8 @@ extern int rs6000_long_double_type_size; - extern int rs6000_ieeequad; - extern int rs6000_altivec_abi; - extern int rs6000_spe_abi; -+extern int rs6000_spe; -+extern int rs6000_isel; - extern int rs6000_float_gprs; - extern int rs6000_alignment_flags; - extern const char *rs6000_sched_insert_nops_str; -@@ -378,7 +389,7 @@ extern enum rs6000_nop_insertion rs6000_ - #define TARGET_SPE_ABI 0 - #define TARGET_SPE 0 - #define TARGET_E500 0 --#define TARGET_ISEL 0 -+#define TARGET_ISEL rs6000_isel - #define TARGET_FPRS 1 - #define TARGET_E500_SINGLE 0 - #define TARGET_E500_DOUBLE 0 -@@ -561,7 +572,7 @@ extern enum rs6000_nop_insertion rs6000_ - #define LOCAL_ALIGNMENT(TYPE, ALIGN) \ - ((TARGET_ALTIVEC && TREE_CODE (TYPE) == VECTOR_TYPE) ? 128 : \ - (TARGET_E500_DOUBLE \ -- && (TYPE_MODE (TYPE) == DFmode || TYPE_MODE (TYPE) == DDmode)) ? 64 : \ -+ && TYPE_MODE (TYPE) == DFmode) ? 64 : \ - ((TARGET_SPE && TREE_CODE (TYPE) == VECTOR_TYPE \ - && SPE_VECTOR_MODE (TYPE_MODE (TYPE))) || (TARGET_PAIRED_FLOAT \ - && TREE_CODE (TYPE) == VECTOR_TYPE \ -@@ -587,7 +598,7 @@ extern enum rs6000_nop_insertion rs6000_ - fit into 1, whereas DI still needs two. */ - #define MEMBER_TYPE_FORCES_BLK(FIELD, MODE) \ - ((TARGET_SPE && TREE_CODE (TREE_TYPE (FIELD)) == VECTOR_TYPE) \ -- || (TARGET_E500_DOUBLE && ((MODE) == DFmode || (MODE) == DDmode))) -+ || (TARGET_E500_DOUBLE && (MODE) == DFmode)) - - /* A bit-field declared as `int' forces `int' alignment for the struct. */ - #define PCC_BITFIELD_TYPE_MATTERS 1 -@@ -596,6 +607,7 @@ extern enum rs6000_nop_insertion rs6000_ - Make vector constants quadword aligned. */ - #define CONSTANT_ALIGNMENT(EXP, ALIGN) \ - (TREE_CODE (EXP) == STRING_CST \ -+ && (STRICT_ALIGNMENT || !optimize_size) \ - && (ALIGN) < BITS_PER_WORD \ - ? BITS_PER_WORD \ - : (ALIGN)) -@@ -607,7 +619,7 @@ extern enum rs6000_nop_insertion rs6000_ - (TREE_CODE (TYPE) == VECTOR_TYPE ? ((TARGET_SPE_ABI \ - || TARGET_PAIRED_FLOAT) ? 64 : 128) \ - : (TARGET_E500_DOUBLE \ -- && (TYPE_MODE (TYPE) == DFmode || TYPE_MODE (TYPE) == DDmode)) ? 64 \ -+ && TYPE_MODE (TYPE) == DFmode) ? 64 \ - : TREE_CODE (TYPE) == ARRAY_TYPE \ - && TYPE_MODE (TREE_TYPE (TYPE)) == QImode \ - && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN)) -@@ -731,8 +743,8 @@ extern enum rs6000_nop_insertion rs6000_ - 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 \ - } -@@ -750,8 +762,8 @@ extern enum rs6000_nop_insertion rs6000_ - 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 \ - } -@@ -1189,7 +1201,7 @@ enum reg_class - (((CLASS) == FLOAT_REGS) \ - ? ((GET_MODE_SIZE (MODE) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD) \ - : (TARGET_E500_DOUBLE && (CLASS) == GENERAL_REGS \ -- && ((MODE) == DFmode || (MODE) == DDmode)) \ -+ && (MODE) == DFmode) \ - ? 1 \ - : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)) - ---- a/gcc/config/rs6000/rs6000.md -+++ b/gcc/config/rs6000/rs6000.md -@@ -133,7 +133,7 @@ - ;; Processor type -- this attribute must exactly match the processor_type - ;; enumeration in rs6000.h. - --(define_attr "cpu" "rios1,rios2,rs64a,mpccore,ppc403,ppc405,ppc440,ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,ppc750,ppc7400,ppc7450,ppc8540,power4,power5,power6,cell" -+(define_attr "cpu" "rios1,rios2,rs64a,mpccore,ppc403,ppc405,ppc440,ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,ppc750,ppc7400,ppc7450,ppc8540,ppce300c2,ppce300c3,ppce500mc,power4,power5,power6,cell" - (const (symbol_ref "rs6000_cpu_attr"))) - - -@@ -166,6 +166,8 @@ - (include "7xx.md") - (include "7450.md") - (include "8540.md") -+(include "e300c2c3.md") -+(include "e500mc.md") - (include "power4.md") - (include "power5.md") - (include "power6.md") -@@ -8887,7 +8889,7 @@ - rtx label = gen_label_rtx (); - if (TARGET_E500_DOUBLE) - { -- if (flag_unsafe_math_optimizations) -+ if (flag_finite_math_only && !flag_trapping_math) - emit_insn (gen_spe_abstf2_tst (operands[0], operands[1], label)); - else - emit_insn (gen_spe_abstf2_cmp (operands[0], operands[1], label)); -@@ -11642,7 +11644,7 @@ - - (define_expand "bltgt" - [(use (match_operand 0 "" ""))] -- "" -+ "! (TARGET_HARD_FLOAT && !TARGET_FPRS)" - "{ rs6000_emit_cbranch (LTGT, operands[0]); DONE; }") - - ;; For SNE, we would prefer that the xor/abs sequence be used for integers. -@@ -11776,7 +11778,7 @@ - - (define_expand "sltgt" - [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))] -- "" -+ "! (TARGET_HARD_FLOAT && !TARGET_FPRS)" - "{ rs6000_emit_sCOND (LTGT, operands[0]); DONE; }") - - (define_expand "stack_protect_set" -@@ -12084,7 +12086,7 @@ - (define_insn "move_from_CR_gt_bit" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (unspec:SI [(match_operand 1 "cc_reg_operand" "y")] UNSPEC_MV_CR_GT))] -- "TARGET_E500" -+ "TARGET_HARD_FLOAT && !TARGET_FPRS" - "mfcr %0\;{rlinm|rlwinm} %0,%0,%D1,31,31" - [(set_attr "type" "mfcr") - (set_attr "length" "8")]) -@@ -14469,10 +14471,23 @@ - "{stm|stmw} %2,%1" - [(set_attr "type" "store_ux")]) - -+(define_insn "*save_gpregs_" -+ [(match_parallel 0 "any_parallel_operand" -+ [(clobber (reg:P 65)) -+ (use (match_operand:P 1 "symbol_ref_operand" "s")) -+ (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") -+ (set_attr "length" "4")]) -+ - (define_insn "*save_fpregs_" - [(match_parallel 0 "any_parallel_operand" - [(clobber (reg:P 65)) -- (use (match_operand:P 1 "call_operand" "s")) -+ (use (match_operand:P 1 "symbol_ref_operand" "s")) -+ (use (reg:P 11)) - (set (match_operand:DF 2 "memory_operand" "=m") - (match_operand:DF 3 "gpc_reg_operand" "f"))])] - "" -@@ -14562,15 +14577,43 @@ - ; FIXME: This would probably be somewhat simpler if the Cygnus sibcall - ; stuff was in GCC. Oh, and "any_parallel_operand" is a bit flexible... - -+(define_insn "*restore_gpregs_" -+ [(match_parallel 0 "any_parallel_operand" -+ [(clobber (match_operand:P 1 "register_operand" "=l")) -+ (use (match_operand:P 2 "symbol_ref_operand" "s")) -+ (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") -+ (set_attr "length" "4")]) -+ -+(define_insn "*return_and_restore_gpregs_" -+ [(match_parallel 0 "any_parallel_operand" -+ [(return) -+ (clobber (match_operand:P 1 "register_operand" "=l")) -+ (use (match_operand:P 2 "symbol_ref_operand" "s")) -+ (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") -+ (set_attr "length" "4")]) -+ - (define_insn "*return_and_restore_fpregs_" - [(match_parallel 0 "any_parallel_operand" - [(return) -- (use (reg:P 65)) -- (use (match_operand:P 1 "call_operand" "s")) -- (set (match_operand:DF 2 "gpc_reg_operand" "=f") -- (match_operand:DF 3 "memory_operand" "m"))])] -+ (clobber (match_operand:P 1 "register_operand" "=l")) -+ (use (match_operand:P 2 "symbol_ref_operand" "s")) -+ (use (reg:P 11)) -+ (set (match_operand:DF 3 "gpc_reg_operand" "=f") -+ (match_operand:DF 4 "memory_operand" "m"))])] - "" -- "b %z1") -+ "b %z2" -+ [(set_attr "type" "branch") -+ (set_attr "length" "4")]) - - ; This is used in compiling the unwind routines. - (define_expand "eh_return" -@@ -14617,6 +14660,120 @@ - }" - [(set_attr "type" "load")]) - -+;;; 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; -+ } -+}") -+ - - (include "sync.md") - (include "altivec.md") ---- a/gcc/config/rs6000/rs6000.opt -+++ b/gcc/config/rs6000/rs6000.opt -@@ -190,7 +190,7 @@ Target RejectNegative Joined - -mvrsave=yes/no Deprecated option. Use -mvrsave/-mno-vrsave instead - - misel --Target Var(rs6000_isel) -+Target - Generate isel instructions - - misel= -@@ -198,7 +198,7 @@ Target RejectNegative Joined - -misel=yes/no Deprecated option. Use -misel/-mno-isel instead - - mspe --Target Var(rs6000_spe) -+Target - Generate SPE SIMD instructions on E500 - - mpaired ---- a/gcc/config/rs6000/sol-ci.asm -+++ b/gcc/config/rs6000/sol-ci.asm -@@ -36,7 +36,6 @@ - # This file just supplies labeled starting points for the .got* and other - # special sections. It is linked in first before other modules. - -- .file "scrti.s" - .ident "GNU C scrti.s" - - #ifndef __powerpc64__ ---- a/gcc/config/rs6000/sol-cn.asm -+++ b/gcc/config/rs6000/sol-cn.asm -@@ -36,7 +36,6 @@ - # This file just supplies labeled ending points for the .got* and other - # special sections. It is linked in last after other modules. - -- .file "scrtn.s" - .ident "GNU C scrtn.s" - - #ifndef __powerpc64__ ---- 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"))) -@@ -2933,7 +2933,8 @@ - [(compare:CCFP (match_operand:SF 1 "gpc_reg_operand" "r") - (match_operand:SF 2 "gpc_reg_operand" "r"))] - 1000))] -- "TARGET_HARD_FLOAT && !TARGET_FPRS && !flag_unsafe_math_optimizations" -+ "TARGET_HARD_FLOAT && !TARGET_FPRS -+ && !(flag_finite_math_only && !flag_trapping_math)" - "efscmpeq %0,%1,%2" - [(set_attr "type" "veccmp")]) - -@@ -2943,7 +2944,8 @@ - [(compare:CCFP (match_operand:SF 1 "gpc_reg_operand" "r") - (match_operand:SF 2 "gpc_reg_operand" "r"))] - 1001))] -- "TARGET_HARD_FLOAT && !TARGET_FPRS && flag_unsafe_math_optimizations" -+ "TARGET_HARD_FLOAT && !TARGET_FPRS -+ && flag_finite_math_only && !flag_trapping_math" - "efststeq %0,%1,%2" - [(set_attr "type" "veccmpsimple")]) - -@@ -2953,7 +2955,8 @@ - [(compare:CCFP (match_operand:SF 1 "gpc_reg_operand" "r") - (match_operand:SF 2 "gpc_reg_operand" "r"))] - 1002))] -- "TARGET_HARD_FLOAT && !TARGET_FPRS && !flag_unsafe_math_optimizations" -+ "TARGET_HARD_FLOAT && !TARGET_FPRS -+ && !(flag_finite_math_only && !flag_trapping_math)" - "efscmpgt %0,%1,%2" - [(set_attr "type" "veccmp")]) - -@@ -2963,7 +2966,8 @@ - [(compare:CCFP (match_operand:SF 1 "gpc_reg_operand" "r") - (match_operand:SF 2 "gpc_reg_operand" "r"))] - 1003))] -- "TARGET_HARD_FLOAT && !TARGET_FPRS && flag_unsafe_math_optimizations" -+ "TARGET_HARD_FLOAT && !TARGET_FPRS -+ && flag_finite_math_only && !flag_trapping_math" - "efststgt %0,%1,%2" - [(set_attr "type" "veccmpsimple")]) - -@@ -2973,7 +2977,8 @@ - [(compare:CCFP (match_operand:SF 1 "gpc_reg_operand" "r") - (match_operand:SF 2 "gpc_reg_operand" "r"))] - 1004))] -- "TARGET_HARD_FLOAT && !TARGET_FPRS && !flag_unsafe_math_optimizations" -+ "TARGET_HARD_FLOAT && !TARGET_FPRS -+ && !(flag_finite_math_only && !flag_trapping_math)" - "efscmplt %0,%1,%2" - [(set_attr "type" "veccmp")]) - -@@ -2983,7 +2988,8 @@ - [(compare:CCFP (match_operand:SF 1 "gpc_reg_operand" "r") - (match_operand:SF 2 "gpc_reg_operand" "r"))] - 1005))] -- "TARGET_HARD_FLOAT && !TARGET_FPRS && flag_unsafe_math_optimizations" -+ "TARGET_HARD_FLOAT && !TARGET_FPRS -+ && flag_finite_math_only && !flag_trapping_math" - "efststlt %0,%1,%2" - [(set_attr "type" "veccmpsimple")]) - -@@ -2995,7 +3001,8 @@ - [(compare:CCFP (match_operand:DF 1 "gpc_reg_operand" "r") - (match_operand:DF 2 "gpc_reg_operand" "r"))] - CMPDFEQ_GPR))] -- "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && !flag_unsafe_math_optimizations" -+ "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE -+ && !(flag_finite_math_only && !flag_trapping_math)" - "efdcmpeq %0,%1,%2" - [(set_attr "type" "veccmp")]) - -@@ -3005,7 +3012,8 @@ - [(compare:CCFP (match_operand:DF 1 "gpc_reg_operand" "r") - (match_operand:DF 2 "gpc_reg_operand" "r"))] - TSTDFEQ_GPR))] -- "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && flag_unsafe_math_optimizations" -+ "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE -+ && flag_finite_math_only && !flag_trapping_math" - "efdtsteq %0,%1,%2" - [(set_attr "type" "veccmpsimple")]) - -@@ -3015,7 +3023,8 @@ - [(compare:CCFP (match_operand:DF 1 "gpc_reg_operand" "r") - (match_operand:DF 2 "gpc_reg_operand" "r"))] - CMPDFGT_GPR))] -- "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && !flag_unsafe_math_optimizations" -+ "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE -+ && !(flag_finite_math_only && !flag_trapping_math)" - "efdcmpgt %0,%1,%2" - [(set_attr "type" "veccmp")]) - -@@ -3025,7 +3034,8 @@ - [(compare:CCFP (match_operand:DF 1 "gpc_reg_operand" "r") - (match_operand:DF 2 "gpc_reg_operand" "r"))] - TSTDFGT_GPR))] -- "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && flag_unsafe_math_optimizations" -+ "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE -+ && flag_finite_math_only && !flag_trapping_math" - "efdtstgt %0,%1,%2" - [(set_attr "type" "veccmpsimple")]) - -@@ -3035,7 +3045,8 @@ - [(compare:CCFP (match_operand:DF 1 "gpc_reg_operand" "r") - (match_operand:DF 2 "gpc_reg_operand" "r"))] - CMPDFLT_GPR))] -- "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && !flag_unsafe_math_optimizations" -+ "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE -+ && !(flag_finite_math_only && !flag_trapping_math)" - "efdcmplt %0,%1,%2" - [(set_attr "type" "veccmp")]) - -@@ -3045,7 +3056,8 @@ - [(compare:CCFP (match_operand:DF 1 "gpc_reg_operand" "r") - (match_operand:DF 2 "gpc_reg_operand" "r"))] - TSTDFLT_GPR))] -- "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && flag_unsafe_math_optimizations" -+ "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE -+ && flag_finite_math_only && !flag_trapping_math" - "efdtstlt %0,%1,%2" - [(set_attr "type" "veccmpsimple")]) - -@@ -3059,7 +3071,7 @@ - CMPTFEQ_GPR))] - "!TARGET_IEEEQUAD - && TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && TARGET_LONG_DOUBLE_128 -- && !flag_unsafe_math_optimizations" -+ && !(flag_finite_math_only && !flag_trapping_math)" - "efdcmpeq %0,%1,%2\;bng %0,$+8\;efdcmpeq %0,%L1,%L2" - [(set_attr "type" "veccmp") - (set_attr "length" "12")]) -@@ -3072,7 +3084,7 @@ - TSTTFEQ_GPR))] - "!TARGET_IEEEQUAD - && TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && TARGET_LONG_DOUBLE_128 -- && flag_unsafe_math_optimizations" -+ && flag_finite_math_only && !flag_trapping_math" - "efdtsteq %0,%1,%2\;bng %0,$+8\;efdtsteq %0,%L1,%L2" - [(set_attr "type" "veccmpsimple") - (set_attr "length" "12")]) -@@ -3085,7 +3097,7 @@ - CMPTFGT_GPR))] - "!TARGET_IEEEQUAD - && TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && TARGET_LONG_DOUBLE_128 -- && !flag_unsafe_math_optimizations" -+ && !(flag_finite_math_only && !flag_trapping_math)" - "efdcmpgt %0,%1,%2\;bgt %0,$+16\;efdcmpeq %0,%1,%2\;bng %0,$+8\;efdcmpgt %0,%L1,%L2" - [(set_attr "type" "veccmp") - (set_attr "length" "20")]) -@@ -3098,7 +3110,7 @@ - TSTTFGT_GPR))] - "!TARGET_IEEEQUAD - && TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && TARGET_LONG_DOUBLE_128 -- && flag_unsafe_math_optimizations" -+ && flag_finite_math_only && !flag_trapping_math" - "efdtstgt %0,%1,%2\;bgt %0,$+16\;efdtsteq %0,%1,%2\;bng %0,$+8\;efdtstgt %0,%L1,%L2" - [(set_attr "type" "veccmpsimple") - (set_attr "length" "20")]) -@@ -3111,7 +3123,7 @@ - CMPTFLT_GPR))] - "!TARGET_IEEEQUAD - && TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && TARGET_LONG_DOUBLE_128 -- && !flag_unsafe_math_optimizations" -+ && !(flag_finite_math_only && !flag_trapping_math)" - "efdcmplt %0,%1,%2\;bgt %0,$+16\;efdcmpeq %0,%1,%2\;bng %0,$+8\;efdcmplt %0,%L1,%L2" - [(set_attr "type" "veccmp") - (set_attr "length" "20")]) -@@ -3124,7 +3136,7 @@ - TSTTFLT_GPR))] - "!TARGET_IEEEQUAD - && TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && TARGET_LONG_DOUBLE_128 -- && flag_unsafe_math_optimizations" -+ && flag_finite_math_only && !flag_trapping_math" - "efdtstlt %0,%1,%2\;bgt %0,$+16\;efdtsteq %0,%1,%2\;bng %0,$+8\;efdtstlt %0,%L1,%L2" - [(set_attr "type" "veccmpsimple") - (set_attr "length" "20")]) -@@ -3135,6 +3147,44 @@ - (unspec:CCFP [(match_operand 1 "cc_reg_operand" "y") - (match_operand 2 "cc_reg_operand" "y")] - E500_CR_IOR_COMPARE))] -- "TARGET_E500" -+ "TARGET_HARD_FLOAT && !TARGET_FPRS" - "cror 4*%0+gt,4*%1+gt,4*%2+gt" - [(set_attr "type" "cr_logical")]) -+ -+;; Out-of-line prologues and epilogues. -+(define_insn "*save_gpregs_spe" -+ [(match_parallel 0 "any_parallel_operand" -+ [(clobber (reg:P 65)) -+ (use (match_operand:P 1 "symbol_ref_operand" "s")) -+ (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") -+ (set_attr "length" "4")]) -+ -+(define_insn "*restore_gpregs_spe" -+ [(match_parallel 0 "any_parallel_operand" -+ [(clobber (reg:P 65)) -+ (use (match_operand:P 1 "symbol_ref_operand" "s")) -+ (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") -+ (set_attr "length" "4")]) -+ -+(define_insn "*return_and_restore_gpregs_spe" -+ [(match_parallel 0 "any_parallel_operand" -+ [(return) -+ (clobber (reg:P 65)) -+ (use (match_operand:P 1 "symbol_ref_operand" "s")) -+ (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") -+ (set_attr "length" "4")]) ---- a/gcc/config/rs6000/sysv4.h -+++ b/gcc/config/rs6000/sysv4.h -@@ -266,19 +266,27 @@ do { \ - #endif - - /* Define cutoff for using external functions to save floating point. -- Currently on V.4, always use inline stores. */ --#define FP_SAVE_INLINE(FIRST_REG) ((FIRST_REG) < 64) -+ Currently on 64-bit V.4, always use inline stores. When optimizing -+ for size on 32-bit targets, use external functions when -+ profitable. */ -+#define FP_SAVE_INLINE(FIRST_REG) (optimize_size && !TARGET_64BIT \ -+ ? ((FIRST_REG) == 62 \ -+ || (FIRST_REG) == 63) \ -+ : (FIRST_REG) < 64) -+/* And similarly for general purpose registers. */ -+#define GP_SAVE_INLINE(FIRST_REG) ((FIRST_REG) < 32 \ -+ && (TARGET_64BIT || !optimize_size)) - - /* Put jump tables in read-only memory, rather than in .text. */ - #define JUMP_TABLES_IN_TEXT_SECTION 0 - - /* Prefix and suffix to use to saving floating point. */ - #define SAVE_FP_PREFIX "_savefpr_" --#define SAVE_FP_SUFFIX "_l" -+#define SAVE_FP_SUFFIX (TARGET_64BIT ? "_l" : "") - - /* Prefix and suffix to use to restoring floating point. */ - #define RESTORE_FP_PREFIX "_restfpr_" --#define RESTORE_FP_SUFFIX "_l" -+#define RESTORE_FP_SUFFIX (TARGET_64BIT ? "_l" : "") - - /* Type used for ptrdiff_t, as a string used in a declaration. */ - #define PTRDIFF_TYPE "int" -@@ -577,9 +585,9 @@ extern int fixuplabelno; - /* Override svr4.h definition. */ - #undef ASM_SPEC - #define ASM_SPEC "%(asm_cpu) \ --%{,assembler|,assembler-with-cpp: %{mregnames} %{mno-regnames}} \ --%{v:-V} %{Qy:} %{!Qn:-Qy} %{n} %{T} %{Ym,*} %{Yd,*} %{Wa,*:%*} \ --%{mrelocatable} %{mrelocatable-lib} %{fpic|fpie|fPIC|fPIE:-K PIC} \ -+%{,assembler|,assembler-with-cpp: %{mregnames} %{mno-regnames}}" \ -+SVR4_ASM_SPEC \ -+"%{mrelocatable} %{mrelocatable-lib} %{fpic|fpie|fPIC|fPIE:-K PIC} \ - %{memb|msdata|msdata=eabi: -memb} \ - %{mlittle|mlittle-endian:-mlittle; \ - mbig|mbig-endian :-mbig; \ -@@ -606,6 +614,9 @@ extern int fixuplabelno; - #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); \ -@@ -630,7 +641,7 @@ extern int fixuplabelno; - %{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, for cross compilers. */ - #ifndef CROSS_DIRECTORY_STRUCTURE -@@ -777,19 +788,19 @@ extern int fixuplabelno; - /* Override svr4.h definition. */ - #undef ENDFILE_SPEC - #define ENDFILE_SPEC "\ --%{mads : crtsavres.o%s %(endfile_ads) ; \ -- myellowknife : crtsavres.o%s %(endfile_yellowknife) ; \ -- mmvme : crtsavres.o%s %(endfile_mvme) ; \ -- msim : crtsavres.o%s %(endfile_sim) ; \ -+%{mads : %(endfile_ads) ; \ -+ myellowknife : %(endfile_yellowknife) ; \ -+ mmvme : %(endfile_mvme) ; \ -+ msim : %(endfile_sim) ; \ - mwindiss : %(endfile_windiss) ; \ -- mcall-freebsd: crtsavres.o%s %(endfile_freebsd) ; \ -- mcall-linux : crtsavres.o%s %(endfile_linux) ; \ -- mcall-gnu : crtsavres.o%s %(endfile_gnu) ; \ -- mcall-netbsd : crtsavres.o%s %(endfile_netbsd) ; \ -- mcall-openbsd: crtsavres.o%s %(endfile_openbsd) ; \ -+ mcall-freebsd: %(endfile_freebsd) ; \ -+ mcall-linux : %(endfile_linux) ; \ -+ mcall-gnu : %(endfile_gnu) ; \ -+ mcall-netbsd : %(endfile_netbsd) ; \ -+ mcall-openbsd: %(endfile_openbsd) ; \ - : %(crtsavres_default) %(endfile_default) }" - --#define CRTSAVRES_DEFAULT_SPEC "crtsavres.o%s" -+#define CRTSAVRES_DEFAULT_SPEC "" - - #define ENDFILE_DEFAULT_SPEC "crtend.o%s ecrtn.o%s" - -@@ -833,15 +844,15 @@ extern int fixuplabelno; - #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-cs-eabi -@@ -0,0 +1,17 @@ -+# Multilibs for powerpc embedded ELF targets. -+ -+MULTILIB_OPTIONS = te500v1/te500v2/te600/te500mc \ -+ msoft-float -+ -+MULTILIB_DIRNAMES = te500v1 te500v2 te600 te500mc \ -+ nof -+ -+MULTILIB_EXCEPTIONS = *te600*/*msoft-float* \ -+ *te500v1*/*msoft-float* \ -+ *te500v2*/*msoft-float* \ -+ *te500mc*/*msoft-float* -+ -+MULTILIB_EXTRA_OPTS = mno-eabi mstrict-align -+ -+MULTILIB_MATCHES = ${MULTILIB_MATCHES_FLOAT} \ -+ ${MULTILIB_MATCHES_ENDIAN} ---- /dev/null -+++ b/gcc/config/rs6000/t-linux -@@ -0,0 +1,12 @@ -+# Multilibs for powerpc-linux-gnu targets. -+ -+MULTILIB_OPTIONS = te500v1/te500v2/te600/te500mc \ -+ msoft-float -+ -+MULTILIB_DIRNAMES = te500v1 te500v2 te600 te500mc \ -+ nof -+ -+MULTILIB_EXCEPTIONS = *te600*/*msoft-float* \ -+ *te500v1*/*msoft-float* \ -+ *te500v2*/*msoft-float* \ -+ *te500mc*/*msoft-float* ---- /dev/null -+++ b/gcc/config/rs6000/t-montavista-linux -@@ -0,0 +1,26 @@ -+# MontaVista GNU/Linux Configuration. -+# 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 -+# . -+ -+# Build hard-float, soft-float, E500mc, E500v2 and E600 -+# libraries. -+MULTILIB_OPTIONS = msoft-float/te500mc/te500v2/te600 -+MULTILIB_DIRNAMES = soft-float te500mc te500v2 te600 -+MULTILIB_EXCEPTIONS = -+MULTILIB_OSDIRNAMES = msoft-float=!soft-float ---- a/gcc/config/rs6000/t-netbsd -+++ b/gcc/config/rs6000/t-netbsd -@@ -2,13 +2,32 @@ - - LIB2FUNCS_EXTRA = tramp.S - -+LIB2FUNCS_STATIC_EXTRA = crtsavfpr.S crtresfpr.S \ -+ crtsavgpr.S crtresgpr.S \ -+ crtresxfpr.S crtresxgpr.S -+ - tramp.S: $(srcdir)/config/rs6000/tramp.asm - cat $(srcdir)/config/rs6000/tramp.asm > tramp.S - --crtsavres.S: $(srcdir)/config/rs6000/crtsavres.asm -- cat $(srcdir)/config/rs6000/crtsavres.asm >crtsavres.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 - --EXTRA_PARTS += crtsavres$(objext) -+EXTRA_PARTS += libcrtsavres.a - - # It is important that crtbegin.o, etc., aren't surprised by stuff in .sdata. - CRTSTUFF_T_CFLAGS += -msdata=none -@@ -37,6 +56,20 @@ EXTRA_MULTILIB_PARTS = crtbegin$(objext) - crtbeginS$(objext) crtendS$(objext) crtbeginT$(objext) \ - crtsavres$(objext) - --$(T)crtsavres$(objext): crtsavres.S -- $(GCC_FOR_TARGET) $(CRTSTUFF_CFLAGS) $(CRTSTUFF_T_CFLAGS) \ -- -c crtsavres.S -o $(T)crtsavres$(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) ---- /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 -@@ -2,11 +2,24 @@ - - LIB2FUNCS_EXTRA += tramp.S $(srcdir)/config/rs6000/darwin-ldouble.c - --# This one 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 -+# These can't end up in shared libgcc -+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 -@@ -18,8 +31,7 @@ MULTILIB_MATCHES_SYSV = mcall-sysv=mcall - EXTRA_MULTILIB_PARTS = crtbegin$(objext) crtend$(objext) \ - crtbeginS$(objext) crtendS$(objext) crtbeginT$(objext) \ - ecrti$(objext) ecrtn$(objext) \ -- ncrti$(objext) ncrtn$(objext) \ -- crtsavres$(objext) -+ ncrti$(objext) ncrtn$(objext) - - # We build {e,n}crti.o and {e,n}crtn.o, which serve to add begin and - # end labels to all of the special sections used when we link using gcc. -@@ -37,8 +49,62 @@ ncrti.S: $(srcdir)/config/rs6000/sol-ci. - ncrtn.S: $(srcdir)/config/rs6000/sol-cn.asm - cat $(srcdir)/config/rs6000/sol-cn.asm >ncrtn.S - --crtsavres.S: $(srcdir)/config/rs6000/crtsavres.asm -- cat $(srcdir)/config/rs6000/crtsavres.asm >crtsavres.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 -@@ -53,8 +119,62 @@ $(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)crtsavres$(objext): crtsavres.S -- $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c crtsavres.S -o $(T)crtsavres$(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 ---- a/gcc/config/rs6000/t-ppcgas -+++ b/gcc/config/rs6000/t-ppcgas -@@ -1,14 +1,16 @@ - # Multilibs for powerpc embedded ELF targets. - --MULTILIB_OPTIONS = msoft-float \ -- mlittle/mbig \ -- fleading-underscore -+MULTILIB_OPTIONS = te500v1/te500v2/te600 \ -+ msoft-float - --MULTILIB_DIRNAMES = nof \ -- le be \ -- und -+MULTILIB_DIRNAMES = te500v1 te500v2 te600 \ -+ nof - --MULTILIB_EXTRA_OPTS = mrelocatable-lib mno-eabi mstrict-align -+MULTILIB_EXCEPTIONS = *te600*/*msoft-float* \ -+ *te500v1*/*msoft-float* \ -+ *te500v2*/*msoft-float* -+ -+MULTILIB_EXTRA_OPTS = mno-eabi mstrict-align - - MULTILIB_MATCHES = ${MULTILIB_MATCHES_FLOAT} \ - ${MULTILIB_MATCHES_ENDIAN} ---- /dev/null -+++ b/gcc/config/rs6000/t-timesys -@@ -0,0 +1,17 @@ -+# Overrides for timesys -+ -+# We want to build six multilibs: -+# . (default, -mcpu=740) -+# 4xx (-mcpu=405) -+# 44x (-mcpu=440) -+# 8xx (-mcpu=801) -+# 85xx (-te500v1) -+# 74xx (-te600) -+ -+MULTILIB_OPTIONS = mcpu=405/mcpu=440/mcpu=801/te500v1/te600 -+ -+MULTILIB_DIRNAMES = 4xx 44x 8xx 85xx 74xx -+ -+MULTILIB_MATCHES = -+ -+MULTILIB_EXCEPTIONS = ---- /dev/null -+++ b/gcc/config/rs6000/t-wrs-linux -@@ -0,0 +1,30 @@ -+# Wind River GNU/Linux Configuration. -+# Copyright (C) 2006, 2007 -+# 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 -+# . -+ -+# Build hard-float (32-bit and 64-bit), soft-float, E500v1 and E500v2 -+# libraries. -+MULTILIB_OPTIONS = muclibc m64 msoft-float te500v1 te500v2 -+MULTILIB_DIRNAMES = uclibc 64 soft-float te500v1 te500v2 -+MULTILIB_EXCEPTIONS = *muclibc*/*m64* *muclibc*/*msoft-float* -+MULTILIB_EXCEPTIONS += *muclibc*/*te500v1* *muclibc*/*te500v2* -+MULTILIB_EXCEPTIONS += *m64*/*msoft-float* *m64*/*te500v1* *m64*/*te500v2* -+MULTILIB_EXCEPTIONS += *msoft-float*/*te500v1* *msoft-float*/*te500v2* -+MULTILIB_EXCEPTIONS += *te500v1*/*te500v2* -+MULTILIB_OSDIRNAMES = muclibc=!uclibc m64=../lib64 msoft-float=!soft-float ---- /dev/null -+++ b/gcc/config/rs6000/timesys-linux.h -@@ -0,0 +1,41 @@ -+/* Configuration file for timesys ARM GNU/Linux EABI targets. -+ Copyright (C) 2007 -+ Free Software Foundation, Inc. -+ Contributed 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 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 -+ . */ -+ -+/* Add -t flags for convenience in generating multilibs. */ -+#undef CC1_EXTRA_SPEC -+#define CC1_EXTRA_SPEC \ -+ "%{te500v1: -mcpu=8540 -mfloat-gprs=single -mspe=yes -mabi=spe} " \ -+ "%{te600: -mcpu=7400 -maltivec -mabi=altivec} " -+ -+#undef ASM_DEFAULT_SPEC -+#define ASM_DEFAULT_SPEC \ -+ "%{te500v1:-mppc -mspe -me500 ; \ -+ te600:-mppc -maltivec ; \ -+ mcpu=405:-m405 ; \ -+ mcpu=440:-m440 ; \ -+ :-mppc%{m64:64}}" -+ -+ -+/* FIXME:We should be dynamically creating this from the makefile. -+ See m68k for an example. */ -+#undef SYSROOT_SUFFIX_SPEC -+#define SYSROOT_SUFFIX_SPEC \ -+ "%{mcpu=405:/4xx ; mcpu=440:/44x ; mcpu=801:/8xx ; te500v1:/85xx ; te600:/74xx}" ---- /dev/null -+++ b/gcc/config/rs6000/wrs-linux.h -@@ -0,0 +1,44 @@ -+/* Wind River GNU/Linux Configuration. -+ Copyright (C) 2006, 2007 -+ 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 -+. */ -+ -+/* 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}" -+ -+#undef ASM_DEFAULT_SPEC -+#define ASM_DEFAULT_SPEC \ -+ "%{te500v1:-mppc -mspe -me500 ; \ -+ te500v2:-mppc -mspe -me500 ; \ -+ :-mppc%{m64:64}}" -+ -+/* The GLIBC headers are in /usr/include, relative to the sysroot; the -+ uClibc headers are in /uclibc/usr/include. */ -+#undef SYSROOT_HEADERS_SUFFIX_SPEC -+#define SYSROOT_HEADERS_SUFFIX_SPEC \ -+ "%{muclibc:/uclibc}" -+ -+/* The various C libraries each have their own subdirectory. */ -+#undef SYSROOT_SUFFIX_SPEC -+#define SYSROOT_SUFFIX_SPEC \ -+ "%{muclibc:/uclibc ; \ -+ msoft-float:/soft-float ; \ -+ te500v1:/te500v1 ; \ -+ te500v2:/te500v2}" ---- /dev/null -+++ b/gcc/config/sh/cs-sgxxlite-linux.h -@@ -0,0 +1,23 @@ -+/* SH SourceryG++ GNU/Linux Configuration. -+ Copyright (C) 2008 -+ 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 -+. */ -+ -+#undef SYSROOT_HEADERS_SUFFIX_SPEC -+#define SYSROOT_HEADERS_SUFFIX_SPEC \ -+ "%{muclibc:/uclibc}" ---- a/gcc/config/sh/lib1funcs.asm -+++ b/gcc/config/sh/lib1funcs.asm -@@ -2084,8 +2084,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 ---- a/gcc/config/sh/linux-unwind.h -+++ b/gcc/config/sh/linux-unwind.h -@@ -27,7 +27,10 @@ the Free Software Foundation, 51 Frankli - Boston, MA 02110-1301, USA. */ - - /* 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 - #include -@@ -251,3 +254,5 @@ sh_fallback_frame_state (struct _Unwind_ - return _URC_NO_REASON; - } - #endif /* defined (__SH5__) */ -+ -+#endif /* inhibit_libc */ ---- 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/ ---- /dev/null -+++ b/gcc/config/sh/t-sgxxlite-linux -@@ -0,0 +1,3 @@ -+MULTILIB_OPTIONS += muclibc -+MULTILIB_OSDIRNAMES += muclibc=!uclibc m4al/muclibc=!m4al/uclibc mb/muclibc=!mb/uclibc -+MULTILIB_EXCEPTIONS += mb/m4al/muclibc ---- 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 -@@ -49,10 +49,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 - - #undef ASM_CPU_DEFAULT_SPEC - #define ASM_CPU_DEFAULT_SPEC "-Av9a" -@@ -167,7 +172,7 @@ along with GCC; see the file COPYING3. - { "link_arch_default", LINK_ARCH_DEFAULT_SPEC }, \ - { "link_arch", LINK_ARCH_SPEC }, - --#define LINK_ARCH32_SPEC "-m elf32_sparc -Y P,/usr/lib %{shared:-shared} \ -+#define LINK_ARCH32_SPEC "-m elf32_sparc -Y P,%R/usr/lib %{shared:-shared} \ - %{!shared: \ - %{!ibcs: \ - %{!static: \ -@@ -176,7 +181,7 @@ along with GCC; see the file COPYING3. - %{static:-static}}} \ - " - --#define LINK_ARCH64_SPEC "-m elf64_sparc -Y P,/usr/lib64 %{shared:-shared} \ -+#define LINK_ARCH64_SPEC "-m elf64_sparc -Y P,%R/usr/lib64 %{shared:-shared} \ - %{!shared: \ - %{!ibcs: \ - %{!static: \ -@@ -257,7 +262,7 @@ along with GCC; see the file COPYING3. - #else /* !SPARC_BI_ARCH */ - - #undef LINK_SPEC --#define LINK_SPEC "-m elf64_sparc -Y P,/usr/lib64 %{shared:-shared} \ -+#define LINK_SPEC "-m elf64_sparc -Y P,%R/usr/lib64 %{shared:-shared} \ - %{!shared: \ - %{!ibcs: \ - %{!static: \ ---- 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 -@@ -2371,6 +2371,8 @@ emit_soft_tfmode_cvt (enum rtx_code code - { - case SImode: - func = "_Qp_itoq"; -+ if (TARGET_ARCH64) -+ operands[1] = gen_rtx_SIGN_EXTEND (DImode, operands[1]); - break; - case DImode: - func = "_Qp_xtoq"; -@@ -2385,6 +2387,8 @@ emit_soft_tfmode_cvt (enum rtx_code code - { - case SImode: - func = "_Qp_uitoq"; -+ if (TARGET_ARCH64) -+ operands[1] = gen_rtx_ZERO_EXTEND (DImode, operands[1]); - break; - case DImode: - func = "_Qp_uxtoq"; -@@ -4623,6 +4627,7 @@ function_arg_slotno (const struct sparc_ - { - case MODE_FLOAT: - case MODE_COMPLEX_FLOAT: -+ case MODE_VECTOR_INT: - if (TARGET_ARCH64 && TARGET_FPU && named) - { - if (slotno >= SPARC_FP_ARG_MAX) -@@ -6097,7 +6102,7 @@ void - 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; - - switch (comparison) -@@ -6159,7 +6164,8 @@ sparc_emit_float_lib_cmp (rtx x, rtx y, - else - 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); -@@ -6168,7 +6174,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); - -@@ -6180,7 +6187,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/svr4.h -+++ b/gcc/config/svr4.h -@@ -55,7 +55,8 @@ along with GCC; see the file COPYING3. - && strcmp (STR, "Tdata") && strcmp (STR, "Ttext") \ - && strcmp (STR, "Tbss")) - --/* Provide an ASM_SPEC appropriate for svr4. Here we try to support as -+/* Provide an ASM_SPEC appropriate for svr4. -+ If we're not using GAS, we try to support as - many of the specialized svr4 assembler options as seems reasonable, - given that there are certain options which we can't (or shouldn't) - support directly due to the fact that they conflict with other options -@@ -74,9 +75,16 @@ along with GCC; see the file COPYING3. - read its stdin. - */ - --#undef ASM_SPEC --#define ASM_SPEC \ -+#ifdef USE_GAS -+#define SVR4_ASM_SPEC \ -+ "%{v:-V} %{Wa,*:%*}" -+#else -+#define SVR4_ASM_SPEC \ - "%{v:-V} %{Qy:} %{!Qn:-Qy} %{n} %{T} %{Ym,*} %{Yd,*} %{Wa,*:%*}" -+#endif -+ -+#undef ASM_SPEC -+#define ASM_SPEC SVR4_ASM_SPEC - - #define AS_NEEDS_DASH_FOR_PIPED_INPUT - ---- /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])) -+ ---- /dev/null -+++ b/gcc/config/t-sysroot-suffix -@@ -0,0 +1,6 @@ -+# Generate SYSROOT_SUFFIX_SPEC from MULTILIB_OSDIRNAMES -+ -+sysroot-suffix.h: $(srcdir)/config/print-sysroot-suffix.sh -+ $(SHELL) $(srcdir)/config/print-sysroot-suffix.sh \ -+ "$(MULTILIB_OSDIRNAMES)" "$(MULTILIB_OPTIONS)" \ -+ "$(MULTILIB_MATCHES)" "$(MULTILIB_ALIASES)" > $@ ---- a/gcc/configure -+++ b/gcc/configure -@@ -458,7 +458,7 @@ ac_includes_default="\ - # include - #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 NO_MINUS_C_MINUS_O OUTPUT_OPTION CPP EGREP loose_warn cxx_compat_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 host_cc_for_libada CROSS ALL SYSTEM_HEADER_DIR inhibit_libc CC_FOR_BUILD BUILD_CFLAGS STMP_FIXINC STMP_FIXPROTO collect2 LIBTOOL SED FGREP GREP LD DUMPBIN ac_ct_DUMPBIN ac_ct_AR STRIP ac_ct_STRIP lt_ECHO 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 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 target_cpu_default GMPLIBS GMPINC 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 licensedir build_libsubdir build_subdir host_subdir target_subdir GENINSRC CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT NO_MINUS_C_MINUS_O OUTPUT_OPTION CPP EGREP loose_warn cxx_compat_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 CONFIGURE_SPECS EGLIBC_CONFIGS 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 host_cc_for_libada CROSS ALL SYSTEM_HEADER_DIR inhibit_libc CC_FOR_BUILD BUILD_CFLAGS STMP_FIXINC STMP_FIXPROTO collect2 LIBTOOL SED FGREP GREP LD DUMPBIN ac_ct_DUMPBIN ac_ct_AR STRIP ac_ct_STRIP lt_ECHO 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 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_CPU_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 target_cpu_default GMPLIBS GMPINC LIBOBJS LTLIBOBJS' - ac_subst_files='language_hooks' - - # Initialize some variables set by options. -@@ -1048,6 +1048,7 @@ Optional Features: - arrange to use setjmp/longjmp exception handling - --enable-secureplt enable -msecure-plt by default for PowerPC - --enable-cld enable -mcld by default for 32bit x86 -+ --enable-mips-nonpic enable non-PIC ABI by default for MIPS GNU/Linux o32 - --disable-win32-registry - disable lookup of installation paths in the - Registry on Windows hosts -@@ -1068,6 +1069,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] -@@ -1089,6 +1092,9 @@ 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-specs=SPECS add SPECS to driver command-line processing -+ --with-eglibc-configs=CONFIGS -+ build multilibs for these EGLIBC configurations - --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-gnu-ld assume the C compiler uses GNU ld default=no -@@ -7367,6 +7373,28 @@ 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; -+ -+ -+ -+# 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; -+ -+ - # Build with intermodule optimisations - # Check whether --enable-intermodule or --disable-intermodule was given. - if test "${enable_intermodule+set}" = set; then -@@ -12971,7 +12999,7 @@ else - *) realsrcdir=../${srcdir};; - esac - saved_CFLAGS="${CFLAGS}" -- CC="${CC_FOR_BUILD}" CFLAGS="${CFLAGS_FOR_BUILD}" \ -+ CC="${CC_FOR_BUILD}" CFLAGS="${CFLAGS_FOR_BUILD}" LDFLAGS="" \ - ${realsrcdir}/configure \ - --enable-languages=${enable_languages-all} \ - --target=$target_alias --host=$build_alias --build=$build_alias -@@ -13119,6 +13147,12 @@ else - enable_cld=no - fi; - -+# Check whether --enable-mips-nonpic or --disable-mips-nonpic was given. -+if test "${enable_mips_nonpic+set}" = set; then -+ enableval="$enable_mips_nonpic" -+ -+fi; -+ - # Windows32 Registry support for specifying GCC installation paths. - # Check whether --enable-win32-registry or --disable-win32-registry was given. - if test "${enable_win32_registry+set}" = set; then -@@ -14064,13 +14098,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:14067: $ac_compile\"" >&5) -+ (eval echo "\"\$as_me:14173: $ac_compile\"" >&5) - (eval "$ac_compile" 2>conftest.err) - cat conftest.err >&5 -- (eval echo "\"\$as_me:14070: $NM \\\"conftest.$ac_objext\\\"\"" >&5) -+ (eval echo "\"\$as_me:14176: $NM \\\"conftest.$ac_objext\\\"\"" >&5) - (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) - cat conftest.err >&5 -- (eval echo "\"\$as_me:14073: output\"" >&5) -+ (eval echo "\"\$as_me:14179: output\"" >&5) - cat conftest.out >&5 - if $GREP 'External.*some_variable' conftest.out > /dev/null; then - lt_cv_nm_interface="MS dumpbin" -@@ -15125,7 +15159,7 @@ ia64-*-hpux*) - ;; - *-*-irix6*) - # Find out which ABI we are using. -- echo '#line 15128 "configure"' > conftest.$ac_ext -+ echo '#line 15234 "configure"' > conftest.$ac_ext - if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? -@@ -15745,11 +15779,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:15748: $lt_compile\"" >&5) -+ (eval echo "\"\$as_me:15854: $lt_compile\"" >&5) - (eval "$lt_compile" 2>conftest.err) - ac_status=$? - cat conftest.err >&5 -- echo "$as_me:15752: \$? = $ac_status" >&5 -+ echo "$as_me:15858: \$? = $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. -@@ -16067,11 +16101,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:16070: $lt_compile\"" >&5) -+ (eval echo "\"\$as_me:16176: $lt_compile\"" >&5) - (eval "$lt_compile" 2>conftest.err) - ac_status=$? - cat conftest.err >&5 -- echo "$as_me:16074: \$? = $ac_status" >&5 -+ echo "$as_me:16180: \$? = $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. -@@ -16172,11 +16206,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:16175: $lt_compile\"" >&5) -+ (eval echo "\"\$as_me:16281: $lt_compile\"" >&5) - (eval "$lt_compile" 2>out/conftest.err) - ac_status=$? - cat out/conftest.err >&5 -- echo "$as_me:16179: \$? = $ac_status" >&5 -+ echo "$as_me:16285: \$? = $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 -@@ -16227,11 +16261,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:16230: $lt_compile\"" >&5) -+ (eval echo "\"\$as_me:16336: $lt_compile\"" >&5) - (eval "$lt_compile" 2>out/conftest.err) - ac_status=$? - cat out/conftest.err >&5 -- echo "$as_me:16234: \$? = $ac_status" >&5 -+ echo "$as_me:16340: \$? = $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 -@@ -19024,7 +19058,7 @@ else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF --#line 19027 "configure" -+#line 19133 "configure" - #include "confdefs.h" - - #if HAVE_DLFCN_H -@@ -19124,7 +19158,7 @@ else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF --#line 19127 "configure" -+#line 19233 "configure" - #include "confdefs.h" - - #if HAVE_DLFCN_H -@@ -20592,6 +20626,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 -@@ -22098,7 +22148,8 @@ esac - case "$target" in - i?86*-*-* | mips*-*-* | alpha*-*-* | powerpc*-*-* | sparc*-*-* | m68*-*-* \ - | x86_64*-*-* | hppa*-*-* | arm*-*-* | strongarm*-*-* | xscale*-*-* \ -- | xstormy16*-*-* | cris-*-* | xtensa-*-* | bfin-*-* | score*-*-* | spu-*-*) -+ | xstormy16*-*-* | cris-*-* | xtensa-*-* | bfin-*-* | score*-*-* \ -+ | spu-*-* | fido*-*-*) - insn="nop" - ;; - ia64*-*-* | s390*-*-*) -@@ -23088,6 +23139,21 @@ fi - 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 -+ - - # Check whether --with-datarootdir or --without-datarootdir was given. - if test "${with_datarootdir+set}" = set; then -@@ -23175,6 +23241,10 @@ fi; - - - -+ -+ -+ -+ - # Echo link setup. - if test x${build} = x${host} ; then - if test x${host} = x${target} ; then -@@ -23844,6 +23914,7 @@ s,@target_cpu@,$target_cpu,;t t - s,@target_vendor@,$target_vendor,;t t - s,@target_os@,$target_os,;t t - s,@target_noncanonical@,$target_noncanonical,;t t -+s,@licensedir@,$licensedir,;t t - s,@build_libsubdir@,$build_libsubdir,;t t - s,@build_subdir@,$build_subdir,;t t - s,@host_subdir@,$host_subdir,;t t -@@ -23877,6 +23948,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,@CONFIGURE_SPECS@,$CONFIGURE_SPECS,;t t -+s,@EGLIBC_CONFIGS@,$EGLIBC_CONFIGS,;t t - s,@onestep@,$onestep,;t t - s,@PKGVERSION@,$PKGVERSION,;t t - s,@REPORT_BUGS_TO@,$REPORT_BUGS_TO,;t t -@@ -23983,6 +24056,10 @@ 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_CPU_CONFIG@,$TM_CPU_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 -@@ -767,6 +767,22 @@ AC_SUBST(TARGET_SYSTEM_ROOT) - AC_SUBST(TARGET_SYSTEM_ROOT_DEFINE) - AC_SUBST(CROSS_SYSTEM_HEADER_DIR) - -+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) -+ -+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) -+ - # Build with intermodule optimisations - AC_ARG_ENABLE(intermodule, - [ --enable-intermodule build the compiler in one step], -@@ -1479,7 +1495,7 @@ else - *) realsrcdir=../${srcdir};; - esac - saved_CFLAGS="${CFLAGS}" -- CC="${CC_FOR_BUILD}" CFLAGS="${CFLAGS_FOR_BUILD}" \ -+ CC="${CC_FOR_BUILD}" CFLAGS="${CFLAGS_FOR_BUILD}" LDFLAGS="" \ - ${realsrcdir}/configure \ - --enable-languages=${enable_languages-all} \ - --target=$target_alias --host=$build_alias --build=$build_alias -@@ -1552,6 +1568,10 @@ AC_ARG_ENABLE(cld, - [ --enable-cld enable -mcld by default for 32bit x86], [], - [enable_cld=no]) - -+AC_ARG_ENABLE(mips-nonpic, -+[ --enable-mips-nonpic enable non-PIC ABI by default for MIPS GNU/Linux o32], -+[], []) -+ - # Windows32 Registry support for specifying GCC installation paths. - AC_ARG_ENABLE(win32-registry, - [ --disable-win32-registry -@@ -2455,6 +2475,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 -@@ -3077,7 +3113,8 @@ esac - case "$target" in - i?86*-*-* | mips*-*-* | alpha*-*-* | powerpc*-*-* | sparc*-*-* | m68*-*-* \ - | x86_64*-*-* | hppa*-*-* | arm*-*-* | strongarm*-*-* | xscale*-*-* \ -- | xstormy16*-*-* | cris-*-* | xtensa-*-* | bfin-*-* | score*-*-* | spu-*-*) -+ | xstormy16*-*-* | cris-*-* | xtensa-*-* | bfin-*-* | score*-*-* \ -+ | spu-*-* | fido*-*-*) - insn="nop" - ;; - ia64*-*-* | s390*-*-*) -@@ -3731,6 +3768,16 @@ else - fi) - AC_SUBST(slibdir) - -+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 -+ - AC_ARG_WITH(datarootdir, - [ --with-datarootdir=DIR Use DIR as the data root [[PREFIX/share]]], - datarootdir="\${prefix}/$with_datarootdir", -@@ -3768,6 +3815,10 @@ 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_CPU_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 -@@ -6030,7 +6030,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 -@@ -6179,13 +6179,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 -@@ -6237,19 +6232,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/cvt.c -+++ b/gcc/cp/cvt.c -@@ -580,6 +580,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; -@@ -628,6 +629,9 @@ ocp_convert (tree type, tree expr, int c - } - } - -+ if (e1 = targetm.convert_to_type (type, e)) -+ return e1; -+ - if (code == VOID_TYPE && (convtype & CONV_STATIC)) - { - e = convert_to_void (e, /*implicit=*/NULL); -@@ -1190,11 +1194,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 -@@ -4379,7 +4379,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); - } - } - -@@ -7413,6 +7413,7 @@ grokdeclarator (const cp_declarator *dec - bool type_was_error_mark_node = false; - bool parameter_pack_p = declarator? declarator->parameter_pack_p : false; - bool set_no_warning = false; -+ const char *errmsg; - - signed_p = declspecs->specs[(int)ds_signed]; - unsigned_p = declspecs->specs[(int)ds_unsigned]; -@@ -8092,6 +8093,12 @@ grokdeclarator (const cp_declarator *dec - 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; -+ } - - /* Pick up type qualifiers which should be applied to `this'. */ - memfn_quals = declarator->u.function.qualifiers; -@@ -8585,8 +8592,14 @@ 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 (TYPE_NAME (t) == oldname) -+ { -+ debug_hooks->set_name (t, decl); -+ TYPE_NAME (t) = decl; -+ } -+ } -+ - - if (TYPE_LANG_SPECIFIC (type)) - TYPE_WAS_ANONYMOUS (type) = 1; -@@ -9378,6 +9391,7 @@ grokparms (cp_parameter_declarator *firs - tree init = parm->default_argument; - tree attrs; - tree decl; -+ const char *errmsg; - - if (parm == no_parameters) - break; -@@ -9418,6 +9432,14 @@ grokparms (cp_parameter_declarator *firs - 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) - { - /* Top-level qualifiers on the parameters are ---- a/gcc/cp/decl2.c -+++ b/gcc/cp/decl2.c -@@ -1682,6 +1682,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; -@@ -1963,6 +1967,14 @@ determine_visibility (tree decl) - /* tinfo visibility is based on the type it's for. */ - constrain_visibility - (decl, type_visibility (TREE_TYPE (DECL_NAME (decl)))); -+ -+ /* Give the target a chance to override the visibility associated -+ with DECL. */ -+ if (TREE_PUBLIC (decl) -+ && !DECL_REALLY_EXTERN (decl) -+ && CLASS_TYPE_P (TREE_TYPE (DECL_NAME (decl))) -+ && !CLASSTYPE_VISIBILITY_SPECIFIED (TREE_TYPE (DECL_NAME (decl)))) -+ targetm.cxx.determine_class_data_visibility (decl); - } - else if (use_template) - /* Template instantiations and specializations get visibility based ---- a/gcc/cp/mangle.c -+++ b/gcc/cp/mangle.c -@@ -1593,6 +1593,13 @@ write_type (tree type) - if (target_mangling) - { - write_string (target_mangling); -+ /* Add substitutions for types other than fundamental -+ types. */ -+ if (TREE_CODE (type) != VOID_TYPE -+ && TREE_CODE (type) != INTEGER_TYPE -+ && TREE_CODE (type) != REAL_TYPE -+ && TREE_CODE (type) != BOOLEAN_TYPE) -+ add_substitution (type); - return; - } - ---- a/gcc/cp/semantics.c -+++ b/gcc/cp/semantics.c -@@ -3218,8 +3218,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 -@@ -1627,10 +1627,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_ENUMERATION_TYPE_P (TREE_TYPE (exp))) -+ else if (INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (exp))) - exp = perform_integral_promotions (exp); - /* Perform the other conversions. */ - exp = decay_conversion (exp); -@@ -4837,6 +4841,12 @@ build_compound_expr (tree lhs, tree rhs) - 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); - } - -@@ -6814,6 +6824,7 @@ static int - comp_ptr_ttypes_real (tree to, tree from, int constp) - { - bool to_more_cv_qualified = false; -+ bool is_opaque_pointer = false; - - for (; ; to = TREE_TYPE (to), from = TREE_TYPE (from)) - { -@@ -6848,9 +6859,13 @@ comp_ptr_ttypes_real (tree to, tree from - constp &= TYPE_READONLY (to); - } - -+ if (TREE_CODE (to) == VECTOR_TYPE) -+ is_opaque_pointer = vector_targets_convertible_p (to, from); -+ - if (TREE_CODE (to) != POINTER_TYPE && !TYPE_PTRMEM_P (to)) - return ((constp >= 0 || to_more_cv_qualified) -- && same_type_ignoring_top_level_qualifiers_p (to, from)); -+ && (is_opaque_pointer -+ || same_type_ignoring_top_level_qualifiers_p (to, from))); - } - } - -@@ -6911,6 +6926,8 @@ ptr_reasonably_similar (const_tree to, c - bool - comp_ptr_ttypes_const (tree to, tree from) - { -+ bool is_opaque_pointer = false; -+ - for (; ; to = TREE_TYPE (to), from = TREE_TYPE (from)) - { - if (TREE_CODE (to) != TREE_CODE (from)) -@@ -6921,8 +6938,12 @@ comp_ptr_ttypes_const (tree to, tree fro - TYPE_OFFSET_BASETYPE (to))) - continue; - -+ if (TREE_CODE (to) == VECTOR_TYPE) -+ is_opaque_pointer = vector_targets_convertible_p (to, from); -+ - if (TREE_CODE (to) != POINTER_TYPE) -- return same_type_ignoring_top_level_qualifiers_p (to, from); -+ return (is_opaque_pointer -+ || same_type_ignoring_top_level_qualifiers_p (to, from)); - } - } - ---- a/gcc/cse.c -+++ b/gcc/cse.c -@@ -5776,6 +5776,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 -@@ -373,6 +373,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 */ ---- a/gcc/debug.c -+++ b/gcc/debug.c -@@ -49,6 +49,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 */ - }; - ---- a/gcc/debug.h -+++ b/gcc/debug.h -@@ -124,6 +124,8 @@ struct gcc_debug_hooks - text sections. */ - void (* switch_text_section) (void); - -+ 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; ---- a/gcc/doc/extend.texi -+++ b/gcc/doc/extend.texi -@@ -28,10 +28,10 @@ extensions, accepted by GCC in C89 mode - * Local Labels:: Labels local to a block. - * Labels as Values:: Getting pointers to labels, and computed gotos. - * Nested Functions:: As in Algol and Pascal, lexical scoping of functions. --* Constructing Calls:: Dispatching a call to another function. -+* Constructing Calls:: Dispatching a call to another function. - * Typeof:: @code{typeof}: referring to the type of an expression. - * Conditionals:: Omitting the middle operand of a @samp{?:} expression. --* Long Long:: Double-word integers---@code{long long int}. -+* Long Long:: Double-word integers---@code{long long int}. - * Complex:: Data types for complex numbers. - * Floating Types:: Additional Floating Types. - * Decimal Float:: Decimal Floating Types. -@@ -40,41 +40,41 @@ extensions, accepted by GCC in C89 mode - * Zero Length:: Zero-length arrays. - * Variable Length:: Arrays whose length is computed at run time. - * Empty Structures:: Structures with no members. --* Variadic Macros:: Macros with a variable number of arguments. -+* Variadic Macros:: Macros with a variable number of arguments. - * Escaped Newlines:: Slightly looser rules for escaped newlines. - * Subscripting:: Any array can be subscripted, even if not an lvalue. - * Pointer Arith:: Arithmetic on @code{void}-pointers and function pointers. - * Initializers:: Non-constant initializers. - * Compound Literals:: Compound literals give structures, unions -- or arrays as values. --* Designated Inits:: Labeling elements of initializers. -+ or arrays as values. -+* Designated Inits:: Labeling elements of initializers. - * Cast to Union:: Casting to union type from any member of the union. --* Case Ranges:: `case 1 ... 9' and such. --* Mixed Declarations:: Mixing declarations and code. -+* Case Ranges:: `case 1 ... 9' and such. -+* Mixed Declarations:: Mixing declarations and code. - * Function Attributes:: Declaring that functions have no side effects, -- or that they can never return. -+ or that they can never return. - * Attribute Syntax:: Formal syntax for attributes. - * Function Prototypes:: Prototype declarations and old-style definitions. - * C++ Comments:: C++ comments are recognized. - * Dollar Signs:: Dollar sign is allowed in identifiers. - * Character Escapes:: @samp{\e} stands for the character @key{ESC}. --* Variable Attributes:: Specifying attributes of variables. --* Type Attributes:: Specifying attributes of types. -+* Variable Attributes:: Specifying attributes of variables. -+* Type Attributes:: Specifying attributes of types. - * Alignment:: Inquiring about the alignment of a type or variable. - * Inline:: Defining inline functions (as fast as macros). - * Extended Asm:: Assembler instructions with C expressions as operands. -- (With them you can define ``built-in'' functions.) -+ (With them you can define ``built-in'' functions.) - * Constraints:: Constraints for asm operands - * Asm Labels:: Specifying the assembler name to use for a C symbol. - * Explicit Reg Vars:: Defining variables residing in specified registers. - * Alternate Keywords:: @code{__const__}, @code{__asm__}, etc., for header files. - * Incomplete Enums:: @code{enum foo;}, with details to follow. --* Function Names:: Printable strings which are the name of the current -- function. -+* Function Names:: Printable strings which are the name of the current -+ function. - * Return Address:: Getting the return or frame address of a function. - * Vector Extensions:: Using vector instructions through built-in functions. - * Offsetof:: Special syntax for implementing @code{offsetof}. --* Atomic Builtins:: Built-in functions for atomic memory access. -+* Atomic Builtins:: Built-in functions for atomic memory access. - * Object Size Checking:: Built-in functions for limited buffer overflow - checking. - * Other Builtins:: Other built-in functions. -@@ -2486,7 +2486,13 @@ defined by shared libraries. - @cindex function without a prologue/epilogue code - Use this attribute on the ARM, AVR, IP2K and SPU ports to indicate that - the specified function does not need prologue/epilogue sequences generated by --the compiler. It is up to the programmer to provide these sequences. -+the compiler. It is up to the programmer to provide these sequences. The -+only statements that can be safely included in naked functions are -+@code{asm} statements that do not have operands. All other statements, -+including declarations of local variables, @code{if} statements, and so -+forth, should be avoided. Naked functions should be used to implement the -+body of an assembly function, while allowing the compiler to construct -+the requisite function declaration for the assembler. - - @item near - @cindex functions which do not handle memory bank switching on 68HC11/68HC12 -@@ -2539,7 +2545,7 @@ be non-null pointers. For instance, the - @smallexample - extern void * - my_memcpy (void *dest, const void *src, size_t len) -- __attribute__((nonnull (1, 2))); -+ __attribute__((nonnull (1, 2))); - @end smallexample - - @noindent -@@ -2557,7 +2563,7 @@ following declaration is equivalent to t - @smallexample - extern void * - my_memcpy (void *dest, const void *src, size_t len) -- __attribute__((nonnull)); -+ __attribute__((nonnull)); - @end smallexample - - @item noreturn -@@ -3710,13 +3716,13 @@ targets. You can use @code{__declspec ( - compilers. - - @item weak --The @code{weak} attribute is described in @xref{Function Attributes}. -+The @code{weak} attribute is described in @ref{Function Attributes}. - - @item dllimport --The @code{dllimport} attribute is described in @xref{Function Attributes}. -+The @code{dllimport} attribute is described in @ref{Function Attributes}. - - @item dllexport --The @code{dllexport} attribute is described in @xref{Function Attributes}. -+The @code{dllexport} attribute is described in @ref{Function Attributes}. - - @end table - -@@ -3897,21 +3903,21 @@ Three attributes currently are defined f - @code{altivec}, @code{ms_struct} and @code{gcc_struct}. - - For full documentation of the struct attributes please see the --documentation in the @xref{i386 Variable Attributes}, section. -+documentation in @ref{i386 Variable Attributes}. - - For documentation of @code{altivec} attribute please see the --documentation in the @xref{PowerPC Type Attributes}, section. -+documentation in @ref{PowerPC Type Attributes}. - - @subsection SPU Variable Attributes - - The SPU supports the @code{spu_vector} attribute for variables. For --documentation of this attribute please see the documentation in the --@xref{SPU Type Attributes}, section. -+documentation of this attribute please see the documentation in -+@ref{SPU Type Attributes}. - - @subsection Xstormy16 Variable Attributes - - One attribute is currently defined for xstormy16 configurations: --@code{below100} -+@code{below100}. - - @table @code - @item below100 -@@ -4231,6 +4237,8 @@ and caught in another, the class must ha - Otherwise the two shared objects will be unable to use the same - typeinfo node and exception handling will break. - -+@end table -+ - @subsection ARM Type Attributes - - On those ARM targets that support @code{dllimport} (such as Symbian -@@ -4258,7 +4266,9 @@ most Symbian OS code uses @code{__declsp - @subsection i386 Type Attributes - - Two attributes are currently defined for i386 configurations: --@code{ms_struct} and @code{gcc_struct} -+@code{ms_struct} and @code{gcc_struct}. -+ -+@table @code - - @item ms_struct - @itemx gcc_struct -@@ -4286,8 +4296,8 @@ packed))}. - Three attributes currently are defined for PowerPC configurations: - @code{altivec}, @code{ms_struct} and @code{gcc_struct}. - --For full documentation of the struct attributes please see the --documentation in the @xref{i386 Type Attributes}, section. -+For full documentation of the @code{ms_struct} and @code{gcc_struct} -+attributes please see the documentation in @ref{i386 Type Attributes}. - - The @code{altivec} attribute allows one to declare AltiVec vector data - types supported by the AltiVec Programming Interface Manual. The -@@ -5231,7 +5241,6 @@ GCC provides three magic variables which - function, as a string. The first of these is @code{__func__}, which - is part of the C99 standard: - --@display - The identifier @code{__func__} is implicitly declared by the translator - as if, immediately following the opening brace of each function - definition, the declaration -@@ -5240,9 +5249,9 @@ definition, the declaration - static const char __func__[] = "function-name"; - @end smallexample - -+@noindent - appeared, where function-name is the name of the lexically-enclosing - function. This name is the unadorned name of the function. --@end display - - @code{__FUNCTION__} is another name for @code{__func__}. Older - versions of GCC recognize only this name. However, it is not -@@ -5451,12 +5460,12 @@ the @code{offsetof} macro. - - @smallexample - primary: -- "__builtin_offsetof" "(" @code{typename} "," offsetof_member_designator ")" -+ "__builtin_offsetof" "(" @code{typename} "," offsetof_member_designator ")" - - offsetof_member_designator: -- @code{identifier} -- | offsetof_member_designator "." @code{identifier} -- | offsetof_member_designator "[" @code{expr} "]" -+ @code{identifier} -+ | offsetof_member_designator "." @code{identifier} -+ | offsetof_member_designator "[" @code{expr} "]" - @end smallexample - - This extension is sufficient such that -@@ -5649,7 +5658,7 @@ assert (__builtin_object_size (p, 0) == - assert (__builtin_object_size (p, 1) == sizeof (var.buf1) - 1); - /* The object q points to is var. */ - assert (__builtin_object_size (q, 0) -- == (char *) (&var + 1) - (char *) &var.b); -+ == (char *) (&var + 1) - (char *) &var.b); - /* The subobject q points to is var.b. */ - assert (__builtin_object_size (q, 1) == sizeof (var.b)); - @end smallexample -@@ -5701,11 +5710,11 @@ There are also checking built-in functio - @smallexample - int __builtin___sprintf_chk (char *s, int flag, size_t os, const char *fmt, ...); - int __builtin___snprintf_chk (char *s, size_t maxlen, int flag, size_t os, -- const char *fmt, ...); -+ const char *fmt, ...); - int __builtin___vsprintf_chk (char *s, int flag, size_t os, const char *fmt, -- va_list ap); -+ va_list ap); - int __builtin___vsnprintf_chk (char *s, size_t maxlen, int flag, size_t os, -- const char *fmt, va_list ap); -+ const char *fmt, va_list ap); - @end smallexample - - The added @var{flag} argument is passed unchanged to @code{__sprintf_chk} -@@ -11518,7 +11527,7 @@ test specifically for GNU C++ (@pxref{Co - Predefined Macros,cpp,The GNU C Preprocessor}). - - @menu --* Volatiles:: What constitutes an access to a volatile object. -+* Volatiles:: What constitutes an access to a volatile object. - * Restricted Pointers:: C99 restricted pointers and references. - * Vague Linkage:: Where G++ puts inlines, vtables and such. - * C++ Interface:: You can use a single C++ header file for both -@@ -12039,7 +12048,7 @@ interface table mechanism, instead of re - - @end table - --See also @xref{Namespace Association}. -+See also @ref{Namespace Association}. - - @node Namespace Association - @section Namespace Association -@@ -12266,7 +12275,7 @@ should work just fine for standard-confo - Previously it was possible to use an empty prototype parameter list to - indicate an unspecified number of parameters (like C), rather than no - parameters, as C++ demands. This feature has been removed, except where --it is required for backwards compatibility @xref{Backwards Compatibility}. -+it is required for backwards compatibility. @xref{Backwards Compatibility}. - @end table - - G++ allows a virtual function returning @samp{void *} to be overridden -@@ -12317,7 +12326,7 @@ used to be acceptable in previous drafts - compilation of C++ written to such drafts, G++ contains some backwards - compatibilities. @emph{All such backwards compatibility features are - liable to disappear in future versions of G++.} They should be considered --deprecated @xref{Deprecated Features}. -+deprecated. @xref{Deprecated Features}. - - @table @code - @item For scope ---- a/gcc/doc/fragments.texi -+++ b/gcc/doc/fragments.texi -@@ -143,6 +143,22 @@ options enabled. Therefore @code{MULTIL - *mthumb/*mhard-float* - @end smallexample - -+@findex MULTILIB_ALIASES -+@item MULTILIB_ALIASES -+Sometimes it is desirable to support a large set of multilib options, but -+only build libraries for a subset of those multilibs. The remaining -+combinations use a sutiable alternative multilb. In that case, set -+@code{MULTILIB_ALIASES} to a list of the form @samp{realname=aliasname}. -+ -+For example, consider a little-endian ARM toolchain with big-endian and -+Thumb multilibs. If a big-endian Thumb multilib is not wanted, then -+setting @code{MULTILIB_ALIASES} to @samp{mbig-endian=mbig-endian/mthumb} -+makes this combination use the big-endian ARM libraries instead. -+ -+If the multilib is instead excluded by setting @code{MULTILIB_EXCEPTIONS} -+then big-endian Thumb code uses the default multilib as none of the -+remaining multilibs match. -+ - @findex MULTILIB_EXTRA_OPTS - @item MULTILIB_EXTRA_OPTS - Sometimes it is desirable that when building multiple versions of ---- a/gcc/doc/gcc.texi -+++ b/gcc/doc/gcc.texi -@@ -147,12 +147,12 @@ Introduction, gccint, GNU Compiler Colle - * GNU Project:: The GNU Project and GNU/Linux. - - * Copying:: GNU General Public License says -- how you can copy and share GCC. -+ how you can copy and share GCC. - * GNU Free Documentation License:: How you can copy and share this manual. - * Contributors:: People who have contributed to GCC. - - * Option Index:: Index to command line options. --* Keyword Index:: Index of concepts and symbol names. -+* Keyword Index:: Index of concepts and symbol names. - @end menu - - @include frontends.texi ---- a/gcc/doc/install.texi -+++ b/gcc/doc/install.texi -@@ -671,7 +671,7 @@ internal data files of GCC@. The defaul - - @item --libexecdir=@var{dirname} - Specify the installation directory for internal executables of GCC@. -- The default is @file{@var{exec-prefix}/libexec}. -+The default is @file{@var{exec-prefix}/libexec}. - - @item --with-slibdir=@var{dirname} - Specify the installation directory for the shared libgcc library. The -@@ -3513,15 +3513,17 @@ applications. There are no standard Uni - @end html - @heading @anchor{m68k-x-x}m68k-*-* - By default, @samp{m68k-*-aout}, @samp{m68k-*-coff*}, --@samp{m68k-*-elf*}, @samp{m68k-*-rtems} and @samp{m68k-*-uclinux} -+@samp{m68k-*-elf*}, @samp{m68k-*-rtems}, @samp{m68k-*-uclinux} and -+@samp{m68k-*-linux} - build libraries for both M680x0 and ColdFire processors. If you only - need the M680x0 libraries, you can omit the ColdFire ones by passing - @option{--with-arch=m68k} to @command{configure}. Alternatively, you - can omit the M680x0 libraries by passing @option{--with-arch=cf} to --@command{configure}. These targets default to 5206 code when -+@command{configure}. These targets default to 5206 or 5475 code as -+appropriate for the target system when - configured with @option{--with-arch=cf} and 68020 code otherwise. - --The @samp{m68k-*-linux-gnu}, @samp{m68k-*-netbsd} and -+The @samp{m68k-*-netbsd} and - @samp{m68k-*-openbsd} targets also support the @option{--with-arch} - option. They will generate ColdFire CFV4e code when configured with - @option{--with-arch=cf} and 68020 code otherwise. ---- a/gcc/doc/invoke.texi -+++ b/gcc/doc/invoke.texi -@@ -120,11 +120,11 @@ only one of these two forms, whichever o - @xref{Option Index}, for an index to GCC's options. - - @menu --* Option Summary:: Brief list of all options, without explanations. -+* Option Summary:: Brief list of all options, without explanations. - * Overall Options:: Controlling the kind of output: - an executable, object files, assembler files, - or preprocessed source. --* Invoking G++:: Compiling C++ programs. -+* Invoking G++:: Compiling C++ programs. - * C Dialect Options:: Controlling the variant of C language compiled. - * C++ Dialect Options:: Variations on C++. - * Objective-C and Objective-C++ Dialect Options:: Variations on Objective-C -@@ -248,6 +248,7 @@ Objective-C and Objective-C++ Dialects}. - -Wno-multichar -Wnonnull -Wno-overflow @gol - -Woverlength-strings -Wpacked -Wpadded @gol - -Wparentheses -Wpointer-arith -Wno-pointer-to-int-cast @gol -+-Wno-poison-system-directories @gol - -Wredundant-decls @gol - -Wreturn-type -Wsequence-point -Wshadow @gol - -Wsign-compare -Wsign-conversion -Wstack-protector @gol -@@ -309,13 +310,13 @@ Objective-C and Objective-C++ Dialects}. - -p -pg -print-file-name=@var{library} -print-libgcc-file-name @gol - -print-multi-directory -print-multi-lib @gol - -print-prog-name=@var{program} -print-search-dirs -Q @gol ---print-sysroot-headers-suffix @gol -+-print-sysroot -print-sysroot-headers-suffix @gol - -save-temps -time} - - @item Optimization Options - @xref{Optimize Options,,Options that Control Optimization}. - @gccoptlist{ ---falign-functions[=@var{n}] -falign-jumps[=@var{n}] @gol -+-falign-arrays -falign-functions[=@var{n}] -falign-jumps[=@var{n}] @gol - -falign-labels[=@var{n}] -falign-loops[=@var{n}] -fassociative-math @gol - -fauto-inc-dec -fbranch-probabilities -fbranch-target-load-optimize @gol - -fbranch-target-load-optimize2 -fbtr-bb-exclusive -fcaller-saves @gol -@@ -388,7 +389,7 @@ Objective-C and Objective-C++ Dialects}. - @gccoptlist{@var{object-file-name} -l@var{library} @gol - -nostartfiles -nodefaultlibs -nostdlib -pie -rdynamic @gol - -s -static -static-libgcc -shared -shared-libgcc -symbolic @gol ---Wl,@var{option} -Xlinker @var{option} @gol -+-T @var{script} -Wl,@var{option} -Xlinker @var{option} @gol - -u @var{symbol}} - - @item Directory Options -@@ -421,8 +422,11 @@ Objective-C and Objective-C++ Dialects}. - -msched-prolog -mno-sched-prolog @gol - -mlittle-endian -mbig-endian -mwords-little-endian @gol - -mfloat-abi=@var{name} -msoft-float -mhard-float -mfpe @gol -+-mfp16-format=@var{name} - -mthumb-interwork -mno-thumb-interwork @gol -+-mfix-janus-2cc @gol - -mcpu=@var{name} -march=@var{name} -mfpu=@var{name} @gol -+-mmarvell-div @gol - -mstructure-size-boundary=@var{n} @gol - -mabort-on-noreturn @gol - -mlong-calls -mno-long-calls @gol -@@ -434,7 +438,9 @@ Objective-C and Objective-C++ Dialects}. - -mthumb -marm @gol - -mtpcs-frame -mtpcs-leaf-frame @gol - -mcaller-super-interworking -mcallee-super-interworking @gol ---mtp=@var{name}} -+-mtp=@var{name} @gol -+-mlow-irq-latency -mword-relocations @gol -+-mfix-cortex-m3-ldrd} - - @emph{AVR Options} - @gccoptlist{-mmcu=@var{mcu} -msize -minit-stack=@var{n} -mno-interrupts @gol -@@ -602,7 +608,8 @@ Objective-C and Objective-C++ Dialects}. - -mnobitfield -mrtd -mno-rtd -mdiv -mno-div -mshort @gol - -mno-short -mhard-float -m68881 -msoft-float -mpcrel @gol - -malign-int -mstrict-align -msep-data -mno-sep-data @gol ---mshared-library-id=n -mid-shared-library -mno-id-shared-library} -+-mshared-library-id=n -mid-shared-library -mno-id-shared-library @gol -+-mxgot -mno-xgot} - - @emph{M68hc1x Options} - @gccoptlist{-m6811 -m6812 -m68hc11 -m68hc12 -m68hcs12 @gol -@@ -619,7 +626,7 @@ Objective-C and Objective-C++ Dialects}. - @emph{MIPS Options} - @gccoptlist{-EL -EB -march=@var{arch} -mtune=@var{arch} @gol - -mips1 -mips2 -mips3 -mips4 -mips32 -mips32r2 -mips64 @gol ---mips16 -mno-mips16 -mflip-mips16 @gol -+-mips16 -mips16e -mno-mips16 -mflip-mips16 @gol - -minterlink-mips16 -mno-interlink-mips16 @gol - -mabi=@var{abi} -mabicalls -mno-abicalls @gol - -mshared -mno-shared -mxgot -mno-xgot -mgp32 -mgp64 @gol -@@ -642,11 +649,12 @@ Objective-C and Objective-C++ Dialects}. - -mmad -mno-mad -mfused-madd -mno-fused-madd -nocpp @gol - -mfix-r4000 -mno-fix-r4000 -mfix-r4400 -mno-fix-r4400 @gol - -mfix-vr4120 -mno-fix-vr4120 -mfix-vr4130 -mno-fix-vr4130 @gol ---mfix-sb1 -mno-fix-sb1 @gol -+-mfix-ice9a -mno-fix-ice9a -mfix-sb1 -mno-fix-sb1 @gol - -mflush-func=@var{func} -mno-flush-func @gol - -mbranch-cost=@var{num} -mbranch-likely -mno-branch-likely @gol - -mfp-exceptions -mno-fp-exceptions @gol ---mvr4130-align -mno-vr4130-align} -+-mvr4130-align -mno-vr4130-align @gol -+-mwarn-framesize=@var{framesize}} - - @emph{MMIX Options} - @gccoptlist{-mlibfuncs -mno-libfuncs -mepsilon -mno-epsilon -mabi=gnu @gol -@@ -746,7 +754,7 @@ See RS/6000 and PowerPC Options. - -mprefergot -musermode -multcost=@var{number} -mdiv=@var{strategy} @gol - -mdivsi3_libfunc=@var{name} @gol - -madjust-unroll -mindexed-addressing -mgettrcost=@var{number} -mpt-fixed @gol -- -minvalid-symbols} -+-minvalid-symbols} - - @emph{SPARC Options} - @gccoptlist{-mcpu=@var{cpu-type} @gol -@@ -3377,6 +3385,14 @@ code. However, note that using @option{ - option will @emph{not} warn about unknown pragmas in system - headers---for that, @option{-Wunknown-pragmas} must also be used. - -+@item -Wno-poison-system-directories -+@opindex Wno-poison-system-directories -+Do not warn for @option{-I} or @option{-L} options using system -+directories such as @file{/usr/include} when cross compiling. This -+option is intended for use in chroot environments when such -+directories contain the correct headers and libraries for the target -+system rather than the host. -+ - @item -Wfloat-equal - @opindex Wfloat-equal - @opindex Wno-float-equal -@@ -5065,6 +5081,14 @@ variable @env{GCC_EXEC_PREFIX} to the di - Don't forget the trailing @samp{/}. - @xref{Environment Variables}. - -+@item -print-sysroot -+@opindex print-sysroot -+Print the target sysroot directory that will be used during -+compilation. This is the target sysroot specified either at configure -+time or or using the @option{--sysroot} option, possibly with an extra -+suffix that depends on compilation options. If no target sysroot is -+specified, the options prints nothing. -+ - @item -print-sysroot-headers-suffix - @opindex print-sysroot-headers-suffix - Print the suffix added to the target sysroot when searching for -@@ -5128,7 +5152,13 @@ the compiler to use information gained f - compiling each of them. - - Not all optimizations are controlled directly by a flag. Only --optimizations that have a flag are listed. -+optimizations that have a flag are listed in this section. -+ -+Depending on the target and how GCC was configured, a slightly different -+set of optimizations may be enabled at each @option{-O} level than -+those listed here. You can invoke GCC with @samp{-Q --help=optimizers} -+to find out the exact set of optimizations that are enabled at each level. -+@xref{Overall Options}, for examples. - - @table @gcctabopt - @item -O -@@ -5355,9 +5385,9 @@ as follows: - - @table @gcctabopt - @item max-inline-insns-single -- is set to @var{n}/2. -+is set to @var{n}/2. - @item max-inline-insns-auto -- is set to @var{n}/2. -+is set to @var{n}/2. - @end table - - See below for a documentation of the individual -@@ -6207,6 +6237,14 @@ arithmetic on constants, the overflowed - The @option{-fstrict-overflow} option is enabled at levels - @option{-O2}, @option{-O3}, @option{-Os}. - -+@item -falign-arrays -+@opindex falign-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. This option may be -+helpful when compiling legacy code that uses type punning on arrays that -+does not strictly conform to the C standard. -+ - @item -falign-functions - @itemx -falign-functions=@var{n} - @opindex falign-functions -@@ -6757,6 +6795,21 @@ int foo (void) - - Not all targets support this option. - -+@item -fremove-local-statics -+@opindex fremove-local-statics -+Converts function-local static variables to automatic variables when it -+is safe to do so. This transformation can reduce the number of -+instructions executed due to automatic variables being cheaper to -+read/write than static variables. -+ -+@item -fpromote-loop-indices -+@opindex fpromote-loop-indices -+Converts loop indices that have a type shorter than the word size to -+word-sized quantities. This transformation can reduce the overhead -+associated with sign/zero-extension and truncation of such variables. -+Using @option{-funsafe-loop-optimizations} with this option may result -+in more effective optimization. -+ - @item --param @var{name}=@var{value} - @opindex param - In some places, GCC uses various constants to control the amount of -@@ -7582,23 +7635,42 @@ about any unresolved references (unless - option @samp{-Xlinker -z -Xlinker defs}). Only a few systems support - this option. - -+@item -T @var{script} -+@opindex T -+@cindex linker script -+Use @var{script} as the linker script. This option is supported by most -+systems using the GNU linker. On some targets, such as bare-board -+targets without an operating system, the @option{-T} option may be required -+when linking to avoid references to undefined symbols. -+ - @item -Xlinker @var{option} - @opindex Xlinker - Pass @var{option} as an option to the linker. You can use this to - supply system-specific linker options which GCC does not know how to - recognize. - --If you want to pass an option that takes an argument, you must use -+If you want to pass an option that takes a separate argument, you must use - @option{-Xlinker} twice, once for the option and once for the argument. - For example, to pass @option{-assert definitions}, you must write - @samp{-Xlinker -assert -Xlinker definitions}. It does not work to write - @option{-Xlinker "-assert definitions"}, because this passes the entire - string as a single argument, which is not what the linker expects. - -+When using the GNU linker, it is usually more convenient to pass -+arguments to linker options using the @option{@var{option}=@var{value}} -+syntax than as separate arguments. For example, you can specify -+@samp{-Xlinker -Map=output.map} rather than -+@samp{-Xlinker -Map -Xlinker output.map}. Other linkers may not support -+this syntax for command-line options. -+ - @item -Wl,@var{option} - @opindex Wl - Pass @var{option} as an option to the linker. If @var{option} contains --commas, it is split into multiple options at the commas. -+commas, it is split into multiple options at the commas. You can use this -+syntax to pass an argument to the option. -+For example, @samp{-Wl,-Map,output.map} passes @samp{-Map output.map} to the -+linker. When using the GNU linker, you can also get the same effect with -+@samp{-Wl,-Map=output.map}. - - @item -u @var{symbol} - @opindex u -@@ -8500,35 +8572,30 @@ different function prologues), and this - locate the start if functions inside an executable piece of code. The - default is @option{-msched-prolog}. - -+@item -mfloat-abi=@var{name} -+@opindex mfloat-abi -+Specifies which floating-point ABI to use. Permissible values -+are: @samp{soft}, @samp{softfp} and @samp{hard}. -+ -+Specifying @samp{soft} causes GCC to generate output containing -+library calls for floating-point operations. -+@samp{softfp} allows the generation of code using hardware floating-point -+instructions, but still uses the soft-float calling conventions. -+@samp{hard} allows generation of floating-point instructions -+and uses FPU-specific calling conventions. -+ -+The default depends on the specific target configuration. Note that -+the hard-float and soft-float ABIs are not link-compatible; you must -+compile your entire program with the same ABI, and link with a -+compatible set of libraries. -+ - @item -mhard-float - @opindex mhard-float --Generate output containing floating point instructions. This is the --default. -+Equivalent to @option{-mfloat-abi=hard}. - - @item -msoft-float - @opindex msoft-float --Generate output containing library calls for floating point. --@strong{Warning:} the requisite libraries are not available for all ARM --targets. Normally the facilities of the machine's usual C compiler are --used, but this cannot be done directly in cross-compilation. You must make --your own arrangements to provide suitable library functions for --cross-compilation. -- --@option{-msoft-float} changes the calling convention in the output file; --therefore, it is only useful if you compile @emph{all} of a program with --this option. In particular, you need to compile @file{libgcc.a}, the --library that comes with GCC, with @option{-msoft-float} in order for --this to work. -- --@item -mfloat-abi=@var{name} --@opindex mfloat-abi --Specifies which ABI to use for floating point values. Permissible values --are: @samp{soft}, @samp{softfp} and @samp{hard}. -- --@samp{soft} and @samp{hard} are equivalent to @option{-msoft-float} --and @option{-mhard-float} respectively. @samp{softfp} allows the generation --of floating point instructions, but still uses the soft-float calling --conventions. -+Equivalent to @option{-mfloat-abi=soft}. - - @item -mlittle-endian - @opindex mlittle-endian -@@ -8567,8 +8634,9 @@ assembly code. Permissible names are: @ - @samp{arm10e}, @samp{arm1020e}, @samp{arm1022e}, - @samp{arm1136j-s}, @samp{arm1136jf-s}, @samp{mpcore}, @samp{mpcorenovfp}, - @samp{arm1156t2-s}, @samp{arm1176jz-s}, @samp{arm1176jzf-s}, --@samp{cortex-a8}, @samp{cortex-r4}, @samp{cortex-m3}, --@samp{xscale}, @samp{iwmmxt}, @samp{ep9312}. -+@samp{cortex-a8}, @samp{cortex-r4}, @samp{cortex-r4f}, @samp{cortex-m3}, -+@samp{cortex-m1}, @samp{cortex-m0}, -+@samp{xscale}, @samp{iwmmxt}, @samp{ep9312} @samp{marvell-f}. - - @itemx -mtune=@var{name} - @opindex mtune -@@ -8600,13 +8668,26 @@ of the @option{-mcpu=} option. Permissi - @opindex mfp - This specifies what floating point hardware (or hardware emulation) is - available on the target. Permissible names are: @samp{fpa}, @samp{fpe2}, --@samp{fpe3}, @samp{maverick}, @samp{vfp}. @option{-mfp} and @option{-mfpe} -+@samp{fpe3}, @samp{maverick}, @samp{vfp}, @samp{vfpv3}, @samp{vfpv3-d16}, -+@samp{neon}, and @samp{neon-fp16}. @option{-mfp} and @option{-mfpe} - are synonyms for @option{-mfpu}=@samp{fpe}@var{number}, for compatibility - with older versions of GCC@. - - If @option{-msoft-float} is specified this specifies the format of - floating point values. - -+@item -mfp16-format=@var{name} -+@opindex mfp16-format -+Specify the format of the @code{__fp16} half-precision floating-point type. -+Permissible names are @samp{none}, @samp{ieee}, and @samp{alternative}; -+the default is @samp{none}, in which case the @code{__fp16} type is not -+defined. Refer to the ARM Half-precision Extensions documentation for -+details of the formats. -+ -+@item -mmarvell-div -+@opindex mmarvell-div -+Generate hardware integer division instructions supported by some Marvell cores. -+ - @item -mstructure-size-boundary=@var{n} - @opindex mstructure-size-boundary - The size of all structures and unions will be rounded up to a multiple -@@ -8714,6 +8795,10 @@ This option automatically enables either - mixed 16/32-bit Thumb-2 instructions based on the @option{-mcpu=@var{name}} - and @option{-march=@var{name}} options. - -+@item -mfix-janus-2cc -+@opindex mfix-janus-2cc -+Work around hardware errata for Avalent Janus 2CC cores. -+ - @item -mtpcs-frame - @opindex mtpcs-frame - Generate a stack frame that is compliant with the Thumb Procedure Call -@@ -8749,6 +8834,25 @@ models are @option{soft}, which generate - best available method for the selected processor. The default setting is - @option{auto}. - -+@item -mlow-irq-latency -+@opindex mlow-irq-latency -+Avoid instructions with high interrupt latency when generating -+code. This can increase code size and reduce performance. -+The option is off by default. -+ -+@item -mword-relocations -+@opindex mword-relocations -+Only generate absolute relocations on word sized values (i.e. R_ARM_ABS32). -+This is enabled by default on targets (uClinux, SymbianOS) where the runtime -+loader imposes this restriction. -+ -+@item -mfix-cortex-m3-ldrd -+@opindex mfix-cortex-m3-ldrd -+Some Cortex-M3 cores can cause data corruption when @code{ldrd} instructions -+with overlapping destination and base registers are used. This option avoids -+generating these instructions. This option is enabled by default when -+@option{-mcpu=cortex-m3} is specified. -+ - @end table - - @node AVR Options -@@ -11402,7 +11506,7 @@ below, which also classifies the CPUs in - - @multitable @columnfractions 0.20 0.80 - @item @strong{Family} @tab @strong{@samp{-mcpu} arguments} --@item @samp{51qe} @tab @samp{51qe} -+@item @samp{51} @tab @samp{51} @samp{51ac} @samp{51cn} @samp{51em} @samp{51qe} - @item @samp{5206} @tab @samp{5202} @samp{5204} @samp{5206} - @item @samp{5206e} @tab @samp{5206e} - @item @samp{5208} @tab @samp{5207} @samp{5208} -@@ -11411,6 +11515,7 @@ below, which also classifies the CPUs in - @item @samp{5216} @tab @samp{5214} @samp{5216} - @item @samp{52235} @tab @samp{52230} @samp{52231} @samp{52232} @samp{52233} @samp{52234} @samp{52235} - @item @samp{5225} @tab @samp{5224} @samp{5225} -+@item @samp{52259} @tab @samp{52252} @samp{52254} @samp{52255} @samp{52256} @samp{52258} @samp{52259} - @item @samp{5235} @tab @samp{5232} @samp{5233} @samp{5234} @samp{5235} @samp{523x} - @item @samp{5249} @tab @samp{5249} - @item @samp{5250} @tab @samp{5250} -@@ -11418,6 +11523,7 @@ below, which also classifies the CPUs in - @item @samp{5272} @tab @samp{5272} - @item @samp{5275} @tab @samp{5274} @samp{5275} - @item @samp{5282} @tab @samp{5280} @samp{5281} @samp{5282} @samp{528x} -+@item @samp{53017} @tab @samp{53011} @samp{53012} @samp{53013} @samp{53014} @samp{53015} @samp{53016} @samp{53017} - @item @samp{5307} @tab @samp{5307} - @item @samp{5329} @tab @samp{5327} @samp{5328} @samp{5329} @samp{532x} - @item @samp{5373} @tab @samp{5372} @samp{5373} @samp{537x} -@@ -11711,6 +11817,38 @@ compiled. Specifying a value of 0 will - other values will force the allocation of that number to the current - library but is no more space or time efficient than omitting this option. - -+@item -mxgot -+@itemx -mno-xgot -+@opindex mxgot -+@opindex mno-xgot -+When generating position-independent code for ColdFire, generate code -+that works if the GOT has more than 8192 entries. This code is -+larger and slower than code generated without this option. On M680x0 -+processors, this option is not needed; @option{-fPIC} suffices. -+ -+GCC normally uses a single instruction to load values from the GOT@. -+While this is relatively efficient, it only works if the GOT -+is smaller than about 64k. Anything larger causes the linker -+to report an error such as: -+ -+@cindex relocation truncated to fit (ColdFire) -+@smallexample -+relocation truncated to fit: R_68K_GOT16O foobar -+@end smallexample -+ -+If this happens, you should recompile your code with @option{-mxgot}. -+It should then work with very large GOTs. However, code generated with -+@option{-mxgot} is less efficient, since it takes 4 instructions to fetch -+the value of a global symbol. -+ -+Note that some linkers, including newer versions of the GNU linker, -+can create multiple GOTs and sort GOT entries. If you have such a linker, -+you should only need to use @option{-mxgot} when compiling a single -+object file that accesses more than 8192 GOT entries. Very few do. -+ -+These options have no effect unless GCC is generating -+position-independent code. -+ - @end table - - @node M68hc1x Options -@@ -11871,6 +12009,7 @@ The processor names are: - @samp{24kec}, @samp{24kef2_1}, @samp{24kef1_1}, - @samp{34kc}, @samp{34kf2_1}, @samp{34kf1_1}, - @samp{74kc}, @samp{74kf2_1}, @samp{74kf1_1}, @samp{74kf3_2}, -+@samp{ice9}, - @samp{m4k}, - @samp{orion}, - @samp{r2000}, @samp{r3000}, @samp{r3900}, @samp{r4000}, @samp{r4400}, -@@ -11879,7 +12018,8 @@ The processor names are: - @samp{sb1}, - @samp{sr71000}, - @samp{vr4100}, @samp{vr4111}, @samp{vr4120}, @samp{vr4130}, @samp{vr4300}, --@samp{vr5000}, @samp{vr5400} and @samp{vr5500}. -+@samp{vr5000}, @samp{vr5400}, @samp{vr5500} -+and @samp{xlr}. - The special value @samp{from-abi} selects the - most compatible architecture for the selected ABI (that is, - @samp{mips1} for 32-bit ABIs and @samp{mips3} for 64-bit ABIs)@. -@@ -11957,11 +12097,14 @@ Equivalent to @samp{-march=mips32r2}. - Equivalent to @samp{-march=mips64}. - - @item -mips16 -+@itemx -mips16e - @itemx -mno-mips16 - @opindex mips16 -+@opindex mips16e - @opindex mno-mips16 - Generate (do not generate) MIPS16 code. If GCC is targetting a - MIPS32 or MIPS64 architecture, it will make use of the MIPS16e ASE@. -+@option{-mips16e} is a deprecated alias for @option{-mips16}. - - MIPS16 code generation can also be controlled on a per-function basis - by means of @code{mips16} and @code{nomips16} attributes. -@@ -12453,6 +12596,12 @@ although GCC will avoid using @code{mflo - VR4130 @code{macc}, @code{macchi}, @code{dmacc} and @code{dmacchi} - instructions are available instead. - -+@item -mfix-ice9a -+@itemx -mno-fix-ice9a -+@opindex mfix-ice9a -+Work around ICE9A double floating-point multiplication -+errata. When enabled, the preprocessor defines @code{_MIPS_FIX_ICE9A}. -+ - @item -mfix-sb1 - @itemx -mno-fix-sb1 - @opindex mfix-sb1 -@@ -12512,6 +12661,13 @@ thinks should execute in parallel. - This option only has an effect when optimizing for the VR4130. - It normally makes code faster, but at the expense of making it bigger. - It is enabled by default at optimization level @option{-O3}. -+ -+@item -mwarn-framesize=@var{framesize} -+@opindex mwarn-framesize -+Emit a compile-time warning if the current function exceeds the given -+frame size. This is intended to help identify functions which -+may cause a stack overflow in run-time environments with limited or -+absent stack, e.g., BIOS. - @end table - - @node MMIX Options -@@ -12943,11 +13099,12 @@ Supported values for @var{cpu_type} are - @samp{601}, @samp{602}, @samp{603}, @samp{603e}, @samp{604}, - @samp{604e}, @samp{620}, @samp{630}, @samp{740}, @samp{7400}, - @samp{7450}, @samp{750}, @samp{801}, @samp{821}, @samp{823}, --@samp{860}, @samp{970}, @samp{8540}, @samp{ec603e}, @samp{G3}, --@samp{G4}, @samp{G5}, @samp{power}, @samp{power2}, @samp{power3}, --@samp{power4}, @samp{power5}, @samp{power5+}, @samp{power6}, --@samp{power6x}, @samp{common}, @samp{powerpc}, @samp{powerpc64}, --@samp{rios}, @samp{rios1}, @samp{rios2}, @samp{rsc}, and @samp{rs64}. -+@samp{860}, @samp{970}, @samp{8540}, @samp{e300c2}, @samp{e300c3}, -+@samp{e500mc}, @samp{ec603e}, @samp{G3}, @samp{G4}, @samp{G5}, -+@samp{power}, @samp{power2}, @samp{power3}, @samp{power4}, -+@samp{power5}, @samp{power5+}, @samp{power6}, @samp{power6x}, -+@samp{common}, @samp{powerpc}, @samp{powerpc64}, @samp{rios}, -+@samp{rios1}, @samp{rios2}, @samp{rsc}, and @samp{rs64}. - - @option{-mcpu=common} selects a completely generic processor. Code - generated under this option will run on any POWER or PowerPC processor. -@@ -13482,12 +13639,11 @@ header to indicate that @samp{eabi} exte - On System V.4 and embedded PowerPC systems do (do not) adhere to the - Embedded Applications Binary Interface (eabi) which is a set of - modifications to the System V.4 specifications. Selecting @option{-meabi} --means that the stack is aligned to an 8 byte boundary, a function --@code{__eabi} is called to from @code{main} to set up the eabi --environment, and the @option{-msdata} option can use both @code{r2} and -+means that the stack is aligned to an 8 byte boundary, -+and the @option{-msdata} option can use both @code{r2} and - @code{r13} to point to two separate small data areas. Selecting - @option{-mno-eabi} means that the stack is aligned to a 16 byte boundary, --do not call an initialization function from @code{main}, and the -+and the - @option{-msdata} option will only use @code{r13} to point to a single - small data area. The @option{-meabi} option is on by default if you - configured GCC using one of the @samp{powerpc*-*-eabi*} options. -@@ -14916,12 +15072,25 @@ Use it to conform to a non-default appli - - @item -fno-common - @opindex fno-common --In C, allocate even uninitialized global variables in the data section of the --object file, rather than generating them as common blocks. This has the --effect that if the same variable is declared (without @code{extern}) in --two different compilations, you will get an error when you link them. --The only reason this might be useful is if you wish to verify that the --program will work on other systems which always work this way. -+In C code, controls the placement of uninitialized global variables. -+Unix C compilers have traditionally permitted multiple definitions of -+such variables in different compilation units by placing the variables -+in a common block. -+This is the behavior specified by @option{-fcommon}, and is the default -+for GCC on most targets. -+On the other hand, this behavior is not required by ISO C, and on some -+targets may carry a speed or code size penalty on variable references. -+The @option{-fno-common} option specifies that the compiler should place -+uninitialized global variables in the data section of the object file, -+rather than generating them as common blocks. -+This has the effect that if the same variable is declared -+(without @code{extern}) in two different compilations, -+you will get a multiple-definition error when you link them. -+In this case, you must compile with @option{-fcommon} instead. -+Compiling with @option{-fno-common} is useful on targets for which -+it provides better performance, or if you wish to verify that the -+program will work on other systems which always treat uninitialized -+variable declarations this way. - - @item -fno-ident - @opindex fno-ident ---- a/gcc/doc/md.texi -+++ b/gcc/doc/md.texi -@@ -25,11 +25,11 @@ See the next chapter for information on - * Example:: An explained example of a @code{define_insn} pattern. - * RTL Template:: The RTL template defines what insns match a pattern. - * Output Template:: The output template says how to make assembler code -- from such an insn. -+ from such an insn. - * Output Statement:: For more generality, write C code to output -- the assembler code. -+ the assembler code. - * Predicates:: Controlling what kinds of operands can be used -- for an insn. -+ for an insn. - * Constraints:: Fine-tuning operand selection. - * Standard Names:: Names mark patterns to use for code generation. - * Pattern Ordering:: When the order of patterns makes a difference. -@@ -38,13 +38,13 @@ See the next chapter for information on - * Looping Patterns:: How to define patterns for special looping insns. - * Insn Canonicalizations::Canonicalization of Instructions - * Expander Definitions::Generating a sequence of several RTL insns -- for a standard operation. -+ for a standard operation. - * Insn Splitting:: Splitting Instructions into Multiple Instructions. --* Including Patterns:: Including Patterns in Machine Descriptions. -+* Including Patterns:: Including Patterns in Machine Descriptions. - * Peephole Definitions::Defining machine-specific peephole optimizations. - * Insn Attributes:: Specifying the value of attributes for generated insns. - * Conditional Execution::Generating @code{define_insn} patterns for -- predication. -+ predication. - * Constant Definitions::Defining symbolic constants that can be used in the - md file. - * Iterators:: Using iterators to generate patterns from a template. -@@ -1626,7 +1626,7 @@ it includes both constraints that are us - constraints that aren't. The compiler source file mentioned in the - table heading for each architecture is the definitive reference for - the meanings of that architecture's constraints. -- -+ - @table @emph - @item ARM family---@file{config/arm/arm.h} - @table @code -@@ -2889,10 +2889,10 @@ Signed 16-bit constant (@minus{}32768--3 - @item L - Value appropriate as displacement. - @table @code -- @item (0..4095) -- for short displacement -- @item (-524288..524287) -- for long displacement -+@item (0..4095) -+for short displacement -+@item (-524288..524287) -+for long displacement - @end table - - @item M -@@ -2901,14 +2901,14 @@ Constant integer with a value of 0x7ffff - @item N - Multiple letter constraint followed by 4 parameter letters. - @table @code -- @item 0..9: -- number of the part counting from most to least significant -- @item H,Q: -- mode of the part -- @item D,S,H: -- mode of the containing operand -- @item 0,F: -- value of the other parts (F---all bits set) -+@item 0..9: -+number of the part counting from most to least significant -+@item H,Q: -+mode of the part -+@item D,S,H: -+mode of the containing operand -+@item 0,F: -+value of the other parts (F---all bits set) - @end table - The constraint matches if the specified part of a constant - has a value different from its other parts. -@@ -3345,8 +3345,8 @@ definition from the i386 machine descrip - (define_peephole2 - [(match_scratch:SI 3 "r") - (set (match_operand:SI 0 "register_operand" "") -- (mult:SI (match_operand:SI 1 "memory_operand" "") -- (match_operand:SI 2 "immediate_operand" "")))] -+ (mult:SI (match_operand:SI 1 "memory_operand" "") -+ (match_operand:SI 2 "immediate_operand" "")))] - - "!satisfies_constraint_K (operands[2])" - -@@ -5378,15 +5378,15 @@ following for its @code{dbra} instructio - @group - (define_insn "decrement_and_branch_until_zero" - [(set (pc) -- (if_then_else -- (ge (plus:SI (match_operand:SI 0 "general_operand" "+d*am") -- (const_int -1)) -- (const_int 0)) -- (label_ref (match_operand 1 "" "")) -- (pc))) -+ (if_then_else -+ (ge (plus:SI (match_operand:SI 0 "general_operand" "+d*am") -+ (const_int -1)) -+ (const_int 0)) -+ (label_ref (match_operand 1 "" "")) -+ (pc))) - (set (match_dup 0) -- (plus:SI (match_dup 0) -- (const_int -1)))] -+ (plus:SI (match_dup 0) -+ (const_int -1)))] - "find_reg_note (insn, REG_NONNEG, 0)" - "@dots{}") - @end group -@@ -5404,14 +5404,14 @@ pattern will not be matched by the combi - @group - (define_insn "decrement_and_branch_until_zero" - [(set (pc) -- (if_then_else -- (ge (match_operand:SI 0 "general_operand" "+d*am") -- (const_int 1)) -- (label_ref (match_operand 1 "" "")) -- (pc))) -+ (if_then_else -+ (ge (match_operand:SI 0 "general_operand" "+d*am") -+ (const_int 1)) -+ (label_ref (match_operand 1 "" "")) -+ (pc))) - (set (match_dup 0) -- (plus:SI (match_dup 0) -- (const_int -1)))] -+ (plus:SI (match_dup 0) -+ (const_int -1)))] - "find_reg_note (insn, REG_NONNEG, 0)" - "@dots{}") - @end group -@@ -6033,7 +6033,7 @@ from i386.md: - "&& reload_completed" - [(parallel [(set (match_dup 0) - (and:SI (match_dup 0) (const_int 65535))) -- (clobber (reg:CC 17))])] -+ (clobber (reg:CC 17))])] - "" - [(set_attr "type" "alu1")]) - -@@ -7158,10 +7158,10 @@ the instruction issue is possible if the - automaton state to another one. This algorithm is very fast, and - furthermore, its speed is not dependent on processor - complexity@footnote{However, the size of the automaton depends on -- processor complexity. To limit this effect, machine descriptions -- can split orthogonal parts of the machine description among several -- automata: but then, since each of these must be stepped independently, -- this does cause a small decrease in the algorithm's performance.}. -+processor complexity. To limit this effect, machine descriptions -+can split orthogonal parts of the machine description among several -+automata: but then, since each of these must be stepped independently, -+this does cause a small decrease in the algorithm's performance.}. - - @cindex automaton based pipeline description - The rest of this section describes the directives that constitute -@@ -7761,8 +7761,8 @@ rtx-based construct, such as a @code{def - - @menu - * Defining Mode Iterators:: Defining a new mode iterator. --* Substitutions:: Combining mode iterators with substitutions --* Examples:: Examples -+* Substitutions:: Combining mode iterators with substitutions -+* Examples:: Examples - @end menu - - @node Defining Mode Iterators ---- a/gcc/doc/options.texi -+++ b/gcc/doc/options.texi -@@ -29,13 +29,13 @@ The files can contain the following type - - @itemize @bullet - @item --A language definition record.  These records have two fields: the --string @samp{Language} and the name of the language.  Once a language -+A language definition record. These records have two fields: the -+string @samp{Language} and the name of the language. Once a language - has been declared in this way, it can be used as an option property. - @xref{Option properties}. - - @item --An option definition record.  These records have the following fields: -+An option definition record. These records have the following fields: - - @enumerate - @item -@@ -62,11 +62,11 @@ tab forms the help text. This allows yo - of argument the option takes. - - @item --A target mask record.  These records have one field of the form --@samp{Mask(@var{x})}.  The options-processing script will automatically -+A target mask record. These records have one field of the form -+@samp{Mask(@var{x})}. The options-processing script will automatically - allocate a bit in @code{target_flags} (@pxref{Run-time Target}) for - each mask name @var{x} and set the macro @code{MASK_@var{x}} to the --appropriate bitmask.  It will also declare a @code{TARGET_@var{x}} -+appropriate bitmask. It will also declare a @code{TARGET_@var{x}} - macro that has the value 1 when bit @code{MASK_@var{x}} is set and - 0 otherwise. - ---- a/gcc/doc/passes.texi -+++ b/gcc/doc/passes.texi -@@ -20,7 +20,7 @@ where near complete. - @menu - * Parsing pass:: The language front end turns text into bits. - * Gimplification pass:: The bits are turned into something we can optimize. --* Pass manager:: Sequencing the optimization passes. -+* Pass manager:: Sequencing the optimization passes. - * Tree-SSA passes:: Optimizations on a high-level representation. - * RTL passes:: Optimizations on a low-level representation. - @end menu ---- a/gcc/doc/rtl.texi -+++ b/gcc/doc/rtl.texi -@@ -3019,11 +3019,9 @@ represents @var{x} before @var{x} is mod - @var{m} must be the machine mode for pointers on the machine in use. - - The expression @var{y} must be one of three forms: --@table @code - @code{(plus:@var{m} @var{x} @var{z})}, - @code{(minus:@var{m} @var{x} @var{z})}, or - @code{(plus:@var{m} @var{x} @var{i})}, --@end table - where @var{z} is an index register and @var{i} is a constant. - - Here is an example of its use: ---- a/gcc/doc/sourcebuild.texi -+++ b/gcc/doc/sourcebuild.texi -@@ -198,9 +198,7 @@ timestamp. - - @itemize @bullet - @item The standard GNU @file{config.sub} and @file{config.guess} --files, kept in the top level directory, are used. FIXME: when is the --@file{config.guess} file in the @file{gcc} directory (that just calls --the top level one) used? -+files, kept in the top level directory, are used. - - @item The file @file{config.gcc} is used to handle configuration - specific to the particular target machine. The file -@@ -1021,7 +1019,11 @@ an empty @var{exclude-opts} list. - - @item @{ dg-xfail-if @var{comment} @{ @var{selector} @} @{ @var{include-opts} @} @{ @var{exclude-opts} @} @} - Expect the test to fail if the conditions (which are the same as for --@code{dg-skip-if}) are met. -+@code{dg-skip-if}) are met. This does not affect the execute step. -+ -+@item @{ dg-xfail-run-if @var{comment} @{ @var{selector} @} @{ @var{include-opts} @} @{ @var{exclude-opts} @} @} -+Expect the execute step of a test to fail if the conditions (which are -+the same as for @code{dg-skip-if}) and @code{dg-xfail-if}) are met. - - @item @{ dg-require-@var{support} args @} - Skip the test if the target does not provide the required support; ---- a/gcc/doc/tm.texi -+++ b/gcc/doc/tm.texi -@@ -35,7 +35,7 @@ through the macros defined in the @file{ - * Register Classes:: Defining the classes of hardware registers. - * Old Constraints:: The old way to define machine-specific constraints. - * Stack and Calling:: Defining which way the stack grows and by how much. --* Varargs:: Defining the varargs macros. -+* Varargs:: Defining the varargs macros. - * Trampolines:: Code set up at run time to enter a nested function. - * Library Calls:: Controlling how library routines are implicitly called. - * Addressing Modes:: Defining addressing modes valid for memory operands. -@@ -44,7 +44,7 @@ through the macros defined in the @file{ - * Costs:: Defining relative costs of different operations. - * Scheduling:: Adjusting the behavior of the instruction scheduler. - * Sections:: Dividing storage into text, data, and other sections. --* PIC:: Macros for position independent code. -+* PIC:: Macros for position independent code. - * Assembler Format:: Defining how to write insns and pseudo-ops to output. - * Debugging Info:: Defining the format of debugging output. - * Floating Point:: Handling floating point for cross-compilers. -@@ -1138,6 +1138,9 @@ macro is used instead of that alignment - - If this macro is not defined, then @var{basic-align} is used. - -+This macro should never be used directly; use -+@code{calculate_global_alignment} instead. -+ - @findex strcpy - One use of this macro is to increase alignment of medium-size data to - make it all fit in fewer cache lines. Another is to cause character -@@ -1169,6 +1172,9 @@ If this macro is not defined, then @var{ - - One use of this macro is to increase alignment of medium-size data to - make it all fit in fewer cache lines. -+ -+This macro should never be used directly; use -+@code{calculate_local_alignment} instead. - @end defmac - - @defmac EMPTY_FIELD_BOUNDARY -@@ -1895,11 +1901,11 @@ For passing values in registers, see @re - For returning values in registers, see @ref{Scalar Return}. - - @menu --* Register Basics:: Number and kinds of registers. --* Allocation Order:: Order in which registers are allocated. --* Values in Registers:: What kinds of values each reg can hold. --* Leaf Functions:: Renumbering registers for leaf functions. --* Stack Registers:: Handling a register stack such as 80387. -+* Register Basics:: Number and kinds of registers. -+* Allocation Order:: Order in which registers are allocated. -+* Values in Registers:: What kinds of values each reg can hold. -+* Leaf Functions:: Renumbering registers for leaf functions. -+* Stack Registers:: Handling a register stack such as 80387. - @end menu - - @node Register Basics -@@ -2064,6 +2070,15 @@ machines, define @code{REG_ALLOC_ORDER} - the highest numbered allocable register first. - @end defmac - -+@deftypefn {Target Hook} void TARGET_ADJUST_REG_ALLOC_ORDER (int *@var{order}) -+If @code{REG_ALLOC_ORDER} has been defined, this hook is called after -+all command-line options have been processed. It enables adjustment of -+the allocation order based on target-specific flags. Any such adjustment -+should be performed by the hook directly on the elements of the -+array @code{order}. On entry to the hook this array is an -+unmodified copy of @code{REG_ALLOC_ORDER}. -+@end deftypefn -+ - @defmac ORDER_REGS_FOR_LOCAL_ALLOC - A C statement (sans semicolon) to choose the order in which to allocate - hard registers for pseudo-registers local to a basic block. -@@ -2476,6 +2491,15 @@ address where its value is either multip - added to another register (as well as added to a displacement). - @end defmac - -+@defmac MODE_INDEX_REG_CLASS (@var{mode}) -+This is a variation of the @code{INDEX_REG_CLASS} macro which allows -+the selection of an index register in a mode dependent manner. It can -+return @code{NO_REGS} for modes that do not support any form of index -+register. If @var{mode} is @code{VOIDmode} then the macro should -+return a class of registers that is suitable for all addresses in -+which an index register of some form is allowed. -+@end defmac -+ - @defmac REGNO_OK_FOR_BASE_P (@var{num}) - A C expression which is nonzero if register number @var{num} is - suitable for use as a base register in operand addresses. It may be -@@ -2535,6 +2559,14 @@ looking for one that is valid, and will - only if neither labeling works. - @end defmac - -+@defmac REGNO_MODE_OK_FOR_INDEX_P (@var{num}, @var{mode}) -+A C expression that is just like @code{REGNO_OK_FOR_INDEX_P}, except -+that the expression may examine the mode of the memory reference -+in @var{mode}. If @var{mode} is @code{VOIDmode}, the macro should -+return true if @var{x} is suitable for all modes in which some -+form of index register is allowed. -+@end defmac -+ - @defmac PREFERRED_RELOAD_CLASS (@var{x}, @var{class}) - A C expression that places additional restrictions on the register class - to use when it is necessary to copy value @var{x} into a register in class -@@ -2969,7 +3001,7 @@ be treated like memory constraints by th - - It should return 1 if the operand type represented by the constraint - at the start of @var{str}, the first letter of which is the letter @var{c}, -- comprises a subset of all memory references including -+comprises a subset of all memory references including - all those whose address is simply a base register. This allows the reload - pass to reload an operand, if it does not directly correspond to the operand - type of @var{c}, by copying its address into a base register. -@@ -4272,6 +4304,18 @@ The definition of @code{LIBRARY_VALUE} n - data types, because none of the library functions returns such types. - @end defmac - -+@deftypefn {Target Hook} rtx TARGET_LIBCALL_VALUE (enum machine_mode -+@var{mode}, rtx @var{fun}) -+Define this hook if the back-end needs to know the name of the libcall -+function in order to determine where the result should be returned. -+ -+The mode of the result is given by @var{mode} and the name of the called -+library function is given by @var{fun}. The hook should return an RTX -+representing the place where the library function result will be returned. -+ -+If this hook is not defined, then LIBCALL_VALUE will be used. -+@end deftypefn -+ - @defmac FUNCTION_VALUE_REGNO_P (@var{regno}) - A C expression that is nonzero if @var{regno} is the number of a hard - register in which the values of called function may come back. -@@ -6741,10 +6785,10 @@ instructions do. - * Uninitialized Data:: Output of uninitialized variables. - * Label Output:: Output and generation of labels. - * Initialization:: General principles of initialization -- and termination routines. -+ and termination routines. - * Macros for Initialization:: -- Specific macros that control the handling of -- initialization and termination routines. -+ Specific macros that control the handling of -+ initialization and termination routines. - * Instruction Output:: Output of actual instructions. - * Dispatch Tables:: Output of jump tables. - * Exception Region Output:: Output of exception region code. -@@ -6873,7 +6917,7 @@ This is true on most ELF targets. - Choose a set of section attributes for use by @code{TARGET_ASM_NAMED_SECTION} - based on a variable or function decl, a section name, and whether or not the - declaration's initializer may contain runtime relocations. @var{decl} may be -- null, in which case read-write data should be assumed. -+null, in which case read-write data should be assumed. - - The default version of this function handles choosing code vs data, - read-only vs read-write data, and @code{flag_pic}. You should only -@@ -7077,7 +7121,7 @@ assembler for grouping arithmetic expres - default to normal parentheses, which is correct for most assemblers. - @end deftypevr - -- These macros are provided by @file{real.h} for writing the definitions -+These macros are provided by @file{real.h} for writing the definitions - of @code{ASM_OUTPUT_DOUBLE} and the like: - - @defmac REAL_VALUE_TO_TARGET_SINGLE (@var{x}, @var{l}) -@@ -10355,6 +10399,36 @@ and @var{type2}, or @code{NULL} if valid - the front end. - @end deftypefn - -+@deftypefn {Target Hook} {const char *} TARGET_INVALID_PARAMETER_TYPE (tree @var{type}) -+If defined, this macro returns the diagnostic message when it is -+invalid for functions to include parameters of type @var{type}, -+or @code{NULL} if validity should be determined by -+the front end. -+@end deftypefn -+ -+@deftypefn {Target Hook} {const char *} TARGET_INVALID_RETURN_TYPE (tree @var{type}) -+If defined, this macro returns the diagnostic message when it is -+invalid for functions to have return type @var{type}, -+or @code{NULL} if validity should be determined by -+the front end. -+@end deftypefn -+ -+@deftypefn {Target Hook} {tree} TARGET_PROMOTED_TYPE (tree @var{type}) -+If defined, this target hook returns the type to which values of -+@var{type} should be promoted when they appear in expressions, -+analogous to the integer promotions, or @code{NULL_TREE} to use the -+front end's normal promotion rules. This hook is useful when there are -+target-specific types with special promotion rules. -+@end deftypefn -+ -+@deftypefn {Target Hook} {tree} TARGET_CONVERT_TO_TYPE (tree @var{type}, tree @var{expr}) -+If defined, this hook returns the result of converting @var{expr} to -+@var{type}. It should return the converted expression, -+or @code{NULL_TREE} to apply the front end's normal conversion rules. -+This hook is useful when there are target-specific types with special -+conversion rules. -+@end deftypefn -+ - @defmac TARGET_USE_JCR_SECTION - This macro determines whether to use the JCR section to register Java - classes. By default, TARGET_USE_JCR_SECTION is defined to 1 if both -@@ -10372,3 +10446,14 @@ to the functions in @file{libgcc} that p - call stack unwinding. It is used in declarations in @file{unwind-generic.h} - and the associated definitions of those functions. - @end defmac -+ -+@deftypefn {Target Hook} {bool} TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS (void) -+When optimization is disabled, this hook indicates whether or not -+arguments should be allocated to stack slots. Normally, GCC allocates -+stacks slots for arguments when not optimizing in order to make -+debugging easier. However, when a function is declared with -+@code{__attribute__((naked))}, there is no stack frame, and the compiler -+cannot safely move arguments from the registers in which they are passed -+to the stack. Therefore, this hook should return true in general, but -+false for naked functions. The default implementation always returns true. -+@end deftypefn ---- a/gcc/doc/tree-ssa.texi -+++ b/gcc/doc/tree-ssa.texi -@@ -37,12 +37,12 @@ functions and programming constructs nee - passes for GIMPLE@. - - @menu --* GENERIC:: A high-level language-independent representation. -+* GENERIC:: A high-level language-independent representation. - * GIMPLE:: A lower-level factored tree representation. --* Annotations:: Attributes for statements and variables. --* Statement Operands:: Variables referenced by GIMPLE statements. --* SSA:: Static Single Assignment representation. --* Alias analysis:: Representing aliased loads and stores. -+* Annotations:: Attributes for statements and variables. -+* Statement Operands:: Variables referenced by GIMPLE statements. -+* SSA:: Static Single Assignment representation. -+* Alias analysis:: Representing aliased loads and stores. - @end menu - - @node GENERIC -@@ -735,10 +735,10 @@ void f() - | RELOP - op0 -> val - op1 -> val -- | COND_EXPR -- op0 -> condition -- op1 -> val -- op2 -> val -+ | COND_EXPR -+ op0 -> condition -+ op1 -> val -+ op2 -> val - @end smallexample - - @node Annotations -@@ -943,7 +943,7 @@ How to choose the appropriate iterator: - - @enumerate - @item Determine whether you are need to see the operand pointers, or just the -- trees, and choose the appropriate macro: -+trees, and choose the appropriate macro: - - @smallexample - Need Macro: -@@ -954,12 +954,12 @@ tree FOR_EACH_SSA_TREE_OPERAN - @end smallexample - - @item You need to declare a variable of the type you are interested -- in, and an ssa_op_iter structure which serves as the loop -- controlling variable. -+in, and an ssa_op_iter structure which serves as the loop controlling -+variable. - - @item Determine which operands you wish to use, and specify the flags of -- those you are interested in. They are documented in -- @file{tree-ssa-operands.h}: -+those you are interested in. They are documented in -+@file{tree-ssa-operands.h}: - - @smallexample - #define SSA_OP_USE 0x01 /* @r{Real USE operands.} */ -@@ -1228,27 +1228,27 @@ which''. - - The following macros can be used to examine PHI nodes - --@defmac PHI_RESULT (@var{phi}) -+@defmac PHI_RESULT (@var{phi}) - Returns the @code{SSA_NAME} created by PHI node @var{phi} (i.e., - @var{phi}'s LHS)@. - @end defmac - --@defmac PHI_NUM_ARGS (@var{phi}) -+@defmac PHI_NUM_ARGS (@var{phi}) - Returns the number of arguments in @var{phi}. This number is exactly - the number of incoming edges to the basic block holding @var{phi}@. - @end defmac - --@defmac PHI_ARG_ELT (@var{phi}, @var{i}) -+@defmac PHI_ARG_ELT (@var{phi}, @var{i}) - Returns a tuple representing the @var{i}th argument of @var{phi}@. - Each element of this tuple contains an @code{SSA_NAME} @var{var} and - the incoming edge through which @var{var} flows. - @end defmac - --@defmac PHI_ARG_EDGE (@var{phi}, @var{i}) -+@defmac PHI_ARG_EDGE (@var{phi}, @var{i}) - Returns the incoming edge for the @var{i}th argument of @var{phi}. - @end defmac - --@defmac PHI_ARG_DEF (@var{phi}, @var{i}) -+@defmac PHI_ARG_DEF (@var{phi}, @var{i}) - Returns the @code{SSA_NAME} for the @var{i}th argument of @var{phi}. - @end defmac - -@@ -1274,36 +1274,36 @@ the program@. - For instance, given the following code: - - @smallexample -- 1 L0: -- 2 x_1 = PHI (0, x_5) -- 3 if (x_1 < 10) -- 4 if (x_1 > 7) -- 5 y_2 = 0 -- 6 else -- 7 y_3 = x_1 + x_7 -- 8 endif -- 9 x_5 = x_1 + 1 -+ 1 L0: -+ 2 x_1 = PHI (0, x_5) -+ 3 if (x_1 < 10) -+ 4 if (x_1 > 7) -+ 5 y_2 = 0 -+ 6 else -+ 7 y_3 = x_1 + x_7 -+ 8 endif -+ 9 x_5 = x_1 + 1 - 10 goto L0; -- 11 endif -+ 11 endif - @end smallexample - - Suppose that we insert new names @code{x_10} and @code{x_11} (lines - @code{4} and @code{8})@. - - @smallexample -- 1 L0: -- 2 x_1 = PHI (0, x_5) -- 3 if (x_1 < 10) -- 4 x_10 = @dots{} -- 5 if (x_1 > 7) -- 6 y_2 = 0 -- 7 else -- 8 x_11 = @dots{} -- 9 y_3 = x_1 + x_7 -- 10 endif -- 11 x_5 = x_1 + 1 -- 12 goto L0; -- 13 endif -+ 1 L0: -+ 2 x_1 = PHI (0, x_5) -+ 3 if (x_1 < 10) -+ 4 x_10 = @dots{} -+ 5 if (x_1 > 7) -+ 6 y_2 = 0 -+ 7 else -+ 8 x_11 = @dots{} -+ 9 y_3 = x_1 + x_7 -+ 10 endif -+ 11 x_5 = x_1 + 1 -+ 12 goto L0; -+ 13 endif - @end smallexample - - We want to replace all the uses of @code{x_1} with the new definitions -@@ -1341,40 +1341,40 @@ There are several @code{TODO} flags that - - @itemize @bullet - @item @code{TODO_update_ssa}. Update the SSA form inserting PHI nodes -- for newly exposed symbols and virtual names marked for updating. -- When updating real names, only insert PHI nodes for a real name -- @code{O_j} in blocks reached by all the new and old definitions for -- @code{O_j}. If the iterated dominance frontier for @code{O_j} -- is not pruned, we may end up inserting PHI nodes in blocks that -- have one or more edges with no incoming definition for -- @code{O_j}. This would lead to uninitialized warnings for -- @code{O_j}'s symbol@. -+for newly exposed symbols and virtual names marked for updating. -+When updating real names, only insert PHI nodes for a real name -+@code{O_j} in blocks reached by all the new and old definitions for -+@code{O_j}. If the iterated dominance frontier for @code{O_j} -+is not pruned, we may end up inserting PHI nodes in blocks that -+have one or more edges with no incoming definition for -+@code{O_j}. This would lead to uninitialized warnings for -+@code{O_j}'s symbol@. - - @item @code{TODO_update_ssa_no_phi}. Update the SSA form without -- inserting any new PHI nodes at all. This is used by passes that -- have either inserted all the PHI nodes themselves or passes that -- need only to patch use-def and def-def chains for virtuals -- (e.g., DCE)@. -+inserting any new PHI nodes at all. This is used by passes that -+have either inserted all the PHI nodes themselves or passes that -+need only to patch use-def and def-def chains for virtuals -+(e.g., DCE)@. - - - @item @code{TODO_update_ssa_full_phi}. Insert PHI nodes everywhere -- they are needed. No pruning of the IDF is done. This is used -- by passes that need the PHI nodes for @code{O_j} even if it -- means that some arguments will come from the default definition -- of @code{O_j}'s symbol (e.g., @code{pass_linear_transform})@. -- -- WARNING: If you need to use this flag, chances are that your -- pass may be doing something wrong. Inserting PHI nodes for an -- old name where not all edges carry a new replacement may lead to -- silent codegen errors or spurious uninitialized warnings@. -+they are needed. No pruning of the IDF is done. This is used -+by passes that need the PHI nodes for @code{O_j} even if it -+means that some arguments will come from the default definition -+of @code{O_j}'s symbol (e.g., @code{pass_linear_transform})@. -+ -+WARNING: If you need to use this flag, chances are that your -+pass may be doing something wrong. Inserting PHI nodes for an -+old name where not all edges carry a new replacement may lead to -+silent codegen errors or spurious uninitialized warnings@. - - @item @code{TODO_update_ssa_only_virtuals}. Passes that update the -- SSA form on their own may want to delegate the updating of -- virtual names to the generic updater. Since FUD chains are -- easier to maintain, this simplifies the work they need to do. -- NOTE: If this flag is used, any OLD->NEW mappings for real names -- are explicitly destroyed and only the symbols marked for -- renaming are processed@. -+SSA form on their own may want to delegate the updating of -+virtual names to the generic updater. Since FUD chains are -+easier to maintain, this simplifies the work they need to do. -+NOTE: If this flag is used, any OLD->NEW mappings for real names -+are explicitly destroyed and only the symbols marked for -+renaming are processed@. - @end itemize - - @subsection Preserving the virtual SSA form -@@ -1445,8 +1445,8 @@ slightly different. For each argument @ - function will: - - @enumerate --@item Walk the use-def chains for @var{arg}. --@item Call @code{FN (@var{arg}, @var{phi}, @var{data})}. -+@item Walk the use-def chains for @var{arg}. -+@item Call @code{FN (@var{arg}, @var{phi}, @var{data})}. - @end enumerate - - Note how the first argument to @var{fn} is no longer the original -@@ -1466,26 +1466,26 @@ hooks to execute custom code at various - - @enumerate - @item Once to initialize any local data needed while processing -- @var{bb} and its children. This local data is pushed into an -- internal stack which is automatically pushed and popped as the -- walker traverses the dominator tree. -+@var{bb} and its children. This local data is pushed into an -+internal stack which is automatically pushed and popped as the -+walker traverses the dominator tree. - - @item Once before traversing all the statements in the @var{bb}. - - @item Once for every statement inside @var{bb}. - - @item Once after traversing all the statements and before recursing -- into @var{bb}'s dominator children. -+into @var{bb}'s dominator children. - - @item It then recurses into all the dominator children of @var{bb}. - - @item After recursing into all the dominator children of @var{bb} it -- can, optionally, traverse every statement in @var{bb} again -- (i.e., repeating steps 2 and 3). -+can, optionally, traverse every statement in @var{bb} again -+(i.e., repeating steps 2 and 3). - - @item Once after walking the statements in @var{bb} and @var{bb}'s -- dominator children. At this stage, the block local data stack -- is popped. -+dominator children. At this stage, the block local data stack -+is popped. - @end enumerate - @end deftypefn - -@@ -1535,16 +1535,16 @@ int bar (void) - If you copy the symbol tag for a variable for some reason, you probably - also want to copy the subvariables for that variable. - --@item Points-to and escape analysis. -+@item Points-to and escape analysis. - - This phase walks the use-def chains in the SSA web looking for - three things: - -- @itemize @bullet -- @item Assignments of the form @code{P_i = &VAR} -- @item Assignments of the form P_i = malloc() -- @item Pointers and ADDR_EXPR that escape the current function. -- @end itemize -+@itemize @bullet -+@item Assignments of the form @code{P_i = &VAR} -+@item Assignments of the form P_i = malloc() -+@item Pointers and ADDR_EXPR that escape the current function. -+@end itemize - - The concept of `escaping' is the same one used in the Java world. - When a pointer or an ADDR_EXPR escapes, it means that it has been -@@ -1562,7 +1562,7 @@ call-clobbered. Simply put, if an ADDR_ - variable is call-clobbered. If a pointer P_i escapes, then all - the variables pointed-to by P_i (and its memory tag) also escape. - --@item Compute flow-sensitive aliases -+@item Compute flow-sensitive aliases - - We have two classes of memory tags. Memory tags associated with - the pointed-to data type of the pointers in the program. These -@@ -1579,7 +1579,7 @@ associated with each pointer P_i. If P_ - call-clobbered the variables it points to and its tag. - - --@item Compute flow-insensitive aliases -+@item Compute flow-insensitive aliases - - This pass will compare the alias set of every symbol memory tag and - every addressable variable found in the program. Given a symbol ---- a/gcc/doc/trouble.texi -+++ b/gcc/doc/trouble.texi -@@ -19,21 +19,21 @@ missing features that are too much work - where people's opinions differ as to what is best. - - @menu --* Actual Bugs:: Bugs we will fix later. --* Cross-Compiler Problems:: Common problems of cross compiling with GCC. -+* Actual Bugs:: Bugs we will fix later. -+* Cross-Compiler Problems:: Common problems of cross compiling with GCC. - * Interoperation:: Problems using GCC with other compilers, -- and with certain linkers, assemblers and debuggers. -+ and with certain linkers, assemblers and debuggers. - * Incompatibilities:: GCC is incompatible with traditional C. - * Fixed Headers:: GCC uses corrected versions of system header files. -- This is necessary, but doesn't always work smoothly. -+ This is necessary, but doesn't always work smoothly. - * Standard Libraries:: GCC uses the system C library, which might not be -- compliant with the ISO C standard. -+ compliant with the ISO C standard. - * Disappointments:: Regrettable things we can't change, but not quite bugs. --* C++ Misunderstandings:: Common misunderstandings with GNU C++. -+* C++ Misunderstandings:: Common misunderstandings with GNU C++. - * Protoize Caveats:: Things to watch out for when using @code{protoize}. --* Non-bugs:: Things we think are right, but some others disagree. -+* Non-bugs:: Things we think are right, but some others disagree. - * Warnings and Errors:: Which problems in your code get warnings, -- and which get errors. -+ and which get errors. - @end menu - - @node Actual Bugs ---- a/gcc/dse.c -+++ b/gcc/dse.c -@@ -228,7 +228,7 @@ struct store_info - /* An bitmask as wide as the number of bytes in the word that - contains a 1 if the byte may be needed. The store is unused if - all of the bits are 0. */ -- long positions_needed; -+ unsigned HOST_WIDEST_INT positions_needed; - - /* The next store info for this insn. */ - struct store_info *next; -@@ -239,6 +239,15 @@ struct store_info - rtx rhs; - }; - -+/* Return a bitmask with the first N low bits set. */ -+ -+static unsigned HOST_WIDEST_INT -+lowpart_bitmask (int n) -+{ -+ unsigned HOST_WIDEST_INT mask = ~(unsigned HOST_WIDEST_INT) 0; -+ return mask >> (HOST_BITS_PER_WIDEST_INT - n); -+} -+ - typedef struct store_info *store_info_t; - static alloc_pool cse_store_info_pool; - static alloc_pool rtx_store_info_pool; -@@ -1153,6 +1162,39 @@ clear_rhs_from_active_local_stores (void - } - } - -+/* Mark byte POS bytes from the beginning of store S_INFO as unneeded. */ -+ -+static inline void -+set_position_unneeded (store_info_t s_info, int pos) -+{ -+ s_info->positions_needed &= ~(((unsigned HOST_WIDEST_INT) 1) << pos); -+} -+ -+/* Mark the whole store S_INFO as unneeded. */ -+ -+static inline void -+set_all_positions_unneeded (store_info_t s_info) -+{ -+ s_info->positions_needed = (unsigned HOST_WIDEST_INT) 0; -+} -+ -+/* Return TRUE if any bytes from S_INFO store are needed. */ -+ -+static inline bool -+any_positions_needed_p (store_info_t s_info) -+{ -+ return (s_info->positions_needed != (unsigned HOST_WIDEST_INT) 0); -+} -+ -+/* Return TRUE if all bytes START through START+WIDTH-1 from S_INFO -+ store are needed. */ -+ -+static inline bool -+all_positions_needed_p (store_info_t s_info, int start, int width) -+{ -+ unsigned HOST_WIDEST_INT mask = lowpart_bitmask (width) << start; -+ return (s_info->positions_needed & mask) == mask; -+} - - /* BODY is an instruction pattern that belongs to INSN. Return 1 if - there is a candidate store, after adding it to the appropriate -@@ -1223,6 +1265,7 @@ record_store (rtx body, bb_info_t bb_inf - } - - width = GET_MODE_SIZE (GET_MODE (mem)); -+ gcc_assert ((unsigned) width <= HOST_BITS_PER_WIDEST_INT); - - if (spill_alias_set) - { -@@ -1308,7 +1351,7 @@ record_store (rtx body, bb_info_t bb_inf - && (GET_MODE (mem) == entry->mode)) - { - delete = true; -- s_info->positions_needed = 0; -+ set_all_positions_unneeded (s_info); - } - if (dump_file) - fprintf (dump_file, " trying spill store in insn=%d alias_set=%d\n", -@@ -1322,9 +1365,10 @@ record_store (rtx body, bb_info_t bb_inf - fprintf (dump_file, " trying store in insn=%d gid=%d[%d..%d)\n", - INSN_UID (ptr->insn), s_info->group_id, - (int)s_info->begin, (int)s_info->end); -- for (i = offset; i < offset+width; i++) -- if (i >= s_info->begin && i < s_info->end) -- s_info->positions_needed &= ~(1L << (i - s_info->begin)); -+ for (i = MAX (offset, s_info->begin); -+ i < offset + width && i < s_info->end; -+ i++) -+ set_position_unneeded (s_info, i - s_info->begin); - } - else if (s_info->rhs) - /* Need to see if it is possible for this store to overwrite -@@ -1340,9 +1384,9 @@ record_store (rtx body, bb_info_t bb_inf - - /* An insn can be deleted if every position of every one of - its s_infos is zero. */ -- if (s_info->positions_needed != 0) -+ if (any_positions_needed_p (s_info)) - delete = false; -- -+ - if (delete) - { - insn_info_t insn_to_delete = ptr; -@@ -1360,8 +1404,6 @@ record_store (rtx body, bb_info_t bb_inf - ptr = next; - } - -- gcc_assert ((unsigned) width < sizeof (store_info->positions_needed) * CHAR_BIT); -- - /* Finish filling in the store_info. */ - store_info->next = insn_info->store_rec; - insn_info->store_rec = store_info; -@@ -1369,7 +1411,7 @@ record_store (rtx body, bb_info_t bb_inf - store_info->alias_set = spill_alias_set; - store_info->mem_addr = get_addr (XEXP (mem, 0)); - store_info->cse_base = base; -- store_info->positions_needed = (1L << width) - 1; -+ store_info->positions_needed = lowpart_bitmask (width); - store_info->group_id = group_id; - store_info->begin = offset; - store_info->end = offset + width; -@@ -1820,16 +1862,14 @@ check_mem_read_rtx (rtx *loc, void *data - else - { - if (store_info->rhs -- && (offset >= store_info->begin) -- && (offset + width <= store_info->end)) -- { -- int mask = ((1L << width) - 1) << (offset - store_info->begin); -- -- if ((store_info->positions_needed & mask) == mask -- && replace_read (store_info, i_ptr, -- read_info, insn_info, loc)) -- return 0; -- } -+ && offset >= store_info->begin -+ && offset + width <= store_info->end -+ && all_positions_needed_p (store_info, -+ offset - store_info->begin, -+ width) -+ && replace_read (store_info, i_ptr, read_info, -+ insn_info, loc)) -+ return 0; - /* The bases are the same, just see if the offsets - overlap. */ - if ((offset < store_info->end) -@@ -1887,16 +1927,12 @@ check_mem_read_rtx (rtx *loc, void *data - if (store_info->rhs - && store_info->group_id == -1 - && store_info->cse_base == base -- && (offset >= store_info->begin) -- && (offset + width <= store_info->end)) -- { -- int mask = ((1L << width) - 1) << (offset - store_info->begin); -- -- if ((store_info->positions_needed & mask) == mask -- && replace_read (store_info, i_ptr, -- read_info, insn_info, loc)) -- return 0; -- } -+ && offset >= store_info->begin -+ && offset + width <= store_info->end -+ && all_positions_needed_p (store_info, -+ offset - store_info->begin, width) -+ && replace_read (store_info, i_ptr, read_info, insn_info, loc)) -+ return 0; - - if (!store_info->alias_set) - remove = canon_true_dependence (store_info->mem, ---- a/gcc/dwarf2out.c -+++ b/gcc/dwarf2out.c -@@ -1705,7 +1705,7 @@ static dw_cfa_location cfa_temp; - static void - dwarf2out_frame_debug_expr (rtx expr, const char *label) - { -- rtx src, dest; -+ rtx src, dest, span; - HOST_WIDE_INT offset; - - /* If RTX_FRAME_RELATED_P is set on a PARALLEL, process each member of -@@ -2081,7 +2081,32 @@ dwarf2out_frame_debug_expr (rtx expr, co - } - - def_cfa_1 (label, &cfa); -- queue_reg_save (label, src, NULL_RTX, offset); -+ { -+ span = targetm.dwarf_register_span (src); -+ -+ if (!span) -+ queue_reg_save (label, src, NULL_RTX, offset); -+ else -+ { -+ /* We have a PARALLEL describing where the contents of SRC -+ live. Queue register saves for each piece of the -+ PARALLEL. */ -+ int par_index; -+ int limit; -+ HOST_WIDE_INT span_offset = offset; -+ -+ gcc_assert (GET_CODE (span) == PARALLEL); -+ -+ limit = XVECLEN (span, 0); -+ for (par_index = 0; par_index < limit; par_index++) -+ { -+ rtx elem = XVECEXP (span, 0, par_index); -+ -+ queue_reg_save (label, elem, NULL_RTX, span_offset); -+ span_offset += GET_MODE_SIZE (GET_MODE (elem)); -+ } -+ } -+ } - break; - - default: -@@ -3914,6 +3939,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. */ - -@@ -3947,6 +3973,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 -@@ -5334,12 +5361,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; - -@@ -5360,6 +5384,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; -@@ -14538,6 +14574,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/emit-rtl.c -+++ b/gcc/emit-rtl.c -@@ -1909,6 +1909,7 @@ adjust_address_1 (rtx memref, enum machi - rtx memoffset = MEM_OFFSET (memref); - rtx size = 0; - unsigned int memalign = MEM_ALIGN (memref); -+ int pbits; - - /* If there are no changes, just return the original memory reference. */ - if (mode == GET_MODE (memref) && !offset -@@ -1920,6 +1921,16 @@ adjust_address_1 (rtx memref, enum machi - (plus (plus reg reg) const_int) -- so do this always. */ - addr = copy_rtx (addr); - -+ /* Convert a possibly large offset to a signed value within the -+ range of the target address space. */ -+ pbits = GET_MODE_BITSIZE (Pmode); -+ if (HOST_BITS_PER_WIDE_INT > pbits) -+ { -+ int shift = HOST_BITS_PER_WIDE_INT - pbits; -+ offset = (((HOST_WIDE_INT) ((unsigned HOST_WIDE_INT) offset << shift)) -+ >> shift); -+ } -+ - if (adjust) - { - /* If MEMREF is a LO_SUM and the offset is within the alignment of the ---- a/gcc/explow.c -+++ b/gcc/explow.c -@@ -489,6 +489,7 @@ memory_address (enum machine_mode mode, - - done: - -+ gcc_assert (memory_address_p (mode, x)); - /* If we didn't change the address, we are done. Otherwise, mark - a reg as a pointer if we have REG or REG + CONST_INT. */ - if (oldx == x) -@@ -1489,9 +1490,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[NUM_MACHINE_MODES]; - static int neg_cost[NUM_MACHINE_MODES]; - static int shift_cost[NUM_MACHINE_MODES][MAX_BITS_PER_WORD]; - static int shiftadd_cost[NUM_MACHINE_MODES][MAX_BITS_PER_WORD]; --static int shiftsub_cost[NUM_MACHINE_MODES][MAX_BITS_PER_WORD]; -+static int shiftsub0_cost[NUM_MACHINE_MODES][MAX_BITS_PER_WORD]; -+static int shiftsub1_cost[NUM_MACHINE_MODES][MAX_BITS_PER_WORD]; - static int mul_cost[NUM_MACHINE_MODES]; - static int sdiv_cost[NUM_MACHINE_MODES]; - static int udiv_cost[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]; -@@ -202,9 +204,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 (mode = GET_CLASS_NARROWEST_MODE (MODE_INT); - mode != VOIDmode; -@@ -222,7 +228,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[mode] = rtx_cost (&all.plus, SET); - neg_cost[mode] = rtx_cost (&all.neg, SET); -@@ -248,7 +255,7 @@ init_expmed (void) - } - - shift_cost[mode][0] = 0; -- shiftadd_cost[mode][0] = shiftsub_cost[mode][0] = add_cost[mode]; -+ shiftadd_cost[mode][0] = shiftsub0_cost[mode][0] = shiftsub1_cost[mode][0] = add_cost[mode]; - - n = MIN (MAX_BITS_PER_WORD, GET_MODE_BITSIZE (mode)); - for (m = 1; m < n; m++) -@@ -258,7 +265,8 @@ init_expmed (void) - - shift_cost[mode][m] = rtx_cost (&all.shift, SET); - shiftadd_cost[mode][m] = rtx_cost (&all.shift_add, SET); -- shiftsub_cost[mode][m] = rtx_cost (&all.shift_sub, SET); -+ shiftsub0_cost[mode][m] = rtx_cost (&all.shift_sub0, SET); -+ shiftsub1_cost[mode][m] = rtx_cost (&all.shift_sub1, SET); - } - } - } -@@ -976,7 +984,10 @@ store_fixed_bit_field (rtx op0, unsigned - } - - if (op0 != temp) -- emit_move_insn (op0, temp); -+ { -+ op0 = copy_rtx (op0); -+ emit_move_insn (op0, temp); -+ } - } - - /* Store a bit field that is split across multiple accessible memory objects. -@@ -2426,6 +2437,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; -@@ -2568,6 +2580,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[mode], -+ shift_cost[mode][m]). */ -+ op_cost = m * add_cost[mode]; -+ if (shift_cost[mode][m] < op_cost) -+ op_cost = shift_cost[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; -@@ -2630,6 +2674,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[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; - } -@@ -2699,9 +2766,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[mode] + shift_cost[mode][m]; -- if (shiftsub_cost[mode][m] < op_cost) -+ if (shiftsub0_cost[mode][m] < op_cost) - { -- op_cost = shiftsub_cost[mode][m]; -+ op_cost = shiftsub0_cost[mode][m]; - op_latency = op_cost; - } - else -@@ -2764,7 +2831,7 @@ synth_mult (struct algorithm *alg_out, u - m = exact_log2 (q); - if (m >= 0 && m < maxm) - { -- op_cost = shiftsub_cost[mode][m]; -+ op_cost = shiftsub0_cost[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 -@@ -2038,10 +2038,55 @@ emit_group_store (rtx orig_dst, rtx src, - HOST_WIDE_INT bytepos = INTVAL (XEXP (XVECEXP (src, 0, i), 1)); - enum machine_mode mode = GET_MODE (tmps[i]); - unsigned int bytelen = GET_MODE_SIZE (mode); -+ unsigned int adj_bytelen = bytelen; - rtx dest = dst; - - /* Handle trailing fragments that run over the size of the struct. */ - if (ssize >= 0 && bytepos + (HOST_WIDE_INT) bytelen > ssize) -+ adj_bytelen = ssize - bytepos; -+ -+ if (GET_CODE (dst) == CONCAT) -+ { -+ if (bytepos + adj_bytelen -+ <= GET_MODE_SIZE (GET_MODE (XEXP (dst, 0)))) -+ dest = XEXP (dst, 0); -+ else if (bytepos >= GET_MODE_SIZE (GET_MODE (XEXP (dst, 0)))) -+ { -+ bytepos -= GET_MODE_SIZE (GET_MODE (XEXP (dst, 0))); -+ dest = XEXP (dst, 1); -+ } -+ else -+ { -+ enum machine_mode dest_mode = GET_MODE (dest); -+ enum machine_mode tmp_mode = GET_MODE (tmps[i]); -+ -+ gcc_assert (bytepos == 0 && XVECLEN (src, 0)); -+ -+ if (GET_MODE_ALIGNMENT (dest_mode) -+ >= GET_MODE_ALIGNMENT (tmp_mode)) -+ { -+ dest = assign_stack_temp (dest_mode, -+ GET_MODE_SIZE (dest_mode), -+ 0); -+ emit_move_insn (adjust_address (dest, -+ tmp_mode, -+ bytepos), -+ tmps[i]); -+ dst = dest; -+ } -+ else -+ { -+ dest = assign_stack_temp (tmp_mode, -+ GET_MODE_SIZE (tmp_mode), -+ 0); -+ emit_move_insn (dest, tmps[i]); -+ dst = adjust_address (dest, dest_mode, bytepos); -+ } -+ break; -+ } -+ } -+ -+ if (ssize >= 0 && bytepos + (HOST_WIDE_INT) bytelen > ssize) - { - /* store_bit_field always takes its value from the lsb. - Move the fragment to the lsb if it's not already there. */ -@@ -2059,28 +2104,7 @@ emit_group_store (rtx orig_dst, rtx src, - build_int_cst (NULL_TREE, shift), - tmps[i], 0); - } -- bytelen = ssize - bytepos; -- } -- -- if (GET_CODE (dst) == CONCAT) -- { -- if (bytepos + bytelen <= GET_MODE_SIZE (GET_MODE (XEXP (dst, 0)))) -- dest = XEXP (dst, 0); -- else if (bytepos >= GET_MODE_SIZE (GET_MODE (XEXP (dst, 0)))) -- { -- bytepos -= GET_MODE_SIZE (GET_MODE (XEXP (dst, 0))); -- dest = XEXP (dst, 1); -- } -- else -- { -- gcc_assert (bytepos == 0 && XVECLEN (src, 0)); -- dest = assign_stack_temp (GET_MODE (dest), -- GET_MODE_SIZE (GET_MODE (dest)), 0); -- emit_move_insn (adjust_address (dest, GET_MODE (tmps[i]), bytepos), -- tmps[i]); -- dst = dest; -- break; -- } -+ bytelen = adj_bytelen; - } - - /* Optimize the access just a bit. */ ---- a/gcc/expr.h -+++ b/gcc/expr.h -@@ -729,7 +729,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 -@@ -893,6 +893,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); -@@ -902,31 +903,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; -@@ -1390,6 +1390,9 @@ asm_insn_count (rtx body) - else - template = decode_asm_operands (body, NULL, NULL, NULL, NULL, NULL); - -+ if (*template == '\0') -+ return 0; -+ - for (; *template; template++) - if (IS_ASM_LOGICAL_LINE_SEPARATOR (*template, template) - || *template == '\n') -@@ -2003,48 +2006,41 @@ final_scan_insn (rtx insn, FILE *file, i - } - - 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 -@@ -2290,7 +2290,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/function.c -+++ b/gcc/function.c -@@ -73,6 +73,10 @@ along with GCC; see the file COPYING3. - #define LOCAL_ALIGNMENT(TYPE, ALIGNMENT) ALIGNMENT - #endif - -+#ifndef DATA_ALIGNMENT -+#define DATA_ALIGNMENT(TYPE, ALIGNMENT) ALIGNMENT -+#endif -+ - #ifndef STACK_ALIGNMENT_NEEDED - #define STACK_ALIGNMENT_NEEDED 1 - #endif -@@ -419,7 +423,7 @@ assign_stack_local_1 (enum machine_mode - stack slot. */ - type = lang_hooks.types.type_for_mode (mode, 0); - if (type) -- alignment = LOCAL_ALIGNMENT (type, alignment); -+ alignment = calculate_local_alignment (type, alignment); - - alignment /= BITS_PER_UNIT; - } -@@ -625,7 +629,7 @@ assign_stack_temp_for_type (enum machine - type = lang_hooks.types.type_for_mode (mode, 0); - - if (type) -- align = LOCAL_ALIGNMENT (type, align); -+ align = calculate_local_alignment (type, align); - - /* Try to find an available, already-allocated temporary of the proper - mode which meets the size and alignment requirements. Choose the -@@ -1530,6 +1534,7 @@ instantiate_virtual_regs_in_insn (rtx in - } - x = simplify_gen_subreg (recog_data.operand_mode[i], new, - GET_MODE (new), SUBREG_BYTE (x)); -+ gcc_assert (x); - break; - - default: -@@ -1845,6 +1850,9 @@ aggregate_value_p (const_tree exp, const - bool - use_register_for_decl (const_tree decl) - { -+ if (!targetm.calls.allocate_stack_slots_for_args()) -+ return true; -+ - /* Honor volatile. */ - if (TREE_SIDE_EFFECTS (decl)) - return false; -@@ -2425,6 +2433,30 @@ assign_parm_adjust_entry_rtl (struct ass - data->entry_parm = entry_parm; - } - -+/* A subroutine of assign_parms. Reconstitute any values which were -+ passed in multiple registers and would fit in a single register. */ -+ -+static void -+assign_parm_remove_parallels (struct assign_parm_data_one *data) -+{ -+ rtx entry_parm = data->entry_parm; -+ -+ /* Convert the PARALLEL to a REG of the same mode as the parallel. -+ This can be done with register operations rather than on the -+ stack, even if we will store the reconstituted parameter on the -+ stack later. */ -+ if (GET_CODE (entry_parm) == PARALLEL -+ && data->passed_mode != BLKmode) -+ { -+ rtx parmreg = gen_reg_rtx (GET_MODE (entry_parm)); -+ emit_group_store (parmreg, entry_parm, NULL_TREE, -+ GET_MODE_SIZE (GET_MODE (entry_parm))); -+ entry_parm = parmreg; -+ } -+ -+ data->entry_parm = entry_parm; -+} -+ - /* A subroutine of assign_parms. Adjust DATA->STACK_RTL such that it's - always valid and properly aligned. */ - -@@ -2470,8 +2502,6 @@ assign_parm_setup_block_p (struct assign - { - if (data->nominal_mode == BLKmode) - return true; -- if (GET_CODE (data->entry_parm) == PARALLEL) -- return true; - - #ifdef BLOCK_REG_PADDING - /* Only assign_parm_setup_block knows how to deal with register arguments -@@ -2497,59 +2527,10 @@ assign_parm_setup_block (struct assign_p - rtx stack_parm = data->stack_parm; - HOST_WIDE_INT size; - HOST_WIDE_INT size_stored; -- rtx orig_entry_parm = entry_parm; - - if (GET_CODE (entry_parm) == PARALLEL) - entry_parm = emit_group_move_into_temps (entry_parm); - -- /* If we've a non-block object that's nevertheless passed in parts, -- reconstitute it in register operations rather than on the stack. */ -- if (GET_CODE (entry_parm) == PARALLEL -- && data->nominal_mode != BLKmode) -- { -- rtx elt0 = XEXP (XVECEXP (orig_entry_parm, 0, 0), 0); -- -- if ((XVECLEN (entry_parm, 0) > 1 -- || hard_regno_nregs[REGNO (elt0)][GET_MODE (elt0)] > 1) -- && use_register_for_decl (parm)) -- { -- rtx parmreg = gen_reg_rtx (data->nominal_mode); -- -- push_to_sequence2 (all->first_conversion_insn, -- all->last_conversion_insn); -- -- /* For values returned in multiple registers, handle possible -- incompatible calls to emit_group_store. -- -- For example, the following would be invalid, and would have to -- be fixed by the conditional below: -- -- emit_group_store ((reg:SF), (parallel:DF)) -- emit_group_store ((reg:SI), (parallel:DI)) -- -- An example of this are doubles in e500 v2: -- (parallel:DF (expr_list (reg:SI) (const_int 0)) -- (expr_list (reg:SI) (const_int 4))). */ -- if (data->nominal_mode != data->passed_mode) -- { -- rtx t = gen_reg_rtx (GET_MODE (entry_parm)); -- emit_group_store (t, entry_parm, NULL_TREE, -- GET_MODE_SIZE (GET_MODE (entry_parm))); -- convert_move (parmreg, t, 0); -- } -- else -- emit_group_store (parmreg, entry_parm, data->nominal_type, -- int_size_in_bytes (data->nominal_type)); -- -- all->first_conversion_insn = get_insns (); -- all->last_conversion_insn = get_last_insn (); -- end_sequence (); -- -- SET_DECL_RTL (parm, parmreg); -- return; -- } -- } -- - size = int_size_in_bytes (data->passed_type); - size_stored = CEIL_ROUND (size, UNITS_PER_WORD); - if (stack_parm == 0) -@@ -2714,6 +2695,8 @@ assign_parm_setup_reg (struct assign_par - else - SET_DECL_RTL (parm, parmreg); - -+ assign_parm_remove_parallels (data); -+ - /* Copy the value into the register. */ - if (data->nominal_mode != data->passed_mode - || promoted_nominal_mode != data->promoted_mode) -@@ -2876,6 +2859,8 @@ assign_parm_setup_stack (struct assign_p - execution. */ - bool to_conversion = false; - -+ assign_parm_remove_parallels (data); -+ - if (data->promoted_mode != data->nominal_mode) - { - /* Conversion is required. */ -@@ -5560,6 +5545,77 @@ current_function_assembler_name (void) - { - return IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (cfun->decl)); - } -+ -+/* Helper function for below. 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. */ -+ -+static 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 || 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); -+} -+ -+/* Return the alignment in bits to be used for a local variable -+ of type TY whose usual alignment would be EXISTING_ALIGNMENT. */ -+ -+unsigned int -+calculate_local_alignment (tree ty, unsigned int existing_alignment) -+{ -+ return alignment_for_aligned_arrays (ty, -+ LOCAL_ALIGNMENT (ty, existing_alignment)); -+} -+ -+/* Return the alignment in bits to be used for a global variable -+ of type TY whose usual alignment would be EXISTING_ALIGNMENT. */ -+ -+unsigned int -+calculate_global_alignment (tree ty, unsigned int existing_alignment) -+{ -+ return alignment_for_aligned_arrays (ty, -+ DATA_ALIGNMENT (ty, existing_alignment)); -+} - - - static unsigned int ---- a/gcc/function.h -+++ b/gcc/function.h -@@ -594,4 +594,10 @@ extern bool reference_callee_copied (CUM - extern void used_types_insert (tree); - - extern int get_next_funcdef_no (void); -+ -+extern unsigned int calculate_local_alignment ( -+ tree ty, unsigned int existing_alignment); -+extern unsigned int calculate_global_alignment ( -+ tree ty, unsigned int existing_alignment); -+ - #endif /* GCC_FUNCTION_H */ ---- a/gcc/gcc.c -+++ b/gcc/gcc.c -@@ -155,6 +155,8 @@ static const char *print_prog_name = NUL - - static int print_multi_directory; - -+static int print_sysroot; -+ - /* Flag saying to print the relative path we'd use to - find OS libraries given the current compiler flags. */ - -@@ -643,8 +645,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. */ -@@ -720,6 +746,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}\ -@@ -874,7 +902,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 -@@ -1150,6 +1178,7 @@ static const struct option_map option_ma - {"--print-multi-directory", "-print-multi-directory", 0}, - {"--print-multi-os-directory", "-print-multi-os-directory", 0}, - {"--print-prog-name", "-print-prog-name=", "aj"}, -+ {"--print-sysroot", "-print-sysroot", 0}, - {"--print-sysroot-headers-suffix", "-print-sysroot-headers-suffix", 0}, - {"--profile", "-p", 0}, - {"--profile-blocks", "-a", 0}, -@@ -3224,6 +3253,7 @@ display_help (void) - -print-multi-lib Display the mapping between command line options and\n\ - multiple library search directories\n"), stdout); - fputs (_(" -print-multi-os-directory Display the relative path to OS libraries\n"), stdout); -+ fputs (_(" -print-sysroot Display the target libraries directory\n"), stdout); - fputs (_(" -print-sysroot-headers-suffix Display the sysroot suffix used to find headers\n"), stdout); - fputs (_(" -Wa, Pass comma-separated on to the assembler\n"), stdout); - fputs (_(" -Wp, Pass comma-separated on to the preprocessor\n"), stdout); -@@ -3668,6 +3698,8 @@ warranty; not even for MERCHANTABILITY o - print_multi_lib = 1; - else if (! strcmp (argv[i], "-print-multi-directory")) - print_multi_directory = 1; -+ else if (! strcmp (argv[i], "-print-sysroot")) -+ print_sysroot = 1; - else if (! strcmp (argv[i], "-print-multi-os-directory")) - print_multi_os_directory = 1; - else if (! strcmp (argv[i], "-print-sysroot-headers-suffix")) -@@ -4099,6 +4131,8 @@ warranty; not even for MERCHANTABILITY o - ; - else if (! strcmp (argv[i], "-print-multi-directory")) - ; -+ else if (! strcmp (argv[i], "-print-sysroot")) -+ ; - else if (! strcmp (argv[i], "-print-multi-os-directory")) - ; - else if (! strcmp (argv[i], "-print-sysroot-headers-suffix")) -@@ -4518,28 +4552,51 @@ 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 = xrealloc (switches, -- sizeof (struct switchstr) * (n_switches + 1)); -- -- switches[n_switches] = switches[first]; -+ n = n_switches + argbuf_index; -+ switches = xrealloc (switches, sizeof (struct switchstr) * (n + 1)); -+ switches[n] = 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++; - } - } - } -@@ -6455,6 +6512,18 @@ main (int argc, char **argv) - return (0); - } - -+ if (print_sysroot) -+ { -+ if (target_system_root) -+ { -+ if (target_sysroot_suffix) -+ printf ("%s%s\n", target_system_root, target_sysroot_suffix); -+ else -+ printf ("%s\n", target_system_root); -+ } -+ return (0); -+ } -+ - if (print_multi_os_directory) - { - if (multilib_os_dir == NULL) -@@ -7949,7 +8018,7 @@ include_spec_function (int argc, const c - if (argc != 1) - abort (); - -- file = find_a_file (&startfile_prefixes, argv[0], R_OK, 0); -+ file = find_a_file (&startfile_prefixes, argv[0], R_OK, true); - read_specs (file ? file : argv[0], FALSE); - - return NULL; ---- a/gcc/gengtype-lex.c -+++ /dev/null -@@ -1,2636 +0,0 @@ --#line 2 "gengtype-lex.c" -- --#line 4 "gengtype-lex.c" -- --#define YY_INT_ALIGNED short int -- --/* A lexical scanner generated by flex */ -- --#define FLEX_SCANNER --#define YY_FLEX_MAJOR_VERSION 2 --#define YY_FLEX_MINOR_VERSION 5 --#define YY_FLEX_SUBMINOR_VERSION 35 --#if YY_FLEX_SUBMINOR_VERSION > 0 --#define FLEX_BETA --#endif -- --/* First, we deal with platform-specific or compiler-specific issues. */ -- --/* begin standard C headers. */ --#include --#include --#include --#include -- --/* end standard C headers. */ -- --/* flex integer type definitions */ -- --#ifndef FLEXINT_H --#define FLEXINT_H -- --/* C99 systems have . Non-C99 systems may or may not. */ -- --#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L -- --/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, -- * if you want the limit (max/min) macros for int types. -- */ --#ifndef __STDC_LIMIT_MACROS --#define __STDC_LIMIT_MACROS 1 --#endif -- --#include --typedef int8_t flex_int8_t; --typedef uint8_t flex_uint8_t; --typedef int16_t flex_int16_t; --typedef uint16_t flex_uint16_t; --typedef int32_t flex_int32_t; --typedef uint32_t flex_uint32_t; --#else --typedef signed char flex_int8_t; --typedef short int flex_int16_t; --typedef int flex_int32_t; --typedef unsigned char flex_uint8_t; --typedef unsigned short int flex_uint16_t; --typedef unsigned int flex_uint32_t; --#endif /* ! C99 */ -- --/* Limits of integral types. */ --#ifndef INT8_MIN --#define INT8_MIN (-128) --#endif --#ifndef INT16_MIN --#define INT16_MIN (-32767-1) --#endif --#ifndef INT32_MIN --#define INT32_MIN (-2147483647-1) --#endif --#ifndef INT8_MAX --#define INT8_MAX (127) --#endif --#ifndef INT16_MAX --#define INT16_MAX (32767) --#endif --#ifndef INT32_MAX --#define INT32_MAX (2147483647) --#endif --#ifndef UINT8_MAX --#define UINT8_MAX (255U) --#endif --#ifndef UINT16_MAX --#define UINT16_MAX (65535U) --#endif --#ifndef UINT32_MAX --#define UINT32_MAX (4294967295U) --#endif -- --#endif /* ! FLEXINT_H */ -- --#ifdef __cplusplus -- --/* The "const" storage-class-modifier is valid. */ --#define YY_USE_CONST -- --#else /* ! __cplusplus */ -- --/* C99 requires __STDC__ to be defined as 1. */ --#if defined (__STDC__) -- --#define YY_USE_CONST -- --#endif /* defined (__STDC__) */ --#endif /* ! __cplusplus */ -- --#ifdef YY_USE_CONST --#define yyconst const --#else --#define yyconst --#endif -- --/* Returned upon end-of-file. */ --#define YY_NULL 0 -- --/* Promotes a possibly negative, possibly signed char to an unsigned -- * integer for use as an array index. If the signed char is negative, -- * we want to instead treat it as an 8-bit unsigned char, hence the -- * double cast. -- */ --#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) -- --/* Enter a start condition. This macro really ought to take a parameter, -- * but we do it the disgusting crufty way forced on us by the ()-less -- * definition of BEGIN. -- */ --#define BEGIN (yy_start) = 1 + 2 * -- --/* Translate the current start state into a value that can be later handed -- * to BEGIN to return to the state. The YYSTATE alias is for lex -- * compatibility. -- */ --#define YY_START (((yy_start) - 1) / 2) --#define YYSTATE YY_START -- --/* Action number for EOF rule of a given start state. */ --#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) -- --/* Special action meaning "start processing a new file". */ --#define YY_NEW_FILE yyrestart(yyin ) -- --#define YY_END_OF_BUFFER_CHAR 0 -- --/* Size of default input buffer. */ --#ifndef YY_BUF_SIZE --#define YY_BUF_SIZE 16384 --#endif -- --/* The state buf must be large enough to hold one state per character in the main buffer. -- */ --#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) -- --#ifndef YY_TYPEDEF_YY_BUFFER_STATE --#define YY_TYPEDEF_YY_BUFFER_STATE --typedef struct yy_buffer_state *YY_BUFFER_STATE; --#endif -- --extern int yyleng; -- --extern FILE *yyin, *yyout; -- --#define EOB_ACT_CONTINUE_SCAN 0 --#define EOB_ACT_END_OF_FILE 1 --#define EOB_ACT_LAST_MATCH 2 -- -- #define YY_LESS_LINENO(n) -- --/* Return all but the first "n" matched characters back to the input stream. */ --#define yyless(n) \ -- do \ -- { \ -- /* Undo effects of setting up yytext. */ \ -- int yyless_macro_arg = (n); \ -- YY_LESS_LINENO(yyless_macro_arg);\ -- *yy_cp = (yy_hold_char); \ -- YY_RESTORE_YY_MORE_OFFSET \ -- (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ -- YY_DO_BEFORE_ACTION; /* set up yytext again */ \ -- } \ -- while ( 0 ) -- --#define unput(c) yyunput( c, (yytext_ptr) ) -- --#ifndef YY_TYPEDEF_YY_SIZE_T --#define YY_TYPEDEF_YY_SIZE_T --typedef size_t yy_size_t; --#endif -- --#ifndef YY_STRUCT_YY_BUFFER_STATE --#define YY_STRUCT_YY_BUFFER_STATE --struct yy_buffer_state -- { -- FILE *yy_input_file; -- -- char *yy_ch_buf; /* input buffer */ -- char *yy_buf_pos; /* current position in input buffer */ -- -- /* Size of input buffer in bytes, not including room for EOB -- * characters. -- */ -- yy_size_t yy_buf_size; -- -- /* Number of characters read into yy_ch_buf, not including EOB -- * characters. -- */ -- int yy_n_chars; -- -- /* Whether we "own" the buffer - i.e., we know we created it, -- * and can realloc() it to grow it, and should free() it to -- * delete it. -- */ -- int yy_is_our_buffer; -- -- /* Whether this is an "interactive" input source; if so, and -- * if we're using stdio for input, then we want to use getc() -- * instead of fread(), to make sure we stop fetching input after -- * each newline. -- */ -- int yy_is_interactive; -- -- /* Whether we're considered to be at the beginning of a line. -- * If so, '^' rules will be active on the next match, otherwise -- * not. -- */ -- int yy_at_bol; -- -- int yy_bs_lineno; /**< The line count. */ -- int yy_bs_column; /**< The column count. */ -- -- /* Whether to try to fill the input buffer when we reach the -- * end of it. -- */ -- int yy_fill_buffer; -- -- int yy_buffer_status; -- --#define YY_BUFFER_NEW 0 --#define YY_BUFFER_NORMAL 1 -- /* When an EOF's been seen but there's still some text to process -- * then we mark the buffer as YY_EOF_PENDING, to indicate that we -- * shouldn't try reading from the input source any more. We might -- * still have a bunch of tokens to match, though, because of -- * possible backing-up. -- * -- * When we actually see the EOF, we change the status to "new" -- * (via yyrestart()), so that the user can continue scanning by -- * just pointing yyin at a new input file. -- */ --#define YY_BUFFER_EOF_PENDING 2 -- -- }; --#endif /* !YY_STRUCT_YY_BUFFER_STATE */ -- --/* Stack of input buffers. */ --static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ --static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ --static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ -- --/* We provide macros for accessing buffer states in case in the -- * future we want to put the buffer states in a more general -- * "scanner state". -- * -- * Returns the top of the stack, or NULL. -- */ --#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ -- ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ -- : NULL) -- --/* Same as previous macro, but useful when we know that the buffer stack is not -- * NULL or when we need an lvalue. For internal use only. -- */ --#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] -- --/* yy_hold_char holds the character lost when yytext is formed. */ --static char yy_hold_char; --static int yy_n_chars; /* number of characters read into yy_ch_buf */ --int yyleng; -- --/* Points to current character in buffer. */ --static char *yy_c_buf_p = (char *) 0; --static int yy_init = 0; /* whether we need to initialize */ --static int yy_start = 0; /* start state number */ -- --/* Flag which is used to allow yywrap()'s to do buffer switches -- * instead of setting up a fresh yyin. A bit of a hack ... -- */ --static int yy_did_buffer_switch_on_eof; -- --void yyrestart (FILE *input_file ); --void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ); --YY_BUFFER_STATE yy_create_buffer (FILE *file,int size ); --void yy_delete_buffer (YY_BUFFER_STATE b ); --void yy_flush_buffer (YY_BUFFER_STATE b ); --void yypush_buffer_state (YY_BUFFER_STATE new_buffer ); --void yypop_buffer_state (void ); -- --static void yyensure_buffer_stack (void ); --static void yy_load_buffer_state (void ); --static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ); -- --#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER ) -- --YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ); --YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ); --YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len ); -- --void *yyalloc (yy_size_t ); --void *yyrealloc (void *,yy_size_t ); --void yyfree (void * ); -- --#define yy_new_buffer yy_create_buffer -- --#define yy_set_interactive(is_interactive) \ -- { \ -- if ( ! YY_CURRENT_BUFFER ){ \ -- yyensure_buffer_stack (); \ -- YY_CURRENT_BUFFER_LVALUE = \ -- yy_create_buffer(yyin,YY_BUF_SIZE ); \ -- } \ -- YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ -- } -- --#define yy_set_bol(at_bol) \ -- { \ -- if ( ! YY_CURRENT_BUFFER ){\ -- yyensure_buffer_stack (); \ -- YY_CURRENT_BUFFER_LVALUE = \ -- yy_create_buffer(yyin,YY_BUF_SIZE ); \ -- } \ -- YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ -- } -- --#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) -- --/* Begin user sect3 */ -- --#define yywrap(n) 1 --#define YY_SKIP_YYWRAP -- --typedef unsigned char YY_CHAR; -- --FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; -- --typedef int yy_state_type; -- --extern int yylineno; -- --int yylineno = 1; -- --extern char *yytext; --#define yytext_ptr yytext -- --static yy_state_type yy_get_previous_state (void ); --static yy_state_type yy_try_NUL_trans (yy_state_type current_state ); --static int yy_get_next_buffer (void ); --static void yy_fatal_error (yyconst char msg[] ); -- --/* Done after the current pattern has been matched and before the -- * corresponding action - sets up yytext. -- */ --#define YY_DO_BEFORE_ACTION \ -- (yytext_ptr) = yy_bp; \ -- yyleng = (size_t) (yy_cp - yy_bp); \ -- (yy_hold_char) = *yy_cp; \ -- *yy_cp = '\0'; \ -- (yy_c_buf_p) = yy_cp; -- --#define YY_NUM_RULES 49 --#define YY_END_OF_BUFFER 50 --/* This struct is not used in this scanner, -- but its presence is necessary. */ --struct yy_trans_info -- { -- flex_int32_t yy_verify; -- flex_int32_t yy_nxt; -- }; --static yyconst flex_int16_t yy_accept[445] = -- { 0, -- 0, 0, 0, 0, 0, 0, 0, 0, 50, 36, -- 36, 33, 45, 36, 45, 34, 36, 36, 34, 34, -- 34, 34, 34, 31, 10, 10, 31, 29, 31, 31, -- 31, 20, 31, 31, 31, 31, 31, 31, 31, 31, -- 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, -- 31, 10, 31, 41, 39, 46, 46, 0, 0, 0, -- 37, 0, 0, 0, 38, 32, 34, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 34, 34, 34, 34, -- 34, 10, 0, 25, 0, 0, 0, 0, 9, 20, -- 24, 0, 0, 0, 0, 0, 0, 0, 0, 26, -- -- 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, -- 42, 44, 43, 0, 35, 0, 0, 0, 0, 0, -- 0, 34, 34, 34, 34, 34, 34, 27, 28, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 34, 34, 34, 34, 34, 34, -- 0, 0, 0, 13, 0, 14, 0, 0, 0, 0, -- 22, 22, 0, 0, 0, 0, 0, 0, 0, 0, -- -- 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, -- 0, 34, 34, 34, 34, 34, 34, 0, 0, 0, -- 0, 0, 17, 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, 34, -- 34, 34, 34, 34, 3, 0, 0, 0, 0, 12, -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, -- 0, 0, 0, 0, 34, 4, 5, 2, 34, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, -- 0, 0, 0, 0, 34, 1, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 22, 22, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 34, 34, 34, -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 21, 0, 0, 0, 0, 0, 0, 34, 7, 6, -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, -- 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, -- 0, 0, 19, 0, 0, 47, 34, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, -- -- 0, 0, 0, 0, 0, 0, 34, 0, 24, 24, -- 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, -- 0, 23, 0, 0, 0, 0, 0, 40, 0, 0, -- 0, 0, 0, 0 -- } ; -- --static yyconst flex_int32_t yy_ec[256] = -- { 0, -- 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, -- 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, -- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -- 1, 2, 1, 4, 5, 1, 6, 1, 7, 8, -- 9, 10, 1, 6, 6, 11, 12, 13, 13, 13, -- 13, 13, 13, 13, 13, 13, 13, 6, 6, 6, -- 6, 6, 1, 1, 14, 15, 16, 17, 18, 19, -- 20, 21, 22, 23, 23, 24, 25, 26, 27, 28, -- 23, 29, 30, 31, 32, 33, 34, 23, 35, 23, -- 36, 37, 38, 1, 39, 1, 40, 41, 42, 43, -- -- 44, 45, 46, 47, 48, 49, 49, 50, 51, 52, -- 53, 54, 49, 55, 56, 57, 58, 59, 49, 60, -- 61, 62, 6, 6, 6, 1, 1, 1, 1, 1, -- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -- -- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -- 1, 1, 1, 1, 1 -- } ; -- --static yyconst flex_int32_t yy_meta[63] = -- { 0, -- 1, 2, 3, 1, 1, 1, 1, 1, 4, 5, -- 1, 1, 6, 7, 7, 7, 7, 7, 7, 7, -- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -- 7, 7, 7, 7, 7, 8, 1, 1, 9, 9, -- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, -- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, -- 9, 9 -- } ; -- --static yyconst flex_int16_t yy_base[483] = -- { 0, -- 0, 38, 96, 12, 12, 13, 15, 16, 1028, 1444, -- 32, 51, 20, 990, 1016, 0, 157, 18, 1007, 964, -- 966, 961, 969, 1444, 25, 27, 27, 1444, 983, 1008, -- 1008, 1004, 215, 253, 5, 32, 29, 974, 45, 962, -- 996, 35, 38, 39, 40, 41, 134, 42, 136, 137, -- 138, 75, 996, 0, 1444, 985, 984, 166, 964, 162, -- 1444, 0, 987, 990, 1444, 1444, 0, 186, 165, 974, -- 931, 933, 928, 936, 168, 943, 967, 928, 140, 930, -- 935, 87, 167, 1444, 979, 974, 977, 968, 1444, 950, -- 1444, 935, 934, 145, 52, 46, 148, 165, 922, 1444, -- -- 1444, 152, 156, 155, 170, 173, 175, 182, 183, 185, -- 211, 214, 222, 218, 221, 269, 957, 956, 291, 0, -- 1444, 1444, 1444, 922, 1444, 937, 898, 195, 900, 905, -- 907, 912, 906, 892, 890, 903, 893, 1444, 1444, 209, -- 254, 251, 353, 248, 391, 354, 350, 351, 340, 355, -- 341, 429, 339, 356, 344, 347, 360, 390, 43, 361, -- 391, 395, 429, 1444, 0, 0, 280, 906, 900, 886, -- 884, 897, 872, 876, 890, 867, 873, 878, 876, 866, -- 381, 348, 382, 1444, 384, 1444, 389, 397, 491, 398, -- 1444, 528, 418, 399, 420, 477, 478, 422, 421, 480, -- -- 479, 0, 449, 1444, 884, 861, 867, 872, 870, 860, -- 859, 892, 857, 866, 850, 862, 586, 493, 496, 494, -- 484, 624, 1444, 0, 878, 876, 876, 834, 839, 841, -- 832, 830, 199, 830, 490, 499, 486, 492, 488, 489, -- 662, 0, 863, 828, 837, 821, 833, 0, 832, 859, -- 700, 738, 776, 829, 1444, 431, 258, 437, 515, 1444, -- 846, 844, 841, 817, 829, 809, 319, 815, 813, 478, -- 809, 512, 528, 520, 525, 814, 1444, 0, 833, 0, -- 0, 0, 803, 551, 808, 1444, 1444, 1444, 852, 383, -- 521, 530, 539, 822, 829, 813, 793, 787, 802, 801, -- -- 556, 793, 783, 785, 792, 787, 523, 545, 535, 1444, -- 0, 795, 0, 561, 585, 1444, 555, 343, 581, 584, -- 794, 811, 792, 773, 772, 1444, 0, 771, 783, 772, -- 764, 552, 890, 558, 0, 623, 778, 784, 928, 966, -- 583, 593, 594, 613, 792, 792, 771, 761, 746, 591, -- 1444, 1004, 0, 778, 0, 0, 766, 776, 1444, 1444, -- 620, 621, 626, 627, 653, 777, 769, 775, 1042, 1444, -- 0, 772, 787, 767, 556, 577, 615, 649, 629, 762, -- 753, 774, 1444, 0, 763, 1444, 773, 632, 659, 662, -- 656, 654, 754, 742, 753, 0, 754, 729, 665, 688, -- -- 667, 744, 742, 683, 0, 695, 692, 689, 715, 722, -- 699, 711, 701, 666, 673, 0, 705, 1080, 704, 749, -- 751, 753, 756, 663, 658, 618, 593, 0, 0, 1444, -- 758, 1444, 760, 600, 588, 543, 483, 1444, 439, 386, -- 247, 206, 167, 1444, 1118, 1127, 1136, 1145, 1154, 1158, -- 1167, 1176, 1185, 1194, 1202, 1211, 1220, 1229, 1238, 1247, -- 1256, 1265, 1273, 1282, 1290, 1298, 1306, 1314, 1323, 1331, -- 1340, 1349, 1357, 1365, 1374, 1383, 1392, 1400, 1409, 1417, -- 1426, 1435 -- } ; -- --static yyconst flex_int16_t yy_def[483] = -- { 0, -- 445, 445, 444, 3, 446, 446, 446, 446, 444, 444, -- 444, 444, 447, 448, 449, 450, 444, 444, 450, 450, -- 450, 450, 450, 444, 444, 444, 451, 444, 452, 444, -- 444, 444, 453, 453, 34, 34, 34, 34, 34, 454, -- 444, 34, 34, 34, 34, 34, 34, 34, 34, 34, -- 34, 444, 455, 456, 444, 457, 457, 444, 444, 447, -- 444, 447, 444, 448, 444, 444, 450, 444, 444, 444, -- 444, 444, 444, 444, 444, 444, 450, 450, 450, 450, -- 450, 444, 451, 444, 451, 444, 452, 444, 444, 444, -- 444, 34, 34, 34, 34, 34, 34, 34, 454, 444, -- -- 444, 34, 34, 34, 34, 34, 34, 34, 34, 34, -- 34, 34, 34, 34, 34, 444, 455, 455, 444, 458, -- 444, 444, 444, 444, 444, 444, 444, 444, 444, 444, -- 444, 450, 450, 450, 450, 450, 450, 444, 444, 34, -- 34, 34, 453, 34, 453, 34, 34, 34, 34, 34, -- 34, 453, 34, 34, 34, 34, 34, 34, 34, 34, -- 34, 34, 119, 444, 119, 459, 444, 444, 444, 444, -- 444, 444, 444, 444, 450, 450, 450, 450, 450, 450, -- 34, 34, 34, 444, 34, 444, 34, 34, 453, 34, -- 444, 444, 34, 34, 34, 34, 34, 34, 34, 34, -- -- 34, 460, 444, 444, 444, 444, 444, 444, 444, 444, -- 444, 450, 450, 450, 450, 450, 450, 34, 34, 34, -- 34, 453, 444, 192, 444, 444, 444, 444, 444, 444, -- 444, 444, 444, 444, 34, 34, 34, 34, 34, 34, -- 453, 461, 444, 444, 444, 444, 444, 462, 444, 450, -- 450, 450, 450, 450, 444, 34, 34, 34, 34, 444, -- 444, 444, 444, 444, 444, 444, 444, 444, 444, 444, -- 444, 34, 34, 34, 34, 453, 444, 463, 444, 464, -- 465, 466, 444, 444, 450, 444, 444, 444, 450, 34, -- 34, 34, 34, 444, 444, 444, 444, 444, 444, 444, -- -- 467, 444, 444, 444, 444, 444, 34, 34, 34, 444, -- 468, 444, 469, 444, 450, 444, 34, 34, 34, 34, -- 444, 444, 444, 444, 444, 444, 192, 444, 444, 444, -- 444, 34, 453, 34, 470, 444, 444, 450, 450, 450, -- 34, 34, 34, 34, 444, 444, 444, 444, 444, 34, -- 444, 453, 471, 444, 472, 473, 444, 450, 444, 444, -- 34, 34, 34, 34, 34, 444, 444, 444, 453, 444, -- 474, 444, 444, 450, 34, 34, 34, 34, 34, 444, -- 444, 444, 444, 475, 444, 444, 450, 34, 34, 34, -- 34, 34, 444, 444, 444, 476, 444, 450, 34, 34, -- -- 34, 444, 444, 444, 477, 444, 450, 34, 444, 478, -- 34, 444, 444, 444, 444, 479, 444, 450, 34, 444, -- 478, 478, 480, 444, 444, 444, 444, 481, 482, 444, -- 444, 444, 480, 444, 444, 444, 444, 444, 444, 444, -- 444, 444, 444, 0, 444, 444, 444, 444, 444, 444, -- 444, 444, 444, 444, 444, 444, 444, 444, 444, 444, -- 444, 444, 444, 444, 444, 444, 444, 444, 444, 444, -- 444, 444, 444, 444, 444, 444, 444, 444, 444, 444, -- 444, 444 -- } ; -- --static yyconst flex_int16_t yy_nxt[1507] = -- { 0, -- 10, 11, 12, 13, 10, 10, 14, 10, 10, 10, -- 10, 15, 10, 52, 55, 55, 53, 55, 55, 75, -- 444, 56, 56, 61, 57, 57, 82, 82, 82, 82, -- 84, 92, 94, 58, 58, 10, 10, 10, 10, 17, -- 12, 13, 18, 10, 14, 10, 10, 10, 10, 15, -- 10, 59, 58, 58, 19, 92, 62, 95, 92, 96, -- 76, 92, 98, 85, 92, 92, 92, 92, 92, 92, -- 59, 92, 92, 10, 10, 10, 116, 82, 92, 117, -- 143, 20, 105, 142, 103, 109, 198, 102, 82, 82, -- 104, 106, 107, 21, 22, 23, 24, 25, 26, 27, -- -- 24, 28, 29, 28, 28, 28, 30, 31, 32, 33, -- 34, 35, 33, 36, 33, 37, 38, 33, 33, 33, -- 33, 33, 33, 33, 33, 33, 33, 33, 39, 33, -- 33, 40, 41, 24, 33, 33, 42, 43, 44, 45, -- 33, 33, 33, 46, 33, 47, 33, 48, 33, 49, -- 33, 50, 33, 51, 33, 33, 33, 33, 68, 58, -- 92, 69, 92, 92, 92, 61, 75, 58, 58, 75, -- 84, 92, 141, 70, 92, 110, 59, 144, 92, 134, -- 145, 92, 92, 112, 113, 59, 108, 68, 58, 115, -- 69, 92, 111, 114, 135, 147, 92, 301, 62, 92, -- -- 71, 92, 70, 85, 146, 59, 148, 76, 92, 92, -- 76, 92, 72, 73, 74, 91, 91, 91, 91, 91, -- 91, 91, 91, 91, 91, 91, 91, 151, 149, 71, -- 150, 152, 181, 153, 170, 92, 301, 92, 154, 155, -- 92, 72, 73, 74, 92, 269, 270, 92, 92, 171, -- 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, -- 91, 91, 91, 91, 91, 156, 157, 158, 161, 182, -- 116, 82, 160, 117, 92, 183, 162, 92, 185, 93, -- 92, 203, 203, 159, 92, 443, 291, 204, 91, 91, -- 91, 163, 163, 164, 163, 163, 163, 163, 163, 163, -- -- 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, -- 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, -- 163, 163, 163, 163, 163, 163, 163, 163, 163, 165, -- 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -- 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -- 165, 165, 165, 184, 184, 184, 184, 184, 184, 184, -- 184, 184, 184, 184, 184, 92, 92, 92, 219, 92, -- 92, 300, 342, 92, 92, 301, 92, 92, 188, 190, -- 92, 92, 92, 194, 152, 195, 92, 92, 184, 184, -- 184, 186, 186, 186, 186, 186, 186, 186, 186, 186, -- -- 186, 186, 186, 152, 152, 189, 187, 92, 92, 92, -- 92, 442, 193, 317, 196, 92, 92, 92, 199, 218, -- 220, 92, 221, 92, 92, 92, 186, 186, 186, 191, -- 192, 192, 191, 191, 191, 191, 191, 191, 191, 191, -- 191, 197, 201, 200, 92, 222, 92, 92, 92, 236, -- 203, 203, 290, 152, 152, 441, 204, 92, 292, 237, -- 239, 235, 240, 92, 191, 191, 191, 163, 163, 163, -- 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, -- 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, -- 163, 223, 223, 223, 223, 223, 223, 223, 223, 223, -- -- 223, 223, 223, 92, 92, 92, 92, 256, 258, 257, -- 92, 273, 92, 301, 92, 92, 92, 259, 92, 92, -- 92, 238, 92, 304, 158, 92, 223, 223, 223, 224, -- 224, 241, 272, 152, 152, 275, 293, 274, 92, 305, -- 273, 92, 225, 226, 152, 276, 92, 92, 227, 92, -- 307, 92, 314, 314, 92, 320, 92, 327, 327, 318, -- 319, 92, 314, 314, 440, 92, 274, 308, 228, 229, -- 230, 92, 309, 341, 334, 231, 332, 232, 92, 388, -- 337, 92, 92, 233, 92, 234, 255, 255, 255, 255, -- 255, 255, 255, 255, 255, 255, 255, 255, 338, 343, -- -- 333, 344, 389, 92, 361, 439, 339, 92, 350, 92, -- 92, 340, 340, 352, 362, 363, 301, 92, 437, 92, -- 92, 255, 255, 255, 260, 260, 260, 260, 260, 260, -- 260, 260, 260, 260, 260, 260, 354, 375, 390, 92, -- 376, 92, 364, 377, 355, 369, 92, 92, 152, 356, -- 356, 365, 92, 92, 392, 92, 436, 378, 92, 260, -- 260, 260, 277, 277, 277, 277, 277, 277, 277, 277, -- 277, 277, 277, 277, 379, 92, 399, 401, 400, 92, -- 92, 408, 92, 435, 152, 92, 434, 391, 92, 409, -- 409, 92, 411, 92, 427, 410, 426, 277, 277, 277, -- -- 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, -- 286, 286, 414, 418, 92, 92, 420, 420, 418, 418, -- 425, 415, 421, 422, 422, 92, 429, 419, 424, 152, -- 92, 429, 429, 417, 152, 286, 286, 286, 287, 287, -- 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, -- 420, 420, 422, 422, 422, 422, 421, 431, 431, 431, -- 431, 431, 431, 413, 432, 412, 432, 407, 432, 406, -- 404, 403, 402, 287, 287, 287, 288, 288, 288, 288, -- 288, 288, 288, 288, 288, 288, 288, 288, 398, 397, -- 395, 394, 393, 387, 386, 385, 382, 381, 380, 374, -- -- 373, 372, 301, 301, 368, 367, 366, 358, 357, 304, -- 349, 288, 288, 288, 310, 310, 310, 310, 310, 310, -- 310, 310, 310, 310, 310, 310, 348, 301, 301, 301, -- 347, 346, 345, 336, 331, 330, 329, 328, 301, 325, -- 324, 301, 301, 323, 322, 321, 315, 313, 312, 310, -- 310, 310, 316, 316, 316, 316, 316, 316, 316, 316, -- 316, 316, 316, 316, 306, 303, 302, 299, 298, 297, -- 296, 295, 294, 289, 285, 284, 283, 282, 281, 280, -- 279, 271, 268, 267, 266, 265, 264, 316, 316, 316, -- 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, -- -- 351, 351, 263, 262, 261, 254, 253, 252, 251, 250, -- 249, 248, 247, 246, 245, 244, 243, 217, 216, 215, -- 214, 213, 212, 211, 210, 351, 351, 351, 359, 359, -- 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, -- 209, 208, 207, 206, 205, 180, 179, 178, 177, 176, -- 175, 174, 173, 172, 169, 168, 167, 118, 118, 100, -- 140, 92, 90, 359, 359, 359, 360, 360, 360, 360, -- 360, 360, 360, 360, 360, 360, 360, 360, 139, 444, -- 138, 444, 137, 136, 133, 132, 131, 130, 129, 128, -- 127, 126, 444, 125, 124, 123, 122, 118, 101, 100, -- -- 97, 360, 360, 360, 370, 370, 370, 370, 370, 370, -- 370, 370, 370, 370, 370, 370, 90, 89, 88, 87, -- 81, 80, 79, 78, 77, 66, 64, 444, 444, 444, -- 444, 444, 444, 444, 444, 444, 444, 444, 444, 370, -- 370, 370, 383, 383, 383, 383, 383, 383, 383, 383, -- 383, 383, 383, 383, 444, 444, 444, 444, 444, 444, -- 444, 444, 444, 444, 444, 444, 444, 444, 444, 444, -- 444, 444, 444, 444, 444, 444, 444, 383, 383, 383, -- 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, -- 430, 430, 444, 444, 444, 444, 444, 444, 444, 444, -- -- 444, 444, 444, 444, 444, 444, 444, 444, 444, 444, -- 444, 444, 444, 444, 444, 430, 430, 430, 16, 16, -- 16, 16, 16, 16, 16, 16, 16, 54, 54, 54, -- 54, 54, 54, 54, 54, 54, 60, 60, 60, 60, -- 60, 60, 60, 60, 60, 63, 63, 63, 63, 63, -- 63, 63, 63, 63, 65, 65, 65, 65, 65, 65, -- 65, 65, 65, 67, 67, 444, 67, 83, 83, 83, -- 83, 83, 83, 83, 83, 83, 86, 86, 86, 86, -- 86, 86, 86, 86, 86, 92, 92, 92, 92, 92, -- 92, 92, 92, 92, 99, 99, 99, 99, 99, 99, -- -- 99, 444, 99, 119, 444, 444, 444, 444, 444, 444, -- 119, 120, 120, 444, 120, 444, 120, 120, 120, 120, -- 121, 121, 121, 121, 121, 121, 121, 121, 121, 166, -- 166, 444, 166, 444, 166, 166, 166, 166, 202, 202, -- 444, 202, 444, 202, 202, 202, 202, 242, 242, 444, -- 242, 444, 242, 242, 242, 242, 278, 278, 444, 278, -- 444, 278, 278, 278, 278, 255, 255, 255, 255, 255, -- 444, 444, 255, 311, 311, 444, 311, 444, 311, 311, -- 311, 311, 286, 286, 286, 286, 286, 444, 444, 286, -- 287, 287, 287, 287, 287, 444, 444, 287, 288, 288, -- -- 288, 288, 288, 444, 444, 288, 326, 326, 326, 326, -- 326, 444, 444, 326, 335, 335, 444, 335, 444, 335, -- 335, 335, 335, 316, 316, 316, 316, 316, 444, 444, -- 316, 353, 353, 444, 353, 444, 353, 353, 353, 353, -- 371, 371, 444, 371, 444, 371, 371, 371, 371, 359, -- 359, 359, 359, 359, 444, 444, 359, 360, 360, 360, -- 360, 360, 444, 444, 360, 384, 384, 444, 384, 444, -- 384, 384, 384, 384, 396, 396, 444, 396, 444, 396, -- 396, 396, 396, 405, 405, 444, 405, 444, 405, 405, -- 405, 405, 416, 416, 444, 416, 444, 416, 416, 416, -- -- 416, 423, 423, 444, 444, 444, 423, 444, 423, 428, -- 428, 444, 428, 444, 428, 428, 428, 428, 433, 433, -- 433, 444, 433, 433, 444, 433, 438, 438, 444, 438, -- 444, 438, 438, 438, 438, 430, 430, 430, 430, 430, -- 444, 444, 430, 9, 444, 444, 444, 444, 444, 444, -- 444, 444, 444, 444, 444, 444, 444, 444, 444, 444, -- 444, 444, 444, 444, 444, 444, 444, 444, 444, 444, -- 444, 444, 444, 444, 444, 444, 444, 444, 444, 444, -- 444, 444, 444, 444, 444, 444, 444, 444, 444, 444, -- 444, 444, 444, 444, 444, 444, 444, 444, 444, 444, -- -- 444, 444, 444, 444, 444, 444 -- } ; -- --static yyconst flex_int16_t yy_chk[1507] = -- { 0, -- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -- 1, 1, 1, 4, 5, 6, 4, 7, 8, 18, -- 0, 5, 6, 13, 7, 8, 25, 25, 26, 26, -- 27, 35, 35, 11, 11, 1, 1, 1, 2, 2, -- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -- 2, 11, 12, 12, 2, 37, 13, 36, 36, 37, -- 18, 42, 39, 27, 43, 44, 45, 46, 48, 159, -- 12, 39, 96, 2, 2, 2, 52, 52, 95, 52, -- 96, 2, 44, 95, 43, 48, 159, 42, 82, 82, -- 43, 45, 46, 2, 2, 2, 3, 3, 3, 3, -- -- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, -- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, -- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, -- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, -- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, -- 3, 3, 3, 3, 3, 3, 3, 3, 17, 17, -- 47, 17, 49, 50, 51, 60, 69, 58, 58, 75, -- 83, 94, 94, 17, 97, 49, 17, 97, 102, 79, -- 98, 104, 103, 50, 50, 58, 47, 68, 68, 51, -- 68, 98, 49, 50, 79, 103, 105, 443, 60, 106, -- -- 17, 107, 68, 83, 102, 68, 104, 69, 108, 109, -- 75, 110, 17, 17, 17, 33, 33, 33, 33, 33, -- 33, 33, 33, 33, 33, 33, 33, 107, 105, 68, -- 106, 107, 140, 108, 128, 140, 442, 111, 109, 110, -- 112, 68, 68, 68, 114, 233, 233, 115, 113, 128, -- 33, 33, 33, 34, 34, 34, 34, 34, 34, 34, -- 34, 34, 34, 34, 34, 111, 112, 113, 115, 141, -- 116, 116, 114, 116, 144, 142, 115, 142, 144, 34, -- 141, 167, 167, 113, 257, 441, 257, 167, 34, 34, -- 34, 119, 119, 119, 119, 119, 119, 119, 119, 119, -- -- 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, -- 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, -- 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, -- 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, -- 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, -- 119, 119, 119, 143, 143, 143, 143, 143, 143, 143, -- 143, 143, 143, 143, 143, 153, 149, 151, 182, 318, -- 155, 267, 318, 156, 182, 267, 147, 148, 149, 151, -- 146, 150, 154, 155, 153, 156, 157, 160, 143, 143, -- 143, 145, 145, 145, 145, 145, 145, 145, 145, 145, -- -- 145, 145, 145, 146, 147, 150, 148, 181, 183, 290, -- 185, 440, 154, 290, 157, 187, 158, 161, 160, 181, -- 183, 162, 185, 188, 190, 194, 145, 145, 145, 152, -- 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, -- 152, 158, 162, 161, 193, 187, 195, 199, 198, 194, -- 203, 203, 256, 188, 190, 439, 203, 256, 258, 195, -- 198, 193, 199, 258, 152, 152, 152, 163, 163, 163, -- 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, -- 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, -- 163, 189, 189, 189, 189, 189, 189, 189, 189, 189, -- -- 189, 189, 189, 196, 197, 201, 200, 218, 220, 219, -- 221, 236, 237, 437, 239, 240, 235, 221, 238, 218, -- 220, 197, 219, 270, 201, 236, 189, 189, 189, 192, -- 192, 200, 235, 196, 238, 237, 259, 236, 272, 270, -- 273, 259, 192, 192, 239, 240, 274, 291, 192, 307, -- 272, 275, 284, 284, 273, 293, 292, 301, 301, 291, -- 292, 309, 314, 314, 436, 293, 273, 274, 192, 192, -- 192, 308, 275, 317, 309, 192, 307, 192, 332, 375, -- 314, 317, 375, 192, 334, 192, 217, 217, 217, 217, -- 217, 217, 217, 217, 217, 217, 217, 217, 315, 319, -- -- 308, 320, 376, 376, 341, 435, 315, 319, 332, 341, -- 320, 315, 315, 334, 342, 343, 434, 350, 427, 342, -- 343, 217, 217, 217, 222, 222, 222, 222, 222, 222, -- 222, 222, 222, 222, 222, 222, 336, 361, 377, 344, -- 362, 377, 344, 363, 336, 350, 361, 362, 388, 336, -- 336, 344, 363, 364, 379, 379, 426, 364, 388, 222, -- 222, 222, 241, 241, 241, 241, 241, 241, 241, 241, -- 241, 241, 241, 241, 365, 378, 389, 391, 390, 365, -- 392, 399, 391, 425, 392, 389, 424, 378, 390, 400, -- 400, 399, 401, 401, 415, 400, 414, 241, 241, 241, -- -- 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, -- 251, 251, 404, 407, 400, 408, 409, 409, 407, 407, -- 413, 404, 409, 410, 410, 411, 417, 408, 412, 411, -- 419, 417, 417, 406, 419, 251, 251, 251, 252, 252, -- 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, -- 420, 420, 421, 421, 422, 422, 420, 423, 423, 431, -- 431, 433, 433, 403, 423, 402, 431, 398, 433, 397, -- 395, 394, 393, 252, 252, 252, 253, 253, 253, 253, -- 253, 253, 253, 253, 253, 253, 253, 253, 387, 385, -- 382, 381, 380, 374, 373, 372, 368, 367, 366, 358, -- -- 357, 354, 349, 348, 347, 346, 345, 338, 337, 331, -- 330, 253, 253, 253, 276, 276, 276, 276, 276, 276, -- 276, 276, 276, 276, 276, 276, 329, 328, 325, 324, -- 323, 322, 321, 312, 306, 305, 304, 303, 302, 300, -- 299, 298, 297, 296, 295, 294, 285, 283, 279, 276, -- 276, 276, 289, 289, 289, 289, 289, 289, 289, 289, -- 289, 289, 289, 289, 271, 269, 268, 266, 265, 264, -- 263, 262, 261, 254, 250, 249, 247, 246, 245, 244, -- 243, 234, 232, 231, 230, 229, 228, 289, 289, 289, -- 333, 333, 333, 333, 333, 333, 333, 333, 333, 333, -- -- 333, 333, 227, 226, 225, 216, 215, 214, 213, 212, -- 211, 210, 209, 208, 207, 206, 205, 180, 179, 178, -- 177, 176, 175, 174, 173, 333, 333, 333, 339, 339, -- 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, -- 172, 171, 170, 169, 168, 137, 136, 135, 134, 133, -- 132, 131, 130, 129, 127, 126, 124, 118, 117, 99, -- 93, 92, 90, 339, 339, 339, 340, 340, 340, 340, -- 340, 340, 340, 340, 340, 340, 340, 340, 88, 87, -- 86, 85, 81, 80, 78, 77, 76, 74, 73, 72, -- 71, 70, 64, 63, 59, 57, 56, 53, 41, 40, -- -- 38, 340, 340, 340, 352, 352, 352, 352, 352, 352, -- 352, 352, 352, 352, 352, 352, 32, 31, 30, 29, -- 23, 22, 21, 20, 19, 15, 14, 9, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 352, -- 352, 352, 369, 369, 369, 369, 369, 369, 369, 369, -- 369, 369, 369, 369, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 369, 369, 369, -- 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, -- 418, 418, 0, 0, 0, 0, 0, 0, 0, 0, -- -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 418, 418, 418, 445, 445, -- 445, 445, 445, 445, 445, 445, 445, 446, 446, 446, -- 446, 446, 446, 446, 446, 446, 447, 447, 447, 447, -- 447, 447, 447, 447, 447, 448, 448, 448, 448, 448, -- 448, 448, 448, 448, 449, 449, 449, 449, 449, 449, -- 449, 449, 449, 450, 450, 0, 450, 451, 451, 451, -- 451, 451, 451, 451, 451, 451, 452, 452, 452, 452, -- 452, 452, 452, 452, 452, 453, 453, 453, 453, 453, -- 453, 453, 453, 453, 454, 454, 454, 454, 454, 454, -- -- 454, 0, 454, 455, 0, 0, 0, 0, 0, 0, -- 455, 456, 456, 0, 456, 0, 456, 456, 456, 456, -- 457, 457, 457, 457, 457, 457, 457, 457, 457, 458, -- 458, 0, 458, 0, 458, 458, 458, 458, 459, 459, -- 0, 459, 0, 459, 459, 459, 459, 460, 460, 0, -- 460, 0, 460, 460, 460, 460, 461, 461, 0, 461, -- 0, 461, 461, 461, 461, 462, 462, 462, 462, 462, -- 0, 0, 462, 463, 463, 0, 463, 0, 463, 463, -- 463, 463, 464, 464, 464, 464, 464, 0, 0, 464, -- 465, 465, 465, 465, 465, 0, 0, 465, 466, 466, -- -- 466, 466, 466, 0, 0, 466, 467, 467, 467, 467, -- 467, 0, 0, 467, 468, 468, 0, 468, 0, 468, -- 468, 468, 468, 469, 469, 469, 469, 469, 0, 0, -- 469, 470, 470, 0, 470, 0, 470, 470, 470, 470, -- 471, 471, 0, 471, 0, 471, 471, 471, 471, 472, -- 472, 472, 472, 472, 0, 0, 472, 473, 473, 473, -- 473, 473, 0, 0, 473, 474, 474, 0, 474, 0, -- 474, 474, 474, 474, 475, 475, 0, 475, 0, 475, -- 475, 475, 475, 476, 476, 0, 476, 0, 476, 476, -- 476, 476, 477, 477, 0, 477, 0, 477, 477, 477, -- -- 477, 478, 478, 0, 0, 0, 478, 0, 478, 479, -- 479, 0, 479, 0, 479, 479, 479, 479, 480, 480, -- 480, 0, 480, 480, 0, 480, 481, 481, 0, 481, -- 0, 481, 481, 481, 481, 482, 482, 482, 482, 482, -- 0, 0, 482, 444, 444, 444, 444, 444, 444, 444, -- 444, 444, 444, 444, 444, 444, 444, 444, 444, 444, -- 444, 444, 444, 444, 444, 444, 444, 444, 444, 444, -- 444, 444, 444, 444, 444, 444, 444, 444, 444, 444, -- 444, 444, 444, 444, 444, 444, 444, 444, 444, 444, -- 444, 444, 444, 444, 444, 444, 444, 444, 444, 444, -- -- 444, 444, 444, 444, 444, 444 -- } ; -- --static yy_state_type yy_last_accepting_state; --static char *yy_last_accepting_cpos; -- --extern int yy_flex_debug; --int yy_flex_debug = 0; -- --/* The intent behind this definition is that it'll catch -- * any uses of REJECT which flex missed. -- */ --#define REJECT reject_used_but_not_detected --#define yymore() yymore_used_but_not_detected --#define YY_MORE_ADJ 0 --#define YY_RESTORE_YY_MORE_OFFSET --char *yytext; --#line 1 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l" --/* -*- indented-text -*- */ --/* Process source files and output type information. -- Copyright (C) 2002, 2003, 2004, 2005, 2007 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 --. */ --#line 22 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l" --#include "bconfig.h" --#include "system.h" -- --#define malloc xmalloc --#define realloc xrealloc -- --#include "gengtype.h" -- --#define YY_DECL int yylex (const char **yylval) --#define yyterminate() return EOF_TOKEN -- --struct fileloc lexer_line; --int lexer_toplevel_done; -- --static void --update_lineno (const char *l, size_t len) --{ -- while (len-- > 0) -- if (*l++ == '\n') -- lexer_line.line++; --} -- -- --#line 984 "gengtype-lex.c" -- --#define INITIAL 0 --#define in_struct 1 --#define in_struct_comment 2 --#define in_comment 3 -- --#ifndef YY_NO_UNISTD_H --/* Special case for "unistd.h", since it is non-ANSI. We include it way -- * down here because we want the user's section 1 to have been scanned first. -- * The user has a chance to override it with an option. -- */ --#include --#endif -- --#ifndef YY_EXTRA_TYPE --#define YY_EXTRA_TYPE void * --#endif -- --static int yy_init_globals (void ); -- --/* Accessor methods to globals. -- These are made visible to non-reentrant scanners for convenience. */ -- --int yylex_destroy (void ); -- --int yyget_debug (void ); -- --void yyset_debug (int debug_flag ); -- --YY_EXTRA_TYPE yyget_extra (void ); -- --void yyset_extra (YY_EXTRA_TYPE user_defined ); -- --FILE *yyget_in (void ); -- --void yyset_in (FILE * in_str ); -- --FILE *yyget_out (void ); -- --void yyset_out (FILE * out_str ); -- --int yyget_leng (void ); -- --char *yyget_text (void ); -- --int yyget_lineno (void ); -- --void yyset_lineno (int line_number ); -- --/* Macros after this point can all be overridden by user definitions in -- * section 1. -- */ -- --#ifndef YY_SKIP_YYWRAP --#ifdef __cplusplus --extern "C" int yywrap (void ); --#else --extern int yywrap (void ); --#endif --#endif -- --#ifndef yytext_ptr --static void yy_flex_strncpy (char *,yyconst char *,int ); --#endif -- --#ifdef YY_NEED_STRLEN --static int yy_flex_strlen (yyconst char * ); --#endif -- --#ifndef YY_NO_INPUT -- --#ifdef __cplusplus --static int yyinput (void ); --#else --static int input (void ); --#endif -- --#endif -- --/* Amount of stuff to slurp up with each read. */ --#ifndef YY_READ_BUF_SIZE --#define YY_READ_BUF_SIZE 8192 --#endif -- --/* Copy whatever the last rule matched to the standard output. */ --#ifndef ECHO --/* This used to be an fputs(), but since the string might contain NUL's, -- * we now use fwrite(). -- */ --#define ECHO fwrite( yytext, yyleng, 1, yyout ) --#endif -- --/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, -- * is returned in "result". -- */ --#ifndef YY_INPUT --#define YY_INPUT(buf,result,max_size) \ -- if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ -- { \ -- int c = '*'; \ -- int n; \ -- for ( n = 0; n < max_size && \ -- (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ -- buf[n] = (char) c; \ -- if ( c == '\n' ) \ -- buf[n++] = (char) c; \ -- if ( c == EOF && ferror( yyin ) ) \ -- YY_FATAL_ERROR( "input in flex scanner failed" ); \ -- result = n; \ -- } \ -- else \ -- { \ -- errno=0; \ -- while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ -- { \ -- if( errno != EINTR) \ -- { \ -- YY_FATAL_ERROR( "input in flex scanner failed" ); \ -- break; \ -- } \ -- errno=0; \ -- clearerr(yyin); \ -- } \ -- }\ --\ -- --#endif -- --/* No semi-colon after return; correct usage is to write "yyterminate();" - -- * we don't want an extra ';' after the "return" because that will cause -- * some compilers to complain about unreachable statements. -- */ --#ifndef yyterminate --#define yyterminate() return YY_NULL --#endif -- --/* Number of entries by which start-condition stack grows. */ --#ifndef YY_START_STACK_INCR --#define YY_START_STACK_INCR 25 --#endif -- --/* Report a fatal error. */ --#ifndef YY_FATAL_ERROR --#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) --#endif -- --/* end tables serialization structures and prototypes */ -- --/* Default declaration of generated scanner - a define so the user can -- * easily add parameters. -- */ --#ifndef YY_DECL --#define YY_DECL_IS_OURS 1 -- --extern int yylex (void); -- --#define YY_DECL int yylex (void) --#endif /* !YY_DECL */ -- --/* Code executed at the beginning of each rule, after yytext and yyleng -- * have been set up. -- */ --#ifndef YY_USER_ACTION --#define YY_USER_ACTION --#endif -- --/* Code executed at the end of each rule. */ --#ifndef YY_BREAK --#define YY_BREAK break; --#endif -- --#define YY_RULE_SETUP \ -- if ( yyleng > 0 ) \ -- YY_CURRENT_BUFFER_LVALUE->yy_at_bol = \ -- (yytext[yyleng - 1] == '\n'); \ -- YY_USER_ACTION -- --/** The main scanner function which does all the work. -- */ --YY_DECL --{ -- register yy_state_type yy_current_state; -- register char *yy_cp, *yy_bp; -- register int yy_act; -- --#line 56 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l" -- -- /* Do this on entry to yylex(): */ -- *yylval = 0; -- if (lexer_toplevel_done) -- { -- BEGIN(INITIAL); -- lexer_toplevel_done = 0; -- } -- -- /* Things we look for in skipping mode: */ --#line 1181 "gengtype-lex.c" -- -- if ( !(yy_init) ) -- { -- (yy_init) = 1; -- --#ifdef YY_USER_INIT -- YY_USER_INIT; --#endif -- -- if ( ! (yy_start) ) -- (yy_start) = 1; /* first start state */ -- -- if ( ! yyin ) -- yyin = stdin; -- -- if ( ! yyout ) -- yyout = stdout; -- -- if ( ! YY_CURRENT_BUFFER ) { -- yyensure_buffer_stack (); -- YY_CURRENT_BUFFER_LVALUE = -- yy_create_buffer(yyin,YY_BUF_SIZE ); -- } -- -- yy_load_buffer_state( ); -- } -- -- while ( 1 ) /* loops until end-of-file is reached */ -- { -- yy_cp = (yy_c_buf_p); -- -- /* Support of yytext. */ -- *yy_cp = (yy_hold_char); -- -- /* yy_bp points to the position in yy_ch_buf of the start of -- * the current run. -- */ -- yy_bp = yy_cp; -- -- yy_current_state = (yy_start); -- yy_current_state += YY_AT_BOL(); --yy_match: -- do -- { -- register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; -- if ( yy_accept[yy_current_state] ) -- { -- (yy_last_accepting_state) = yy_current_state; -- (yy_last_accepting_cpos) = yy_cp; -- } -- while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) -- { -- yy_current_state = (int) yy_def[yy_current_state]; -- if ( yy_current_state >= 445 ) -- yy_c = yy_meta[(unsigned int) yy_c]; -- } -- yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; -- ++yy_cp; -- } -- while ( yy_current_state != 444 ); -- yy_cp = (yy_last_accepting_cpos); -- yy_current_state = (yy_last_accepting_state); -- --yy_find_action: -- yy_act = yy_accept[yy_current_state]; -- -- YY_DO_BEFORE_ACTION; -- --do_action: /* This label is used only to access EOF actions. */ -- -- switch ( yy_act ) -- { /* beginning of action switch */ -- case 0: /* must back up */ -- /* undo the effects of YY_DO_BEFORE_ACTION */ -- *yy_cp = (yy_hold_char); -- yy_cp = (yy_last_accepting_cpos); -- yy_current_state = (yy_last_accepting_state); -- goto yy_find_action; -- --case 1: --/* rule 1 can match eol */ --*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ --(yy_c_buf_p) = yy_cp -= 1; --YY_DO_BEFORE_ACTION; /* set up yytext again */ --YY_RULE_SETUP --#line 67 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l" --{ -- BEGIN(in_struct); -- return TYPEDEF; --} -- YY_BREAK --case 2: --/* rule 2 can match eol */ --*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ --(yy_c_buf_p) = yy_cp -= 1; --YY_DO_BEFORE_ACTION; /* set up yytext again */ --YY_RULE_SETUP --#line 71 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l" --{ -- BEGIN(in_struct); -- return STRUCT; --} -- YY_BREAK --case 3: --/* rule 3 can match eol */ --*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ --(yy_c_buf_p) = yy_cp -= 1; --YY_DO_BEFORE_ACTION; /* set up yytext again */ --YY_RULE_SETUP --#line 75 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l" --{ -- BEGIN(in_struct); -- return UNION; --} -- YY_BREAK --case 4: --/* rule 4 can match eol */ --*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ --(yy_c_buf_p) = yy_cp -= 1; --YY_DO_BEFORE_ACTION; /* set up yytext again */ --YY_RULE_SETUP --#line 79 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l" --{ -- BEGIN(in_struct); -- return EXTERN; --} -- YY_BREAK --case 5: --/* rule 5 can match eol */ --*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ --(yy_c_buf_p) = yy_cp -= 1; --YY_DO_BEFORE_ACTION; /* set up yytext again */ --YY_RULE_SETUP --#line 83 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l" --{ -- BEGIN(in_struct); -- return STATIC; --} -- YY_BREAK --case 6: --/* rule 6 can match eol */ --*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ --(yy_c_buf_p) = yy_cp -= 1; --YY_DO_BEFORE_ACTION; /* set up yytext again */ --YY_RULE_SETUP --#line 88 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l" --{ -- BEGIN(in_struct); -- return DEFVEC_OP; --} -- YY_BREAK --case 7: --/* rule 7 can match eol */ --*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ --(yy_c_buf_p) = yy_cp -= 1; --YY_DO_BEFORE_ACTION; /* set up yytext again */ --YY_RULE_SETUP --#line 92 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l" --{ -- BEGIN(in_struct); -- return DEFVEC_I; --} -- YY_BREAK --case 8: --/* rule 8 can match eol */ --*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ --(yy_c_buf_p) = yy_cp -= 1; --YY_DO_BEFORE_ACTION; /* set up yytext again */ --YY_RULE_SETUP --#line 96 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l" --{ -- BEGIN(in_struct); -- return DEFVEC_ALLOC; --} -- YY_BREAK -- -- --case 9: --YY_RULE_SETUP --#line 104 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l" --{ BEGIN(in_struct_comment); } -- YY_BREAK --case 10: --/* rule 10 can match eol */ --YY_RULE_SETUP --#line 106 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l" --{ update_lineno (yytext, yyleng); } -- YY_BREAK --case 11: --/* rule 11 can match eol */ --YY_RULE_SETUP --#line 107 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l" --{ lexer_line.line++; } -- YY_BREAK --case 12: --/* rule 12 can match eol */ --*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ --(yy_c_buf_p) = yy_cp = yy_bp + 5; --YY_DO_BEFORE_ACTION; /* set up yytext again */ --YY_RULE_SETUP --#line 109 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l" --/* don't care */ -- YY_BREAK --case 13: --/* rule 13 can match eol */ --*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ --(yy_c_buf_p) = yy_cp = yy_bp + 3; --YY_DO_BEFORE_ACTION; /* set up yytext again */ --YY_RULE_SETUP --#line 110 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l" --{ return GTY_TOKEN; } -- YY_BREAK --case 14: --/* rule 14 can match eol */ --*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ --(yy_c_buf_p) = yy_cp = yy_bp + 3; --YY_DO_BEFORE_ACTION; /* set up yytext again */ --YY_RULE_SETUP --#line 111 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l" --{ return VEC_TOKEN; } -- YY_BREAK --case 15: --/* rule 15 can match eol */ --*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ --(yy_c_buf_p) = yy_cp = yy_bp + 5; --YY_DO_BEFORE_ACTION; /* set up yytext again */ --YY_RULE_SETUP --#line 112 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l" --{ return UNION; } -- YY_BREAK --case 16: --/* rule 16 can match eol */ --*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ --(yy_c_buf_p) = yy_cp = yy_bp + 6; --YY_DO_BEFORE_ACTION; /* set up yytext again */ --YY_RULE_SETUP --#line 113 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l" --{ return STRUCT; } -- YY_BREAK --case 17: --/* rule 17 can match eol */ --*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ --(yy_c_buf_p) = yy_cp = yy_bp + 4; --YY_DO_BEFORE_ACTION; /* set up yytext again */ --YY_RULE_SETUP --#line 114 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l" --{ return ENUM; } -- YY_BREAK --case 18: --/* rule 18 can match eol */ --*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ --(yy_c_buf_p) = yy_cp = yy_bp + 9; --YY_DO_BEFORE_ACTION; /* set up yytext again */ --YY_RULE_SETUP --#line 115 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l" --{ return PTR_ALIAS; } -- YY_BREAK --case 19: --/* rule 19 can match eol */ --*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ --(yy_c_buf_p) = yy_cp = yy_bp + 10; --YY_DO_BEFORE_ACTION; /* set up yytext again */ --YY_RULE_SETUP --#line 116 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l" --{ return NESTED_PTR; } -- YY_BREAK --case 20: --YY_RULE_SETUP --#line 117 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l" --{ return NUM; } -- YY_BREAK --case 21: --/* rule 21 can match eol */ --*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ --(yy_c_buf_p) = yy_cp -= 1; --YY_DO_BEFORE_ACTION; /* set up yytext again */ --YY_RULE_SETUP --#line 118 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l" --{ -- *yylval = xmemdup (yytext, yyleng, yyleng+1); -- return PARAM_IS; --} -- YY_BREAK --case 22: --/* rule 22 can match eol */ --*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ --(yy_c_buf_p) = yy_cp -= 1; --YY_DO_BEFORE_ACTION; /* set up yytext again */ --#line 124 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l" --case 23: --/* rule 23 can match eol */ --YY_RULE_SETUP --#line 124 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l" --{ -- size_t len; -- -- for (len = yyleng; ISSPACE (yytext[len-1]); len--) -- ; -- -- *yylval = xmemdup (yytext, len, len+1); -- update_lineno (yytext, yyleng); -- return SCALAR; --} -- YY_BREAK --case 24: --/* rule 24 can match eol */ --*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ --(yy_c_buf_p) = yy_cp -= 1; --YY_DO_BEFORE_ACTION; /* set up yytext again */ --YY_RULE_SETUP --#line 136 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l" --{ -- *yylval = xmemdup (yytext, yyleng, yyleng+1); -- return ID; --} -- YY_BREAK --case 25: --/* rule 25 can match eol */ --YY_RULE_SETUP --#line 141 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l" --{ -- *yylval = xmemdup (yytext+1, yyleng-2, yyleng-1); -- return STRING; --} -- YY_BREAK --/* This "terminal" avoids having to parse integer constant expressions. */ --case 26: --/* rule 26 can match eol */ --YY_RULE_SETUP --#line 146 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l" --{ -- *yylval = xmemdup (yytext+1, yyleng-2, yyleng-1); -- return ARRAY; --} -- YY_BREAK --case 27: --/* rule 27 can match eol */ --YY_RULE_SETUP --#line 150 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l" --{ -- *yylval = xmemdup (yytext+1, yyleng-2, yyleng); -- return CHAR; --} -- YY_BREAK --case 28: --YY_RULE_SETUP --#line 155 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l" --{ return ELLIPSIS; } -- YY_BREAK --case 29: --YY_RULE_SETUP --#line 156 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l" --{ return yytext[0]; } -- YY_BREAK --/* ignore pp-directives */ --case 30: --/* rule 30 can match eol */ --YY_RULE_SETUP --#line 159 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l" --{lexer_line.line++;} -- YY_BREAK --case 31: --YY_RULE_SETUP --#line 161 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l" --{ -- error_at_line (&lexer_line, "unexpected character `%s'", yytext); --} -- YY_BREAK -- --case 32: --YY_RULE_SETUP --#line 166 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l" --{ BEGIN(in_comment); } -- YY_BREAK --case 33: --/* rule 33 can match eol */ --YY_RULE_SETUP --#line 167 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l" --{ lexer_line.line++; } -- YY_BREAK --case 34: --#line 169 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l" --case 35: --/* rule 35 can match eol */ --#line 170 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l" --case 36: --/* rule 36 can match eol */ --YY_RULE_SETUP --#line 170 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l" --/* do nothing */ -- YY_BREAK --case 37: --/* rule 37 can match eol */ --YY_RULE_SETUP --#line 171 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l" --{ update_lineno (yytext, yyleng); } -- YY_BREAK --case 38: --/* rule 38 can match eol */ --*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ --(yy_c_buf_p) = yy_cp = yy_bp + 1; --YY_DO_BEFORE_ACTION; /* set up yytext again */ --YY_RULE_SETUP --#line 172 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l" --/* do nothing */ -- YY_BREAK -- --case 39: --/* rule 39 can match eol */ --YY_RULE_SETUP --#line 175 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l" --{ lexer_line.line++; } -- YY_BREAK --case 40: --#line 177 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l" --case 41: --YY_RULE_SETUP --#line 177 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l" --/* do nothing */ -- YY_BREAK --case 42: --/* rule 42 can match eol */ --*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ --(yy_c_buf_p) = yy_cp = yy_bp + 1; --YY_DO_BEFORE_ACTION; /* set up yytext again */ --YY_RULE_SETUP --#line 178 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l" --/* do nothing */ -- YY_BREAK -- --case 43: --YY_RULE_SETUP --#line 180 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l" --{ BEGIN(INITIAL); } -- YY_BREAK --case 44: --YY_RULE_SETUP --#line 181 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l" --{ BEGIN(in_struct); } -- YY_BREAK --case 45: --#line 184 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l" --case 46: --YY_RULE_SETUP --#line 184 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l" --{ -- error_at_line (&lexer_line, -- "unterminated comment or string; unexpected EOF"); --} -- YY_BREAK --case 47: --/* rule 47 can match eol */ --YY_RULE_SETUP --#line 189 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l" --/* do nothing */ -- YY_BREAK --case 48: --/* rule 48 can match eol */ --YY_RULE_SETUP --#line 190 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l" --{ -- error_at_line (&lexer_line, "stray GTY marker"); --} -- YY_BREAK --case 49: --YY_RULE_SETUP --#line 194 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l" --YY_FATAL_ERROR( "flex scanner jammed" ); -- YY_BREAK --#line 1651 "gengtype-lex.c" --case YY_STATE_EOF(INITIAL): --case YY_STATE_EOF(in_struct): --case YY_STATE_EOF(in_struct_comment): --case YY_STATE_EOF(in_comment): -- yyterminate(); -- -- case YY_END_OF_BUFFER: -- { -- /* Amount of text matched not including the EOB char. */ -- int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; -- -- /* Undo the effects of YY_DO_BEFORE_ACTION. */ -- *yy_cp = (yy_hold_char); -- YY_RESTORE_YY_MORE_OFFSET -- -- if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) -- { -- /* We're scanning a new file or input source. It's -- * possible that this happened because the user -- * just pointed yyin at a new source and called -- * yylex(). If so, then we have to assure -- * consistency between YY_CURRENT_BUFFER and our -- * globals. Here is the right place to do so, because -- * this is the first action (other than possibly a -- * back-up) that will match for the new input source. -- */ -- (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; -- YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; -- YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; -- } -- -- /* Note that here we test for yy_c_buf_p "<=" to the position -- * of the first EOB in the buffer, since yy_c_buf_p will -- * already have been incremented past the NUL character -- * (since all states make transitions on EOB to the -- * end-of-buffer state). Contrast this with the test -- * in input(). -- */ -- if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) -- { /* This was really a NUL. */ -- yy_state_type yy_next_state; -- -- (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; -- -- yy_current_state = yy_get_previous_state( ); -- -- /* Okay, we're now positioned to make the NUL -- * transition. We couldn't have -- * yy_get_previous_state() go ahead and do it -- * for us because it doesn't know how to deal -- * with the possibility of jamming (and we don't -- * want to build jamming into it because then it -- * will run more slowly). -- */ -- -- yy_next_state = yy_try_NUL_trans( yy_current_state ); -- -- yy_bp = (yytext_ptr) + YY_MORE_ADJ; -- -- if ( yy_next_state ) -- { -- /* Consume the NUL. */ -- yy_cp = ++(yy_c_buf_p); -- yy_current_state = yy_next_state; -- goto yy_match; -- } -- -- else -- { -- yy_cp = (yy_last_accepting_cpos); -- yy_current_state = (yy_last_accepting_state); -- goto yy_find_action; -- } -- } -- -- else switch ( yy_get_next_buffer( ) ) -- { -- case EOB_ACT_END_OF_FILE: -- { -- (yy_did_buffer_switch_on_eof) = 0; -- -- if ( yywrap( ) ) -- { -- /* Note: because we've taken care in -- * yy_get_next_buffer() to have set up -- * yytext, we can now set up -- * yy_c_buf_p so that if some total -- * hoser (like flex itself) wants to -- * call the scanner after we return the -- * YY_NULL, it'll still work - another -- * YY_NULL will get returned. -- */ -- (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; -- -- yy_act = YY_STATE_EOF(YY_START); -- goto do_action; -- } -- -- else -- { -- if ( ! (yy_did_buffer_switch_on_eof) ) -- YY_NEW_FILE; -- } -- break; -- } -- -- case EOB_ACT_CONTINUE_SCAN: -- (yy_c_buf_p) = -- (yytext_ptr) + yy_amount_of_matched_text; -- -- yy_current_state = yy_get_previous_state( ); -- -- yy_cp = (yy_c_buf_p); -- yy_bp = (yytext_ptr) + YY_MORE_ADJ; -- goto yy_match; -- -- case EOB_ACT_LAST_MATCH: -- (yy_c_buf_p) = -- &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; -- -- yy_current_state = yy_get_previous_state( ); -- -- yy_cp = (yy_c_buf_p); -- yy_bp = (yytext_ptr) + YY_MORE_ADJ; -- goto yy_find_action; -- } -- break; -- } -- -- default: -- YY_FATAL_ERROR( -- "fatal flex scanner internal error--no action found" ); -- } /* end of action switch */ -- } /* end of scanning one token */ --} /* end of yylex */ -- --/* yy_get_next_buffer - try to read in a new buffer -- * -- * Returns a code representing an action: -- * EOB_ACT_LAST_MATCH - -- * EOB_ACT_CONTINUE_SCAN - continue scanning from current position -- * EOB_ACT_END_OF_FILE - end of file -- */ --static int yy_get_next_buffer (void) --{ -- register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; -- register char *source = (yytext_ptr); -- register int number_to_move, i; -- int ret_val; -- -- if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) -- YY_FATAL_ERROR( -- "fatal flex scanner internal error--end of buffer missed" ); -- -- if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) -- { /* Don't try to fill the buffer, so this is an EOF. */ -- if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) -- { -- /* We matched a single character, the EOB, so -- * treat this as a final EOF. -- */ -- return EOB_ACT_END_OF_FILE; -- } -- -- else -- { -- /* We matched some text prior to the EOB, first -- * process it. -- */ -- return EOB_ACT_LAST_MATCH; -- } -- } -- -- /* Try to read more data. */ -- -- /* First move last chars to start of buffer. */ -- number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; -- -- for ( i = 0; i < number_to_move; ++i ) -- *(dest++) = *(source++); -- -- if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) -- /* don't do the read, it's not guaranteed to return an EOF, -- * just force an EOF -- */ -- YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; -- -- else -- { -- int num_to_read = -- YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; -- -- while ( num_to_read <= 0 ) -- { /* Not enough room in the buffer - grow it. */ -- -- /* just a shorter name for the current buffer */ -- YY_BUFFER_STATE b = YY_CURRENT_BUFFER; -- -- int yy_c_buf_p_offset = -- (int) ((yy_c_buf_p) - b->yy_ch_buf); -- -- if ( b->yy_is_our_buffer ) -- { -- int new_size = b->yy_buf_size * 2; -- -- if ( new_size <= 0 ) -- b->yy_buf_size += b->yy_buf_size / 8; -- else -- b->yy_buf_size *= 2; -- -- b->yy_ch_buf = (char *) -- /* Include room in for 2 EOB chars. */ -- yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); -- } -- else -- /* Can't grow it, we don't own it. */ -- b->yy_ch_buf = 0; -- -- if ( ! b->yy_ch_buf ) -- YY_FATAL_ERROR( -- "fatal error - scanner input buffer overflow" ); -- -- (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; -- -- num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - -- number_to_move - 1; -- -- } -- -- if ( num_to_read > YY_READ_BUF_SIZE ) -- num_to_read = YY_READ_BUF_SIZE; -- -- /* Read in more data. */ -- YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), -- (yy_n_chars), (size_t) num_to_read ); -- -- YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); -- } -- -- if ( (yy_n_chars) == 0 ) -- { -- if ( number_to_move == YY_MORE_ADJ ) -- { -- ret_val = EOB_ACT_END_OF_FILE; -- yyrestart(yyin ); -- } -- -- else -- { -- ret_val = EOB_ACT_LAST_MATCH; -- YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = -- YY_BUFFER_EOF_PENDING; -- } -- } -- -- else -- ret_val = EOB_ACT_CONTINUE_SCAN; -- -- if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { -- /* Extend the array by 50%, plus the number we really need. */ -- yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); -- YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); -- if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) -- YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); -- } -- -- (yy_n_chars) += number_to_move; -- YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; -- YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; -- -- (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; -- -- return ret_val; --} -- --/* yy_get_previous_state - get the state just before the EOB char was reached */ -- -- static yy_state_type yy_get_previous_state (void) --{ -- register yy_state_type yy_current_state; -- register char *yy_cp; -- -- yy_current_state = (yy_start); -- yy_current_state += YY_AT_BOL(); -- -- for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) -- { -- register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); -- if ( yy_accept[yy_current_state] ) -- { -- (yy_last_accepting_state) = yy_current_state; -- (yy_last_accepting_cpos) = yy_cp; -- } -- while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) -- { -- yy_current_state = (int) yy_def[yy_current_state]; -- if ( yy_current_state >= 445 ) -- yy_c = yy_meta[(unsigned int) yy_c]; -- } -- yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; -- } -- -- return yy_current_state; --} -- --/* yy_try_NUL_trans - try to make a transition on the NUL character -- * -- * synopsis -- * next_state = yy_try_NUL_trans( current_state ); -- */ -- static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) --{ -- register int yy_is_jam; -- register char *yy_cp = (yy_c_buf_p); -- -- register YY_CHAR yy_c = 1; -- if ( yy_accept[yy_current_state] ) -- { -- (yy_last_accepting_state) = yy_current_state; -- (yy_last_accepting_cpos) = yy_cp; -- } -- while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) -- { -- yy_current_state = (int) yy_def[yy_current_state]; -- if ( yy_current_state >= 445 ) -- yy_c = yy_meta[(unsigned int) yy_c]; -- } -- yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; -- yy_is_jam = (yy_current_state == 444); -- -- return yy_is_jam ? 0 : yy_current_state; --} -- --#ifndef YY_NO_INPUT --#ifdef __cplusplus -- static int yyinput (void) --#else -- static int input (void) --#endif -- --{ -- int c; -- -- *(yy_c_buf_p) = (yy_hold_char); -- -- if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) -- { -- /* yy_c_buf_p now points to the character we want to return. -- * If this occurs *before* the EOB characters, then it's a -- * valid NUL; if not, then we've hit the end of the buffer. -- */ -- if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) -- /* This was really a NUL. */ -- *(yy_c_buf_p) = '\0'; -- -- else -- { /* need more input */ -- int offset = (yy_c_buf_p) - (yytext_ptr); -- ++(yy_c_buf_p); -- -- switch ( yy_get_next_buffer( ) ) -- { -- case EOB_ACT_LAST_MATCH: -- /* This happens because yy_g_n_b() -- * sees that we've accumulated a -- * token and flags that we need to -- * try matching the token before -- * proceeding. But for input(), -- * there's no matching to consider. -- * So convert the EOB_ACT_LAST_MATCH -- * to EOB_ACT_END_OF_FILE. -- */ -- -- /* Reset buffer status. */ -- yyrestart(yyin ); -- -- /*FALLTHROUGH*/ -- -- case EOB_ACT_END_OF_FILE: -- { -- if ( yywrap( ) ) -- return EOF; -- -- if ( ! (yy_did_buffer_switch_on_eof) ) -- YY_NEW_FILE; --#ifdef __cplusplus -- return yyinput(); --#else -- return input(); --#endif -- } -- -- case EOB_ACT_CONTINUE_SCAN: -- (yy_c_buf_p) = (yytext_ptr) + offset; -- break; -- } -- } -- } -- -- c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ -- *(yy_c_buf_p) = '\0'; /* preserve yytext */ -- (yy_hold_char) = *++(yy_c_buf_p); -- -- YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (c == '\n'); -- -- return c; --} --#endif /* ifndef YY_NO_INPUT */ -- --/** Immediately switch to a different input stream. -- * @param input_file A readable stream. -- * -- * @note This function does not reset the start condition to @c INITIAL . -- */ -- void yyrestart (FILE * input_file ) --{ -- -- if ( ! YY_CURRENT_BUFFER ){ -- yyensure_buffer_stack (); -- YY_CURRENT_BUFFER_LVALUE = -- yy_create_buffer(yyin,YY_BUF_SIZE ); -- } -- -- yy_init_buffer(YY_CURRENT_BUFFER,input_file ); -- yy_load_buffer_state( ); --} -- --/** Switch to a different input buffer. -- * @param new_buffer The new input buffer. -- * -- */ -- void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ) --{ -- -- /* TODO. We should be able to replace this entire function body -- * with -- * yypop_buffer_state(); -- * yypush_buffer_state(new_buffer); -- */ -- yyensure_buffer_stack (); -- if ( YY_CURRENT_BUFFER == new_buffer ) -- return; -- -- if ( YY_CURRENT_BUFFER ) -- { -- /* Flush out information for old buffer. */ -- *(yy_c_buf_p) = (yy_hold_char); -- YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); -- YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); -- } -- -- YY_CURRENT_BUFFER_LVALUE = new_buffer; -- yy_load_buffer_state( ); -- -- /* We don't actually know whether we did this switch during -- * EOF (yywrap()) processing, but the only time this flag -- * is looked at is after yywrap() is called, so it's safe -- * to go ahead and always set it. -- */ -- (yy_did_buffer_switch_on_eof) = 1; --} -- --static void yy_load_buffer_state (void) --{ -- (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; -- (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; -- yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; -- (yy_hold_char) = *(yy_c_buf_p); --} -- --/** Allocate and initialize an input buffer state. -- * @param file A readable stream. -- * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. -- * -- * @return the allocated buffer state. -- */ -- YY_BUFFER_STATE yy_create_buffer (FILE * file, int size ) --{ -- YY_BUFFER_STATE b; -- -- b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); -- if ( ! b ) -- YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); -- -- b->yy_buf_size = size; -- -- /* yy_ch_buf has to be 2 characters longer than the size given because -- * we need to put in 2 end-of-buffer characters. -- */ -- b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 ); -- if ( ! b->yy_ch_buf ) -- YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); -- -- b->yy_is_our_buffer = 1; -- -- yy_init_buffer(b,file ); -- -- return b; --} -- --/** Destroy the buffer. -- * @param b a buffer created with yy_create_buffer() -- * -- */ -- void yy_delete_buffer (YY_BUFFER_STATE b ) --{ -- -- if ( ! b ) -- return; -- -- if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ -- YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; -- -- if ( b->yy_is_our_buffer ) -- yyfree((void *) b->yy_ch_buf ); -- -- yyfree((void *) b ); --} -- --/* Initializes or reinitializes a buffer. -- * This function is sometimes called more than once on the same buffer, -- * such as during a yyrestart() or at EOF. -- */ -- static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file ) -- --{ -- int oerrno = errno; -- -- yy_flush_buffer(b ); -- -- b->yy_input_file = file; -- b->yy_fill_buffer = 1; -- -- /* If b is the current buffer, then yy_init_buffer was _probably_ -- * called from yyrestart() or through yy_get_next_buffer. -- * In that case, we don't want to reset the lineno or column. -- */ -- if (b != YY_CURRENT_BUFFER){ -- b->yy_bs_lineno = 1; -- b->yy_bs_column = 0; -- } -- -- b->yy_is_interactive = 0; -- -- errno = oerrno; --} -- --/** Discard all buffered characters. On the next scan, YY_INPUT will be called. -- * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. -- * -- */ -- void yy_flush_buffer (YY_BUFFER_STATE b ) --{ -- if ( ! b ) -- return; -- -- b->yy_n_chars = 0; -- -- /* We always need two end-of-buffer characters. The first causes -- * a transition to the end-of-buffer state. The second causes -- * a jam in that state. -- */ -- b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; -- b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; -- -- b->yy_buf_pos = &b->yy_ch_buf[0]; -- -- b->yy_at_bol = 1; -- b->yy_buffer_status = YY_BUFFER_NEW; -- -- if ( b == YY_CURRENT_BUFFER ) -- yy_load_buffer_state( ); --} -- --/** Pushes the new state onto the stack. The new state becomes -- * the current state. This function will allocate the stack -- * if necessary. -- * @param new_buffer The new state. -- * -- */ --void yypush_buffer_state (YY_BUFFER_STATE new_buffer ) --{ -- if (new_buffer == NULL) -- return; -- -- yyensure_buffer_stack(); -- -- /* This block is copied from yy_switch_to_buffer. */ -- if ( YY_CURRENT_BUFFER ) -- { -- /* Flush out information for old buffer. */ -- *(yy_c_buf_p) = (yy_hold_char); -- YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); -- YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); -- } -- -- /* Only push if top exists. Otherwise, replace top. */ -- if (YY_CURRENT_BUFFER) -- (yy_buffer_stack_top)++; -- YY_CURRENT_BUFFER_LVALUE = new_buffer; -- -- /* copied from yy_switch_to_buffer. */ -- yy_load_buffer_state( ); -- (yy_did_buffer_switch_on_eof) = 1; --} -- --/** Removes and deletes the top of the stack, if present. -- * The next element becomes the new top. -- * -- */ --void yypop_buffer_state (void) --{ -- if (!YY_CURRENT_BUFFER) -- return; -- -- yy_delete_buffer(YY_CURRENT_BUFFER ); -- YY_CURRENT_BUFFER_LVALUE = NULL; -- if ((yy_buffer_stack_top) > 0) -- --(yy_buffer_stack_top); -- -- if (YY_CURRENT_BUFFER) { -- yy_load_buffer_state( ); -- (yy_did_buffer_switch_on_eof) = 1; -- } --} -- --/* Allocates the stack if it does not exist. -- * Guarantees space for at least one push. -- */ --static void yyensure_buffer_stack (void) --{ -- int num_to_alloc; -- -- if (!(yy_buffer_stack)) { -- -- /* First allocation is just for 2 elements, since we don't know if this -- * scanner will even need a stack. We use 2 instead of 1 to avoid an -- * immediate realloc on the next call. -- */ -- num_to_alloc = 1; -- (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc -- (num_to_alloc * sizeof(struct yy_buffer_state*) -- ); -- if ( ! (yy_buffer_stack) ) -- YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); -- -- memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); -- -- (yy_buffer_stack_max) = num_to_alloc; -- (yy_buffer_stack_top) = 0; -- return; -- } -- -- if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ -- -- /* Increase the buffer to prepare for a possible push. */ -- int grow_size = 8 /* arbitrary grow size */; -- -- num_to_alloc = (yy_buffer_stack_max) + grow_size; -- (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc -- ((yy_buffer_stack), -- num_to_alloc * sizeof(struct yy_buffer_state*) -- ); -- if ( ! (yy_buffer_stack) ) -- YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); -- -- /* zero only the new slots.*/ -- memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); -- (yy_buffer_stack_max) = num_to_alloc; -- } --} -- --/** Setup the input buffer state to scan directly from a user-specified character buffer. -- * @param base the character buffer -- * @param size the size in bytes of the character buffer -- * -- * @return the newly allocated buffer state object. -- */ --YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) --{ -- YY_BUFFER_STATE b; -- -- if ( size < 2 || -- base[size-2] != YY_END_OF_BUFFER_CHAR || -- base[size-1] != YY_END_OF_BUFFER_CHAR ) -- /* They forgot to leave room for the EOB's. */ -- return 0; -- -- b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); -- if ( ! b ) -- YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); -- -- b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ -- b->yy_buf_pos = b->yy_ch_buf = base; -- b->yy_is_our_buffer = 0; -- b->yy_input_file = 0; -- b->yy_n_chars = b->yy_buf_size; -- b->yy_is_interactive = 0; -- b->yy_at_bol = 1; -- b->yy_fill_buffer = 0; -- b->yy_buffer_status = YY_BUFFER_NEW; -- -- yy_switch_to_buffer(b ); -- -- return b; --} -- --/** Setup the input buffer state to scan a string. The next call to yylex() will -- * scan from a @e copy of @a str. -- * @param yystr a NUL-terminated string to scan -- * -- * @return the newly allocated buffer state object. -- * @note If you want to scan bytes that may contain NUL values, then use -- * yy_scan_bytes() instead. -- */ --YY_BUFFER_STATE yy_scan_string (yyconst char * yystr ) --{ -- -- return yy_scan_bytes(yystr,strlen(yystr) ); --} -- --/** Setup the input buffer state to scan the given bytes. The next call to yylex() will -- * scan from a @e copy of @a bytes. -- * @param bytes the byte buffer to scan -- * @param len the number of bytes in the buffer pointed to by @a bytes. -- * -- * @return the newly allocated buffer state object. -- */ --YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len ) --{ -- YY_BUFFER_STATE b; -- char *buf; -- yy_size_t n; -- int i; -- -- /* Get memory for full buffer, including space for trailing EOB's. */ -- n = _yybytes_len + 2; -- buf = (char *) yyalloc(n ); -- if ( ! buf ) -- YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); -- -- for ( i = 0; i < _yybytes_len; ++i ) -- buf[i] = yybytes[i]; -- -- buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; -- -- b = yy_scan_buffer(buf,n ); -- if ( ! b ) -- YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); -- -- /* It's okay to grow etc. this buffer, and we should throw it -- * away when we're done. -- */ -- b->yy_is_our_buffer = 1; -- -- return b; --} -- --#ifndef YY_EXIT_FAILURE --#define YY_EXIT_FAILURE 2 --#endif -- --static void yy_fatal_error (yyconst char* msg ) --{ -- (void) fprintf( stderr, "%s\n", msg ); -- exit( YY_EXIT_FAILURE ); --} -- --/* Redefine yyless() so it works in section 3 code. */ -- --#undef yyless --#define yyless(n) \ -- do \ -- { \ -- /* Undo effects of setting up yytext. */ \ -- int yyless_macro_arg = (n); \ -- YY_LESS_LINENO(yyless_macro_arg);\ -- yytext[yyleng] = (yy_hold_char); \ -- (yy_c_buf_p) = yytext + yyless_macro_arg; \ -- (yy_hold_char) = *(yy_c_buf_p); \ -- *(yy_c_buf_p) = '\0'; \ -- yyleng = yyless_macro_arg; \ -- } \ -- while ( 0 ) -- --/* Accessor methods (get/set functions) to struct members. */ -- --/** Get the current line number. -- * -- */ --int yyget_lineno (void) --{ -- -- return yylineno; --} -- --/** Get the input stream. -- * -- */ --FILE *yyget_in (void) --{ -- return yyin; --} -- --/** Get the output stream. -- * -- */ --FILE *yyget_out (void) --{ -- return yyout; --} -- --/** Get the length of the current token. -- * -- */ --int yyget_leng (void) --{ -- return yyleng; --} -- --/** Get the current token. -- * -- */ -- --char *yyget_text (void) --{ -- return yytext; --} -- --/** Set the current line number. -- * @param line_number -- * -- */ --void yyset_lineno (int line_number ) --{ -- -- yylineno = line_number; --} -- --/** Set the input stream. This does not discard the current -- * input buffer. -- * @param in_str A readable stream. -- * -- * @see yy_switch_to_buffer -- */ --void yyset_in (FILE * in_str ) --{ -- yyin = in_str ; --} -- --void yyset_out (FILE * out_str ) --{ -- yyout = out_str ; --} -- --int yyget_debug (void) --{ -- return yy_flex_debug; --} -- --void yyset_debug (int bdebug ) --{ -- yy_flex_debug = bdebug ; --} -- --static int yy_init_globals (void) --{ -- /* Initialization is the same as for the non-reentrant scanner. -- * This function is called from yylex_destroy(), so don't allocate here. -- */ -- -- (yy_buffer_stack) = 0; -- (yy_buffer_stack_top) = 0; -- (yy_buffer_stack_max) = 0; -- (yy_c_buf_p) = (char *) 0; -- (yy_init) = 0; -- (yy_start) = 0; -- --/* Defined in main.c */ --#ifdef YY_STDINIT -- yyin = stdin; -- yyout = stdout; --#else -- yyin = (FILE *) 0; -- yyout = (FILE *) 0; --#endif -- -- /* For future reference: Set errno on error, since we are called by -- * yylex_init() -- */ -- return 0; --} -- --/* yylex_destroy is for both reentrant and non-reentrant scanners. */ --int yylex_destroy (void) --{ -- -- /* Pop the buffer stack, destroying each element. */ -- while(YY_CURRENT_BUFFER){ -- yy_delete_buffer(YY_CURRENT_BUFFER ); -- YY_CURRENT_BUFFER_LVALUE = NULL; -- yypop_buffer_state(); -- } -- -- /* Destroy the stack itself. */ -- yyfree((yy_buffer_stack) ); -- (yy_buffer_stack) = NULL; -- -- /* Reset the globals. This is important in a non-reentrant scanner so the next time -- * yylex() is called, initialization will occur. */ -- yy_init_globals( ); -- -- return 0; --} -- --/* -- * Internal utility routines. -- */ -- --#ifndef yytext_ptr --static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) --{ -- register int i; -- for ( i = 0; i < n; ++i ) -- s1[i] = s2[i]; --} --#endif -- --#ifdef YY_NEED_STRLEN --static int yy_flex_strlen (yyconst char * s ) --{ -- register int n; -- for ( n = 0; s[n]; ++n ) -- ; -- -- return n; --} --#endif -- --void *yyalloc (yy_size_t size ) --{ -- return (void *) malloc( size ); --} -- --void *yyrealloc (void * ptr, yy_size_t size ) --{ -- /* The cast to (char *) in the following accommodates both -- * implementations that use char* generic pointers, and those -- * that use void* generic pointers. It works with the latter -- * because both ANSI C and C++ allow castless assignment from -- * any pointer type to void*, and deal with argument conversions -- * as though doing an assignment. -- */ -- return (void *) realloc( (char *) ptr, size ); --} -- --void yyfree (void * ptr ) --{ -- free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ --} -- --#define YYTABLES_NAME "yytables" -- --#line 194 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l" -- -- -- --void --yybegin (const char *fname) --{ -- yyin = fopen (fname, "r"); -- if (yyin == NULL) -- { -- perror (fname); -- exit (1); -- } -- lexer_line.file = fname; -- lexer_line.line = 1; --} -- --void --yyend (void) --{ -- fclose (yyin); --} -- ---- 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 -@@ -1846,6 +1846,23 @@ move_insn (rtx insn) - 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 - { -@@ -1902,13 +1919,15 @@ static int - max_issue (struct ready_list *ready, int *index, int max_points) - { - int n, i, all, n_ready, best, delay, tries_num, points = -1; -+ int rest; - struct choice_entry *top; - rtx insn; - - best = 0; - memcpy (choice_stack->state, curr_state, dfa_state_size); - top = choice_stack; -- top->rest = cached_first_cycle_multipass_dfa_lookahead; -+ /* Add +1 to account the empty initial state. */ -+ top->rest = cached_first_cycle_multipass_dfa_lookahead + 1; - top->n = 0; - n_ready = ready->n_ready; - for (all = i = 0; i < n_ready; i++) -@@ -1918,7 +1937,10 @@ max_issue (struct ready_list *ready, int - tries_num = 0; - for (;;) - { -- if (top->rest == 0 || i >= n_ready) -+ if (/* Enough instructions are issued (or we won't issue more). */ -+ top->rest == 0 -+ /* Or there's nothing left to try. */ -+ || i >= n_ready) - { - if (top == choice_stack) - break; -@@ -1942,17 +1964,27 @@ max_issue (struct ready_list *ready, int - break; - insn = ready_element (ready, i); - delay = state_transition (curr_state, insn); -+ - if (delay < 0) - { -- if (state_dead_lock_p (curr_state)) -- top->rest = 0; -+ rest = top->rest; -+ if (state_dead_lock_p (curr_state) -+ || insn_finishes_cycle_p (insn)) -+ /* We won't issue any more instructions in the next -+ choice_state. */ -+ rest = 0; - else -- top->rest--; -+ rest--; -+ - n = top->n; - if (memcmp (top->state, curr_state, dfa_state_size) != 0) - n += ISSUE_POINTS (insn); -+ -+ /* Go to next choice_state. */ - top++; -- top->rest = cached_first_cycle_multipass_dfa_lookahead; -+ -+ /* Initialize it. */ -+ top->rest = rest; - top->index = i; - top->n = n; - memcpy (top->state, curr_state, dfa_state_size); ---- a/gcc/hooks.c -+++ b/gcc/hooks.c -@@ -34,6 +34,12 @@ hook_void_void (void) - { - } - -+/* Generic hook that receives an int * and does nothing. */ -+void -+hook_intp_void (int *p ATTRIBUTE_UNUSED) -+{ -+} -+ - /* Generic hook that takes no arguments and returns false. */ - bool - hook_bool_void_false (void) -@@ -319,3 +325,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 -@@ -51,6 +51,7 @@ extern bool hook_bool_tree_tree_false (t - extern bool hook_bool_tree_bool_false (tree, bool); - - extern void hook_void_void (void); -+extern void hook_intp_void (int *); - extern void hook_void_constcharptr (const char *); - extern void hook_void_FILEptr_constcharptr (FILE *, const char *); - extern void hook_void_tree (tree); -@@ -62,6 +63,8 @@ extern int hook_int_rtx_0 (rtx); - 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_3rd_identity (tree, tree, tree); - extern tree hook_tree_tree_tree_bool_null (tree, tree, bool); ---- a/gcc/integrate.c -+++ b/gcc/integrate.c -@@ -81,8 +81,9 @@ function_attribute_inlinable_p (const_tr - int i; - - for (i = 0; targetm.attribute_table[i].name != NULL; i++) -- if (is_attribute_p (targetm.attribute_table[i].name, name)) -- return targetm.function_attribute_inlinable_p (fndecl); -+ if (is_attribute_p (targetm.attribute_table[i].name, name) -+ && !targetm.function_attribute_inlinable_p (fndecl)) -+ return false; - } - } - ---- a/gcc/java/Make-lang.in -+++ b/gcc/java/Make-lang.in -@@ -303,11 +303,13 @@ java/jcf-io.o: java/jcf-io.c $(CONFIG_H) - $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(ZLIBINC) \ - $(srcdir)/java/jcf-io.c $(OUTPUT_OPTION) - -+# This must match the setting in libjava/Makefile.am. -+jardir = $(prefix)/$(target_noncanonical)/share/java - # jcf-path.o needs a -D. - java/jcf-path.o: java/jcf-path.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ - java/jcf.h - $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ -- -DLIBGCJ_ZIP_FILE='"$(datadir)/java/libgcj-$(version).jar"' \ -+ -DLIBGCJ_ZIP_FILE='"$(jardir)/libgcj-$(version).jar"' \ - -DDEFAULT_TARGET_VERSION=\"$(version)\" \ - $(srcdir)/java/jcf-path.c $(OUTPUT_OPTION) - ---- a/gcc/jump.c -+++ b/gcc/jump.c -@@ -1551,12 +1551,22 @@ rtx_renumbered_equal_p (const_rtx x, con - - if (reg_renumber[reg_x] >= 0) - { -+ if (!subreg_offset_representable_p (reg_renumber[reg_x], -+ GET_MODE (SUBREG_REG (x)), -+ byte_x, -+ GET_MODE (x))) -+ return 0; - reg_x = subreg_regno_offset (reg_renumber[reg_x], - GET_MODE (SUBREG_REG (x)), - byte_x, - GET_MODE (x)); - byte_x = 0; - } -+ else if (!subreg_offset_representable_p (reg_x, -+ GET_MODE (SUBREG_REG (x)), -+ byte_x, -+ GET_MODE (x))) -+ return 0; - } - else - { -@@ -1572,12 +1582,22 @@ rtx_renumbered_equal_p (const_rtx x, con - - if (reg_renumber[reg_y] >= 0) - { -+ if (!subreg_offset_representable_p (reg_renumber[reg_y], -+ GET_MODE (SUBREG_REG (y)), -+ byte_y, -+ GET_MODE (y))) -+ return 0; - reg_y = subreg_regno_offset (reg_renumber[reg_y], - GET_MODE (SUBREG_REG (y)), - byte_y, - GET_MODE (y)); - byte_y = 0; - } -+ else if (!subreg_offset_representable_p (reg_y, -+ GET_MODE (SUBREG_REG (y)), -+ byte_y, -+ GET_MODE (y))) -+ return 0; - } - else - { ---- a/gcc/libgcc2.c -+++ b/gcc/libgcc2.c -@@ -1830,6 +1830,7 @@ CTYPE - CONCAT3(__mul,MODE,3) (MTYPE a, MTYPE b, MTYPE c, MTYPE d) - { - MTYPE ac, bd, ad, bc, x, y; -+ CTYPE res; - - ac = a * c; - bd = b * d; -@@ -1886,7 +1887,9 @@ CONCAT3(__mul,MODE,3) (MTYPE a, MTYPE b, - } - } - -- return x + I * y; -+ __real__ res = x; -+ __imag__ res = y; -+ return res; - } - #endif /* complex multiply */ - -@@ -1897,6 +1900,7 @@ CTYPE - CONCAT3(__div,MODE,3) (MTYPE a, MTYPE b, MTYPE c, MTYPE d) - { - MTYPE denom, ratio, x, y; -+ CTYPE res; - - /* ??? We can get better behavior from logarithmic scaling instead of - the division. But that would mean starting to link libgcc against -@@ -1942,7 +1946,9 @@ CONCAT3(__div,MODE,3) (MTYPE a, MTYPE b, - } - } - -- return x + I * y; -+ __real__ res = x; -+ __imag__ res = y; -+ return res; - } - #endif /* complex divide */ - -@@ -2137,7 +2143,8 @@ __do_global_dtors (void) - (*(p-1)) (); - } - #endif --#if defined (EH_FRAME_SECTION_NAME) && !defined (HAS_INIT_SECTION) -+#if defined (EH_FRAME_SECTION_NAME) && !defined (HAS_INIT_SECTION) \ -+ && !defined (__MINGW32__) - { - static int completed = 0; - if (! completed) -@@ -2156,14 +2163,14 @@ __do_global_dtors (void) - void - __do_global_ctors (void) - { --#ifdef EH_FRAME_SECTION_NAME -+ atexit (__do_global_dtors); -+#if defined (EH_FRAME_SECTION_NAME) && !defined (__MINGW32__) - { - static struct object object; - __register_frame_info (__EH_FRAME_BEGIN__, &object); - } - #endif - DO_GLOBAL_CTORS_BODY; -- atexit (__do_global_dtors); - } - #endif /* no HAS_INIT_SECTION */ - ---- a/gcc/modulo-sched.c -+++ b/gcc/modulo-sched.c -@@ -268,6 +268,7 @@ static struct sched_info sms_sched_info - sms_print_insn, - NULL, - compute_jump_reg_dependencies, -+ NULL, /* insn_finishes_block_p */ - NULL, NULL, - NULL, NULL, - 0, 0, 0, ---- a/gcc/optabs.c -+++ b/gcc/optabs.c -@@ -2140,6 +2140,10 @@ expand_binop (enum machine_mode mode, op - && GET_MODE (op0) != mode) - op0 = convert_to_mode (mode, op0, unsignedp); - -+ /* Force things into registers so subreg handling comes out right. */ -+ op0 = force_reg (mode, op0); -+ op1x = force_reg (op1_mode, op1x); -+ - /* Pass 1 for NO_QUEUE so we don't lose any increments - if the libcall is cse'd or moved. */ - value = emit_library_call_value (libfunc, -@@ -3281,7 +3285,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 (); - -@@ -4508,10 +4513,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; -@@ -4519,7 +4526,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 -@@ -1787,6 +1787,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 -@@ -522,6 +522,7 @@ init_optimization_passes (void) - NEXT_PASS (pass_cleanup_cfg); - NEXT_PASS (pass_rename_ssa_copies); - NEXT_PASS (pass_ccp); -+ NEXT_PASS (pass_promote_short_indices); - NEXT_PASS (pass_forwprop); - NEXT_PASS (pass_update_address_taken); - NEXT_PASS (pass_simple_dse); -@@ -561,6 +562,7 @@ init_optimization_passes (void) - execute TODO_rebuild_alias at this point even if - pass_create_structure_vars was disabled. */ - NEXT_PASS (pass_build_alias); -+ NEXT_PASS (pass_remove_local_statics); - NEXT_PASS (pass_return_slot); - NEXT_PASS (pass_rename_ssa_copies); - ---- 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); -+} -+ - - /* 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" - -@@ -705,17 +706,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; -@@ -823,8 +826,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; -@@ -838,8 +841,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 -@@ -4379,6 +4379,165 @@ const struct real_format decimal_quad_fo - false - }; - -+/* 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, -+ 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, -+ false, -+ false, -+ true, -+ true, -+ false, -+ false -+ }; -+ - /* 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 -@@ -286,6 +286,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/recog.c -+++ b/gcc/recog.c -@@ -587,6 +587,7 @@ validate_replace_rtx_1 (rtx *loc, rtx fr - simplifications, as it is not our job. */ - - if (SWAPPABLE_OPERANDS_P (x) -+ && !reload_in_progress - && swap_commutative_operands_p (XEXP (x, 0), XEXP (x, 1))) - { - validate_unshare_change (object, loc, ---- a/gcc/regclass.c -+++ b/gcc/regclass.c -@@ -468,6 +468,24 @@ init_reg_sets_1 (void) - inv_reg_alloc_order[reg_alloc_order[i]] = i; - #endif - -+#ifdef REG_ALLOC_ORDER -+ /* Allow the target to change the allocation order based on -+ supplied flags. */ -+ targetm.adjust_reg_alloc_order (reg_alloc_order); -+ -+ /* Now the contents of reg_alloc_order are fixed, calculate the -+ inverse map. */ -+ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) -+ inv_reg_alloc_order[reg_alloc_order[i]] = i; -+#endif -+ -+ restore_register_info (); -+ -+#ifdef REG_ALLOC_ORDER -+ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) -+ inv_reg_alloc_order[reg_alloc_order[i]] = i; -+#endif -+ - /* This macro allows the fixed or call-used registers - and the register classes to depend on target flags. */ - -@@ -995,10 +1013,10 @@ static void reg_scan_mark_refs (rtx, rtx - /* 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 during regclass, when all pseudos -@@ -2073,7 +2091,7 @@ record_address_regs (enum machine_mode m - enum reg_class class; - - if (context == 1) -- class = INDEX_REG_CLASS; -+ class = index_reg_class (mode); - else - class = base_reg_class (mode, outer_code, index_code); - -@@ -2123,7 +2141,8 @@ record_address_regs (enum machine_mode m - 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)) -@@ -2149,7 +2168,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, -@@ -2157,7 +2176,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/regrename.c -+++ b/gcc/regrename.c -@@ -566,14 +566,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; -@@ -598,7 +598,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); -@@ -820,7 +820,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) -@@ -1486,14 +1486,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; -@@ -1518,8 +1518,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 -@@ -5034,7 +5034,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); -@@ -5042,8 +5042,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 -@@ -5436,13 +5436,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); - -@@ -5534,17 +5534,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); -@@ -5552,7 +5552,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); -@@ -5622,7 +5622,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, ---- a/gcc/reload1.c -+++ b/gcc/reload1.c -@@ -7677,6 +7677,9 @@ emit_reload_insns (struct insn_chain *ch - } - } - -+ if (i < 0 && rld[r].in != NULL_RTX && rld[r].reg_rtx != NULL_RTX) -+ forget_old_reloads_1 (rld[r].reg_rtx, NULL_RTX, NULL); -+ - /* The following if-statement was #if 0'd in 1.34 (or before...). - It's reenabled in 1.35 because supposedly nothing else - deals with this problem. */ ---- a/gcc/rtl-factoring.c -+++ b/gcc/rtl-factoring.c -@@ -444,15 +444,17 @@ collect_pattern_seqs (void) - htab_iterator hti0, hti1, hti2; - p_hash_bucket hash_bucket; - p_hash_elem e0, e1; --#ifdef STACK_REGS -+#if defined STACK_REGS || defined HAVE_cc0 - basic_block bb; -- bitmap_head stack_reg_live; -+ bitmap_head dont_collect; - - /* Extra initialization step to ensure that no stack registers (if present) -- are live across abnormal edges. Set a flag in STACK_REG_LIVE for an insn -- if a stack register is live after the insn. */ -- bitmap_initialize (&stack_reg_live, NULL); -+ or cc0 code (if present) are live across abnormal edges. -+ Set a flag in DONT_COLLECT for an insn if a stack register is live -+ after the insn or the insn is cc0 setter or user. */ -+ bitmap_initialize (&dont_collect, NULL); - -+#ifdef STACK_REGS - FOR_EACH_BB (bb) - { - regset_head live; -@@ -476,7 +478,7 @@ collect_pattern_seqs (void) - { - if (REGNO_REG_SET_P (&live, reg)) - { -- bitmap_set_bit (&stack_reg_live, INSN_UID (insn)); -+ bitmap_set_bit (&dont_collect, INSN_UID (insn)); - break; - } - } -@@ -493,6 +495,28 @@ collect_pattern_seqs (void) - } - #endif - -+#ifdef HAVE_cc0 -+ /* Mark CC0 setters and users as ineligible for collection into sequences. -+ This is an over-conservative fix, since it is OK to include -+ a cc0_setter, but only if we also include the corresponding cc0_user, -+ and vice versa. */ -+ FOR_EACH_BB (bb) -+ { -+ rtx insn; -+ rtx next_tail; -+ -+ next_tail = NEXT_INSN (BB_END (bb)); -+ -+ for (insn = BB_HEAD (bb); insn != next_tail; insn = NEXT_INSN (insn)) -+ { -+ if (INSN_P (insn) && reg_mentioned_p (cc0_rtx, PATTERN (insn))) -+ bitmap_set_bit (&dont_collect, INSN_UID (insn)); -+ } -+ } -+#endif -+ -+#endif /* defined STACK_REGS || defined HAVE_cc0 */ -+ - /* Initialize PATTERN_SEQS to empty. */ - pattern_seqs = 0; - -@@ -505,15 +529,15 @@ collect_pattern_seqs (void) - FOR_EACH_HTAB_ELEMENT (hash_bucket->seq_candidates, e1, p_hash_elem, - hti2) - if (e0 != e1 --#ifdef STACK_REGS -- && !bitmap_bit_p (&stack_reg_live, INSN_UID (e0->insn)) -- && !bitmap_bit_p (&stack_reg_live, INSN_UID (e1->insn)) -+#if defined STACK_REGS || defined HAVE_cc0 -+ && !bitmap_bit_p (&dont_collect, INSN_UID (e0->insn)) -+ && !bitmap_bit_p (&dont_collect, INSN_UID (e1->insn)) - #endif - ) - match_seqs (e0, e1); --#ifdef STACK_REGS -+#if defined STACK_REGS || defined HAVE_cc0 - /* Free unused data. */ -- bitmap_clear (&stack_reg_live); -+ bitmap_clear (&dont_collect); - #endif - } - ---- a/gcc/sched-ebb.c -+++ b/gcc/sched-ebb.c -@@ -271,6 +271,7 @@ static struct sched_info ebb_sched_info - ebb_print_insn, - contributes_to_priority, - compute_jump_reg_dependencies, -+ NULL, /* insn_finishes_block_p */ - - NULL, NULL, - NULL, NULL, ---- a/gcc/sched-int.h -+++ b/gcc/sched-int.h -@@ -376,6 +376,10 @@ struct sched_info - the jump in the regset. */ - void (*compute_jump_reg_dependencies) (rtx, regset, regset, regset); - -+ /* 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 -@@ -2210,6 +2210,19 @@ compute_jump_reg_dependencies (rtx insn - add_branch_dependences. */ - } - -+/* 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). */ - -@@ -2223,6 +2236,7 @@ static struct sched_info region_sched_in - rgn_print_insn, - contributes_to_priority, - compute_jump_reg_dependencies, -+ rgn_insn_finishes_block_p, - - NULL, NULL, - NULL, NULL, ---- a/gcc/sdbout.c -+++ b/gcc/sdbout.c -@@ -336,6 +336,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/target-def.h -+++ b/gcc/target-def.h -@@ -461,6 +461,7 @@ - #define TARGET_CANNOT_MODIFY_JUMPS_P hook_bool_void_false - #define TARGET_BRANCH_TARGET_REGISTER_CLASS hook_int_void_no_regs - #define TARGET_BRANCH_TARGET_REGISTER_CALLEE_SAVED hook_bool_bool_false -+#define TARGET_ADJUST_REG_ALLOC_ORDER hook_intp_void - #define TARGET_CANNOT_FORCE_CONST_MEM hook_bool_rtx_false - #define TARGET_CANNOT_COPY_INSN_P NULL - #define TARGET_COMMUTATIVE_P hook_bool_const_rtx_commutative_p -@@ -512,6 +513,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 - -@@ -568,7 +573,9 @@ - #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_ALLOCATE_STACK_SLOTS_FOR_ARGS hook_bool_void_true - - #define TARGET_CALLS { \ - TARGET_PROMOTE_FUNCTION_ARGS, \ -@@ -588,7 +595,9 @@ - TARGET_ARG_PARTIAL_BYTES, \ - TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN, \ - TARGET_FUNCTION_VALUE, \ -- TARGET_INTERNAL_ARG_POINTER \ -+ TARGET_LIBCALL_VALUE, \ -+ TARGET_INTERNAL_ARG_POINTER, \ -+ TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS \ - } - - #ifndef TARGET_UNWIND_TABLES_DEFAULT -@@ -731,6 +740,7 @@ - TARGET_CANNOT_MODIFY_JUMPS_P, \ - TARGET_BRANCH_TARGET_REGISTER_CLASS, \ - TARGET_BRANCH_TARGET_REGISTER_CALLEE_SAVED, \ -+ TARGET_ADJUST_REG_ALLOC_ORDER, \ - TARGET_CANNOT_FORCE_CONST_MEM, \ - TARGET_CANNOT_COPY_INSN_P, \ - TARGET_COMMUTATIVE_P, \ -@@ -782,6 +792,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_SECONDARY_RELOAD, \ - TARGET_EXPAND_TO_RTL_HOOK, \ - TARGET_INSTANTIATE_DECLS, \ ---- a/gcc/target.h -+++ b/gcc/target.h -@@ -555,6 +555,11 @@ struct gcc_target - already been generated. */ - bool (* branch_target_register_callee_saved) (bool after_pe_gen); - -+ /* Called only if REG_ALLOC_ORDER is defined. Given an array that has -+ been initialized from REG_ALLOC_ORDER, make any target-specific -+ adjustments that cannot be expressed in the definition of that macro. */ -+ void (* adjust_reg_alloc_order) (int *); -+ - /* True if the constant X cannot be placed in the constant pool. */ - bool (* cannot_force_const_mem) (rtx); - -@@ -830,9 +835,18 @@ 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); -+ -+ /* Return true if all function parameters should be spilled to the -+ stack. */ -+ bool (*allocate_stack_slots_for_args) (void); -+ - } calls; - - /* Return the diagnostic message string if conversion from FROMTYPE -@@ -847,6 +861,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 class for a secondary reload, and fill in extra information. */ - enum reg_class (*secondary_reload) (bool, rtx, enum reg_class, - enum machine_mode, ---- a/gcc/targhooks.c -+++ b/gcc/targhooks.c -@@ -565,6 +565,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 ---- a/gcc/targhooks.h -+++ b/gcc/targhooks.h -@@ -87,6 +87,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); - extern enum reg_class default_secondary_reload (bool, rtx, enum reg_class, - enum machine_mode, ---- a/gcc/timevar.def -+++ b/gcc/timevar.def -@@ -129,6 +129,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") -@@ -136,6 +137,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_CGRAPH_VERIFY , "callgraph verifier") - DEFTIMEVAR (TV_DOM_FRONTIERS , "dominance frontiers") - DEFTIMEVAR (TV_DOMINANCE , "dominance computation") ---- a/gcc/toplev.h -+++ b/gcc/toplev.h -@@ -131,6 +131,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; - - /* Things to do with target switches. */ ---- a/gcc/tree-pass.h -+++ b/gcc/tree-pass.h -@@ -264,6 +264,7 @@ extern struct tree_opt_pass pass_iv_cano - extern struct tree_opt_pass pass_scev_cprop; - extern struct tree_opt_pass pass_empty_loop; - extern struct tree_opt_pass pass_record_bounds; -+extern struct tree_opt_pass pass_promote_short_indices; - extern struct tree_opt_pass pass_if_conversion; - extern struct tree_opt_pass pass_vectorize; - extern struct tree_opt_pass pass_complete_unroll; -@@ -328,6 +329,7 @@ extern struct tree_opt_pass pass_reassoc - extern struct tree_opt_pass pass_rebuild_cgraph_edges; - extern struct tree_opt_pass pass_build_cgraph_edges; - extern struct tree_opt_pass pass_reset_cc_flags; -+extern struct tree_opt_pass pass_remove_local_statics; - - /* IPA Passes */ - extern struct tree_opt_pass pass_ipa_matrix_reorg; ---- a/gcc/tree-predcom.c -+++ b/gcc/tree-predcom.c -@@ -1294,6 +1294,7 @@ ref_at_iteration (struct loop *loop, tre - { - tree idx, *idx_p, type, val, op0 = NULL_TREE, ret; - affine_iv iv; -+ tree fs; - bool ok; - - if (handled_component_p (ref)) -@@ -1341,7 +1342,10 @@ ref_at_iteration (struct loop *loop, tre - else - return NULL_TREE; - -- ok = simple_iv (loop, first_stmt (loop->header), idx, &iv, true); -+ fs = first_stmt (loop->header); -+ if (!fs) -+ return NULL_TREE; -+ ok = simple_iv (loop, fs, idx, &iv, true); - if (!ok) - return NULL_TREE; - iv.base = expand_simple_operations (iv.base); ---- a/gcc/tree-ssa-loop-ivopts.c -+++ b/gcc/tree-ssa-loop-ivopts.c -@@ -1391,10 +1391,75 @@ idx_record_use (tree base, tree *idx, - return true; - } - --/* Returns true if memory reference REF may be unaligned. */ -+/* If we can prove that TOP = cst * BOT for some constant cst, -+ store cst to MUL and return true. Otherwise return false. -+ The returned value is always sign-extended, regardless of the -+ signedness of TOP and BOT. */ - - static bool --may_be_unaligned_p (tree ref) -+constant_multiple_of (tree top, tree bot, double_int *mul) -+{ -+ tree mby; -+ enum tree_code code; -+ double_int res, p0, p1; -+ unsigned precision = TYPE_PRECISION (TREE_TYPE (top)); -+ -+ STRIP_NOPS (top); -+ STRIP_NOPS (bot); -+ -+ if (operand_equal_p (top, bot, 0)) -+ { -+ *mul = double_int_one; -+ return true; -+ } -+ -+ code = TREE_CODE (top); -+ switch (code) -+ { -+ case MULT_EXPR: -+ mby = TREE_OPERAND (top, 1); -+ if (TREE_CODE (mby) != INTEGER_CST) -+ return false; -+ -+ if (!constant_multiple_of (TREE_OPERAND (top, 0), bot, &res)) -+ return false; -+ -+ *mul = double_int_sext (double_int_mul (res, tree_to_double_int (mby)), -+ precision); -+ return true; -+ -+ case PLUS_EXPR: -+ case MINUS_EXPR: -+ if (!constant_multiple_of (TREE_OPERAND (top, 0), bot, &p0) -+ || !constant_multiple_of (TREE_OPERAND (top, 1), bot, &p1)) -+ return false; -+ -+ if (code == MINUS_EXPR) -+ p1 = double_int_neg (p1); -+ *mul = double_int_sext (double_int_add (p0, p1), precision); -+ return true; -+ -+ case INTEGER_CST: -+ if (TREE_CODE (bot) != INTEGER_CST) -+ return false; -+ -+ p0 = double_int_sext (tree_to_double_int (top), precision); -+ p1 = double_int_sext (tree_to_double_int (bot), precision); -+ if (double_int_zero_p (p1)) -+ return false; -+ *mul = double_int_sext (double_int_sdivmod (p0, p1, FLOOR_DIV_EXPR, &res), -+ precision); -+ return double_int_zero_p (res); -+ -+ default: -+ return false; -+ } -+} -+ -+/* Returns true if memory reference REF with step STEP may be unaligned. */ -+ -+static bool -+may_be_unaligned_p (tree ref, tree step) - { - tree base; - tree base_type; -@@ -1418,11 +1483,20 @@ may_be_unaligned_p (tree ref) - base_type = TREE_TYPE (base); - base_align = TYPE_ALIGN (base_type); - -- if (mode != BLKmode -- && (base_align < GET_MODE_ALIGNMENT (mode) -+ if (mode != BLKmode) -+ { -+ double_int mul; -+ tree al = build_int_cst (TREE_TYPE (step), -+ GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT); -+ -+ if (base_align < GET_MODE_ALIGNMENT (mode) - || bitpos % GET_MODE_ALIGNMENT (mode) != 0 -- || bitpos % BITS_PER_UNIT != 0)) -- return true; -+ || bitpos % BITS_PER_UNIT != 0) -+ return true; -+ -+ if (! constant_multiple_of (step, al, &mul)) -+ return true; -+ } - - return false; - } -@@ -1549,7 +1623,7 @@ find_interesting_uses_address (struct iv - - /* Moreover, on strict alignment platforms, check that it is - sufficiently aligned. */ -- if (STRICT_ALIGNMENT && may_be_unaligned_p (base)) -+ if (STRICT_ALIGNMENT && may_be_unaligned_p (base, step)) - goto fail; - - base = build_fold_addr_expr (base); -@@ -2585,71 +2659,6 @@ tree_int_cst_sign_bit (const_tree t) - return (w >> bitno) & 1; - } - --/* If we can prove that TOP = cst * BOT for some constant cst, -- store cst to MUL and return true. Otherwise return false. -- The returned value is always sign-extended, regardless of the -- signedness of TOP and BOT. */ -- --static bool --constant_multiple_of (tree top, tree bot, double_int *mul) --{ -- tree mby; -- enum tree_code code; -- double_int res, p0, p1; -- unsigned precision = TYPE_PRECISION (TREE_TYPE (top)); -- -- STRIP_NOPS (top); -- STRIP_NOPS (bot); -- -- if (operand_equal_p (top, bot, 0)) -- { -- *mul = double_int_one; -- return true; -- } -- -- code = TREE_CODE (top); -- switch (code) -- { -- case MULT_EXPR: -- mby = TREE_OPERAND (top, 1); -- if (TREE_CODE (mby) != INTEGER_CST) -- return false; -- -- if (!constant_multiple_of (TREE_OPERAND (top, 0), bot, &res)) -- return false; -- -- *mul = double_int_sext (double_int_mul (res, tree_to_double_int (mby)), -- precision); -- return true; -- -- case PLUS_EXPR: -- case MINUS_EXPR: -- if (!constant_multiple_of (TREE_OPERAND (top, 0), bot, &p0) -- || !constant_multiple_of (TREE_OPERAND (top, 1), bot, &p1)) -- return false; -- -- if (code == MINUS_EXPR) -- p1 = double_int_neg (p1); -- *mul = double_int_sext (double_int_add (p0, p1), precision); -- return true; -- -- case INTEGER_CST: -- if (TREE_CODE (bot) != INTEGER_CST) -- return false; -- -- p0 = double_int_sext (tree_to_double_int (top), precision); -- p1 = double_int_sext (tree_to_double_int (bot), precision); -- if (double_int_zero_p (p1)) -- return false; -- *mul = double_int_sext (double_int_sdivmod (p0, p1, FLOOR_DIV_EXPR, &res), -- precision); -- return double_int_zero_p (res); -- -- default: -- return false; -- } --} -- - /* If A is (TYPE) BA and B is (TYPE) BB, and the types of BA and BB have the - same precision that is at least as wide as the precision of TYPE, stores - BA to A and BB to B, and returns the type of BA. Otherwise, returns the ---- /dev/null -+++ b/gcc/tree-ssa-loop-promote.c -@@ -0,0 +1,1555 @@ -+/* 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 -+. */ -+ -+/* 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 "tree-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" -+#include "tree-chrec.h" -+#include "tree-scalar-evolution.h" -+#include "tree-inline.h" -+ -+struct promote_info { -+ /* The loop being analyzed. */ -+ struct loop *loop; -+ -+ /* The COND_EXPR controlling exit from the loop. */ -+ tree 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; -+ -+ -+/* 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, tree cond, -+ tree 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 = TREE_OPERAND (cond, 0); -+ op1 = TREE_OPERAND (cond, 1); -+ -+ /* See if there's a path from CANDIDATE to an operand of COND. */ -+ while (true) -+ { -+ use_operand_p use; -+ imm_use_iterator iui; -+ tree use_stmt = NULL_TREE; -+ -+ 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) -+ { -+ tree stmt = USE_STMT (use); -+ -+ if (bb_for_stmt (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_generic_expr (dump_file, use_stmt, 0); -+ fprintf (dump_file, "\nsecond use: "); -+ print_generic_expr (dump_file, stmt, 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_TREE) -+ return NULL_TREE; -+ -+ if (TREE_CODE (use_stmt) != GIMPLE_MODIFY_STMT -+ || TREE_CODE (GIMPLE_STMT_OPERAND (use_stmt, 0)) != SSA_NAME -+ || (TREE_CODE (GIMPLE_STMT_OPERAND (use_stmt, 1)) != NOP_EXPR -+ && TREE_CODE (GIMPLE_STMT_OPERAND (use_stmt, 1)) != CONVERT_EXPR)) -+ { -+ if (dump_file) -+ { -+ fprintf (dump_file, "Rejecting "); -+ print_generic_expr (dump_file, candidate, 0); -+ fprintf (dump_file, " because of use in "); -+ print_generic_expr (dump_file, use_stmt, 0); -+ fprintf (dump_file, "\n"); -+ } -+ return NULL_TREE; -+ } -+ -+ candidate = GIMPLE_STMT_OPERAND (use_stmt, 0); -+ } -+ -+ /* 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, tree expr, tree *limit) -+{ -+ tree cond = COND_EXPR_COND (expr); -+ tree phi; -+ tree candidate = NULL_TREE; -+ -+ switch (TREE_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 (phi = phi_nodes (loop->header); phi != NULL_TREE; phi = PHI_CHAIN (phi)) -+ { -+ 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_generic_expr (dump_file, expr, 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 EXPR's suitability with respect to being able to promote VAR. -+ ASSIGNED_TO is true if EXPR is being assigned to VAR; otherwise, EXPR -+ contains a use of VAR. */ -+ -+static bool -+check_expr_for_promotability (struct promote_info *pi, tree var, -+ tree expr, bool assigning_to) -+{ -+ tree type = TREE_TYPE (expr); -+ bool ok = true; -+ -+ switch (TREE_CODE (expr)) -+ { -+ 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 = TREE_OPERAND (expr, 0); -+ tree op1 = TREE_OPERAND (expr, 1); -+ -+ ok = ((op0 == var && could_be_promoted (op1)) -+ || (op1 == var && could_be_promoted (op0))); -+ break; -+ } -+ case COND_EXPR: -+ if (TREE_TYPE (expr) == NULL -+ || TREE_TYPE (expr) == 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: -+ ok = (expr == var || could_be_promoted (expr)); -+ break; -+ case NOP_EXPR: -+ case CONVERT_EXPR: -+ if (!assigning_to) -+ { -+ add_casted_type (pi, type); -+ break; -+ } -+ /* Fallthrough. */ -+ default: -+ ok = false; -+ } -+ -+ 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; -+ tree rhs; -+ tree bad_stmt = NULL_TREE; -+ const char *reason = NULL; -+ -+ FOR_EACH_IMM_USE_FAST (use, iui, var) -+ { -+ basic_block bb; -+ tree use_stmt = USE_STMT (use); -+ -+ /* Uses must exist only within the loop. */ -+ bb = bb_for_stmt (use_stmt); -+ -+ if (dump_file) -+ { -+ fprintf (dump_file, "Checking "); -+ print_generic_expr (dump_file, use_stmt, 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 (stmt_references_memory_p (use_stmt)) -+ { -+ bad_stmt = use_stmt; -+ reason = " is stored to memory in "; -+ break; -+ } -+ -+ /* We cannot pass the variable to a function. */ -+ if (get_call_expr_in (use_stmt)) -+ { -+ bad_stmt = use_stmt; -+ reason = " is passed to function in "; -+ break; -+ } -+ -+ if (TREE_CODE (use_stmt) == GIMPLE_MODIFY_STMT) -+ { -+ tree lhs = GIMPLE_STMT_OPERAND (use_stmt, 0); -+ rhs = GIMPLE_STMT_OPERAND (use_stmt, 1); -+ -+ if (!check_expr_for_promotability (pi, var, rhs, -+ /*is_assign=*/false)) -+ { -+ bad_stmt = rhs; -+ reason = " is involved in non-promotable expression "; -+ break; -+ } -+ else if ((TREE_CODE_CLASS (TREE_CODE (rhs)) == tcc_binary -+ || TREE_CODE (rhs) == SSA_NAME) -+ && !check_expr_for_promotability (pi, var, lhs, -+ /*is_assign=*/true)) -+ { -+ bad_stmt = lhs; -+ reason = " is being assigned to non-promotable variable "; -+ break; -+ } -+ } -+ else if (TREE_CODE (use_stmt) != COND_EXPR -+ && TREE_CODE (use_stmt) != PHI_NODE) -+ { -+ /* 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_generic_expr (dump_file, bad_stmt, 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, tree stmt, void *data) -+{ -+ struct promote_info *pi = data; -+ tree t; -+ -+ if (dump_file) -+ { -+ fprintf (dump_file, "Analyzing loop index "); -+ print_generic_expr (dump_file, var, 0); -+ fprintf (dump_file, " defined in "); -+ print_generic_expr (dump_file, stmt, 0); -+ fprintf (dump_file, "\n"); -+ } -+ -+ /* Check the definition. */ -+ switch (TREE_CODE (stmt)) -+ { -+ case PHI_NODE: -+ /* Phi nodes are OK. */ -+ break; -+ -+ case GIMPLE_MODIFY_STMT: -+ t = GIMPLE_STMT_OPERAND (stmt, 1); -+ if (!check_expr_for_promotability (pi, var, t, -+ /*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 (TREE_CODE (stmt) == PHI_NODE) -+ { -+ int i; -+ -+ for (i = 0; i < 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_generic_expr (dump_file, stmt, 0); -+ fprintf (dump_file, "...%s to analyze\n\n", -+ pi->can_be_promoted_p ? "continuing" : "not continuing"); -+ } -+ return !pi->can_be_promoted_p; -+} -+ -+/* 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 "(short) 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 tree -+upcast_operand_p (tree t) -+{ -+ tree def, nop; -+ -+ 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 (TREE_CODE (def) != GIMPLE_MODIFY_STMT) -+ return NULL_TREE; -+ -+ nop = GIMPLE_STMT_OPERAND (def, 1); -+ if (TREE_CODE (nop) != CONVERT_EXPR -+ && TREE_CODE (nop) != NOP_EXPR) -+ return NULL_TREE; -+ -+ return TREE_OPERAND (nop, 0); -+} -+ -+static bool -+signed_arithmetic_overflow_idiom_p (tree rhs, tree *op0, tree *op1) -+{ -+ tree tmp = TREE_OPERAND (rhs, 0); -+ tree op_stmt = SSA_NAME_DEF_STMT (tmp); -+ tree expr, x2, y2; -+ bool yes = false; -+ enum tree_code code; -+ -+ if (!has_single_use (tmp) -+ || TREE_CODE (op_stmt) != GIMPLE_MODIFY_STMT) -+ goto done; -+ expr = GIMPLE_STMT_OPERAND (op_stmt, 1); -+ -+ /* This could probably profitably be expanded to consider -+ MINUS_EXPR, MULT_EXPR, etc. */ -+ code = TREE_CODE (expr); -+ if (code != PLUS_EXPR) -+ goto done; -+ x2 = TREE_OPERAND (expr, 0); -+ y2 = TREE_OPERAND (expr, 1); -+ -+ 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; -+} -+ -+/* 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 -+stmt_in_loop_p (tree t, struct loop *loop) -+{ -+ basic_block bb; -+ -+ if (t == NULL_TREE) -+ return false; -+ -+ bb = bb_for_stmt (t); -+ if (bb == NULL) -+ return false; -+ -+ return flow_bb_inside_loop_p (loop, bb); -+} -+ -+static bool -+analyze_loop_index_definition_pattern (struct promote_info *pi) -+{ -+ tree phi = SSA_NAME_DEF_STMT (pi->loop_index_name); -+ bool ok = false, warn = false; -+ tree in0, in1; -+ bool inside0, inside1; -+ tree def0, def1, rhs, op0, op1, increment = NULL_TREE; -+ -+ if (TREE_CODE (phi) != PHI_NODE -+ || 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 = SSA_NAME_DEF_STMT (in0); -+ def1 = SSA_NAME_DEF_STMT (in1); -+ -+ 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; -+ in0 = in1; -+ in1 = t; -+ t = def0; -+ def0 = def1; -+ def1 = t; -+ } -+ else if (!inside1) -+ goto done; -+ -+ /* IN0 comes from outside the loop, IN1 from inside. Analyze IN1. */ -+ if (TREE_CODE (def1) != GIMPLE_MODIFY_STMT) -+ goto done; -+ -+ rhs = GIMPLE_STMT_OPERAND (def1, 1); -+ -+ switch (TREE_CODE (rhs)) -+ { -+ case CONVERT_EXPR: -+ case NOP_EXPR: -+ if (!signed_arithmetic_overflow_idiom_p (rhs, &op0, &op1)) -+ goto done; -+ goto plus; -+ case PLUS_EXPR: -+ op0 = TREE_OPERAND (rhs, 0); -+ op1 = TREE_OPERAND (rhs, 1); -+ 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. */ -+ { -+ tree cond = COND_EXPR_COND (pi->exit_expr); -+ enum tree_code code = TREE_CODE (cond); -+ -+ op0 = TREE_OPERAND (cond, 0); -+ op1 = TREE_OPERAND (cond, 1); -+ -+ 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; -+ tree 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 (TREE_CODE (def) == GIMPLE_MODIFY_STMT) -+ { -+ tree rhs = GIMPLE_STMT_OPERAND (def, 1); -+ -+ if (TREE_CODE (rhs) != NOP_EXPR -+ && TREE_CODE (rhs) != CONVERT_EXPR) -+ break; -+ -+ v = TREE_OPERAND (rhs, 0); -+ 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 = 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, tree def_stmt, void *data) -+{ -+ tree promoted_var = (tree) data; -+ void **p; -+ -+ gcc_assert (promoted_var != NULL_TREE); -+ -+ if (TREE_CODE (def_stmt) == PHI_NODE) -+ 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 = 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_MODIFY_STMT and -+ indicates the type of the lhs. */ -+ -+static tree -+rebuild_with_promotion_1 (tree t, tree stmt, tree type, -+ block_stmt_iterator bsi, -+ struct promote_info *pi) -+{ -+ tree op0, op1; -+ -+ switch (TREE_CODE (t)) -+ { -+ case GIMPLE_MODIFY_STMT: -+ { -+ tree orig_op0 = GIMPLE_STMT_OPERAND (t, 0); -+ tree orig_op1 = GIMPLE_STMT_OPERAND (t, 1); -+ tree x, y; -+ void **v; -+ -+ /* If we are defining a promotable variable, check for special -+ idioms. */ -+ v = pointer_map_contains (variable_map, orig_op0); -+ if (v != NULL -+ && *(tree *)v == pi->promoted_var -+ && (TREE_CODE (orig_op1) == NOP_EXPR -+ || TREE_CODE (orig_op1) == CONVERT_EXPR) -+ && signed_arithmetic_overflow_idiom_p (orig_op1, &x, &y)) -+ { -+ tree tmp = TREE_OPERAND (orig_op1, 0); -+ void **xp; -+ void **yp; -+ -+ if (TYPE_PRECISION (TREE_TYPE (tmp)) -+ >= 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: -+ orig_op1 = build2 (PLUS_EXPR, TREE_TYPE (x), x, y); -+ if (dump_file) -+ { -+ fprintf (dump_file, "Substituting "); -+ print_generic_expr (dump_file, orig_op1, 0); -+ fprintf (dump_file, " for rhs of original statement\n"); -+ } -+ done: -+ ; -+ } -+ -+ op0 = rebuild_with_promotion_1 (orig_op0, stmt, type, bsi, pi); -+ op1 = rebuild_with_promotion_1 (orig_op1, stmt, TREE_TYPE (op0), bsi, pi); -+ /* Something must have been rebuilt. */ -+ gcc_assert ((op0 != orig_op0) || (op1 != orig_op1)); -+ if (op0 != orig_op0) -+ GIMPLE_STMT_OPERAND (t, 0) = op0; -+ if (op1 != orig_op1) -+ GIMPLE_STMT_OPERAND (t, 1) = op1; -+ return t; -+ } -+ case NOP_EXPR: -+ case CONVERT_EXPR: -+ { -+ tree pvar = rebuild_with_promotion_1 (TREE_OPERAND (t, 0), stmt, type, bsi, 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_with_promotion_1 (orig_op0, stmt, type, bsi, 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_with_promotion_1 (op0, stmt, type, bsi, pi); -+ op1 = rebuild_with_promotion_1 (op1, stmt, type, bsi, 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: -+ { -+ tree tmp, nop, cast; -+ 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")); -+ tree stmt = build_gimple_modify_stmt (tmp, to_upcast); -+ bsi_insert_before (&bsi, stmt, BSI_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 = build_gimple_modify_stmt (tmp, nop); -+ if (dump_file) -+ { -+ fprintf (dump_file, "Inserting cast "); -+ print_generic_expr (dump_file, cast, 0); -+ fprintf (dump_file, " prior to "); -+ print_generic_expr (dump_file, stmt, 0); -+ fprintf (dump_file, "\n"); -+ } -+ bsi_insert_before (&bsi, cast, BSI_SAME_STMT); -+ return tmp; -+ } -+ } -+} -+ -+/* Rebuild STMT, which contains uses or a def of the promotable variable -+ associated with PI. */ -+ -+static void -+rebuild_with_promotion (tree stmt, struct promote_info *pi) -+{ -+ tree rebuilt; -+ block_stmt_iterator bsi; -+ -+ if (pointer_set_insert (promoted_stmts, stmt)) -+ return; -+ -+ if (dump_file) -+ { -+ fprintf (dump_file, "Rebuilding stmt "); -+ print_generic_expr (dump_file, stmt, 0); -+ fprintf (dump_file, "\n"); -+ } -+ -+ bsi = bsi_for_stmt (stmt); -+ rebuilt = rebuild_with_promotion_1 (stmt, stmt, NULL, bsi, pi); -+ if (dump_file) -+ { -+ fprintf (dump_file, "Converted stmt "); -+ print_generic_expr (dump_file, rebuilt, 0); -+ fprintf (dump_file, "\n\n"); -+ } -+ update_stmt (rebuilt); -+} -+ -+/* Helper function for promote_variable that walks over use/def -+ chains. */ -+ -+static bool -+promote_variable_1 (tree var, tree stmt, void *data) -+{ -+ struct promote_info *pi = (struct promote_info *) data; -+ imm_use_iterator imi; -+ tree use_stmt; -+ -+ /* Due to the way walk_use_def_chains works, when STMT is a PHI_NODE, -+ VAR is actually an argument to the phi node, not the result of it. -+ Rebuild uses of the phi node's result after handle integer constant -+ inputs to the phi node. */ -+ if (TREE_CODE (stmt) == PHI_NODE) -+ { -+ if (TREE_CODE (var) == INTEGER_CST) -+ { -+ edge e = loop_preheader_edge (pi->loop); -+ basic_block preheader = e->src; -+ block_stmt_iterator bsi = bsi_last (preheader); -+ tree cst = build_int_cst_wide (pi->promoted_type, -+ TREE_INT_CST_LOW (var), -+ TREE_INT_CST_HIGH (var)); -+ tree assign = build_gimple_modify_stmt (pi->promoted_var, cst); -+ bsi_insert_after (&bsi, assign, BSI_NEW_STMT); -+ } -+ var = PHI_RESULT (stmt); -+ } -+ else -+ rebuild_with_promotion (stmt, pi); -+ -+ FOR_EACH_IMM_USE_STMT (use_stmt, imi, var) -+ { -+ if (TREE_CODE (use_stmt) != PHI_NODE) -+ 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; -+ tree exit_cond = last_stmt (header); -+ -+ if (exit_cond && TREE_CODE (exit_cond) == COND_EXPR) -+ { -+ tree loop_index; -+ tree limit; -+ struct promote_info *pi; -+ -+ loop_index = find_promotion_candidate (loop, exit_cond, &limit); -+ if (loop_index == NULL_TREE) -+ continue; -+ -+ if (dump_file) -+ { -+ fprintf (dump_file, "Found loop index "); -+ print_generic_expr (dump_file, loop_index, 0); -+ fprintf (dump_file, " involved in "); -+ print_generic_expr (dump_file, exit_cond, 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 = SSA_NAME_VAR (loop_index); -+ /* 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_generic_expr (dump_file, exit_cond, 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 flag_promote_loop_indices; -+} -+ -+struct tree_opt_pass pass_promote_short_indices = -+{ -+ "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 */ -+ 0 /* letter */ -+}; ---- a/gcc/tree-ssa-pre.c -+++ b/gcc/tree-ssa-pre.c -@@ -2006,7 +2006,7 @@ compute_antic (void) - fprintf (dump_file, "Starting iteration %d\n", num_iterations); - num_iterations++; - changed = false; -- for (i = 0; i < last_basic_block - NUM_FIXED_BLOCKS; i++) -+ for (i = 0; i < n_basic_blocks - NUM_FIXED_BLOCKS; i++) - { - if (TEST_BIT (changed_blocks, postorder[i])) - { -@@ -2038,7 +2038,7 @@ compute_antic (void) - fprintf (dump_file, "Starting iteration %d\n", num_iterations); - num_iterations++; - changed = false; -- for (i = 0; i < last_basic_block - NUM_FIXED_BLOCKS; i++) -+ for (i = 0; i < n_basic_blocks - NUM_FIXED_BLOCKS; i++) - { - if (TEST_BIT (changed_blocks, postorder[i])) - { -@@ -2345,6 +2345,10 @@ create_expression_by_pieces (basic_block - tree op2 = TREE_OPERAND (expr, 1); - tree genop1 = find_or_generate_expression (block, op1, stmts); - tree genop2 = find_or_generate_expression (block, op2, stmts); -+ /* Ensure op2 is a sizetype for POINTER_PLUS_EXPR. It -+ may be a constant with the wrong type. */ -+ if (TREE_CODE(expr) == POINTER_PLUS_EXPR) -+ genop2 = fold_convert (sizetype, genop2); - folded = fold_build2 (TREE_CODE (expr), TREE_TYPE (expr), - genop1, genop2); - break; ---- /dev/null -+++ b/gcc/tree-ssa-remove-local-statics.c -@@ -0,0 +1,813 @@ -+/* Local static variable elimination pass. -+ Copyright (C) 2007 Free Software Foundation, Inc. -+ Contributed by Nathan Froyd -+ -+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 -+. */ -+ -+/* 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 "tree-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. */ -+ tree 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 = x; -+ const struct rls_decl_info *b = 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 = x; -+ const struct rls_stmt_info *b = y; -+ -+ return a->stmt == b->stmt; -+} -+ -+static void -+rls_free_use_info (void *info) -+{ -+ struct rls_stmt_info *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 = 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; -+ } -+} -+ -+ -+/* 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, tree 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 -+ && 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); -+ -+ 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_generic_stmt (dump_file, stmt, TDF_DETAILS); -+ } -+ 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) -+ { -+ block_stmt_iterator i; -+ -+ for (i = bsi_start (bb); !bsi_end_p (i); bsi_next (&i)) -+ { -+ tree var; -+ ssa_op_iter iter; -+ tree stmt = bsi_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 CALL_EXPR. */ -+ if (get_call_expr_in (stmt) == NULL_TREE) -+ 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); -+ } -+ } -+ } -+} -+ -+ -+/* 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 = *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 = 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_stmt (dump_file, info->new_var, TDF_DETAILS); -+ } -+ -+ /* Inform SSA about this new variable. */ -+ create_var_ann (info->new_var); -+ mark_sym_for_renaming (info->new_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 = *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 = *slot; -+ -+ if (!TEST_BIT (info->defined, decl->index)) -+ { -+ if (dump_file) -+ { -+ fprintf (dump_file, "not optimizing "); -+ print_generic_stmt (dump_file, decl->orig_var, TDF_DETAILS); -+ fprintf (dump_file, "due to uncovered use in "); -+ print_generic_stmt (dump_file, info->stmt, TDF_DETAILS); -+ 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 = *slot; -+ tree stmt = (tree) data; -+ tree vdef; -+ tree vuse; -+ -+ /* 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) -+ && TREE_CODE (stmt) == GIMPLE_MODIFY_STMT -+ && TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 0)) == VAR_DECL -+ && GIMPLE_STMT_OPERAND (stmt, 0) == 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_STMT_OPERAND (stmt, 0) = info->new_var; -+ -+ update_stmt (stmt); -+ -+ /* None of the other optimizable static variables can occur -+ in this statement. Stop the scan. */ -+ return 0; -+ } -+ -+ /* Check for virtual uses. */ -+ vuse = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_VUSE); -+ -+ if (vuse != NULL -+ && TREE_CODE (stmt) == GIMPLE_MODIFY_STMT -+ && TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 1)) == VAR_DECL -+ && GIMPLE_STMT_OPERAND (stmt, 1) == info->orig_var) -+ { -+ /* Make the statement use the new name. */ -+ GIMPLE_STMT_OPERAND (stmt, 1) = info->new_var; -+ -+ update_stmt (stmt); -+ -+ /* None of the other optimizable static variables can occur -+ in this statement. Stop the scan. */ -+ return 0; -+ } -+ -+ /* Continue scanning. */ -+ return 1; -+} -+ -+/* 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) -+ { -+ block_stmt_iterator bsi; -+ -+ for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi)) -+ { -+ tree stmt = bsi_stmt (bsi); -+ -+ 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 = *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 = 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 = bb->aux; -+ block_stmt_iterator bsi; -+ -+ sbitmap_copy (data->defined_out, data->defined_in); -+ -+ for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi)) -+ { -+ tree stmt = bsi_stmt (bsi); -+ struct rls_stmt_info dummy; -+ void **slot; -+ -+ /* First 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 = *slot; -+ -+ gcc_assert (get_call_expr_in (stmt) == NULL_TREE); -+ -+ 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; -+ } -+ } -+ else if (get_call_expr_in (stmt) != NULL_TREE) -+ /* 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); -+ } -+} -+ -+/* 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 = 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 = 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 -+ && !current_function_calls_setjmp -+ && !cgraph_node (current_function_decl)->ever_was_nested); -+} -+ -+struct tree_opt_pass pass_remove_local_statics = -+{ -+ "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_update_ssa, /* todo_flags_finish */ -+ 0 /* letter */ -+}; ---- a/gcc/tree-ssa-sink.c -+++ b/gcc/tree-ssa-sink.c -@@ -458,6 +458,46 @@ 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 (stmt_references_memory_p (stmt)) -+ { -+ tree fromblock = TREE_BLOCK (stmt); -+ while (fromblock -+ && fromblock != current_function_decl -+ && !BLOCK_VARS (fromblock)) -+ fromblock = BLOCK_SUPERCONTEXT (fromblock); -+ if (fromblock && fromblock != current_function_decl) -+ { -+ tree tostmt; -+ tree toblock; -+ if (bsi_end_p (tobsi)) -+ tostmt = last_stmt (tobb); -+ else -+ tostmt = bsi_stmt (tobsi); -+ if (tostmt) -+ toblock = TREE_BLOCK (tostmt); -+ else -+ toblock = NULL; -+ while (toblock -+ && toblock != current_function_decl -+ && toblock != fromblock) -+ toblock = BLOCK_SUPERCONTEXT (toblock); -+ if (!toblock || toblock != fromblock) -+ { -+ if (!bsi_end_p (bsi)) -+ bsi_prev (&bsi); -+ last = false; -+ continue; -+ } -+ } -+ } -+ - if (dump_file) - { - fprintf (dump_file, "Sinking "); ---- a/gcc/tree-vect-transform.c -+++ b/gcc/tree-vect-transform.c -@@ -1366,22 +1366,41 @@ vect_get_constant_vectors (slp_tree slp_ - tree stmt = VEC_index (tree, stmts, 0); - stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt); - tree vectype = STMT_VINFO_VECTYPE (stmt_vinfo); -- int nunits = TYPE_VECTOR_SUBPARTS (vectype); -+ int nunits; - tree vec_cst; - tree t = NULL_TREE; - int j, number_of_places_left_in_vector; - tree vector_type; -- tree op, vop, operation; -+ tree op, vop; - int group_size = VEC_length (tree, stmts); - unsigned int vec_num, i; - int number_of_copies = 1; -- bool is_store = false; - unsigned int number_of_vectors = SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node); - VEC (tree, heap) *voprnds = VEC_alloc (tree, heap, number_of_vectors); -- bool constant_p; -+ bool constant_p, is_store; - -+ op = GIMPLE_STMT_OPERAND (stmt, 1); - if (STMT_VINFO_DATA_REF (stmt_vinfo)) - is_store = true; -+ else -+ { -+ is_store = false; -+ op = TREE_OPERAND (op, op_num); -+ } -+ -+ if (CONSTANT_CLASS_P (op)) -+ { -+ vector_type = vectype; -+ constant_p = true; -+ } -+ else -+ { -+ vector_type = get_vectype_for_scalar_type (TREE_TYPE (op)); -+ gcc_assert (vector_type); -+ constant_p = false; -+ } -+ -+ nunits = TYPE_VECTOR_SUBPARTS (vector_type); - - /* NUMBER_OF_COPIES is the number of times we need to use the same values in - created vectors. It is greater than 1 if unrolling is performed. -@@ -1402,18 +1421,13 @@ vect_get_constant_vectors (slp_tree slp_ - number_of_copies = least_common_multiple (nunits, group_size) / group_size; - - number_of_places_left_in_vector = nunits; -- constant_p = true; - for (j = 0; j < number_of_copies; j++) - { - for (i = group_size - 1; VEC_iterate (tree, stmts, i, stmt); i--) - { -- operation = GIMPLE_STMT_OPERAND (stmt, 1); -- if (is_store) -- op = operation; -- else -- op = TREE_OPERAND (operation, op_num); -- if (!CONSTANT_CLASS_P (op)) -- constant_p = false; -+ op = GIMPLE_STMT_OPERAND (stmt, 1); -+ if (!STMT_VINFO_DATA_REF (stmt_vinfo)) -+ op = TREE_OPERAND (op, op_num); - - /* Create 'vect_ = {op0,op1,...,opn}'. */ - t = tree_cons (NULL_TREE, op, t); -@@ -1424,16 +1438,12 @@ vect_get_constant_vectors (slp_tree slp_ - { - number_of_places_left_in_vector = nunits; - -- vector_type = get_vectype_for_scalar_type (TREE_TYPE (op)); -- gcc_assert (vector_type); - if (constant_p) - vec_cst = build_vector (vector_type, t); - else - vec_cst = build_constructor_from_list (vector_type, t); -- constant_p = true; - VEC_quick_push (tree, voprnds, -- vect_init_vector (stmt, vec_cst, vector_type, -- NULL)); -+ vect_init_vector (stmt, vec_cst, vector_type, NULL)); - t = NULL_TREE; - } - } -@@ -1829,7 +1839,7 @@ vect_get_vec_def_for_operand (tree op, t - stmt_vec_info def_stmt_info = NULL; - stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt); - tree vectype = STMT_VINFO_VECTYPE (stmt_vinfo); -- int nunits = TYPE_VECTOR_SUBPARTS (vectype); -+ unsigned int nunits = TYPE_VECTOR_SUBPARTS (vectype); - loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo); - tree vec_inv; - tree vec_cst; -@@ -1878,16 +1888,17 @@ vect_get_vec_def_for_operand (tree op, t - { - t = tree_cons (NULL_TREE, op, t); - } -- vector_type = get_vectype_for_scalar_type (TREE_TYPE (op)); -- gcc_assert (vector_type); -- vec_cst = build_vector (vector_type, t); -- -- return vect_init_vector (stmt, vec_cst, vector_type, NULL); -+ vec_cst = build_vector (vectype, t); -+ return vect_init_vector (stmt, vec_cst, vectype, NULL); - } - - /* Case 2: operand is defined outside the loop - loop invariant. */ - case vect_invariant_def: - { -+ vector_type = get_vectype_for_scalar_type (TREE_TYPE (def)); -+ gcc_assert (vector_type); -+ nunits = TYPE_VECTOR_SUBPARTS (vector_type); -+ - if (scalar_def) - *scalar_def = def; - -@@ -1901,8 +1912,6 @@ vect_get_vec_def_for_operand (tree op, t - } - - /* FIXME: use build_constructor directly. */ -- vector_type = get_vectype_for_scalar_type (TREE_TYPE (def)); -- gcc_assert (vector_type); - vec_inv = build_constructor_from_list (vector_type, t); - return vect_init_vector (stmt, vec_inv, vector_type, NULL); - } -@@ -2167,6 +2176,7 @@ get_initial_def_for_reduction (tree stmt - struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo); - tree vectype = STMT_VINFO_VECTYPE (stmt_vinfo); - int nunits = TYPE_VECTOR_SUBPARTS (vectype); -+ tree scalar_type = TREE_TYPE (vectype); - enum tree_code code = TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 1)); - tree type = TREE_TYPE (init_val); - tree vecdef; -@@ -2174,7 +2184,6 @@ get_initial_def_for_reduction (tree stmt - tree init_def; - tree t = NULL_TREE; - int i; -- tree vector_type; - bool nested_in_vect_loop = false; - - gcc_assert (POINTER_TYPE_P (type) || INTEGRAL_TYPE_P (type) || SCALAR_FLOAT_TYPE_P (type)); -@@ -2195,15 +2204,14 @@ get_initial_def_for_reduction (tree stmt - else - *adjustment_def = init_val; - /* Create a vector of zeros for init_def. */ -- if (SCALAR_FLOAT_TYPE_P (type)) -- def_for_init = build_real (type, dconst0); -+ if (SCALAR_FLOAT_TYPE_P (scalar_type)) -+ def_for_init = build_real (scalar_type, dconst0); - else -- def_for_init = build_int_cst (type, 0); -+ def_for_init = build_int_cst (scalar_type, 0); -+ - for (i = nunits - 1; i >= 0; --i) - t = tree_cons (NULL_TREE, def_for_init, t); -- vector_type = get_vectype_for_scalar_type (TREE_TYPE (def_for_init)); -- gcc_assert (vector_type); -- init_def = build_vector (vector_type, t); -+ init_def = build_vector (vectype, t); - break; - - case MIN_EXPR: ---- a/gcc/tree.c -+++ b/gcc/tree.c -@@ -4031,6 +4031,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. */ -@@ -4078,9 +4079,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)) -@@ -4122,6 +4125,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 -@@ -399,7 +399,10 @@ struct tree_base GTY(()) - unsigned lang_flag_6 : 1; - unsigned visited : 1; - -- unsigned spare : 23; -+ /* For tree_type. */ -+ unsigned packed_flag : 1; -+ -+ unsigned spare : 22; - - /* FIXME tuples: Eventually, we need to move this somewhere external to - the trees. */ -@@ -2287,7 +2290,7 @@ struct tree_block GTY(()) - - /* 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 -@@ -2306,17 +2309,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 : 7; -+ unsigned string_flag : 1; -+ - unsigned lang_flag_0 : 1; - unsigned lang_flag_1 : 1; - unsigned lang_flag_2 : 1; ---- a/gcc/unwind-dw2.c -+++ b/gcc/unwind-dw2.c -@@ -1402,16 +1402,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) -@@ -1419,7 +1415,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) - { -@@ -1433,7 +1429,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 - { -@@ -1459,6 +1456,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 -@@ -297,10 +297,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 -@@ -90,7 +90,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 -@@ -203,7 +204,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; -@@ -226,7 +228,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 -@@ -256,7 +259,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); -@@ -285,7 +289,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 -@@ -555,7 +555,7 @@ get_section (const char *name, unsigned - static bool - use_object_blocks_p (void) - { -- return flag_section_anchors; -+ return flag_section_anchors && flag_toplevel_reorder; - } - - /* Return the object_block structure for section SECT. Create a new -@@ -1095,13 +1095,12 @@ align_variable (tree decl, bool dont_out - /* On some machines, it is good to increase alignment sometimes. */ - if (! DECL_USER_ALIGN (decl)) - { --#ifdef DATA_ALIGNMENT -- unsigned int data_align = DATA_ALIGNMENT (TREE_TYPE (decl), align); -+ unsigned int data_align = -+ calculate_global_alignment (TREE_TYPE (decl), 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) - { ---- a/gcc/vmsdbgout.c -+++ b/gcc/vmsdbgout.c -@@ -211,6 +211,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 -@@ -583,6 +583,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 -@@ -119,7 +119,7 @@ stamp-h1: $(srcdir)/config.in config.sta - -rm -f stamp-h1 - $(SHELL) ./config.status config.h - --$(srcdir)/config.in: @MAINT@ $(srcdir)/configure -+$(srcdir)/config.in: @MAINT@ $(srcdir)/configure.ac - cd $(srcdir) && $(AUTOHEADER) - -rm -f stamp-h1 - ---- a/libcpp/configure -+++ b/libcpp/configure -@@ -8311,6 +8311,7 @@ case $target in - sparc64*-*-* | ultrasparc-*-freebsd* | \ - sparcv9-*-solaris2* | \ - sparc-*-solaris2.[789] | sparc-*-solaris2.1[0-9]* | \ -+ sparc-wrs-linux-gnu | \ - spu-*-* | \ - sh[123456789l]*-*-*) - need_64bit_hwint=yes ;; ---- a/libcpp/configure.ac -+++ b/libcpp/configure.ac -@@ -129,6 +129,7 @@ case $target in - sparc64*-*-* | ultrasparc-*-freebsd* | \ - sparcv9-*-solaris2* | \ - sparc-*-solaris2.[789] | sparc-*-solaris2.1[0-9]* | \ -+ sparc-wrs-linux-gnu | \ - spu-*-* | \ - sh[123456789l]*-*-*) - need_64bit_hwint=yes ;; ---- a/libcpp/lex.c -+++ b/libcpp/lex.c -@@ -1240,7 +1240,7 @@ cpp_token_len (const cpp_token *token) - - switch (TOKEN_SPELL (token)) - { -- default: len = 4; break; -+ default: len = 6; break; - case SPELL_LITERAL: len = token->val.str.len; break; - case SPELL_IDENT: len = NODE_LEN (token->val.node) * 10; break; - } ---- a/libffi/Makefile.am -+++ b/libffi/Makefile.am -@@ -156,7 +156,9 @@ nodist_libffi_convenience_la_SOURCES = $ - - AM_CFLAGS = -Wall -g -fexceptions - --libffi_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` -+LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS)) -+ -+libffi_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(LTLDFLAGS) - - AM_CPPFLAGS = -I. -I$(top_srcdir)/include -Iinclude -I$(top_srcdir)/src - AM_CCASFLAGS = $(AM_CPPFLAGS) ---- a/libffi/Makefile.in -+++ b/libffi/Makefile.in -@@ -439,7 +439,8 @@ nodist_libffi_la_SOURCES = $(am__append_ - libffi_convenience_la_SOURCES = $(libffi_la_SOURCES) - nodist_libffi_convenience_la_SOURCES = $(nodist_libffi_la_SOURCES) - AM_CFLAGS = -Wall -g -fexceptions --libffi_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` -+LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS)) -+libffi_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(LTLDFLAGS) - AM_CPPFLAGS = -I. -I$(top_srcdir)/include -Iinclude -I$(top_srcdir)/src - AM_CCASFLAGS = $(AM_CPPFLAGS) - all: fficonfig.h ---- a/libgcc/Makefile.in -+++ b/libgcc/Makefile.in -@@ -388,18 +388,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 -@@ -223,12 +223,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*) - ;; -@@ -438,8 +441,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*) - ;; -@@ -461,6 +468,10 @@ mips64vr-*-elf* | mips64vrel-*-elf*) - ;; - mips64orion-*-elf* | mips64orionel-*-elf*) - ;; -+mips64octeon-wrs-elf* | mips64octeonel-wrs-elf*) -+ ;; -+mips64octeon-montavista-elf*) -+ ;; - mips*-*-rtems*) - ;; - mips-wrs-vxworks) ---- /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 -@@ -1,5 +1,21 @@ --EXTRA_PARTS += ecrti$(objext) ecrtn$(objext) ncrti$(objext) ncrtn$(objext) \ -- crtsavres$(objext) -+LIB2ADD_ST += 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 -+ -+EXTRA_PARTS += ecrti$(objext) ecrtn$(objext) ncrti$(objext) ncrtn$(objext) - - # We build {e,n}crti.o and {e,n}crtn.o, which serve to add begin and - # end labels to all of the special sections used when we link using gcc. -@@ -17,8 +33,62 @@ ncrti.S: $(gcc_srcdir)/config/rs6000/sol - ncrtn.S: $(gcc_srcdir)/config/rs6000/sol-cn.asm - cat $(gcc_srcdir)/config/rs6000/sol-cn.asm >ncrtn.S - --crtsavres.S: $(gcc_srcdir)/config/rs6000/crtsavres.asm -- cat $(gcc_srcdir)/config/rs6000/crtsavres.asm >crtsavres.S -+crtsavfpr.S: $(gcc_srcdir)/config/rs6000/crtsavfpr.asm -+ cat $(gcc_srcdir)/config/rs6000/crtsavfpr.asm >crtsavfpr.S -+ -+crtresfpr.S: $(gcc_srcdir)/config/rs6000/crtresfpr.asm -+ cat $(gcc_srcdir)/config/rs6000/crtresfpr.asm >crtresfpr.S -+ -+crtsavgpr.S: $(gcc_srcdir)/config/rs6000/crtsavgpr.asm -+ cat $(gcc_srcdir)/config/rs6000/crtsavgpr.asm >crtsavgpr.S -+ -+crtresgpr.S: $(gcc_srcdir)/config/rs6000/crtresgpr.asm -+ cat $(gcc_srcdir)/config/rs6000/crtresgpr.asm >crtresgpr.S -+ -+crtresxfpr.S: $(gcc_srcdir)/config/rs6000/crtresxfpr.asm -+ cat $(gcc_srcdir)/config/rs6000/crtresxfpr.asm >crtresxfpr.S -+ -+crtresxgpr.S: $(gcc_srcdir)/config/rs6000/crtresxgpr.asm -+ cat $(gcc_srcdir)/config/rs6000/crtresxgpr.asm >crtresxgpr.S -+ -+e500crtres32gpr.S: $(gcc_srcdir)/config/rs6000/e500crtres32gpr.asm -+ cat $(gcc_srcdir)/config/rs6000/e500crtres32gpr.asm >e500crtres32gpr.S -+ -+e500crtres64gpr.S: $(gcc_srcdir)/config/rs6000/e500crtres64gpr.asm -+ cat $(gcc_srcdir)/config/rs6000/e500crtres64gpr.asm >e500crtres64gpr.S -+ -+e500crtres64gprctr.S: $(gcc_srcdir)/config/rs6000/e500crtres64gprctr.asm -+ cat $(gcc_srcdir)/config/rs6000/e500crtres64gprctr.asm >e500crtres64gprctr.S -+ -+e500crtrest32gpr.S: $(gcc_srcdir)/config/rs6000/e500crtrest32gpr.asm -+ cat $(gcc_srcdir)/config/rs6000/e500crtrest32gpr.asm >e500crtrest32gpr.S -+ -+e500crtrest64gpr.S: $(gcc_srcdir)/config/rs6000/e500crtrest64gpr.asm -+ cat $(gcc_srcdir)/config/rs6000/e500crtrest64gpr.asm >e500crtrest64gpr.S -+ -+e500crtresx32gpr.S: $(gcc_srcdir)/config/rs6000/e500crtresx32gpr.asm -+ cat $(gcc_srcdir)/config/rs6000/e500crtresx32gpr.asm >e500crtresx32gpr.S -+ -+e500crtresx64gpr.S: $(gcc_srcdir)/config/rs6000/e500crtresx64gpr.asm -+ cat $(gcc_srcdir)/config/rs6000/e500crtresx64gpr.asm >e500crtresx64gpr.S -+ -+e500crtsav32gpr.S: $(gcc_srcdir)/config/rs6000/e500crtsav32gpr.asm -+ cat $(gcc_srcdir)/config/rs6000/e500crtsav32gpr.asm >e500crtsav32gpr.S -+ -+e500crtsav64gpr.S: $(gcc_srcdir)/config/rs6000/e500crtsav64gpr.asm -+ cat $(gcc_srcdir)/config/rs6000/e500crtsav64gpr.asm >e500crtsav64gpr.S -+ -+e500crtsav64gprctr.S: $(gcc_srcdir)/config/rs6000/e500crtsav64gprctr.asm -+ cat $(gcc_srcdir)/config/rs6000/e500crtsav64gprctr.asm >e500crtsav64gprctr.S -+ -+e500crtsavg32gpr.S: $(gcc_srcdir)/config/rs6000/e500crtsavg32gpr.asm -+ cat $(gcc_srcdir)/config/rs6000/e500crtsavg32gpr.asm >e500crtsavg32gpr.S -+ -+e500crtsavg64gpr.S: $(gcc_srcdir)/config/rs6000/e500crtsavg64gpr.asm -+ cat $(gcc_srcdir)/config/rs6000/e500crtsavg64gpr.asm >e500crtsavg64gpr.S -+ -+e500crtsavg64gprctr.S: $(gcc_srcdir)/config/rs6000/e500crtsavg64gprctr.asm -+ cat $(gcc_srcdir)/config/rs6000/e500crtsavg64gprctr.asm >e500crtsavg64gprctr.S - - ecrti$(objext): ecrti.S - $(crt_compile) -c ecrti.S -@@ -34,3 +104,60 @@ ncrtn$(objext): 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 - -@@ -39,6 +44,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 -@@ -48,10 +59,31 @@ 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-data-local: install-html -+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) -@@ -69,6 +101,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 -@@ -94,8 +94,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 = -@@ -217,9 +215,12 @@ USE_FORTRAN_TRUE = @USE_FORTRAN_TRUE@ - VERSION = @VERSION@ - XCFLAGS = @XCFLAGS@ - XLDFLAGS = @XLDFLAGS@ -+ac_ct_AR = @ac_ct_AR@ - ac_ct_CC = @ac_ct_CC@ - ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ - ac_ct_FC = @ac_ct_FC@ -+ac_ct_RANLIB = @ac_ct_RANLIB@ -+ac_ct_STRIP = @ac_ct_STRIP@ - am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ - am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ - am__include = @am__include@ -@@ -237,7 +238,6 @@ config_path = @config_path@ - datadir = @datadir@ - datarootdir = @datarootdir@ - docdir = @docdir@ --dvidir = @dvidir@ - enable_shared = @enable_shared@ - enable_static = @enable_static@ - exec_prefix = @exec_prefix@ -@@ -254,7 +254,6 @@ libdir = @libdir@ - libexecdir = @libexecdir@ - libtool_VERSION = @libtool_VERSION@ - link_gomp = @link_gomp@ --localedir = @localedir@ - localstatedir = @localstatedir@ - lt_ECHO = @lt_ECHO@ - mandir = @mandir@ -@@ -264,7 +263,6 @@ oldincludedir = @oldincludedir@ - pdfdir = @pdfdir@ - prefix = @prefix@ - program_transform_name = @program_transform_name@ --psdir = @psdir@ - sbindir = @sbindir@ - sharedstatedir = @sharedstatedir@ - sysconfdir = @sysconfdir@ -@@ -297,6 +295,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 -@@ -304,6 +309,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 -@@ -545,13 +551,10 @@ dist-info: $(INFO_DEPS) - $(srcdir)/*) base=`echo "$$base" | sed "s|^$$srcdirstrip/||"`;; \ - esac; \ - if test -f $$base; then d=.; else d=$(srcdir); fi; \ -- base_i=`echo "$$base" | sed 's|\.info$$||;s|$$|.i|'`; \ -- for file in $$d/$$base $$d/$$base-[0-9] $$d/$$base-[0-9][0-9] $$d/$$base_i[0-9] $$d/$$base_i[0-9][0-9]; do \ -- if test -f $$file; then \ -- relfile=`expr "$$file" : "$$d/\(.*\)"`; \ -- test -f $(distdir)/$$relfile || \ -- cp -p $$file $(distdir)/$$relfile; \ -- else :; fi; \ -+ for file in $$d/$$base*; do \ -+ relfile=`expr "$$file" : "$$d/\(.*\)"`; \ -+ test -f $(distdir)/$$relfile || \ -+ cp -p $$file $(distdir)/$$relfile; \ - done; \ - done - -@@ -955,7 +958,8 @@ info: info-recursive - - info-am: $(INFO_DEPS) - --install-data-am: install-info-am install-nodist_fincludeHEADERS \ -+install-data-am: install-data-local install-info-am \ -+ install-nodist_fincludeHEADERS \ - install-nodist_libsubincludeHEADERS - - install-exec-am: install-multi install-nodist_toolexeclibHEADERS \ -@@ -1035,9 +1039,9 @@ uninstall-info: uninstall-info-recursive - distclean-multi distclean-recursive distclean-tags \ - distcleancheck distdir distuninstallcheck dvi dvi-am html \ - html-am info info-am install install-am install-data \ -- install-data-am install-exec install-exec-am install-info \ -- install-info-am install-man install-multi \ -- install-nodist_fincludeHEADERS \ -+ install-data-am install-data-local install-exec \ -+ install-exec-am install-info install-info-am install-man \ -+ install-multi install-nodist_fincludeHEADERS \ - install-nodist_libsubincludeHEADERS \ - install-nodist_toolexeclibHEADERS install-strip \ - install-toolexeclibLTLIBRARIES installcheck installcheck-am \ -@@ -1064,9 +1068,26 @@ 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-data-local: install-html -+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) ---- /dev/null -+++ b/libgomp/config/linux/mips/futex.h -@@ -0,0 +1,75 @@ -+/* Copyright (C) 2005, 2008 Free Software Foundation, Inc. -+ Contributed by Ilie Garbacea , Chao-ying Fu . -+ -+ This file is part of the GNU OpenMP Library (libgomp). -+ -+ Libgomp is free software; you can redistribute it and/or modify it -+ under the terms of the GNU Lesser General Public License as published by -+ the Free Software Foundation; either version 2.1 of the License, or -+ (at your option) any later version. -+ -+ Libgomp 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 Lesser General Public License for -+ more details. -+ -+ You should have received a copy of the GNU Lesser General Public License -+ along with libgomp; see the file COPYING.LIB. If not, write to the -+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, -+ MA 02110-1301, USA. */ -+ -+/* As a special exception, if you link this library with other files, some -+ of which are compiled with GCC, to produce an executable, this library -+ does not by itself 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. */ -+ -+/* Provide target-specific access to the futex system call. */ -+ -+#include -+#define FUTEX_WAIT 0 -+#define FUTEX_WAKE 1 -+ -+static inline void -+sys_futex0 (int *addr, int op, int val) -+{ -+ register unsigned long __v0 asm("$2") = (unsigned long) SYS_futex; -+ register unsigned long __a0 asm("$4") = (unsigned long) addr; -+ register unsigned long __a1 asm("$5") = (unsigned long) op; -+ register unsigned long __a2 asm("$6") = (unsigned long) val; -+ register unsigned long __a3 asm("$7") = 0; -+ -+ __asm volatile ("syscall" -+ /* returns $a3 (errno), $v0 (return value) */ -+ : "=r" (__v0), "=r" (__a3) -+ /* arguments in v0 (syscall) a0-a3 */ -+ : "r" (__v0), "r" (__a0), "r" (__a1), "r" (__a2), "r" (__a3) -+ /* clobbers at, v1, t0-t9, memory */ -+ : "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", "$14", -+ "$15", "$24", "$25", "memory"); -+} -+ -+static inline void -+futex_wait (int *addr, int val) -+{ -+ sys_futex0 (addr, FUTEX_WAIT, val); -+} -+ -+static inline void -+futex_wake (int *addr, int count) -+{ -+ sys_futex0 (addr, FUTEX_WAKE, count); -+} -+ -+static inline void -+cpu_relax (void) -+{ -+ __asm volatile ("" : : : "memory"); -+} -+ -+static inline void -+atomic_write_barrier (void) -+{ -+ __sync_synchronize (); -+} ---- a/libgomp/configure -+++ b/libgomp/configure -@@ -457,7 +457,7 @@ ac_includes_default="\ - # include - #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 lt_ECHO 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 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 lt_ECHO 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 LIBOBJS LTLIBOBJS' - ac_subst_files='' - - # Initialize some variables set by options. -@@ -1028,6 +1028,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] -@@ -2174,6 +2178,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 -@@ -4219,13 +4263,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:4242: $ac_compile\"" >&5) -+ (eval echo "\"\$as_me:4266: $ac_compile\"" >&5) - (eval "$ac_compile" 2>conftest.err) - cat conftest.err >&5 -- (eval echo "\"\$as_me:4245: $NM \\\"conftest.$ac_objext\\\"\"" >&5) -+ (eval echo "\"\$as_me:4269: $NM \\\"conftest.$ac_objext\\\"\"" >&5) - (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) - cat conftest.err >&5 -- (eval echo "\"\$as_me:4248: output\"" >&5) -+ (eval echo "\"\$as_me:4272: output\"" >&5) - cat conftest.out >&5 - if $GREP 'External.*some_variable' conftest.out > /dev/null; then - lt_cv_nm_interface="MS dumpbin" -@@ -5281,7 +5325,7 @@ ia64-*-hpux*) - ;; - *-*-irix6*) - # Find out which ABI we are using. -- echo '#line 5304 "configure"' > conftest.$ac_ext -+ echo '#line 5328 "configure"' > conftest.$ac_ext - if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? -@@ -6381,11 +6425,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:6404: $lt_compile\"" >&5) -+ (eval echo "\"\$as_me:6428: $lt_compile\"" >&5) - (eval "$lt_compile" 2>conftest.err) - ac_status=$? - cat conftest.err >&5 -- echo "$as_me:6408: \$? = $ac_status" >&5 -+ echo "$as_me:6432: \$? = $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. -@@ -6703,11 +6747,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:6726: $lt_compile\"" >&5) -+ (eval echo "\"\$as_me:6750: $lt_compile\"" >&5) - (eval "$lt_compile" 2>conftest.err) - ac_status=$? - cat conftest.err >&5 -- echo "$as_me:6730: \$? = $ac_status" >&5 -+ echo "$as_me:6754: \$? = $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. -@@ -6808,11 +6852,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:6831: $lt_compile\"" >&5) -+ (eval echo "\"\$as_me:6855: $lt_compile\"" >&5) - (eval "$lt_compile" 2>out/conftest.err) - ac_status=$? - cat out/conftest.err >&5 -- echo "$as_me:6835: \$? = $ac_status" >&5 -+ echo "$as_me:6859: \$? = $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 -@@ -6863,11 +6907,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:6886: $lt_compile\"" >&5) -+ (eval echo "\"\$as_me:6910: $lt_compile\"" >&5) - (eval "$lt_compile" 2>out/conftest.err) - ac_status=$? - cat out/conftest.err >&5 -- echo "$as_me:6890: \$? = $ac_status" >&5 -+ echo "$as_me:6914: \$? = $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 -@@ -9660,7 +9704,7 @@ else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF --#line 9683 "configure" -+#line 9707 "configure" - #include "confdefs.h" - - #if HAVE_DLFCN_H -@@ -9760,7 +9804,7 @@ else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF --#line 9783 "configure" -+#line 9807 "configure" - #include "confdefs.h" - - #if HAVE_DLFCN_H -@@ -10115,7 +10159,7 @@ fi - - - # Provide some information about the compiler. --echo "$as_me:10138:" \ -+echo "$as_me:10162:" \ - "checking for Fortran compiler version" >&5 - ac_compiler=`set X $ac_compile; echo $2` - { (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 -@@ -10351,7 +10395,7 @@ fi - - - # Provide some information about the compiler. --echo "$as_me:10374:" \ -+echo "$as_me:10398:" \ - "checking for Fortran compiler version" >&5 - ac_compiler=`set X $ac_compile; echo $2` - { (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 -@@ -11067,11 +11111,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:11090: $lt_compile\"" >&5) -+ (eval echo "\"\$as_me:11114: $lt_compile\"" >&5) - (eval "$lt_compile" 2>conftest.err) - ac_status=$? - cat conftest.err >&5 -- echo "$as_me:11094: \$? = $ac_status" >&5 -+ echo "$as_me:11118: \$? = $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. -@@ -11166,11 +11210,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:11189: $lt_compile\"" >&5) -+ (eval echo "\"\$as_me:11213: $lt_compile\"" >&5) - (eval "$lt_compile" 2>out/conftest.err) - ac_status=$? - cat out/conftest.err >&5 -- echo "$as_me:11193: \$? = $ac_status" >&5 -+ echo "$as_me:11217: \$? = $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 -@@ -11218,11 +11262,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:11241: $lt_compile\"" >&5) -+ (eval echo "\"\$as_me:11265: $lt_compile\"" >&5) - (eval "$lt_compile" 2>out/conftest.err) - ac_status=$? - cat out/conftest.err >&5 -- echo "$as_me:11245: \$? = $ac_status" >&5 -+ echo "$as_me:11269: \$? = $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 -@@ -16777,7 +16821,7 @@ fi - rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - ;; -- yes) -+ yes) - cat >conftest.$ac_ext <<_ACEOF - /* confdefs.h. */ - _ACEOF -@@ -20485,6 +20529,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/configure.tgt -+++ b/libgomp/configure.tgt -@@ -35,6 +35,10 @@ if test $enable_linux_futex = yes; then - config_path="linux/ia64 linux posix" - ;; - -+ mips*-*-linux*) -+ config_path="linux/mips linux posix" -+ ;; -+ - powerpc*-*-linux*) - config_path="linux/powerpc linux posix" - ;; ---- a/libgomp/libgomp.texi -+++ b/libgomp/libgomp.texi -@@ -95,7 +95,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 - - -@@ -1367,8 +1367,8 @@ Bugs in the GNU OpenMP implementation sh - @c Index - @c --------------------------------------------------------------------- - --@node Index --@unnumbered Index -+@node Library Index -+@unnumbered Library Index - - @printindex cp - ---- a/libiberty/Makefile.in -+++ b/libiberty/Makefile.in -@@ -124,7 +124,7 @@ COMPILE.c = $(CC) -c @DEFS@ $(LIBCFLAGS) - 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 \ -@@ -180,7 +180,7 @@ REQUIRED_OFILES = ./regex.o ./cplus-dem. - # 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 \ -@@ -615,6 +615,13 @@ $(CONFIGURED_OFILES): stamp-picdir - else true; fi - $(COMPILE.c) $(srcdir)/cplus-dem.c $(OUTPUT_OPTION) - -+./cygpath.o: $(srcdir)/cygpath.c stamp-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 stamp-h $(INCDIR)/ansidecl.h \ - $(INCDIR)/dyn-string.h $(INCDIR)/libiberty.h - if [ x"$(PICFLAG)" != x ]; then \ ---- a/libiberty/configure -+++ b/libiberty/configure -@@ -8524,6 +8524,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 -@@ -686,6 +686,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 ---- a/libiberty/cp-demangle.c -+++ b/libiberty/cp-demangle.c -@@ -1885,6 +1885,11 @@ cplus_demangle_builtin_types[D_BUILTIN_T - }; - - CP_STATIC_IF_GLIBCPP_V3 -+const struct demangle_builtin_type_info -+cplus_demangle_builtin_Dh_type = -+ { NL ("__fp16"), NL ("__fp16"), D_PRINT_DEFAULT }; -+ -+CP_STATIC_IF_GLIBCPP_V3 - struct demangle_component * - cplus_demangle_type (struct d_info *di) - { -@@ -1936,6 +1941,21 @@ cplus_demangle_type (struct d_info *di) - d_advance (di, 1); - break; - -+ case 'D': -+ d_advance (di, 1); -+ switch (d_peek_char (di)) -+ { -+ case 'h': -+ ret = d_make_builtin_type (di, &cplus_demangle_builtin_Dh_type); -+ di->expansion += ret->u.s_builtin.type->len; -+ can_subst = 0; -+ d_advance (di, 1); -+ break; -+ default: -+ return NULL; -+ } -+ break; -+ - case 'u': - d_advance (di, 1); - ret = d_make_comp (di, DEMANGLE_COMPONENT_VENDOR_TYPE, ---- /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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#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/make-temp-file.c -+++ b/libiberty/make-temp-file.c -@@ -23,6 +23,7 @@ Boston, MA 02110-1301, USA. */ - - #include /* May get P_tmpdir. */ - #include -+#include - #ifdef HAVE_UNISTD_H - #include - #endif -@@ -35,6 +36,9 @@ Boston, MA 02110-1301, USA. */ - #ifdef HAVE_SYS_FILE_H - #include /* May get R_OK, etc. on some systems. */ - #endif -+#if defined(_WIN32) && !defined(__CYGWIN__) -+#include -+#endif - - #ifndef R_OK - #define R_OK 4 -@@ -55,6 +59,8 @@ extern int mkstemps (char *, int); - #define TEMP_FILE "ccXXXXXX" - #define TEMP_FILE_LEN (sizeof(TEMP_FILE) - 1) - -+#if !defined(_WIN32) || defined(__CYGWIN__) -+ - /* Subroutine of choose_tmpdir. - If BASE is non-NULL, return it. - Otherwise it checks if DIR is a usable directory. -@@ -80,6 +86,8 @@ static const char usrtmp[] = - static const char vartmp[] = - { DIR_SEPARATOR, 'v', 'a', 'r', DIR_SEPARATOR, 't', 'm', 'p', 0 }; - -+#endif -+ - static char *memoized_tmpdir; - - /* -@@ -96,40 +104,58 @@ files in. - char * - choose_tmpdir (void) - { -- const char *base = 0; -- char *tmpdir; -- unsigned int len; -- -- if (memoized_tmpdir) -- return memoized_tmpdir; -- -- base = try_dir (getenv ("TMPDIR"), base); -- base = try_dir (getenv ("TMP"), base); -- base = try_dir (getenv ("TEMP"), base); -- -+ if (!memoized_tmpdir) -+ { -+#if !defined(_WIN32) || defined(__CYGWIN__) -+ const char *base = 0; -+ char *tmpdir; -+ unsigned int len; -+ -+ base = try_dir (getenv ("TMPDIR"), base); -+ base = try_dir (getenv ("TMP"), base); -+ base = try_dir (getenv ("TEMP"), base); -+ - #ifdef P_tmpdir -- base = try_dir (P_tmpdir, base); -+ base = try_dir (P_tmpdir, base); - #endif - -- /* Try /var/tmp, /usr/tmp, then /tmp. */ -- base = try_dir (vartmp, base); -- base = try_dir (usrtmp, base); -- base = try_dir (tmp, base); -- -- /* If all else fails, use the current directory! */ -- if (base == 0) -- base = "."; -- -- /* Append DIR_SEPARATOR to the directory we've chosen -- and return it. */ -- len = strlen (base); -- tmpdir = XNEWVEC (char, len + 2); -- strcpy (tmpdir, base); -- tmpdir[len] = DIR_SEPARATOR; -- tmpdir[len+1] = '\0'; -+ /* Try /var/tmp, /usr/tmp, then /tmp. */ -+ base = try_dir (vartmp, base); -+ base = try_dir (usrtmp, base); -+ base = try_dir (tmp, base); -+ -+ /* If all else fails, use the current directory! */ -+ if (base == 0) -+ base = "."; -+ /* Append DIR_SEPARATOR to the directory we've chosen -+ and return it. */ -+ len = strlen (base); -+ tmpdir = XNEWVEC (char, len + 2); -+ strcpy (tmpdir, base); -+ tmpdir[len] = DIR_SEPARATOR; -+ tmpdir[len+1] = '\0'; -+ memoized_tmpdir = tmpdir; -+#else /* defined(_WIN32) && !defined(__CYGWIN__) */ -+ DWORD len; -+ -+ /* Figure out how much space we need. */ -+ len = GetTempPath(0, NULL); -+ if (len) -+ { -+ memoized_tmpdir = XNEWVEC (char, len); -+ if (!GetTempPath(len, memoized_tmpdir)) -+ { -+ XDELETEVEC (memoized_tmpdir); -+ memoized_tmpdir = NULL; -+ } -+ } -+ if (!memoized_tmpdir) -+ /* If all else fails, use the current directory. */ -+ memoized_tmpdir = xstrdup (".\\"); -+#endif /* defined(_WIN32) && !defined(__CYGWIN__) */ -+ } - -- memoized_tmpdir = tmpdir; -- return tmpdir; -+ return memoized_tmpdir; - } - - /* -@@ -166,11 +192,14 @@ make_temp_file (const char *suffix) - strcpy (temp_filename + base_len + TEMP_FILE_LEN, suffix); - - fd = mkstemps (temp_filename, suffix_len); -- /* If mkstemps failed, then something bad is happening. Maybe we should -- issue a message about a possible security attack in progress? */ -+ /* Mkstemps failed. It may be EPERM, ENOSPC etc. */ - if (fd == -1) -- abort (); -- /* Similarly if we can not close the file. */ -+ { -+ fprintf (stderr, "Cannot create temporary file in %s: %s\n", -+ base, strerror (errno)); -+ abort (); -+ } -+ /* We abort on failed close out of sheer paranoia. */ - if (close (fd)) - abort (); - return temp_filename; ---- a/libiberty/mkstemps.c -+++ b/libiberty/mkstemps.c -@@ -127,6 +127,13 @@ mkstemps (char *pattern, int suffix_len) - if (fd >= 0) - /* The file does not exist. */ - return fd; -+ if (errno != EEXIST -+#ifdef EISDIR -+ && errno != EISDIR -+#endif -+ ) -+ /* Fatal error (EPERM, ENOSPC etc). Doesn't make sense to loop. */ -+ break; - - /* This is a random value. It is only necessary that the next - TMP_MAX values generated by adding 7777 to VALUE are different ---- 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. */ ---- a/libjava/Makefile.am -+++ b/libjava/Makefile.am -@@ -48,9 +48,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) -@@ -81,7 +86,7 @@ bin_PROGRAMS = jv-convert gij grmic grmi - dbexec_DATA = $(db_name) - endif - --bin_SCRIPTS = addr2name.awk -+bin_SCRIPTS = - - if BUILD_ECJ1 - ## We build ecjx and not ecj1 because in one mode, ecjx will not work -@@ -107,12 +112,15 @@ if ANONVERSCRIPT - extra_ldflags_libjava += -Wl,--version-script=$(srcdir)/libgcj.ver - endif - -+LTLDFLAGS = $(shell $(top_srcdir)/../libtool-ldflags $(LDFLAGS)) - GCJLINK = $(LIBTOOL) --tag=GCJ --mode=link $(GCJ) -L$(here) $(JC1FLAGS) \ -- $(LDFLAGS) -o $@ -+ $(LTLDFLAGS) -o $@ - GCJ_FOR_ECJX = @GCJ_FOR_ECJX@ - GCJ_FOR_ECJX_LINK = $(GCJ_FOR_ECJX) -o $@ - LIBLINK = $(LIBTOOL) --tag=CXX --mode=link $(CXX) -L$(here) $(JC1FLAGS) \ -- $(LDFLAGS) $(extra_ldflags_libjava) $(extra_ldflags) -o $@ -+ $(LTLDFLAGS) $(extra_ldflags_libjava) $(extra_ldflags) -o $@ -+CXXLINK = $(LIBTOOL) --tag=CXX --mode=link $(CXXLD) $(AM_CXXFLAGS) \ -+ $(CXXFLAGS) $(AM_LDFLAGS) $(LTLDFLAGS) -o $@ - - GCC_UNWIND_INCLUDE = @GCC_UNWIND_INCLUDE@ - ---- a/libjava/Makefile.in -+++ b/libjava/Makefile.in -@@ -508,8 +508,6 @@ LTCXXCOMPILE = $(LIBTOOL) --tag=CXX --mo - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CXXFLAGS) $(CXXFLAGS) - CXXLD = $(CXX) --CXXLINK = $(LIBTOOL) --tag=CXX --mode=link $(CXXLD) $(AM_CXXFLAGS) \ -- $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ - GCJCOMPILE = $(GCJ) $(AM_GCJFLAGS) $(GCJFLAGS) - LTGCJCOMPILE = $(LIBTOOL) --tag=GCJ --mode=compile $(GCJ) \ - $(AM_GCJFLAGS) $(GCJFLAGS) -@@ -836,8 +834,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) -@@ -847,14 +851,18 @@ jar_DATA = libgcj-$(gcc_version).jar lib - db_name = classmap.db - db_pathtail = $(gcjsubdir)/$(db_name) - @NATIVE_TRUE@dbexec_DATA = $(db_name) --bin_SCRIPTS = addr2name.awk -+bin_SCRIPTS = - GCJ_WITH_FLAGS = $(GCJ) --encoding=UTF-8 -Wno-deprecated -+LTLDFLAGS = $(shell $(top_srcdir)/../libtool-ldflags $(LDFLAGS)) - GCJLINK = $(LIBTOOL) --tag=GCJ --mode=link $(GCJ) -L$(here) $(JC1FLAGS) \ -- $(LDFLAGS) -o $@ -+ $(LTLDFLAGS) -o $@ - - GCJ_FOR_ECJX_LINK = $(GCJ_FOR_ECJX) -o $@ - LIBLINK = $(LIBTOOL) --tag=CXX --mode=link $(CXX) -L$(here) $(JC1FLAGS) \ -- $(LDFLAGS) $(extra_ldflags_libjava) $(extra_ldflags) -o $@ -+ $(LTLDFLAGS) $(extra_ldflags_libjava) $(extra_ldflags) -o $@ -+ -+CXXLINK = $(LIBTOOL) --tag=CXX --mode=link $(CXXLD) $(AM_CXXFLAGS) \ -+ $(CXXFLAGS) $(AM_LDFLAGS) $(LTLDFLAGS) -o $@ - - WARNINGS = -Wextra -Wall - AM_CXXFLAGS = \ ---- a/libjava/classpath/Makefile.in -+++ b/libjava/classpath/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@ - vm_classes = @vm_classes@ - - # lib first, to compile .class files before native code, last examples ---- a/libjava/classpath/configure -+++ b/libjava/classpath/configure -@@ -461,7 +461,7 @@ ac_includes_default="\ - # include - #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 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 toolexeclibdir nativeexeclibdir glibjdir VM_BINARY CREATE_JNI_HEADERS_TRUE CREATE_JNI_HEADERS_FALSE CREATE_WRAPPERS_TRUE CREATE_WRAPPERS_FALSE LN_S LIBTOOL SED FGREP GREP LD DUMPBIN ac_ct_DUMPBIN NM AR ac_ct_AR RANLIB ac_ct_RANLIB lt_ECHO CXX CXXFLAGS ac_ct_CXX CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE CXXCPP PERL COLLECTIONS_PREFIX LIBMAGIC LIBICONV LTLIBICONV WARNING_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 USER_JAVAH CLASSPATH_INCLUDES GCJ JIKES JIKESENCODING JIKESWARNINGS KJC ECJ JAVAC FOUND_GCJ_TRUE FOUND_GCJ_FALSE FOUND_JIKES_TRUE FOUND_JIKES_FALSE FOUND_ECJ_TRUE FOUND_ECJ_FALSE FOUND_JAVAC_TRUE FOUND_JAVAC_FALSE FOUND_KJC_TRUE FOUND_KJC_FALSE USER_CLASSLIB USER_SPECIFIED_CLASSLIB_TRUE USER_SPECIFIED_CLASSLIB_FALSE 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 FASTJAR 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 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 USE_ESCHER_TRUE USE_ESCHER_FALSE PATH_TO_ESCHER ENABLE_LOCAL_SOCKETS_TRUE ENABLE_LOCAL_SOCKETS_FALSE DEFAULT_PREFS_PEER 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 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 target_noncanonical toolexecdir toolexecmainlibdir toolexeclibdir nativeexeclibdir glibjdir VM_BINARY CREATE_JNI_HEADERS_TRUE CREATE_JNI_HEADERS_FALSE CREATE_WRAPPERS_TRUE CREATE_WRAPPERS_FALSE LN_S LIBTOOL SED FGREP GREP LD DUMPBIN ac_ct_DUMPBIN NM AR ac_ct_AR RANLIB ac_ct_RANLIB lt_ECHO CXX CXXFLAGS ac_ct_CXX CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE CXXCPP PERL COLLECTIONS_PREFIX LIBMAGIC LIBICONV LTLIBICONV WARNING_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 USER_JAVAH CLASSPATH_INCLUDES GCJ JIKES JIKESENCODING JIKESWARNINGS KJC ECJ JAVAC FOUND_GCJ_TRUE FOUND_GCJ_FALSE FOUND_JIKES_TRUE FOUND_JIKES_FALSE FOUND_ECJ_TRUE FOUND_ECJ_FALSE FOUND_JAVAC_TRUE FOUND_JAVAC_FALSE FOUND_KJC_TRUE FOUND_KJC_FALSE USER_CLASSLIB USER_SPECIFIED_CLASSLIB_TRUE USER_SPECIFIED_CLASSLIB_FALSE 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 FASTJAR 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 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 USE_ESCHER_TRUE USE_ESCHER_FALSE PATH_TO_ESCHER ENABLE_LOCAL_SOCKETS_TRUE ENABLE_LOCAL_SOCKETS_FALSE DEFAULT_PREFS_PEER LIBOBJS LTLIBOBJS' - ac_subst_files='' - - # Initialize some variables set by options. -@@ -1058,6 +1058,9 @@ Optional Features: - default=no - --disable-plugin compile gcjwebplugin (disabled by --disable-plugin) - 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=no - --enable-tool-wrappers create tool wrapper binaries default=no - --enable-static[=PKGS] -@@ -4753,16 +4756,64 @@ else - 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 -+ -+ -+# 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; - -- 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 - - - - -+ -+ - # Check whether --with-native-libdir or --without-native-libdir was given. - if test "${with_native_libdir+set}" = set; then - withval="$with_native_libdir" -@@ -5702,13 +5753,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:5705: $ac_compile\"" >&5) -+ (eval echo "\"\$as_me:5756: $ac_compile\"" >&5) - (eval "$ac_compile" 2>conftest.err) - cat conftest.err >&5 -- (eval echo "\"\$as_me:5708: $NM \\\"conftest.$ac_objext\\\"\"" >&5) -+ (eval echo "\"\$as_me:5759: $NM \\\"conftest.$ac_objext\\\"\"" >&5) - (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) - cat conftest.err >&5 -- (eval echo "\"\$as_me:5711: output\"" >&5) -+ (eval echo "\"\$as_me:5762: output\"" >&5) - cat conftest.out >&5 - if $GREP 'External.*some_variable' conftest.out > /dev/null; then - lt_cv_nm_interface="MS dumpbin" -@@ -6752,7 +6803,7 @@ ia64-*-hpux*) - ;; - *-*-irix6*) - # Find out which ABI we are using. -- echo '#line 6755 "configure"' > conftest.$ac_ext -+ echo '#line 6806 "configure"' > conftest.$ac_ext - if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? -@@ -7384,11 +7435,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:7387: $lt_compile\"" >&5) -+ (eval echo "\"\$as_me:7438: $lt_compile\"" >&5) - (eval "$lt_compile" 2>conftest.err) - ac_status=$? - cat conftest.err >&5 -- echo "$as_me:7391: \$? = $ac_status" >&5 -+ echo "$as_me:7442: \$? = $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. -@@ -7706,11 +7757,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:7709: $lt_compile\"" >&5) -+ (eval echo "\"\$as_me:7760: $lt_compile\"" >&5) - (eval "$lt_compile" 2>conftest.err) - ac_status=$? - cat conftest.err >&5 -- echo "$as_me:7713: \$? = $ac_status" >&5 -+ echo "$as_me:7764: \$? = $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. -@@ -7811,11 +7862,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:7814: $lt_compile\"" >&5) -+ (eval echo "\"\$as_me:7865: $lt_compile\"" >&5) - (eval "$lt_compile" 2>out/conftest.err) - ac_status=$? - cat out/conftest.err >&5 -- echo "$as_me:7818: \$? = $ac_status" >&5 -+ echo "$as_me:7869: \$? = $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 -@@ -7866,11 +7917,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:7869: $lt_compile\"" >&5) -+ (eval echo "\"\$as_me:7920: $lt_compile\"" >&5) - (eval "$lt_compile" 2>out/conftest.err) - ac_status=$? - cat out/conftest.err >&5 -- echo "$as_me:7873: \$? = $ac_status" >&5 -+ echo "$as_me:7924: \$? = $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 -@@ -10718,7 +10769,7 @@ else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF --#line 10721 "configure" -+#line 10772 "configure" - #include "confdefs.h" - - #if HAVE_DLFCN_H -@@ -10818,7 +10869,7 @@ else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF --#line 10821 "configure" -+#line 10872 "configure" - #include "confdefs.h" - - #if HAVE_DLFCN_H -@@ -15215,11 +15266,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:15218: $lt_compile\"" >&5) -+ (eval echo "\"\$as_me:15269: $lt_compile\"" >&5) - (eval "$lt_compile" 2>conftest.err) - ac_status=$? - cat conftest.err >&5 -- echo "$as_me:15222: \$? = $ac_status" >&5 -+ echo "$as_me:15273: \$? = $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. -@@ -15314,11 +15365,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:15317: $lt_compile\"" >&5) -+ (eval echo "\"\$as_me:15368: $lt_compile\"" >&5) - (eval "$lt_compile" 2>out/conftest.err) - ac_status=$? - cat out/conftest.err >&5 -- echo "$as_me:15321: \$? = $ac_status" >&5 -+ echo "$as_me:15372: \$? = $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 -@@ -15366,11 +15417,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:15369: $lt_compile\"" >&5) -+ (eval echo "\"\$as_me:15420: $lt_compile\"" >&5) - (eval "$lt_compile" 2>out/conftest.err) - ac_status=$? - cat out/conftest.err >&5 -- echo "$as_me:15373: \$? = $ac_status" >&5 -+ echo "$as_me:15424: \$? = $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 -@@ -30956,6 +31007,9 @@ s,@CREATE_QT_PEER_LIBRARIES_TRUE@,$CREAT - s,@CREATE_QT_PEER_LIBRARIES_FALSE@,$CREATE_QT_PEER_LIBRARIES_FALSE,;t t - s,@CREATE_PLUGIN_TRUE@,$CREATE_PLUGIN_TRUE,;t t - s,@CREATE_PLUGIN_FALSE@,$CREATE_PLUGIN_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 -@@ -289,6 +289,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 -@@ -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@ - vm_classes = @vm_classes@ - SUBDIRS = api - EXTRA_DIST = README.jaxp texi2pod.pl $(man_MANS) ---- a/libjava/classpath/doc/api/Makefile.in -+++ b/libjava/classpath/doc/api/Makefile.in -@@ -311,9 +311,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@ - vm_classes = @vm_classes@ - @CREATE_API_DOCS_TRUE@noinst_DATA = html - sourcepath = $(top_builddir):$(top_srcdir):$(top_srcdir)/vm/reference:$(top_srcdir)/external/w3c_dom:$(top_srcdir)/external/sax ---- a/libjava/classpath/examples/Makefile.in -+++ b/libjava/classpath/examples/Makefile.in -@@ -320,9 +320,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@ - vm_classes = @vm_classes@ - GLIBJ_CLASSPATH = '$(top_builddir)/lib':'$(top_builddir)/lib/glibj.zip':'$(top_builddir)/tools/tools.zip' - @FOUND_ECJ_FALSE@@FOUND_JAVAC_TRUE@JCOMPILER = $(JAVAC) -encoding UTF-8 -bootclasspath $(GLIBJ_CLASSPATH) -classpath . ---- a/libjava/classpath/external/Makefile.in -+++ b/libjava/classpath/external/Makefile.in -@@ -318,9 +318,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@ - vm_classes = @vm_classes@ - SUBDIRS = sax w3c_dom relaxngDatatype jsr166 - EXTRA_DIST = README ---- a/libjava/classpath/external/jsr166/Makefile.in -+++ b/libjava/classpath/external/jsr166/Makefile.in -@@ -309,9 +309,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@ - vm_classes = @vm_classes@ - EXTRA_DIST = IMPORTING \ - readme \ ---- a/libjava/classpath/external/relaxngDatatype/Makefile.in -+++ b/libjava/classpath/external/relaxngDatatype/Makefile.in -@@ -309,9 +309,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@ - vm_classes = @vm_classes@ - EXTRA_DIST = README.txt \ - copying.txt \ ---- a/libjava/classpath/external/sax/Makefile.in -+++ b/libjava/classpath/external/sax/Makefile.in -@@ -309,9 +309,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@ - vm_classes = @vm_classes@ - EXTRA_DIST = README \ - org/xml/sax/ext/Attributes2.java \ ---- a/libjava/classpath/external/w3c_dom/Makefile.in -+++ b/libjava/classpath/external/w3c_dom/Makefile.in -@@ -309,9 +309,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@ - vm_classes = @vm_classes@ - EXTRA_DIST = README \ - org/w3c/dom/Attr.java \ ---- a/libjava/classpath/include/Makefile.in -+++ b/libjava/classpath/include/Makefile.in -@@ -310,9 +310,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@ - vm_classes = @vm_classes@ - DISTCLEANFILES = jni_md.h config-int.h - ARG_JNI_JAVAH = -jni ---- a/libjava/classpath/lib/Makefile.in -+++ b/libjava/classpath/lib/Makefile.in -@@ -314,9 +314,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@ - vm_classes = @vm_classes@ - JAVA_DEPEND = java.dep - compile_classpath = $(vm_classes):$(top_srcdir):$(top_srcdir)/external/w3c_dom:$(top_srcdir)/external/sax:$(top_srcdir)/external/relaxngDatatype:$(top_srcdir)/external/jsr166:.:$(USER_CLASSLIB):$(PATH_TO_ESCHER) ---- a/libjava/classpath/m4/acinclude.m4 -+++ b/libjava/classpath/m4/acinclude.m4 -@@ -427,11 +427,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 -@@ -317,9 +317,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@ - vm_classes = @vm_classes@ - @CREATE_JNI_LIBRARIES_TRUE@JNIDIR = jni - @CREATE_GTK_PEER_LIBRARIES_TRUE@JAWTDIR = jawt ---- a/libjava/classpath/native/fdlibm/Makefile.in -+++ b/libjava/classpath/native/fdlibm/Makefile.in -@@ -336,9 +336,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@ - vm_classes = @vm_classes@ - noinst_LTLIBRARIES = libfdlibm.la - libfdlibm_la_SOURCES = \ ---- a/libjava/classpath/native/jawt/Makefile.in -+++ b/libjava/classpath/native/jawt/Makefile.in -@@ -336,9 +336,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@ - vm_classes = @vm_classes@ - nativeexeclib_LTLIBRARIES = libjawt.la - libjawt_la_SOURCES = jawt.c ---- a/libjava/classpath/native/jni/Makefile.in -+++ b/libjava/classpath/native/jni/Makefile.in -@@ -317,9 +317,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@ - vm_classes = @vm_classes@ - @CREATE_CORE_JNI_LIBRARIES_TRUE@JNIDIRS = native-lib java-io java-lang java-net java-nio java-util - @CREATE_ALSA_LIBRARIES_TRUE@ALSADIR = midi-alsa ---- a/libjava/classpath/native/jni/classpath/Makefile.in -+++ b/libjava/classpath/native/jni/classpath/Makefile.in -@@ -327,9 +327,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@ - vm_classes = @vm_classes@ - - # Header needed for jawt implementations such as the one found in ../gtk-peer. ---- a/libjava/classpath/native/jni/gconf-peer/Makefile.in -+++ b/libjava/classpath/native/jni/gconf-peer/Makefile.in -@@ -336,9 +336,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@ - vm_classes = @vm_classes@ - nativeexeclib_LTLIBRARIES = libgconfpeer.la - libgconfpeer_la_SOURCES = GConfNativePeer.c ---- a/libjava/classpath/native/jni/gstreamer-peer/Makefile.in -+++ b/libjava/classpath/native/jni/gstreamer-peer/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@ - vm_classes = @vm_classes@ - nativeexeclib_LTLIBRARIES = libgstreamerpeer.la - libgstreamerpeer_la_SOURCES = GStreamerIOPeer.c \ ---- a/libjava/classpath/native/jni/gtk-peer/Makefile.in -+++ b/libjava/classpath/native/jni/gtk-peer/Makefile.in -@@ -374,9 +374,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@ - 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 -@@ -338,9 +338,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@ - vm_classes = @vm_classes@ - nativeexeclib_LTLIBRARIES = libjavaio.la - libjavaio_la_SOURCES = java_io_VMFile.c \ ---- a/libjava/classpath/native/jni/java-lang/Makefile.in -+++ b/libjava/classpath/native/jni/java-lang/Makefile.in -@@ -352,9 +352,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@ - vm_classes = @vm_classes@ - nativeexeclib_LTLIBRARIES = libjavalang.la libjavalangreflect.la libjavalangmanagement.la - libjavalang_la_SOURCES = java_lang_VMSystem.c \ ---- a/libjava/classpath/native/jni/java-net/Makefile.in -+++ b/libjava/classpath/native/jni/java-net/Makefile.in -@@ -348,9 +348,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@ - vm_classes = @vm_classes@ - nativeexeclib_LTLIBRARIES = libjavanet.la - @ENABLE_LOCAL_SOCKETS_FALSE@local_sources = gnu_java_net_local_LocalSocketImpl.c ---- a/libjava/classpath/native/jni/java-nio/Makefile.in -+++ b/libjava/classpath/native/jni/java-nio/Makefile.in -@@ -346,9 +346,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@ - vm_classes = @vm_classes@ - nativeexeclib_LTLIBRARIES = libjavanio.la - libjavanio_la_SOURCES = gnu_java_nio_VMPipe.c \ ---- a/libjava/classpath/native/jni/java-util/Makefile.in -+++ b/libjava/classpath/native/jni/java-util/Makefile.in -@@ -335,9 +335,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@ - vm_classes = @vm_classes@ - nativeexeclib_LTLIBRARIES = libjavautil.la - libjavautil_la_SOURCES = java_util_VMTimeZone.c ---- a/libjava/classpath/native/jni/midi-alsa/Makefile.in -+++ b/libjava/classpath/native/jni/midi-alsa/Makefile.in -@@ -338,9 +338,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@ - vm_classes = @vm_classes@ - nativeexeclib_LTLIBRARIES = libgjsmalsa.la - libgjsmalsa_la_SOURCES = gnu_javax_sound_midi_alsa_AlsaMidiSequencerDevice.c \ ---- a/libjava/classpath/native/jni/midi-dssi/Makefile.in -+++ b/libjava/classpath/native/jni/midi-dssi/Makefile.in -@@ -338,9 +338,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@ - vm_classes = @vm_classes@ - nativeexeclib_LTLIBRARIES = libgjsmdssi.la - libgjsmdssi_la_SOURCES = gnu_javax_sound_midi_dssi_DSSIMidiDeviceProvider.c \ ---- a/libjava/classpath/native/jni/native-lib/Makefile.in -+++ b/libjava/classpath/native/jni/native-lib/Makefile.in -@@ -327,9 +327,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@ - vm_classes = @vm_classes@ - noinst_LTLIBRARIES = libclasspathnative.la - libclasspathnative_la_SOURCES = cpnet.c \ ---- a/libjava/classpath/native/jni/qt-peer/Makefile.in -+++ b/libjava/classpath/native/jni/qt-peer/Makefile.in -@@ -353,9 +353,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@ - vm_classes = @vm_classes@ - noinst_LTLIBRARIES = libqtpeer.la - AM_LDFLAGS = @CLASSPATH_MODULE@ @QT_LIBS@ ---- a/libjava/classpath/native/jni/xmlj/Makefile.in -+++ b/libjava/classpath/native/jni/xmlj/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@ - vm_classes = @vm_classes@ - nativeexeclib_LTLIBRARIES = libxmlj.la - libxmlj_la_SOURCES = \ ---- a/libjava/classpath/native/plugin/Makefile.in -+++ b/libjava/classpath/native/plugin/Makefile.in -@@ -335,9 +335,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@ - vm_classes = @vm_classes@ - nativeexeclib_LTLIBRARIES = libgcjwebplugin.la - libgcjwebplugin_la_SOURCES = gcjwebplugin.cc ---- a/libjava/classpath/resource/Makefile.in -+++ b/libjava/classpath/resource/Makefile.in -@@ -320,9 +320,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@ - vm_classes = @vm_classes@ - logging_DATA = java/util/logging/logging.properties - loggingdir = $(toolexeclibdir) ---- a/libjava/classpath/scripts/Makefile.in -+++ b/libjava/classpath/scripts/Makefile.in -@@ -310,9 +310,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@ - vm_classes = @vm_classes@ - EXTRA_DIST = check_jni_methods.sh generate-locale-list.sh import-cacerts.sh - all: all-am ---- a/libjava/classpath/tools/Makefile.in -+++ b/libjava/classpath/tools/Makefile.in -@@ -412,9 +412,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@ - vm_classes = @vm_classes@ - GLIBJ_BOOTCLASSPATH = '$(top_srcdir)/lib' - GLIBJ_CLASSPATH = $(srcdir)/asm ---- a/libjava/configure -+++ b/libjava/configure -@@ -18552,6 +18552,9 @@ if { (eval echo "$as_me:$LINENO: \"$ac_c - enable_sjlj_exceptions=yes - elif grep _Unwind_Resume conftest.s >/dev/null 2>&1 ; then - enable_sjlj_exceptions=no -+ elif grep __cxa_end_cleanup conftest.s >/dev/null 2>&1 ; then -+ # ARM EH ABI. -+ enable_sjlj_exceptions=no - fi - fi - CXXFLAGS="$old_CXXFLAGS" -@@ -26229,10 +26232,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 - ---- a/libjava/configure.ac -+++ b/libjava/configure.ac -@@ -605,6 +605,9 @@ if AC_TRY_EVAL(ac_compile); then - enable_sjlj_exceptions=yes - elif grep _Unwind_Resume conftest.s >/dev/null 2>&1 ; then - enable_sjlj_exceptions=no -+ elif grep __cxa_end_cleanup conftest.s >/dev/null 2>&1 ; then -+ # ARM EH ABI. -+ enable_sjlj_exceptions=no - fi - fi - CXXFLAGS="$old_CXXFLAGS" -@@ -1406,10 +1409,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/libstdc++-v3/Makefile.in -+++ b/libstdc++-v3/Makefile.in -@@ -189,6 +189,8 @@ LIBMATHOBJS = @LIBMATHOBJS@ - LIBOBJS = @LIBOBJS@ - LIBS = @LIBS@ - LIBSUPCXX_PICFLAGS = @LIBSUPCXX_PICFLAGS@ -+LIBSUPCXX_PRONLY_FALSE = @LIBSUPCXX_PRONLY_FALSE@ -+LIBSUPCXX_PRONLY_TRUE = @LIBSUPCXX_PRONLY_TRUE@ - LIBTOOL = @LIBTOOL@ - LN_S = @LN_S@ - LTLIBICONV = @LTLIBICONV@ ---- a/libstdc++-v3/config.h.in -+++ b/libstdc++-v3/config.h.in -@@ -114,12 +114,6 @@ - /* Define to 1 if you have the `frexpl' function. */ - #undef HAVE_FREXPL - --/* Define to 1 if you have the header file. */ --#undef HAVE_GCONF_H -- --/* Define to 1 if you have the header file. */ --#undef HAVE_GCONV_H -- - /* Define if _Unwind_GetIPInfo is available. */ - #undef HAVE_GETIPINFO - ---- a/libstdc++-v3/config/cpu/mips/atomicity.h -+++ b/libstdc++-v3/config/cpu/mips/atomicity.h -@@ -41,16 +41,18 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) - - __asm__ __volatile__ - ("/* Inline exchange & add */\n\t" -- "1:\n\t" - ".set push\n\t" - #if _MIPS_SIM == _ABIO32 - ".set mips2\n\t" - #endif -+ "sync \n\t" -+ "1:\n\t" - "ll %0,0(%2)\n\t" - "addu %1,%3,%0\n\t" - "sc %1,0(%2)\n\t" -- ".set pop\n\t" - "beqz %1,1b\n\t" -+ "sync \n\t" -+ ".set pop\n\t" - "/* End exchange & add */" - : "=&r"(__result), "=&r"(__tmp) - : "r"(__mem), "r"(__val) -@@ -67,16 +69,18 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) - - __asm__ __volatile__ - ("/* Inline atomic add */\n\t" -- "1:\n\t" - ".set push\n\t" - #if _MIPS_SIM == _ABIO32 - ".set mips2\n\t" - #endif -+ "sync \n\t" -+ "1:\n\t" - "ll %0,0(%1)\n\t" - "addu %0,%2,%0\n\t" - "sc %0,0(%1)\n\t" -- ".set pop\n\t" - "beqz %0,1b\n\t" -+ "sync \n\t" -+ ".set pop\n\t" - "/* End atomic add */" - : "=&r"(__result) - : "r"(__mem), "r"(__val) ---- a/libstdc++-v3/config/cpu/sh/atomicity.h -+++ b/libstdc++-v3/config/cpu/sh/atomicity.h -@@ -30,47 +30,48 @@ - - #ifdef __SH4A__ - --#ifndef _GLIBCXX_ATOMICITY_H --#define _GLIBCXX_ATOMICITY_H 1 -+#include - --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__ */ - ---- /dev/null -+++ b/libstdc++-v3/config/os/gnu-linux/arm-eabi-extra.ver -@@ -0,0 +1,18 @@ -+# Appended to version file. -+ -+CXXABI_ARM_1.3.3 { -+ # ARM ABI helper functions provided in libsupc++. -+ __aeabi_atexit; -+ __aeabi_vec_ctor_nocookie_nodtor; -+ __aeabi_vec_ctor_cookie_nodtor; -+ __aeabi_vec_cctor_nocookie_nodtor; -+ __aeabi_vec_new_cookie_noctor; -+ __aeabi_vec_new_nocookie; -+ __aeabi_vec_new_cookie_nodtor; -+ __aeabi_vec_new_cookie; -+ __aeabi_vec_dtor; -+ __aeabi_vec_dtor_cookie; -+ __aeabi_vec_delete; -+ __aeabi_vec_delete3; -+ __aeabi_vec_delete3_nodtor; -+}; ---- a/libstdc++-v3/configure -+++ b/libstdc++-v3/configure -@@ -458,7 +458,7 @@ ac_includes_default="\ - # include - #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 lt_ECHO LDFLAGS CXXCPP enable_shared enable_static GLIBCXX_HOSTED_TRUE GLIBCXX_HOSTED_FALSE GLIBCXX_BUILD_PCH_TRUE GLIBCXX_BUILD_PCH_FALSE glibcxx_PCHFLAGS 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_thread_h WERROR SECTION_FLAGS SECTION_LDFLAGS OPT_LDFLAGS LIBMATHOBJS 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 lt_ECHO LDFLAGS CXXCPP enable_shared enable_static GLIBCXX_HOSTED_TRUE GLIBCXX_HOSTED_FALSE GLIBCXX_BUILD_PCH_TRUE GLIBCXX_BUILD_PCH_FALSE glibcxx_PCHFLAGS 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_thread_h WERROR SECTION_FLAGS SECTION_LDFLAGS OPT_LDFLAGS LIBMATHOBJS 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='' - - # Initialize some variables set by options. -@@ -17195,9 +17195,8 @@ if $GLIBCXX_IS_NATIVE; then - - - -- - for ac_header in nan.h ieeefp.h endian.h sys/isa_defs.h machine/endian.h \ -- machine/param.h sys/machine.h fp.h locale.h float.h inttypes.h gconv.h \ -+ machine/param.h sys/machine.h fp.h locale.h float.h inttypes.h \ - sys/types.h sys/ipc.h sys/sem.h - do - as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -@@ -62933,9 +62932,8 @@ _ACEOF - - - -- - for ac_header in nan.h ieeefp.h endian.h sys/isa_defs.h machine/endian.h \ -- machine/param.h sys/machine.h fp.h locale.h float.h inttypes.h gconv.h \ -+ machine/param.h sys/machine.h fp.h locale.h float.h inttypes.h \ - sys/types.h - do - as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -@@ -86333,11 +86331,10 @@ _ACEOF - - - -- - for ac_header in nan.h ieeefp.h endian.h sys/isa_defs.h \ - machine/endian.h machine/param.h sys/machine.h sys/types.h \ - fp.h float.h endian.h inttypes.h locale.h float.h stdint.h \ -- sys/ipc.h sys/sem.h gconf.h -+ sys/ipc.h sys/sem.h - do - as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` - if eval "test \"\${$as_ac_Header+set}\" = set"; then -@@ -108853,6 +108850,223 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu - - - -+ cat >>confdefs.h <<\_ACEOF -+#define _GLIBCXX_USE_RANDOM_TR1 1 -+_ACEOF -+ -+ -+ -+ if test "${ac_cv_header_locale_h+set}" = set; then -+ echo "$as_me:$LINENO: checking for locale.h" >&5 -+echo $ECHO_N "checking for locale.h... $ECHO_C" >&6 -+if test "${ac_cv_header_locale_h+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+fi -+echo "$as_me:$LINENO: result: $ac_cv_header_locale_h" >&5 -+echo "${ECHO_T}$ac_cv_header_locale_h" >&6 -+else -+ # Is the header compilable? -+echo "$as_me:$LINENO: checking locale.h usability" >&5 -+echo $ECHO_N "checking locale.h usability... $ECHO_C" >&6 -+cat >conftest.$ac_ext <<_ACEOF -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+#include -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 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_objext' -+ { (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 -+ ac_header_compiler=yes -+else -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_header_compiler=no -+fi -+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -+echo "${ECHO_T}$ac_header_compiler" >&6 -+ -+# Is the header present? -+echo "$as_me:$LINENO: checking locale.h presence" >&5 -+echo $ECHO_N "checking locale.h presence... $ECHO_C" >&6 -+cat >conftest.$ac_ext <<_ACEOF -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+#include -+_ACEOF -+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 -+ (eval $ac_cpp conftest.$ac_ext) 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); } >/dev/null; then -+ if test -s conftest.err; then -+ ac_cpp_err=$ac_c_preproc_warn_flag -+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag -+ else -+ ac_cpp_err= -+ fi -+else -+ ac_cpp_err=yes -+fi -+if test -z "$ac_cpp_err"; then -+ ac_header_preproc=yes -+else -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ ac_header_preproc=no -+fi -+rm -f conftest.err conftest.$ac_ext -+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -+echo "${ECHO_T}$ac_header_preproc" >&6 -+ -+# So? What about this header? -+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in -+ yes:no: ) -+ { echo "$as_me:$LINENO: WARNING: locale.h: accepted by the compiler, rejected by the preprocessor!" >&5 -+echo "$as_me: WARNING: locale.h: accepted by the compiler, rejected by the preprocessor!" >&2;} -+ { echo "$as_me:$LINENO: WARNING: locale.h: proceeding with the compiler's result" >&5 -+echo "$as_me: WARNING: locale.h: proceeding with the compiler's result" >&2;} -+ ac_header_preproc=yes -+ ;; -+ no:yes:* ) -+ { echo "$as_me:$LINENO: WARNING: locale.h: present but cannot be compiled" >&5 -+echo "$as_me: WARNING: locale.h: present but cannot be compiled" >&2;} -+ { echo "$as_me:$LINENO: WARNING: locale.h: check for missing prerequisite headers?" >&5 -+echo "$as_me: WARNING: locale.h: check for missing prerequisite headers?" >&2;} -+ { echo "$as_me:$LINENO: WARNING: locale.h: see the Autoconf documentation" >&5 -+echo "$as_me: WARNING: locale.h: see the Autoconf documentation" >&2;} -+ { echo "$as_me:$LINENO: WARNING: locale.h: section \"Present But Cannot Be Compiled\"" >&5 -+echo "$as_me: WARNING: locale.h: section \"Present But Cannot Be Compiled\"" >&2;} -+ { echo "$as_me:$LINENO: WARNING: locale.h: proceeding with the preprocessor's result" >&5 -+echo "$as_me: WARNING: locale.h: proceeding with the preprocessor's result" >&2;} -+ { echo "$as_me:$LINENO: WARNING: locale.h: in the future, the compiler will take precedence" >&5 -+echo "$as_me: WARNING: locale.h: in the future, the compiler will take precedence" >&2;} -+ ( -+ cat <<\_ASBOX -+## ----------------------------------------- ## -+## Report this to the package-unused lists. ## -+## ----------------------------------------- ## -+_ASBOX -+ ) | -+ sed "s/^/$as_me: WARNING: /" >&2 -+ ;; -+esac -+echo "$as_me:$LINENO: checking for locale.h" >&5 -+echo $ECHO_N "checking for locale.h... $ECHO_C" >&6 -+if test "${ac_cv_header_locale_h+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+else -+ ac_cv_header_locale_h=$ac_header_preproc -+fi -+echo "$as_me:$LINENO: result: $ac_cv_header_locale_h" >&5 -+echo "${ECHO_T}$ac_cv_header_locale_h" >&6 -+ -+fi -+if test $ac_cv_header_locale_h = yes; then -+ -+ echo "$as_me:$LINENO: checking for LC_MESSAGES" >&5 -+echo $ECHO_N "checking for LC_MESSAGES... $ECHO_C" >&6 -+if test "${ac_cv_val_LC_MESSAGES+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+else -+ 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 -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+#include -+int -+main () -+{ -+return LC_MESSAGES -+ ; -+ 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 -+ ac_cv_val_LC_MESSAGES=yes -+else -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_cv_val_LC_MESSAGES=no -+fi -+rm -f conftest.err conftest.$ac_objext \ -+ conftest$ac_exeext conftest.$ac_ext -+fi -+echo "$as_me:$LINENO: result: $ac_cv_val_LC_MESSAGES" >&5 -+echo "${ECHO_T}$ac_cv_val_LC_MESSAGES" >&6 -+ if test $ac_cv_val_LC_MESSAGES = yes; then -+ -+cat >>confdefs.h <<\_ACEOF -+#define HAVE_LC_MESSAGES 1 -+_ACEOF -+ -+ fi -+ -+fi -+ -+ -+ -+ - # Check for sigsetjmp - cat >conftest.$ac_ext <<_ACEOF - /* confdefs.h. */ -@@ -108905,6 +109119,266 @@ sed 's/^/| /' conftest.$ac_ext >&5 - - fi - rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -+ -+ cat >>confdefs.h <<\_ACEOF -+#define HAVE_MMAP 1 -+_ACEOF -+ -+ -+ # For iconv support. -+ -+ -+ -+ -+ -+ am_save_CPPFLAGS="$CPPFLAGS" -+ -+ for element in $INCICONV; do -+ haveit= -+ for x in $CPPFLAGS; do -+ -+ acl_save_prefix="$prefix" -+ prefix="$acl_final_prefix" -+ acl_save_exec_prefix="$exec_prefix" -+ exec_prefix="$acl_final_exec_prefix" -+ eval x=\"$x\" -+ exec_prefix="$acl_save_exec_prefix" -+ prefix="$acl_save_prefix" -+ -+ if test "X$x" = "X$element"; then -+ haveit=yes -+ break -+ fi -+ done -+ if test -z "$haveit"; then -+ CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }$element" -+ fi -+ done -+ -+ -+ echo "$as_me:$LINENO: checking for iconv" >&5 -+echo $ECHO_N "checking for iconv... $ECHO_C" >&6 -+if test "${am_cv_func_iconv+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+else -+ -+ am_cv_func_iconv="no, consider installing GNU libiconv" -+ am_cv_lib_iconv=no -+ 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 -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+#include -+#include -+int -+main () -+{ -+iconv_t cd = iconv_open("",""); -+ iconv(cd,NULL,NULL,NULL,NULL); -+ iconv_close(cd); -+ ; -+ 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 -+ am_cv_func_iconv=yes -+else -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+fi -+rm -f conftest.err conftest.$ac_objext \ -+ conftest$ac_exeext conftest.$ac_ext -+ if test "$am_cv_func_iconv" != yes; then -+ am_save_LIBS="$LIBS" -+ LIBS="$LIBS $LIBICONV" -+ 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 -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+#include -+#include -+int -+main () -+{ -+iconv_t cd = iconv_open("",""); -+ iconv(cd,NULL,NULL,NULL,NULL); -+ iconv_close(cd); -+ ; -+ 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 -+ am_cv_lib_iconv=yes -+ am_cv_func_iconv=yes -+else -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+fi -+rm -f conftest.err conftest.$ac_objext \ -+ conftest$ac_exeext conftest.$ac_ext -+ LIBS="$am_save_LIBS" -+ fi -+ -+fi -+echo "$as_me:$LINENO: result: $am_cv_func_iconv" >&5 -+echo "${ECHO_T}$am_cv_func_iconv" >&6 -+ if test "$am_cv_func_iconv" = yes; then -+ -+cat >>confdefs.h <<\_ACEOF -+#define HAVE_ICONV 1 -+_ACEOF -+ -+ fi -+ if test "$am_cv_lib_iconv" = yes; then -+ echo "$as_me:$LINENO: checking how to link with libiconv" >&5 -+echo $ECHO_N "checking how to link with libiconv... $ECHO_C" >&6 -+ echo "$as_me:$LINENO: result: $LIBICONV" >&5 -+echo "${ECHO_T}$LIBICONV" >&6 -+ else -+ CPPFLAGS="$am_save_CPPFLAGS" -+ LIBICONV= -+ LTLIBICONV= -+ fi -+ -+ -+ -+ if test "$am_cv_func_iconv" = yes; then -+ echo "$as_me:$LINENO: checking for iconv declaration" >&5 -+echo $ECHO_N "checking for iconv declaration... $ECHO_C" >&6 -+ if test "${am_cv_proto_iconv+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+else -+ -+ cat >conftest.$ac_ext <<_ACEOF -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+ -+#include -+#include -+extern -+#ifdef __cplusplus -+"C" -+#endif -+#if defined(__STDC__) || defined(__cplusplus) -+size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft); -+#else -+size_t iconv(); -+#endif -+ -+int -+main () -+{ -+ -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 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_objext' -+ { (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 -+ am_cv_proto_iconv_arg1="" -+else -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+am_cv_proto_iconv_arg1="const" -+fi -+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -+ am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);" -+fi -+ -+ am_cv_proto_iconv=`echo "$am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'` -+ echo "$as_me:$LINENO: result: ${ac_t:- -+ }$am_cv_proto_iconv" >&5 -+echo "${ECHO_T}${ac_t:- -+ }$am_cv_proto_iconv" >&6 -+ -+cat >>confdefs.h <<_ACEOF -+#define ICONV_CONST $am_cv_proto_iconv_arg1 -+_ACEOF -+ -+ fi -+ - ;; - *-mingw32*) - -@@ -109059,6 +109533,14 @@ fi - - done - -+ cat >>confdefs.h <<\_ACEOF -+#define HAVE_STRTOF 1 -+_ACEOF -+ -+ cat >>confdefs.h <<\_ACEOF -+#define HAVE_STRTOLD 1 -+_ACEOF -+ - - # If we're not using GNU ld, then there's no point in even trying these - # tests. Check for that first. We should have already tested for gld -@@ -115963,6 +116445,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) -@@ -116543,6 +117043,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 -@@ -117580,6 +118087,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 -@@ -138,7 +138,7 @@ if $GLIBCXX_IS_NATIVE; then - - # Check for available headers. - AC_CHECK_HEADERS([nan.h ieeefp.h endian.h sys/isa_defs.h machine/endian.h \ -- machine/param.h sys/machine.h fp.h locale.h float.h inttypes.h gconv.h \ -+ machine/param.h sys/machine.h fp.h locale.h float.h inttypes.h \ - sys/types.h sys/ipc.h sys/sem.h]) - - GLIBCXX_CHECK_LINKER_FEATURES -@@ -344,13 +344,22 @@ 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) - # from GLIBCXX_CHECK_COMPLEX_MATH_SUPPORT: - #AM_CONDITIONAL(GLIBCXX_BUILD_LIBMATH, test $need_libmath = yes) - GLIBCXX_EVALUATE_CONDITIONALS -- -+ - AC_CACHE_SAVE - - if test ${multilib} = yes; then ---- a/libstdc++-v3/configure.host -+++ b/libstdc++-v3/configure.host -@@ -320,6 +320,11 @@ case "${host}" in - abi_baseline_pair=${try_cpu}-linux-gnu - fi - esac -+ case "${host}" in -+ arm*-*-linux-*eabi) -+ port_specific_symbol_files="\$(srcdir)/../config/os/gnu-linux/arm-eabi-extra.ver" -+ ;; -+ esac - ;; - mips*-*-*) - case "${host_os}" in ---- a/libstdc++-v3/crossconfig.m4 -+++ b/libstdc++-v3/crossconfig.m4 -@@ -46,7 +46,7 @@ case "${host}" in - # so we just check for all the features here. - # Check for available headers. - AC_CHECK_HEADERS([nan.h ieeefp.h endian.h sys/isa_defs.h machine/endian.h \ -- machine/param.h sys/machine.h fp.h locale.h float.h inttypes.h gconv.h \ -+ machine/param.h sys/machine.h fp.h locale.h float.h inttypes.h \ - sys/types.h]) - - # Don't call GLIBCXX_CHECK_LINKER_FEATURES, Darwin doesn't have a GNU ld -@@ -197,7 +197,7 @@ case "${host}" in - AC_CHECK_HEADERS([nan.h ieeefp.h endian.h sys/isa_defs.h \ - machine/endian.h machine/param.h sys/machine.h sys/types.h \ - fp.h float.h endian.h inttypes.h locale.h float.h stdint.h \ -- sys/ipc.h sys/sem.h gconf.h]) -+ sys/ipc.h sys/sem.h]) - SECTION_FLAGS='-ffunction-sections -fdata-sections' - AC_SUBST(SECTION_FLAGS) - GLIBCXX_CHECK_COMPILER_FEATURES -@@ -223,6 +223,10 @@ case "${host}" in - # For C99 support to TR1. - GLIBCXX_CHECK_C99_TR1 - -+ AC_DEFINE(_GLIBCXX_USE_RANDOM_TR1) -+ -+ AC_LC_MESSAGES -+ - # Check for sigsetjmp - AC_TRY_COMPILE( - [#include ], -@@ -231,9 +235,16 @@ case "${host}" in - siglongjmp (env, 1); - ], - [AC_DEFINE(HAVE_SIGSETJMP, 1, [Define if sigsetjmp is available.])]) -+ -+ AC_DEFINE(HAVE_MMAP) -+ -+ # For iconv support. -+ AM_ICONV - ;; - *-mingw32*) - AC_CHECK_HEADERS([sys/types.h locale.h float.h]) -+ AC_DEFINE(HAVE_STRTOF) -+ AC_DEFINE(HAVE_STRTOLD) - GLIBCXX_CHECK_LINKER_FEATURES - GLIBCXX_CHECK_COMPLEX_MATH_SUPPORT - ;; ---- a/libstdc++-v3/doc/Makefile.in -+++ b/libstdc++-v3/doc/Makefile.in -@@ -157,6 +157,8 @@ LIBMATHOBJS = @LIBMATHOBJS@ - LIBOBJS = @LIBOBJS@ - LIBS = @LIBS@ - LIBSUPCXX_PICFLAGS = @LIBSUPCXX_PICFLAGS@ -+LIBSUPCXX_PRONLY_FALSE = @LIBSUPCXX_PRONLY_FALSE@ -+LIBSUPCXX_PRONLY_TRUE = @LIBSUPCXX_PRONLY_TRUE@ - LIBTOOL = @LIBTOOL@ - LN_S = @LN_S@ - LTLIBICONV = @LTLIBICONV@ ---- a/libstdc++-v3/include/Makefile.am -+++ b/libstdc++-v3/include/Makefile.am -@@ -1103,8 +1103,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 , - # , , , , , , and any ---- a/libstdc++-v3/include/Makefile.in -+++ b/libstdc++-v3/include/Makefile.in -@@ -157,6 +157,8 @@ LIBMATHOBJS = @LIBMATHOBJS@ - LIBOBJS = @LIBOBJS@ - LIBS = @LIBS@ - LIBSUPCXX_PICFLAGS = @LIBSUPCXX_PICFLAGS@ -+LIBSUPCXX_PRONLY_FALSE = @LIBSUPCXX_PRONLY_FALSE@ -+LIBSUPCXX_PRONLY_TRUE = @LIBSUPCXX_PRONLY_TRUE@ - LIBTOOL = @LIBTOOL@ - LN_S = @LN_S@ - LTLIBICONV = @LTLIBICONV@ -@@ -1492,7 +1494,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 , - # , , , , , , and any ---- a/libstdc++-v3/include/std/type_traits -+++ b/libstdc++-v3/include/std/type_traits -@@ -455,15 +455,18 @@ namespace std - struct __make_unsigned_selector<_Tp, false, true> - { - private: -- // GNU enums start with sizeof short. -- typedef unsigned short __smallest; -- static const bool __b1 = sizeof(_Tp) <= sizeof(__smallest); -+ // With -fshort-enums, an enum may be as small as a char. -+ typedef unsigned char __smallest; -+ static const bool __b0 = sizeof(_Tp) <= sizeof(__smallest); -+ static const bool __b1 = sizeof(_Tp) <= sizeof(unsigned short); - static const bool __b2 = sizeof(_Tp) <= sizeof(unsigned int); -- typedef conditional<__b2, unsigned int, unsigned long> __cond; -- typedef typename __cond::type __cond_type; -+ typedef conditional<__b2, unsigned int, unsigned long> __cond2; -+ typedef typename __cond2::type __cond2_type; -+ typedef conditional<__b1, unsigned short, __cond2_type> __cond1; -+ typedef typename __cond1::type __cond1_type; - - public: -- typedef typename conditional<__b1, __smallest, __cond_type>::type __type; -+ typedef typename conditional<__b0, __smallest, __cond1_type>::type __type; - }; - - // Given an integral/enum type, return the corresponding unsigned -@@ -530,15 +533,18 @@ namespace std - struct __make_signed_selector<_Tp, false, true> - { - private: -- // GNU enums start with sizeof short. -- typedef signed short __smallest; -- static const bool __b1 = sizeof(_Tp) <= sizeof(__smallest); -+ // With -fshort-enums, an enum may be as small as a char. -+ typedef signed char __smallest; -+ static const bool __b0 = sizeof(_Tp) <= sizeof(__smallest); -+ static const bool __b1 = sizeof(_Tp) <= sizeof(signed short); - static const bool __b2 = sizeof(_Tp) <= sizeof(signed int); -- typedef conditional<__b2, signed int, signed long> __cond; -- typedef typename __cond::type __cond_type; -+ typedef conditional<__b2, signed int, signed long> __cond2; -+ typedef typename __cond2::type __cond2_type; -+ typedef conditional<__b1, signed short, __cond2_type> __cond1; -+ typedef typename __cond1::type __cond1_type; - - public: -- typedef typename conditional<__b1, __smallest, __cond_type>::type __type; -+ typedef typename conditional<__b0, __smallest, __cond1_type>::type __type; - }; - - // Given an integral/enum type, return the corresponding signed ---- a/libstdc++-v3/libmath/Makefile.in -+++ b/libstdc++-v3/libmath/Makefile.in -@@ -172,6 +172,8 @@ LIBMATHOBJS = @LIBMATHOBJS@ - LIBOBJS = @LIBOBJS@ - LIBS = @LIBS@ - LIBSUPCXX_PICFLAGS = @LIBSUPCXX_PICFLAGS@ -+LIBSUPCXX_PRONLY_FALSE = @LIBSUPCXX_PRONLY_FALSE@ -+LIBSUPCXX_PRONLY_TRUE = @LIBSUPCXX_PRONLY_TRUE@ - - # Only compiling "C" sources in this directory. - LIBTOOL = @LIBTOOL@ --tag CC ---- a/libstdc++-v3/libsupc++/Makefile.am -+++ b/libstdc++-v3/libsupc++/Makefile.am -@@ -31,6 +31,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 -@@ -83,6 +88,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 -@@ -84,19 +84,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_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_term_handler.lo eh_terminate.lo \ -+@LIBSUPCXX_PRONLY_FALSE@ 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 = -@@ -129,6 +139,8 @@ 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 - glibcxxinstallHEADERS_INSTALL = $(INSTALL_HEADER) - HEADERS = $(glibcxxinstall_HEADERS) - ETAGS = etags -@@ -227,6 +239,8 @@ LIBMATHOBJS = @LIBMATHOBJS@ - LIBOBJS = @LIBOBJS@ - LIBS = @LIBS@ - LIBSUPCXX_PICFLAGS = @LIBSUPCXX_PICFLAGS@ -+LIBSUPCXX_PRONLY_FALSE = @LIBSUPCXX_PRONLY_FALSE@ -+LIBSUPCXX_PRONLY_TRUE = @LIBSUPCXX_PRONLY_TRUE@ - LIBTOOL = @LIBTOOL@ - LN_S = @LN_S@ - LTLIBICONV = @LTLIBICONV@ -@@ -350,55 +364,58 @@ 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 -+@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_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 - --@GLIBCXX_HOSTED_TRUE@c_sources = \ --@GLIBCXX_HOSTED_TRUE@ cp-demangle.c -+@LIBSUPCXX_PRONLY_TRUE@sources = \ -+@LIBSUPCXX_PRONLY_TRUE@ eh_personality.cc - --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_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@headers = \ -+@LIBSUPCXX_PRONLY_FALSE@ exception new typeinfo cxxabi.h cxxabi-forced.h exception_defines.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 -@@ -46,12 +46,14 @@ __cxa_type_match(_Unwind_Exception* ue_h - bool is_reference __attribute__((__unused__)), - void** thrown_ptr_p) - { -- bool foreign_exception = !__is_gxx_exception_class(ue_header->exception_class); -+ bool forced_unwind = __is_gxx_forced_unwind_class(ue_header->exception_class); -+ bool foreign_exception = !forced_unwind && !__is_gxx_exception_class(ue_header->exception_class); - __cxa_exception* xh = __get_exception_header_from_ue(ue_header); - const std::type_info* throw_type; - -- // XXX What to do with forced unwind? -- if (foreign_exception) -+ if (forced_unwind) -+ throw_type = &typeid(abi::__forced_unwind); -+ else if (foreign_exception) - throw_type = &typeid(abi::__foreign_exception); - else - throw_type = xh->exceptionType; ---- a/libstdc++-v3/libsupc++/eh_personality.cc -+++ b/libstdc++-v3/libsupc++/eh_personality.cc -@@ -544,8 +544,12 @@ PERSONALITY_FUNCTION (int version, - - #ifdef __ARM_EABI_UNWINDER__ - throw_type = ue_header; -- if ((actions & _UA_FORCE_UNWIND) -- || foreign_exception) -+ if (actions & _UA_FORCE_UNWIND) -+ { -+ __GXX_INIT_FORCED_UNWIND_CLASS(ue_header->exception_class); -+ thrown_ptr = 0; -+ } -+ else if (foreign_exception) - thrown_ptr = 0; - #else - // During forced unwinding, match a magic exception type. ---- a/libstdc++-v3/libsupc++/unwind-cxx.h -+++ b/libstdc++-v3/libsupc++/unwind-cxx.h -@@ -201,6 +201,32 @@ __GXX_INIT_EXCEPTION_CLASS(_Unwind_Excep - c[7] = '\0'; - } - -+static inline bool -+__is_gxx_forced_unwind_class(_Unwind_Exception_Class c) -+{ -+ return c[0] == 'G' -+ && c[1] == 'N' -+ && c[2] == 'U' -+ && c[3] == 'C' -+ && c[4] == 'F' -+ && c[5] == 'O' -+ && c[6] == 'R' -+ && c[7] == '\0'; -+} -+ -+static inline void -+__GXX_INIT_FORCED_UNWIND_CLASS(_Unwind_Exception_Class c) -+{ -+ c[0] = 'G'; -+ c[1] = 'N'; -+ c[2] = 'U'; -+ c[3] = 'C'; -+ c[4] = 'F'; -+ c[5] = 'O'; -+ c[6] = 'R'; -+ c[7] = '\0'; -+} -+ - static inline void* - __gxx_caught_object(_Unwind_Exception* eo) - { ---- a/libstdc++-v3/libsupc++/vec.cc -+++ b/libstdc++-v3/libsupc++/vec.cc -@@ -461,6 +461,9 @@ namespace __aeabiv1 - __aeabi_vec_dtor_cookie (void *array_address, - abi::__cxa_cdtor_type destructor) - { -+ if (!array_address) -+ return NULL; -+ - abi::__cxa_vec_dtor (array_address, - reinterpret_cast(array_address)[-1], - reinterpret_cast(array_address)[-2], -@@ -473,6 +476,9 @@ namespace __aeabiv1 - __aeabi_vec_delete (void *array_address, - abi::__cxa_cdtor_type destructor) - { -+ if (!array_address) -+ return; -+ - abi::__cxa_vec_delete (array_address, - reinterpret_cast(array_address)[-2], - 2 * sizeof (std::size_t), -@@ -484,6 +490,9 @@ namespace __aeabiv1 - abi::__cxa_cdtor_type destructor, - void (*dealloc) (void *, std::size_t)) - { -+ if (!array_address) -+ return; -+ - abi::__cxa_vec_delete3 (array_address, - reinterpret_cast(array_address)[-2], - 2 * sizeof (std::size_t), -@@ -494,6 +503,9 @@ namespace __aeabiv1 - __aeabi_vec_delete3_nodtor (void *array_address, - void (*dealloc) (void *, std::size_t)) - { -+ if (!array_address) -+ return; -+ - abi::__cxa_vec_delete3 (array_address, - reinterpret_cast(array_address)[-2], - 2 * sizeof (std::size_t), ---- a/libstdc++-v3/po/Makefile.in -+++ b/libstdc++-v3/po/Makefile.in -@@ -157,6 +157,8 @@ LIBMATHOBJS = @LIBMATHOBJS@ - LIBOBJS = @LIBOBJS@ - LIBS = @LIBS@ - LIBSUPCXX_PICFLAGS = @LIBSUPCXX_PICFLAGS@ -+LIBSUPCXX_PRONLY_FALSE = @LIBSUPCXX_PRONLY_FALSE@ -+LIBSUPCXX_PRONLY_TRUE = @LIBSUPCXX_PRONLY_TRUE@ - LIBTOOL = @LIBTOOL@ - LN_S = @LN_S@ - LTLIBICONV = @LTLIBICONV@ ---- a/libstdc++-v3/src/Makefile.in -+++ b/libstdc++-v3/src/Makefile.in -@@ -211,6 +211,8 @@ LIBMATHOBJS = @LIBMATHOBJS@ - LIBOBJS = @LIBOBJS@ - LIBS = @LIBS@ - LIBSUPCXX_PICFLAGS = @LIBSUPCXX_PICFLAGS@ -+LIBSUPCXX_PRONLY_FALSE = @LIBSUPCXX_PRONLY_FALSE@ -+LIBSUPCXX_PRONLY_TRUE = @LIBSUPCXX_PRONLY_TRUE@ - LIBTOOL = @LIBTOOL@ - LN_S = @LN_S@ - LTLIBICONV = @LTLIBICONV@ diff --git a/toolchain/gcc/patches/4.3.3+cs/105-libtool.patch b/toolchain/gcc/patches/4.3.3+cs/105-libtool.patch deleted file mode 100644 index 015f28dfe1..0000000000 --- a/toolchain/gcc/patches/4.3.3+cs/105-libtool.patch +++ /dev/null @@ -1,84 +0,0 @@ -2008-03-02 Ralf Wildenhues - - Backport from upstream Libtool: - - 2007-10-12 Eric Blake - - 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) - diff --git a/toolchain/gcc/patches/4.3.3+cs/106-fix_linker_error.patch b/toolchain/gcc/patches/4.3.3+cs/106-fix_linker_error.patch deleted file mode 100644 index 4dd83db20e..0000000000 --- a/toolchain/gcc/patches/4.3.3+cs/106-fix_linker_error.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- 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 \ diff --git a/toolchain/gcc/patches/4.3.3+cs/301-missing-execinfo_h.patch b/toolchain/gcc/patches/4.3.3+cs/301-missing-execinfo_h.patch deleted file mode 100644 index b3f1e68d3b..0000000000 --- a/toolchain/gcc/patches/4.3.3+cs/301-missing-execinfo_h.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- 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 - # 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 diff --git a/toolchain/gcc/patches/4.3.3+cs/302-c99-snprintf.patch b/toolchain/gcc/patches/4.3.3+cs/302-c99-snprintf.patch deleted file mode 100644 index ba51a0e1d4..0000000000 --- a/toolchain/gcc/patches/4.3.3+cs/302-c99-snprintf.patch +++ /dev/null @@ -1,13 +0,0 @@ -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 diff --git a/toolchain/gcc/patches/4.3.3+cs/305-libmudflap-susv3-legacy.patch b/toolchain/gcc/patches/4.3.3+cs/305-libmudflap-susv3-legacy.patch deleted file mode 100644 index 374b1f8659..0000000000 --- a/toolchain/gcc/patches/4.3.3+cs/305-libmudflap-susv3-legacy.patch +++ /dev/null @@ -1,49 +0,0 @@ -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 */ diff --git a/toolchain/gcc/patches/4.3.3+cs/410-fix_pr37436.patch b/toolchain/gcc/patches/4.3.3+cs/410-fix_pr37436.patch deleted file mode 100644 index e86768e4d1..0000000000 --- a/toolchain/gcc/patches/4.3.3+cs/410-fix_pr37436.patch +++ /dev/null @@ -1,71 +0,0 @@ ---- a/gcc/config/arm/arm.c -+++ b/gcc/config/arm/arm.c -@@ -5073,6 +5073,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 -@@ -4683,7 +4683,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) -@@ -4708,7 +4708,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") -@@ -4719,7 +4719,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) -@@ -4751,7 +4751,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") -@@ -4762,7 +4762,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 -@@ -239,6 +239,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") - { diff --git a/toolchain/gcc/patches/4.3.3+cs/420-fix_pr26515.patch b/toolchain/gcc/patches/4.3.3+cs/420-fix_pr26515.patch deleted file mode 100644 index 24b3720726..0000000000 --- a/toolchain/gcc/patches/4.3.3+cs/420-fix_pr26515.patch +++ /dev/null @@ -1,13 +0,0 @@ ---- a/gcc/config/cris/cris.md -+++ b/gcc/config/cris/cris.md -@@ -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))] diff --git a/toolchain/gcc/patches/4.3.3+cs/810-arm-softfloat-libgcc.patch b/toolchain/gcc/patches/4.3.3+cs/810-arm-softfloat-libgcc.patch deleted file mode 100644 index e3385d2ed0..0000000000 --- a/toolchain/gcc/patches/4.3.3+cs/810-arm-softfloat-libgcc.patch +++ /dev/null @@ -1,25 +0,0 @@ ---- a/gcc/config/arm/t-linux -+++ b/gcc/config/arm/t-linux -@@ -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 ---- 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" - diff --git a/toolchain/gcc/patches/4.3.3+cs/820-libgcc_pic.patch b/toolchain/gcc/patches/4.3.3+cs/820-libgcc_pic.patch deleted file mode 100644 index dc714e4b49..0000000000 --- a/toolchain/gcc/patches/4.3.3+cs/820-libgcc_pic.patch +++ /dev/null @@ -1,36 +0,0 @@ ---- a/libgcc/Makefile.in -+++ b/libgcc/Makefile.in -@@ -686,11 +686,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)"; \ -@@ -712,7 +713,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 -@@ -885,6 +886,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)))) diff --git a/toolchain/gcc/patches/4.3.3+cs/910-mbsd_multi.patch b/toolchain/gcc/patches/4.3.3+cs/910-mbsd_multi.patch deleted file mode 100644 index 17a0173e8f..0000000000 --- a/toolchain/gcc/patches/4.3.3+cs/910-mbsd_multi.patch +++ /dev/null @@ -1,270 +0,0 @@ - - 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 - with copyright assignment to the FSF in effect. - ---- a/gcc/c-opts.c -+++ b/gcc/c-opts.c -@@ -108,6 +108,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); -@@ -462,6 +465,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; -@@ -708,6 +719,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; -@@ -1248,6 +1265,47 @@ c_common_init (void) - /* 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; - } - ---- a/gcc/c.opt -+++ b/gcc/c.opt -@@ -207,6 +207,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 -@@ -590,6 +594,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 -@@ -542,6 +546,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 -@@ -830,9 +830,6 @@ decode_options (unsigned int argc, const - 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; -@@ -853,6 +850,10 @@ decode_options (unsigned int argc, const - - 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; -@@ -1444,6 +1445,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 -@@ -168,6 +168,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 -@@ -233,7 +233,7 @@ Objective-C and Objective-C++ Dialects}. - -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 -@@ -4047,6 +4047,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 -@@ -5522,7 +5538,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 -@@ -5667,7 +5683,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) - { diff --git a/toolchain/gcc/patches/4.3.3+cs/993-arm_insn-opinit-RTX_CODE-fixup.patch b/toolchain/gcc/patches/4.3.3+cs/993-arm_insn-opinit-RTX_CODE-fixup.patch deleted file mode 100644 index cbe9f1b576..0000000000 --- a/toolchain/gcc/patches/4.3.3+cs/993-arm_insn-opinit-RTX_CODE-fixup.patch +++ /dev/null @@ -1,32 +0,0 @@ -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. - ---- 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, ---- a/gcc/genopinit.c -+++ b/gcc/genopinit.c -@@ -487,6 +487,7 @@ from the machine description file `md'. - 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"); - diff --git a/toolchain/gcc/patches/4.3.3+cs/998-gcc-4.3.0-fix-header.00.patch b/toolchain/gcc/patches/4.3.3+cs/998-gcc-4.3.0-fix-header.00.patch deleted file mode 100644 index fd1987370b..0000000000 --- a/toolchain/gcc/patches/4.3.3+cs/998-gcc-4.3.0-fix-header.00.patch +++ /dev/null @@ -1,13 +0,0 @@ -\\\\ -\\ gcc PR33200 ---- a/gcc/config.gcc -+++ b/gcc/config.gcc -@@ -1460,7 +1460,7 @@ i[34567]86-*-uwin*) - if test x$enable_threads = xyes; then - thread_file='win32' - fi -- use_fixproto=yes -+ # XXX: why? use_fixproto=yes - ;; - i[34567]86-*-interix3*) - tm_file="${tm_file} i386/unix.h i386/bsd.h i386/gas.h i386/i386-interix.h i386/i386-interix3.h interix.h interix3.h" diff --git a/toolchain/gcc/patches/4.3.3+cs/999-coldfire.patch b/toolchain/gcc/patches/4.3.3+cs/999-coldfire.patch deleted file mode 100644 index 0e2a8c19e4..0000000000 --- a/toolchain/gcc/patches/4.3.3+cs/999-coldfire.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- a/gcc/config.gcc -+++ b/gcc/config.gcc -@@ -1678,6 +1678,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 diff --git a/toolchain/gcc/patches/4.3.5/100-uclibc-conf.patch b/toolchain/gcc/patches/4.3.5/100-uclibc-conf.patch deleted file mode 100644 index 4ae70b8d0a..0000000000 --- a/toolchain/gcc/patches/4.3.5/100-uclibc-conf.patch +++ /dev/null @@ -1,33 +0,0 @@ ---- a/contrib/regression/objs-gcc.sh -+++ b/contrib/regression/objs-gcc.sh -@@ -105,6 +105,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 diff --git a/toolchain/gcc/patches/4.3.5/104-gnuhurd-uclibc-conf.patch b/toolchain/gcc/patches/4.3.5/104-gnuhurd-uclibc-conf.patch deleted file mode 100644 index 58d9940166..0000000000 --- a/toolchain/gcc/patches/4.3.5/104-gnuhurd-uclibc-conf.patch +++ /dev/null @@ -1,12 +0,0 @@ ---- a/gcc/config.gcc -+++ b/gcc/config.gcc -@@ -529,6 +529,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}" - ;; diff --git a/toolchain/gcc/patches/4.3.5/105-libtool.patch b/toolchain/gcc/patches/4.3.5/105-libtool.patch deleted file mode 100644 index 7faca98220..0000000000 --- a/toolchain/gcc/patches/4.3.5/105-libtool.patch +++ /dev/null @@ -1,79 +0,0 @@ -2008-03-02 Ralf Wildenhues - - Backport from upstream Libtool: - - 2007-10-12 Eric Blake - - 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. - ---- 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]) ---- 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) diff --git a/toolchain/gcc/patches/4.3.5/106-fix_linker_error.patch b/toolchain/gcc/patches/4.3.5/106-fix_linker_error.patch deleted file mode 100644 index 4dd83db20e..0000000000 --- a/toolchain/gcc/patches/4.3.5/106-fix_linker_error.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- 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 \ diff --git a/toolchain/gcc/patches/4.3.5/301-missing-execinfo_h.patch b/toolchain/gcc/patches/4.3.5/301-missing-execinfo_h.patch deleted file mode 100644 index b3f1e68d3b..0000000000 --- a/toolchain/gcc/patches/4.3.5/301-missing-execinfo_h.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- 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 - # 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 diff --git a/toolchain/gcc/patches/4.3.5/302-c99-snprintf.patch b/toolchain/gcc/patches/4.3.5/302-c99-snprintf.patch deleted file mode 100644 index 48023b31aa..0000000000 --- a/toolchain/gcc/patches/4.3.5/302-c99-snprintf.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/libstdc++-v3/include/c_global/cstdio -+++ b/libstdc++-v3/include/c_global/cstdio -@@ -144,7 +144,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) - - _GLIBCXX_END_NAMESPACE - --#if _GLIBCXX_USE_C99 -+#if _GLIBCXX_USE_C99 || defined __UCLIBC__ - - #undef snprintf - #undef vfscanf diff --git a/toolchain/gcc/patches/4.3.5/305-libmudflap-susv3-legacy.patch b/toolchain/gcc/patches/4.3.5/305-libmudflap-susv3-legacy.patch deleted file mode 100644 index 0c38331c50..0000000000 --- a/toolchain/gcc/patches/4.3.5/305-libmudflap-susv3-legacy.patch +++ /dev/null @@ -1,47 +0,0 @@ ---- a/libmudflap/mf-hooks2.c -+++ b/libmudflap/mf-hooks2.c -@@ -427,7 +427,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); - } - - -@@ -437,7 +437,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); - } - - -@@ -447,7 +447,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); - } - - -@@ -456,7 +456,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); - } - - -@@ -465,7 +465,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 */ diff --git a/toolchain/gcc/patches/4.3.5/410-fix_pr37436.patch b/toolchain/gcc/patches/4.3.5/410-fix_pr37436.patch deleted file mode 100644 index 3e1e713d0f..0000000000 --- a/toolchain/gcc/patches/4.3.5/410-fix_pr37436.patch +++ /dev/null @@ -1,71 +0,0 @@ ---- 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") - { diff --git a/toolchain/gcc/patches/4.3.5/810-arm-softfloat-libgcc.patch b/toolchain/gcc/patches/4.3.5/810-arm-softfloat-libgcc.patch deleted file mode 100644 index e3385d2ed0..0000000000 --- a/toolchain/gcc/patches/4.3.5/810-arm-softfloat-libgcc.patch +++ /dev/null @@ -1,25 +0,0 @@ ---- a/gcc/config/arm/t-linux -+++ b/gcc/config/arm/t-linux -@@ -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 ---- 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" - diff --git a/toolchain/gcc/patches/4.3.5/820-libgcc_pic.patch b/toolchain/gcc/patches/4.3.5/820-libgcc_pic.patch deleted file mode 100644 index 0e326a82b2..0000000000 --- a/toolchain/gcc/patches/4.3.5/820-libgcc_pic.patch +++ /dev/null @@ -1,36 +0,0 @@ ---- 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)))) diff --git a/toolchain/gcc/patches/4.3.5/910-mbsd_multi.patch b/toolchain/gcc/patches/4.3.5/910-mbsd_multi.patch deleted file mode 100644 index 3f03f18926..0000000000 --- a/toolchain/gcc/patches/4.3.5/910-mbsd_multi.patch +++ /dev/null @@ -1,270 +0,0 @@ - - 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 - with copyright assignment to the FSF in effect. - ---- a/gcc/c-opts.c -+++ b/gcc/c-opts.c -@@ -108,6 +108,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); -@@ -462,6 +465,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; -@@ -708,6 +719,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; -@@ -1248,6 +1265,47 @@ c_common_init (void) - /* 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; - } - ---- a/gcc/c.opt -+++ b/gcc/c.opt -@@ -207,6 +207,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 -@@ -590,6 +594,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 -@@ -528,6 +532,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 -@@ -830,9 +830,6 @@ decode_options (unsigned int argc, const - 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; -@@ -853,6 +850,10 @@ decode_options (unsigned int argc, const - - 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; -@@ -1444,6 +1445,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 -@@ -168,6 +168,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 -@@ -233,7 +233,7 @@ Objective-C and Objective-C++ Dialects}. - -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 -@@ -4031,6 +4031,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 -@@ -5493,7 +5509,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 -@@ -5638,7 +5654,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) - { diff --git a/toolchain/gcc/patches/4.3.5/930-avr32_support.patch b/toolchain/gcc/patches/4.3.5/930-avr32_support.patch deleted file mode 100644 index cb4c823af0..0000000000 --- a/toolchain/gcc/patches/4.3.5/930-avr32_support.patch +++ /dev/null @@ -1,22417 +0,0 @@ ---- a/gcc/builtins.c -+++ b/gcc/builtins.c -@@ -10779,7 +10779,7 @@ validate_arglist (const_tree callexpr, . - - do - { -- code = va_arg (ap, enum tree_code); -+ code = va_arg (ap, int); - switch (code) - { - case 0: ---- a/gcc/calls.c -+++ b/gcc/calls.c -@@ -3496,7 +3496,7 @@ emit_library_call_value_1 (int retval, r - for (; count < nargs; count++) - { - rtx val = va_arg (p, rtx); -- enum machine_mode mode = va_arg (p, enum machine_mode); -+ enum machine_mode mode = va_arg (p, int); - - /* We cannot convert the arg value to the mode the library wants here; - must do it earlier where we know the signedness of the arg. */ ---- /dev/null -+++ b/gcc/config/avr32/avr32.c -@@ -0,0 +1,8018 @@ -+/* -+ Target hooks and helper functions for AVR32. -+ Copyright 2003,2004,2005,2006,2007,2008,2009,2010 Atmel Corporation. -+ -+ This file is part of GCC. -+ -+ 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 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 this program; if not, write to the Free Software -+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -+ -+#include "config.h" -+#include "system.h" -+#include "coretypes.h" -+#include "tm.h" -+#include "rtl.h" -+#include "tree.h" -+#include "obstack.h" -+#include "regs.h" -+#include "hard-reg-set.h" -+#include "real.h" -+#include "insn-config.h" -+#include "conditions.h" -+#include "output.h" -+#include "insn-attr.h" -+#include "flags.h" -+#include "reload.h" -+#include "function.h" -+#include "expr.h" -+#include "optabs.h" -+#include "toplev.h" -+#include "recog.h" -+#include "ggc.h" -+#include "except.h" -+#include "c-pragma.h" -+#include "integrate.h" -+#include "tm_p.h" -+#include "langhooks.h" -+#include "hooks.h" -+#include "df.h" -+ -+#include "target.h" -+#include "target-def.h" -+ -+#include -+ -+ -+ -+/* Global variables. */ -+typedef struct minipool_node Mnode; -+typedef struct minipool_fixup Mfix; -+ -+/* Obstack for minipool constant handling. */ -+static struct obstack minipool_obstack; -+static char *minipool_startobj; -+static rtx minipool_vector_label; -+ -+/* True if we are currently building a constant table. */ -+int making_const_table; -+ -+tree fndecl_attribute_args = NULL_TREE; -+ -+ -+/* Function prototypes. */ -+static unsigned long avr32_isr_value (tree); -+static unsigned long avr32_compute_func_type (void); -+static tree avr32_handle_isr_attribute (tree *, tree, tree, int, bool *); -+static tree avr32_handle_acall_attribute (tree *, tree, tree, int, bool *); -+static tree avr32_handle_fndecl_attribute (tree * node, tree name, tree args, -+ int flags, bool * no_add_attrs); -+static void avr32_reorg (void); -+bool avr32_return_in_msb (tree type); -+bool avr32_vector_mode_supported (enum machine_mode mode); -+static void avr32_init_libfuncs (void); -+static void avr32_file_end (void); -+static void flashvault_decl_list_add (unsigned int vector_num, const char *name); -+ -+ -+ -+static void -+avr32_add_gc_roots (void) -+{ -+ gcc_obstack_init (&minipool_obstack); -+ minipool_startobj = (char *) obstack_alloc (&minipool_obstack, 0); -+} -+ -+ -+/* List of all known AVR32 parts */ -+static const struct part_type_s avr32_part_types[] = { -+ /* name, part_type, architecture type, macro */ -+ {"none", PART_TYPE_AVR32_NONE, ARCH_TYPE_AVR32_AP, "__AVR32__"}, -+ {"ap7000", PART_TYPE_AVR32_AP7000, ARCH_TYPE_AVR32_AP, "__AVR32_AP7000__"}, -+ {"ap7001", PART_TYPE_AVR32_AP7001, ARCH_TYPE_AVR32_AP, "__AVR32_AP7001__"}, -+ {"ap7002", PART_TYPE_AVR32_AP7002, ARCH_TYPE_AVR32_AP, "__AVR32_AP7002__"}, -+ {"ap7200", PART_TYPE_AVR32_AP7200, ARCH_TYPE_AVR32_AP, "__AVR32_AP7200__"}, -+ {"uc3a0128", PART_TYPE_AVR32_UC3A0128, ARCH_TYPE_AVR32_UCR2, "__AVR32_UC3A0128__"}, -+ {"uc3a0256", PART_TYPE_AVR32_UC3A0256, ARCH_TYPE_AVR32_UCR2, "__AVR32_UC3A0256__"}, -+ {"uc3a0512", PART_TYPE_AVR32_UC3A0512, ARCH_TYPE_AVR32_UCR2, "__AVR32_UC3A0512__"}, -+ {"uc3a0512es", PART_TYPE_AVR32_UC3A0512ES, ARCH_TYPE_AVR32_UCR1, "__AVR32_UC3A0512ES__"}, -+ {"uc3a1128", PART_TYPE_AVR32_UC3A1128, ARCH_TYPE_AVR32_UCR2, "__AVR32_UC3A1128__"}, -+ {"uc3a1256", PART_TYPE_AVR32_UC3A1256, ARCH_TYPE_AVR32_UCR2, "__AVR32_UC3A1256__"}, -+ {"uc3a1512", PART_TYPE_AVR32_UC3A1512, ARCH_TYPE_AVR32_UCR2, "__AVR32_UC3A1512__"}, -+ {"uc3a1512es", PART_TYPE_AVR32_UC3A1512ES, ARCH_TYPE_AVR32_UCR1, "__AVR32_UC3A1512ES__"}, -+ {"uc3a3revd", PART_TYPE_AVR32_UC3A3REVD, ARCH_TYPE_AVR32_UCR2NOMUL, "__AVR32_UC3A3256S__"}, -+ {"uc3a364", PART_TYPE_AVR32_UC3A364, ARCH_TYPE_AVR32_UCR2, "__AVR32_UC3A364__"}, -+ {"uc3a364s", PART_TYPE_AVR32_UC3A364S, ARCH_TYPE_AVR32_UCR2, "__AVR32_UC3A364S__"}, -+ {"uc3a3128", PART_TYPE_AVR32_UC3A3128, ARCH_TYPE_AVR32_UCR2, "__AVR32_UC3A3128__"}, -+ {"uc3a3128s", PART_TYPE_AVR32_UC3A3128S, ARCH_TYPE_AVR32_UCR2, "__AVR32_UC3A3128S__"}, -+ {"uc3a3256", PART_TYPE_AVR32_UC3A3256, ARCH_TYPE_AVR32_UCR2, "__AVR32_UC3A3256__"}, -+ {"uc3a3256s", PART_TYPE_AVR32_UC3A3256S, ARCH_TYPE_AVR32_UCR2, "__AVR32_UC3A3256S__"}, -+ {"uc3b064", PART_TYPE_AVR32_UC3B064, ARCH_TYPE_AVR32_UCR1, "__AVR32_UC3B064__"}, -+ {"uc3b0128", PART_TYPE_AVR32_UC3B0128, ARCH_TYPE_AVR32_UCR1, "__AVR32_UC3B0128__"}, -+ {"uc3b0256", PART_TYPE_AVR32_UC3B0256, ARCH_TYPE_AVR32_UCR1, "__AVR32_UC3B0256__"}, -+ {"uc3b0256es", PART_TYPE_AVR32_UC3B0256ES, ARCH_TYPE_AVR32_UCR1, "__AVR32_UC3B0256ES__"}, -+ {"uc3b0512", PART_TYPE_AVR32_UC3B0512, ARCH_TYPE_AVR32_UCR2, "__AVR32_UC3B0512__"}, -+ {"uc3b0512revc", PART_TYPE_AVR32_UC3B0512REVC, ARCH_TYPE_AVR32_UCR2, "__AVR32_UC3B0512REVC__"}, -+ {"uc3b164", PART_TYPE_AVR32_UC3B164, ARCH_TYPE_AVR32_UCR1, "__AVR32_UC3B164__"}, -+ {"uc3b1128", PART_TYPE_AVR32_UC3B1128, ARCH_TYPE_AVR32_UCR1, "__AVR32_UC3B1128__"}, -+ {"uc3b1256", PART_TYPE_AVR32_UC3B1256, ARCH_TYPE_AVR32_UCR1, "__AVR32_UC3B1256__"}, -+ {"uc3b1256es", PART_TYPE_AVR32_UC3B1256ES, ARCH_TYPE_AVR32_UCR1, "__AVR32_UC3B1256ES__"}, -+ {"uc3b1512", PART_TYPE_AVR32_UC3B1512, ARCH_TYPE_AVR32_UCR2, "__AVR32_UC3B1512__"}, -+ {"uc3b1512revc", PART_TYPE_AVR32_UC3B1512REVC, ARCH_TYPE_AVR32_UCR2, "__AVR32_UC3B1512REVC__"}, -+ {"uc3c0512crevc", PART_TYPE_AVR32_UC3C0512CREVC, ARCH_TYPE_AVR32_UCR3, "__AVR32_UC3C0512CREVC__"}, -+ {"uc3c1512crevc", PART_TYPE_AVR32_UC3C1512CREVC, ARCH_TYPE_AVR32_UCR3, "__AVR32_UC3C1512CREVC__"}, -+ {"uc3c2512crevc", PART_TYPE_AVR32_UC3C2512CREVC, ARCH_TYPE_AVR32_UCR3, "__AVR32_UC3C2512CREVC__"}, -+ {"uc3l0256", PART_TYPE_AVR32_UC3L0256, ARCH_TYPE_AVR32_UCR3, "__AVR32_UC3L0256__"}, -+ {"uc3l0128", PART_TYPE_AVR32_UC3L0128, ARCH_TYPE_AVR32_UCR3, "__AVR32_UC3L0128__"}, -+ {"uc3l064", PART_TYPE_AVR32_UC3L064, ARCH_TYPE_AVR32_UCR3, "__AVR32_UC3L064__"}, -+ {"uc3l032", PART_TYPE_AVR32_UC3L032, ARCH_TYPE_AVR32_UCR3, "__AVR32_UC3L032__"}, -+ {"uc3l016", PART_TYPE_AVR32_UC3L016, ARCH_TYPE_AVR32_UCR3, "__AVR32_UC3L016__"}, -+ {"uc3l064revb", PART_TYPE_AVR32_UC3L064, ARCH_TYPE_AVR32_UCR3, "__AVR32_UC3L064REVB__"}, -+ {"uc3c064c", PART_TYPE_AVR32_UC3C064C, ARCH_TYPE_AVR32_UCR3FP, "__AVR32_UC3C064C__"}, -+ {"uc3c0128c", PART_TYPE_AVR32_UC3C0128C, ARCH_TYPE_AVR32_UCR3FP, "__AVR32_UC3C0128C__"}, -+ {"uc3c0256c", PART_TYPE_AVR32_UC3C0256C, ARCH_TYPE_AVR32_UCR3FP, "__AVR32_UC3C0256C__"}, -+ {"uc3c0512c", PART_TYPE_AVR32_UC3C0512C, ARCH_TYPE_AVR32_UCR3FP, "__AVR32_UC3C0512C__"}, -+ {"uc3c164c", PART_TYPE_AVR32_UC3C164C, ARCH_TYPE_AVR32_UCR3FP, "__AVR32_UC3C164C__"}, -+ {"uc3c1128c", PART_TYPE_AVR32_UC3C1128C, ARCH_TYPE_AVR32_UCR3FP, "__AVR32_UC3C1128C__"}, -+ {"uc3c1256c", PART_TYPE_AVR32_UC3C1256C, ARCH_TYPE_AVR32_UCR3FP, "__AVR32_UC3C1256C__"}, -+ {"uc3c1512c", PART_TYPE_AVR32_UC3C1512C, ARCH_TYPE_AVR32_UCR3FP, "__AVR32_UC3C1512C__"}, -+ {"uc3c264c", PART_TYPE_AVR32_UC3C264C, ARCH_TYPE_AVR32_UCR3FP, "__AVR32_UC3C264C__"}, -+ {"uc3c2128c", PART_TYPE_AVR32_UC3C2128C, ARCH_TYPE_AVR32_UCR3FP, "__AVR32_UC3C2128C__"}, -+ {"uc3c2256c", PART_TYPE_AVR32_UC3C2256C, ARCH_TYPE_AVR32_UCR3FP, "__AVR32_UC3C2256C__"}, -+ {"uc3c2512c", PART_TYPE_AVR32_UC3C2512C, ARCH_TYPE_AVR32_UCR3FP, "__AVR32_UC3C2512C__"}, -+ {"mxt768e", PART_TYPE_AVR32_MXT768E, ARCH_TYPE_AVR32_UCR3, "__AVR32_MXT768E__"}, -+ {NULL, 0, 0, NULL} -+}; -+ -+/* List of all known AVR32 architectures */ -+static const struct arch_type_s avr32_arch_types[] = { -+ /* name, architecture type, microarchitecture type, feature flags, macro */ -+ {"ap", ARCH_TYPE_AVR32_AP, UARCH_TYPE_AVR32B, -+ (FLAG_AVR32_HAS_DSP -+ | FLAG_AVR32_HAS_SIMD -+ | FLAG_AVR32_HAS_UNALIGNED_WORD -+ | FLAG_AVR32_HAS_BRANCH_PRED | FLAG_AVR32_HAS_RETURN_STACK -+ | FLAG_AVR32_HAS_CACHES), -+ "__AVR32_AP__"}, -+ {"ucr1", ARCH_TYPE_AVR32_UCR1, UARCH_TYPE_AVR32A, -+ (FLAG_AVR32_HAS_DSP | FLAG_AVR32_HAS_RMW), -+ "__AVR32_UC__=1"}, -+ {"ucr2", ARCH_TYPE_AVR32_UCR2, UARCH_TYPE_AVR32A, -+ (FLAG_AVR32_HAS_DSP | FLAG_AVR32_HAS_RMW -+ | FLAG_AVR32_HAS_V2_INSNS), -+ "__AVR32_UC__=2"}, -+ {"ucr2nomul", ARCH_TYPE_AVR32_UCR2NOMUL, UARCH_TYPE_AVR32A, -+ (FLAG_AVR32_HAS_DSP | FLAG_AVR32_HAS_RMW -+ | FLAG_AVR32_HAS_V2_INSNS | FLAG_AVR32_HAS_NO_MUL_INSNS), -+ "__AVR32_UC__=2"}, -+ {"ucr3", ARCH_TYPE_AVR32_UCR3, UARCH_TYPE_AVR32A, -+ (FLAG_AVR32_HAS_DSP | FLAG_AVR32_HAS_RMW -+ | FLAG_AVR32_HAS_V2_INSNS), -+ "__AVR32_UC__=3"}, -+ {"ucr3fp", ARCH_TYPE_AVR32_UCR3FP, UARCH_TYPE_AVR32A, -+ (FLAG_AVR32_HAS_DSP | FLAG_AVR32_HAS_RMW | FLAG_AVR32_HAS_FPU -+ | FLAG_AVR32_HAS_V2_INSNS), -+ "__AVR32_UC__=3"}, -+ {NULL, 0, 0, 0, NULL} -+}; -+ -+/* Default arch name */ -+const char *avr32_arch_name = "none"; -+const char *avr32_part_name = "none"; -+ -+const struct part_type_s *avr32_part; -+const struct arch_type_s *avr32_arch; -+ -+ -+/* FIXME: needs to use GC. */ -+struct flashvault_decl_list -+{ -+ struct flashvault_decl_list *next; -+ unsigned int vector_num; -+ const char *name; -+}; -+ -+static struct flashvault_decl_list *flashvault_decl_list_head = NULL; -+ -+ -+/* Set default target_flags. */ -+#undef TARGET_DEFAULT_TARGET_FLAGS -+#define TARGET_DEFAULT_TARGET_FLAGS \ -+ (MASK_HAS_ASM_ADDR_PSEUDOS | MASK_MD_REORG_OPTIMIZATION | MASK_COND_EXEC_BEFORE_RELOAD) -+ -+void -+avr32_optimization_options (int level, int size) -+{ -+ if (AVR32_ALWAYS_PIC) -+ flag_pic = 1; -+ -+ /* Enable section anchors if optimization is enabled. */ -+ if (level > 0 || size) -+ flag_section_anchors = 1; -+} -+ -+ -+/* Override command line options */ -+void -+avr32_override_options (void) -+{ -+ const struct part_type_s *part; -+ const struct arch_type_s *arch; -+ -+ /*Add backward compability*/ -+ if (strcmp ("uc", avr32_arch_name)== 0) -+ { -+ fprintf (stderr, "Warning: Deprecated arch `%s' specified. " -+ "Please use '-march=ucr1' instead. " -+ "Converting to arch 'ucr1'\n", -+ avr32_arch_name); -+ avr32_arch_name="ucr1"; -+ } -+ -+ /* Check if arch type is set. */ -+ for (arch = avr32_arch_types; arch->name; arch++) -+ { -+ if (strcmp (arch->name, avr32_arch_name) == 0) -+ break; -+ } -+ avr32_arch = arch; -+ -+ if (!arch->name && strcmp("none", avr32_arch_name) != 0) -+ { -+ fprintf (stderr, "Unknown arch `%s' specified\n" -+ "Known arch names:\n" -+ "\tuc (deprecated)\n", -+ avr32_arch_name); -+ for (arch = avr32_arch_types; arch->name; arch++) -+ fprintf (stderr, "\t%s\n", arch->name); -+ avr32_arch = &avr32_arch_types[ARCH_TYPE_AVR32_AP]; -+ } -+ -+ /* Check if part type is set. */ -+ for (part = avr32_part_types; part->name; part++) -+ if (strcmp (part->name, avr32_part_name) == 0) -+ break; -+ -+ avr32_part = part; -+ if (!part->name) -+ { -+ fprintf (stderr, "Unknown part `%s' specified\nKnown part names:\n", -+ avr32_part_name); -+ for (part = avr32_part_types; part->name; part++) -+ { -+ if (strcmp("none", part->name) != 0) -+ fprintf (stderr, "\t%s\n", part->name); -+ } -+ /* Set default to NONE*/ -+ avr32_part = &avr32_part_types[PART_TYPE_AVR32_NONE]; -+ } -+ -+ /* NB! option -march= overrides option -mpart -+ * if both are used at the same time */ -+ if (!arch->name) -+ avr32_arch = &avr32_arch_types[avr32_part->arch_type]; -+ -+ /* If optimization level is two or greater, then align start of loops to a -+ word boundary since this will allow folding the first insn of the loop. -+ Do this only for targets supporting branch prediction. */ -+ if (optimize >= 2 && TARGET_BRANCH_PRED) -+ align_loops = 2; -+ -+ -+ /* Enable fast-float library if unsafe math optimizations -+ are used. */ -+ if (flag_unsafe_math_optimizations) -+ target_flags |= MASK_FAST_FLOAT; -+ -+ /* Check if we should set avr32_imm_in_const_pool -+ based on if caches are present or not. */ -+ if ( avr32_imm_in_const_pool == -1 ) -+ { -+ if ( TARGET_CACHES ) -+ avr32_imm_in_const_pool = 1; -+ else -+ avr32_imm_in_const_pool = 0; -+ } -+ -+ if (TARGET_NO_PIC) -+ flag_pic = 0; -+ avr32_add_gc_roots (); -+} -+ -+ -+/* -+If defined, a function that outputs the assembler code for entry to a -+function. The prologue is responsible for setting up the stack frame, -+initializing the frame pointer register, saving registers that must be -+saved, and allocating size additional bytes of storage for the -+local variables. size is an integer. file is a stdio -+stream to which the assembler code should be output. -+ -+The label for the beginning of the function need not be output by this -+macro. That has already been done when the macro is run. -+ -+To determine which registers to save, the macro can refer to the array -+regs_ever_live: element r is nonzero if hard register -+r is used anywhere within the function. This implies the function -+prologue should save register r, provided it is not one of the -+call-used registers. (TARGET_ASM_FUNCTION_EPILOGUE must likewise use -+regs_ever_live.) -+ -+On machines that have ``register windows'', the function entry code does -+not save on the stack the registers that are in the windows, even if -+they are supposed to be preserved by function calls; instead it takes -+appropriate steps to ``push'' the register stack, if any non-call-used -+registers are used in the function. -+ -+On machines where functions may or may not have frame-pointers, the -+function entry code must vary accordingly; it must set up the frame -+pointer if one is wanted, and not otherwise. To determine whether a -+frame pointer is in wanted, the macro can refer to the variable -+frame_pointer_needed. The variable's value will be 1 at run -+time in a function that needs a frame pointer. (see Elimination). -+ -+The function entry code is responsible for allocating any stack space -+required for the function. This stack space consists of the regions -+listed below. In most cases, these regions are allocated in the -+order listed, with the last listed region closest to the top of the -+stack (the lowest address if STACK_GROWS_DOWNWARD is defined, and -+the highest address if it is not defined). You can use a different order -+for a machine if doing so is more convenient or required for -+compatibility reasons. Except in cases where required by standard -+or by a debugger, there is no reason why the stack layout used by GCC -+need agree with that used by other compilers for a machine. -+*/ -+ -+#undef TARGET_ASM_FUNCTION_PROLOGUE -+#define TARGET_ASM_FUNCTION_PROLOGUE avr32_target_asm_function_prologue -+ -+#undef TARGET_ASM_FILE_END -+#define TARGET_ASM_FILE_END avr32_file_end -+ -+#undef TARGET_DEFAULT_SHORT_ENUMS -+#define TARGET_DEFAULT_SHORT_ENUMS hook_bool_void_false -+ -+#undef TARGET_PROMOTE_FUNCTION_ARGS -+#define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true -+ -+#undef TARGET_PROMOTE_FUNCTION_RETURN -+#define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true -+ -+#undef TARGET_PROMOTE_PROTOTYPES -+#define TARGET_PROMOTE_PROTOTYPES hook_bool_tree_true -+ -+#undef TARGET_MUST_PASS_IN_STACK -+#define TARGET_MUST_PASS_IN_STACK avr32_must_pass_in_stack -+ -+#undef TARGET_PASS_BY_REFERENCE -+#define TARGET_PASS_BY_REFERENCE avr32_pass_by_reference -+ -+#undef TARGET_STRICT_ARGUMENT_NAMING -+#define TARGET_STRICT_ARGUMENT_NAMING avr32_strict_argument_naming -+ -+#undef TARGET_VECTOR_MODE_SUPPORTED_P -+#define TARGET_VECTOR_MODE_SUPPORTED_P avr32_vector_mode_supported -+ -+#undef TARGET_RETURN_IN_MEMORY -+#define TARGET_RETURN_IN_MEMORY avr32_return_in_memory -+ -+#undef TARGET_RETURN_IN_MSB -+#define TARGET_RETURN_IN_MSB avr32_return_in_msb -+ -+#undef TARGET_ENCODE_SECTION_INFO -+#define TARGET_ENCODE_SECTION_INFO avr32_encode_section_info -+ -+#undef TARGET_ARG_PARTIAL_BYTES -+#define TARGET_ARG_PARTIAL_BYTES avr32_arg_partial_bytes -+ -+#undef TARGET_STRIP_NAME_ENCODING -+#define TARGET_STRIP_NAME_ENCODING avr32_strip_name_encoding -+ -+#define streq(string1, string2) (strcmp (string1, string2) == 0) -+ -+#undef TARGET_NARROW_VOLATILE_BITFIELD -+#define TARGET_NARROW_VOLATILE_BITFIELD hook_bool_void_false -+ -+#undef TARGET_ATTRIBUTE_TABLE -+#define TARGET_ATTRIBUTE_TABLE avr32_attribute_table -+ -+#undef TARGET_COMP_TYPE_ATTRIBUTES -+#define TARGET_COMP_TYPE_ATTRIBUTES avr32_comp_type_attributes -+ -+ -+#undef TARGET_RTX_COSTS -+#define TARGET_RTX_COSTS avr32_rtx_costs -+ -+#undef TARGET_CANNOT_FORCE_CONST_MEM -+#define TARGET_CANNOT_FORCE_CONST_MEM avr32_cannot_force_const_mem -+ -+#undef TARGET_ASM_INTEGER -+#define TARGET_ASM_INTEGER avr32_assemble_integer -+ -+#undef TARGET_FUNCTION_VALUE -+#define TARGET_FUNCTION_VALUE avr32_function_value -+ -+#undef TARGET_MIN_ANCHOR_OFFSET -+#define TARGET_MIN_ANCHOR_OFFSET (0) -+ -+#undef TARGET_MAX_ANCHOR_OFFSET -+#define TARGET_MAX_ANCHOR_OFFSET ((1 << 15) - 1) -+#undef TARGET_SECONDARY_RELOAD -+#define TARGET_SECONDARY_RELOAD avr32_secondary_reload -+ -+enum reg_class -+avr32_secondary_reload (bool in_p, rtx x, enum reg_class class, -+ enum machine_mode mode, secondary_reload_info *sri) -+{ -+ -+ if ( avr32_rmw_memory_operand (x, mode) ) -+ { -+ if (!in_p) -+ sri->icode = CODE_FOR_reload_out_rmw_memory_operand; -+ else -+ sri->icode = CODE_FOR_reload_in_rmw_memory_operand; -+ } -+ return NO_REGS; -+ -+} -+/* -+ * Switches to the appropriate section for output of constant pool -+ * entry x in mode. You can assume that x is some kind of constant in -+ * RTL. The argument mode is redundant except in the case of a -+ * const_int rtx. Select the section by calling readonly_data_ section -+ * or one of the alternatives for other sections. align is the -+ * constant alignment in bits. -+ * -+ * The default version of this function takes care of putting symbolic -+ * constants in flag_ pic mode in data_section and everything else in -+ * readonly_data_section. -+ */ -+//#undef TARGET_ASM_SELECT_RTX_SECTION -+//#define TARGET_ASM_SELECT_RTX_SECTION avr32_select_rtx_section -+ -+ -+/* -+ * If non-null, this hook performs a target-specific pass over the -+ * instruction stream. The compiler will run it at all optimization -+ * levels, just before the point at which it normally does -+ * delayed-branch scheduling. -+ * -+ * The exact purpose of the hook varies from target to target. Some -+ * use it to do transformations that are necessary for correctness, -+ * such as laying out in-function constant pools or avoiding hardware -+ * hazards. Others use it as an opportunity to do some -+ * machine-dependent optimizations. -+ * -+ * You need not implement the hook if it has nothing to do. The -+ * default definition is null. -+ */ -+#undef TARGET_MACHINE_DEPENDENT_REORG -+#define TARGET_MACHINE_DEPENDENT_REORG avr32_reorg -+ -+/* Target hook for assembling integer objects. -+ Need to handle integer vectors */ -+static bool -+avr32_assemble_integer (rtx x, unsigned int size, int aligned_p) -+{ -+ if (avr32_vector_mode_supported (GET_MODE (x))) -+ { -+ int i, units; -+ -+ if (GET_CODE (x) != CONST_VECTOR) -+ abort (); -+ -+ units = CONST_VECTOR_NUNITS (x); -+ -+ switch (GET_MODE (x)) -+ { -+ case V2HImode: -+ size = 2; -+ break; -+ case V4QImode: -+ size = 1; -+ break; -+ default: -+ abort (); -+ } -+ -+ for (i = 0; i < units; i++) -+ { -+ rtx elt; -+ -+ elt = CONST_VECTOR_ELT (x, i); -+ assemble_integer (elt, size, i == 0 ? 32 : size * BITS_PER_UNIT, 1); -+ } -+ -+ return true; -+ } -+ -+ return default_assemble_integer (x, size, aligned_p); -+} -+ -+ -+/* -+ * This target hook describes the relative costs of RTL expressions. -+ * -+ * The cost may depend on the precise form of the expression, which is -+ * available for examination in x, and the rtx code of the expression -+ * in which it is contained, found in outer_code. code is the -+ * expression code--redundant, since it can be obtained with GET_CODE -+ * (x). -+ * -+ * In implementing this hook, you can use the construct COSTS_N_INSNS -+ * (n) to specify a cost equal to n fast instructions. -+ * -+ * On entry to the hook, *total contains a default estimate for the -+ * cost of the expression. The hook should modify this value as -+ * necessary. Traditionally, the default costs are COSTS_N_INSNS (5) -+ * for multiplications, COSTS_N_INSNS (7) for division and modulus -+ * operations, and COSTS_N_INSNS (1) for all other operations. -+ * -+ * When optimizing for code size, i.e. when optimize_size is non-zero, -+ * this target hook should be used to estimate the relative size cost -+ * of an expression, again relative to COSTS_N_INSNS. -+ * -+ * The hook returns true when all subexpressions of x have been -+ * processed, and false when rtx_cost should recurse. -+ */ -+ -+/* Worker routine for avr32_rtx_costs. */ -+static inline int -+avr32_rtx_costs_1 (rtx x, enum rtx_code code ATTRIBUTE_UNUSED, -+ enum rtx_code outer ATTRIBUTE_UNUSED) -+{ -+ enum machine_mode mode = GET_MODE (x); -+ -+ switch (GET_CODE (x)) -+ { -+ case MEM: -+ /* Using pre decrement / post increment memory operations on the -+ avr32_uc architecture means that two writebacks must be performed -+ and hence two cycles are needed. */ -+ if (!optimize_size -+ && GET_MODE_SIZE (mode) <= 2 * UNITS_PER_WORD -+ && TARGET_ARCH_UC -+ && (GET_CODE (XEXP (x, 0)) == PRE_DEC -+ || GET_CODE (XEXP (x, 0)) == POST_INC)) -+ return COSTS_N_INSNS (5); -+ -+ /* Memory costs quite a lot for the first word, but subsequent words -+ load at the equivalent of a single insn each. */ -+ if (GET_MODE_SIZE (mode) > UNITS_PER_WORD) -+ return COSTS_N_INSNS (3 + (GET_MODE_SIZE (mode) / UNITS_PER_WORD)); -+ -+ return COSTS_N_INSNS (4); -+ case SYMBOL_REF: -+ case CONST: -+ /* These are valid for the pseudo insns: lda.w and call which operates -+ on direct addresses. We assume that the cost of a lda.w is the same -+ as the cost of a ld.w insn. */ -+ return (outer == SET) ? COSTS_N_INSNS (4) : COSTS_N_INSNS (1); -+ case DIV: -+ case MOD: -+ case UDIV: -+ case UMOD: -+ return optimize_size ? COSTS_N_INSNS (1) : COSTS_N_INSNS (16); -+ -+ case ROTATE: -+ case ROTATERT: -+ if (mode == TImode) -+ return COSTS_N_INSNS (100); -+ -+ if (mode == DImode) -+ return COSTS_N_INSNS (10); -+ return COSTS_N_INSNS (4); -+ case ASHIFT: -+ case LSHIFTRT: -+ case ASHIFTRT: -+ case NOT: -+ if (mode == TImode) -+ return COSTS_N_INSNS (10); -+ -+ if (mode == DImode) -+ return COSTS_N_INSNS (4); -+ return COSTS_N_INSNS (1); -+ case PLUS: -+ case MINUS: -+ case NEG: -+ case COMPARE: -+ case ABS: -+ if (GET_MODE_CLASS (mode) == MODE_FLOAT) -+ return COSTS_N_INSNS (100); -+ -+ if (mode == TImode) -+ return COSTS_N_INSNS (50); -+ -+ if (mode == DImode) -+ return COSTS_N_INSNS (2); -+ return COSTS_N_INSNS (1); -+ -+ case MULT: -+ { -+ if (GET_MODE_CLASS (mode) == MODE_FLOAT) -+ return COSTS_N_INSNS (300); -+ -+ if (mode == TImode) -+ return COSTS_N_INSNS (16); -+ -+ if (mode == DImode) -+ return COSTS_N_INSNS (4); -+ -+ if (mode == HImode) -+ return COSTS_N_INSNS (2); -+ -+ return COSTS_N_INSNS (3); -+ } -+ case IF_THEN_ELSE: -+ if (GET_CODE (XEXP (x, 1)) == PC || GET_CODE (XEXP (x, 2)) == PC) -+ return COSTS_N_INSNS (4); -+ return COSTS_N_INSNS (1); -+ case SIGN_EXTEND: -+ case ZERO_EXTEND: -+ /* Sign/Zero extensions of registers cost quite much since these -+ instrcutions only take one register operand which means that gcc -+ often must insert some move instrcutions */ -+ if (mode == QImode || mode == HImode) -+ return (COSTS_N_INSNS (GET_CODE (XEXP (x, 0)) == MEM ? 0 : 1)); -+ return COSTS_N_INSNS (4); -+ case UNSPEC: -+ /* divmod operations */ -+ if (XINT (x, 1) == UNSPEC_UDIVMODSI4_INTERNAL -+ || XINT (x, 1) == UNSPEC_DIVMODSI4_INTERNAL) -+ { -+ return optimize_size ? COSTS_N_INSNS (1) : COSTS_N_INSNS (16); -+ } -+ /* Fallthrough */ -+ default: -+ return COSTS_N_INSNS (1); -+ } -+} -+ -+ -+static bool -+avr32_rtx_costs (rtx x, int code, int outer_code, int *total) -+{ -+ *total = avr32_rtx_costs_1 (x, code, outer_code); -+ return true; -+} -+ -+ -+bool -+avr32_cannot_force_const_mem (rtx x ATTRIBUTE_UNUSED) -+{ -+ /* Do not want symbols in the constant pool when compiling pic or if using -+ address pseudo instructions. */ -+ return ((flag_pic || TARGET_HAS_ASM_ADDR_PSEUDOS) -+ && avr32_find_symbol (x) != NULL_RTX); -+} -+ -+ -+/* Table of machine attributes. */ -+const struct attribute_spec avr32_attribute_table[] = { -+ /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */ -+ /* Interrupt Service Routines have special prologue and epilogue -+ requirements. */ -+ {"isr", 0, 1, false, false, false, avr32_handle_isr_attribute}, -+ {"interrupt", 0, 1, false, false, false, avr32_handle_isr_attribute}, -+ {"acall", 0, 1, false, true, true, avr32_handle_acall_attribute}, -+ {"naked", 0, 0, true, false, false, avr32_handle_fndecl_attribute}, -+ {"rmw_addressable", 0, 0, true, false, false, NULL}, -+ {"flashvault", 0, 1, true, false, false, avr32_handle_fndecl_attribute}, -+ {"flashvault_impl", 0, 1, true, false, false, avr32_handle_fndecl_attribute}, -+ {NULL, 0, 0, false, false, false, NULL} -+}; -+ -+ -+typedef struct -+{ -+ const char *const arg; -+ const unsigned long return_value; -+} -+isr_attribute_arg; -+ -+ -+static const isr_attribute_arg isr_attribute_args[] = { -+ {"FULL", AVR32_FT_ISR_FULL}, -+ {"full", AVR32_FT_ISR_FULL}, -+ {"HALF", AVR32_FT_ISR_HALF}, -+ {"half", AVR32_FT_ISR_HALF}, -+ {"NONE", AVR32_FT_ISR_NONE}, -+ {"none", AVR32_FT_ISR_NONE}, -+ {"UNDEF", AVR32_FT_ISR_NONE}, -+ {"undef", AVR32_FT_ISR_NONE}, -+ {"SWI", AVR32_FT_ISR_NONE}, -+ {"swi", AVR32_FT_ISR_NONE}, -+ {NULL, AVR32_FT_ISR_NONE} -+}; -+ -+ -+/* Returns the (interrupt) function type of the current -+ function, or AVR32_FT_UNKNOWN if the type cannot be determined. */ -+static unsigned long -+avr32_isr_value (tree argument) -+{ -+ const isr_attribute_arg *ptr; -+ const char *arg; -+ -+ /* No argument - default to ISR_NONE. */ -+ if (argument == NULL_TREE) -+ return AVR32_FT_ISR_NONE; -+ -+ /* Get the value of the argument. */ -+ if (TREE_VALUE (argument) == NULL_TREE -+ || TREE_CODE (TREE_VALUE (argument)) != STRING_CST) -+ return AVR32_FT_UNKNOWN; -+ -+ arg = TREE_STRING_POINTER (TREE_VALUE (argument)); -+ -+ /* Check it against the list of known arguments. */ -+ for (ptr = isr_attribute_args; ptr->arg != NULL; ptr++) -+ if (streq (arg, ptr->arg)) -+ return ptr->return_value; -+ -+ /* An unrecognized interrupt type. */ -+ return AVR32_FT_UNKNOWN; -+} -+ -+ -+/* -+These hooks specify assembly directives for creating certain kinds -+of integer object. The TARGET_ASM_BYTE_OP directive creates a -+byte-sized object, the TARGET_ASM_ALIGNED_HI_OP one creates an -+aligned two-byte object, and so on. Any of the hooks may be -+NULL, indicating that no suitable directive is available. -+ -+The compiler will print these strings at the start of a new line, -+followed immediately by the object's initial value. In most cases, -+the string should contain a tab, a pseudo-op, and then another tab. -+*/ -+#undef TARGET_ASM_BYTE_OP -+#define TARGET_ASM_BYTE_OP "\t.byte\t" -+#undef TARGET_ASM_ALIGNED_HI_OP -+#define TARGET_ASM_ALIGNED_HI_OP "\t.align 1\n\t.short\t" -+#undef TARGET_ASM_ALIGNED_SI_OP -+#define TARGET_ASM_ALIGNED_SI_OP "\t.align 2\n\t.int\t" -+#undef TARGET_ASM_ALIGNED_DI_OP -+#define TARGET_ASM_ALIGNED_DI_OP NULL -+#undef TARGET_ASM_ALIGNED_TI_OP -+#define TARGET_ASM_ALIGNED_TI_OP NULL -+#undef TARGET_ASM_UNALIGNED_HI_OP -+#define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t" -+#undef TARGET_ASM_UNALIGNED_SI_OP -+#define TARGET_ASM_UNALIGNED_SI_OP "\t.int\t" -+#undef TARGET_ASM_UNALIGNED_DI_OP -+#define TARGET_ASM_UNALIGNED_DI_OP NULL -+#undef TARGET_ASM_UNALIGNED_TI_OP -+#define TARGET_ASM_UNALIGNED_TI_OP NULL -+ -+#undef TARGET_ASM_OUTPUT_MI_THUNK -+#define TARGET_ASM_OUTPUT_MI_THUNK avr32_output_mi_thunk -+ -+#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK -+#define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true -+ -+ -+static void -+avr32_output_mi_thunk (FILE * file, -+ tree thunk ATTRIBUTE_UNUSED, -+ HOST_WIDE_INT delta, -+ HOST_WIDE_INT vcall_offset, tree function) -+ { -+ int mi_delta = delta; -+ int this_regno = -+ (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function) ? -+ INTERNAL_REGNUM (11) : INTERNAL_REGNUM (12)); -+ -+ -+ if (!avr32_const_ok_for_constraint_p (mi_delta, 'I', "Is21") -+ || vcall_offset) -+ { -+ fputs ("\tpushm\tlr\n", file); -+ } -+ -+ -+ if (mi_delta != 0) -+ { -+ if (avr32_const_ok_for_constraint_p (mi_delta, 'I', "Is21")) -+ { -+ fprintf (file, "\tsub\t%s, %d\n", reg_names[this_regno], -mi_delta); -+ } -+ else -+ { -+ /* Immediate is larger than k21 we must make us a temp register by -+ pushing a register to the stack. */ -+ fprintf (file, "\tmov\tlr, lo(%d)\n", mi_delta); -+ fprintf (file, "\torh\tlr, hi(%d)\n", mi_delta); -+ fprintf (file, "\tadd\t%s, lr\n", reg_names[this_regno]); -+ } -+ } -+ -+ -+ if (vcall_offset != 0) -+ { -+ fprintf (file, "\tld.w\tlr, %s[0]\n", reg_names[this_regno]); -+ fprintf (file, "\tld.w\tlr, lr[%i]\n", (int) vcall_offset); -+ fprintf (file, "\tadd\t%s, lr\n", reg_names[this_regno]); -+ } -+ -+ -+ if (!avr32_const_ok_for_constraint_p (mi_delta, 'I', "Is21") -+ || vcall_offset) -+ { -+ fputs ("\tpopm\tlr\n", file); -+ } -+ -+ /* Jump to the function. We assume that we can use an rjmp since the -+ function to jump to is local and probably not too far away from -+ the thunk. If this assumption proves to be wrong we could implement -+ this jump by calculating the offset between the jump source and destination -+ and put this in the constant pool and then perform an add to pc. -+ This would also be legitimate PIC code. But for now we hope that an rjmp -+ will be sufficient... -+ */ -+ fputs ("\trjmp\t", file); -+ assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0)); -+ fputc ('\n', file); -+ } -+ -+ -+/* Implements target hook vector_mode_supported. */ -+bool -+avr32_vector_mode_supported (enum machine_mode mode) -+{ -+ if ((mode == V2HImode) || (mode == V4QImode)) -+ return true; -+ -+ return false; -+} -+ -+ -+#undef TARGET_INIT_LIBFUNCS -+#define TARGET_INIT_LIBFUNCS avr32_init_libfuncs -+ -+#undef TARGET_INIT_BUILTINS -+#define TARGET_INIT_BUILTINS avr32_init_builtins -+ -+#undef TARGET_EXPAND_BUILTIN -+#define TARGET_EXPAND_BUILTIN avr32_expand_builtin -+ -+tree int_ftype_int, int_ftype_void, short_ftype_short, void_ftype_int_int, -+ void_ftype_ptr_int; -+tree void_ftype_int, void_ftype_ulong, void_ftype_void, int_ftype_ptr_int; -+tree short_ftype_short, int_ftype_int_short, int_ftype_short_short, -+ short_ftype_short_short; -+tree int_ftype_int_int, longlong_ftype_int_short, longlong_ftype_short_short; -+tree void_ftype_int_int_int_int_int, void_ftype_int_int_int; -+tree longlong_ftype_int_int, void_ftype_int_int_longlong; -+tree int_ftype_int_int_int, longlong_ftype_longlong_int_short; -+tree longlong_ftype_longlong_short_short, int_ftype_int_short_short; -+ -+#define def_builtin(NAME, TYPE, CODE) \ -+ add_builtin_function ((NAME), (TYPE), (CODE), \ -+ BUILT_IN_MD, NULL, NULL_TREE) -+ -+#define def_mbuiltin(MASK, NAME, TYPE, CODE) \ -+ do \ -+ { \ -+ if ((MASK)) \ -+ add_builtin_function ((NAME), (TYPE), (CODE), \ -+ BUILT_IN_MD, NULL, NULL_TREE); \ -+ } \ -+ while (0) -+ -+struct builtin_description -+{ -+ const unsigned int mask; -+ const enum insn_code icode; -+ const char *const name; -+ const int code; -+ const enum rtx_code comparison; -+ const unsigned int flag; -+ const tree *ftype; -+}; -+ -+static const struct builtin_description bdesc_2arg[] = { -+ -+#define DSP_BUILTIN(code, builtin, ftype) \ -+ { 1, CODE_FOR_##code, "__builtin_" #code , \ -+ AVR32_BUILTIN_##builtin, 0, 0, ftype } -+ -+ DSP_BUILTIN (mulsathh_h, MULSATHH_H, &short_ftype_short_short), -+ DSP_BUILTIN (mulsathh_w, MULSATHH_W, &int_ftype_short_short), -+ DSP_BUILTIN (mulsatrndhh_h, MULSATRNDHH_H, &short_ftype_short_short), -+ DSP_BUILTIN (mulsatrndwh_w, MULSATRNDWH_W, &int_ftype_int_short), -+ DSP_BUILTIN (mulsatwh_w, MULSATWH_W, &int_ftype_int_short), -+ DSP_BUILTIN (satadd_h, SATADD_H, &short_ftype_short_short), -+ DSP_BUILTIN (satsub_h, SATSUB_H, &short_ftype_short_short), -+ DSP_BUILTIN (satadd_w, SATADD_W, &int_ftype_int_int), -+ DSP_BUILTIN (satsub_w, SATSUB_W, &int_ftype_int_int), -+ DSP_BUILTIN (mulwh_d, MULWH_D, &longlong_ftype_int_short), -+ DSP_BUILTIN (mulnwh_d, MULNWH_D, &longlong_ftype_int_short) -+}; -+ -+ -+void -+avr32_init_builtins (void) -+{ -+ unsigned int i; -+ const struct builtin_description *d; -+ tree endlink = void_list_node; -+ tree int_endlink = tree_cons (NULL_TREE, integer_type_node, endlink); -+ tree longlong_endlink = -+ tree_cons (NULL_TREE, long_long_integer_type_node, endlink); -+ tree short_endlink = -+ tree_cons (NULL_TREE, short_integer_type_node, endlink); -+ tree void_endlink = tree_cons (NULL_TREE, void_type_node, endlink); -+ -+ /* int func (int) */ -+ int_ftype_int = build_function_type (integer_type_node, int_endlink); -+ -+ /* short func (short) */ -+ short_ftype_short -+ = build_function_type (short_integer_type_node, short_endlink); -+ -+ /* short func (short, short) */ -+ short_ftype_short_short -+ = build_function_type (short_integer_type_node, -+ tree_cons (NULL_TREE, short_integer_type_node, -+ short_endlink)); -+ -+ /* long long func (long long, short, short) */ -+ longlong_ftype_longlong_short_short -+ = build_function_type (long_long_integer_type_node, -+ tree_cons (NULL_TREE, long_long_integer_type_node, -+ tree_cons (NULL_TREE, -+ short_integer_type_node, -+ short_endlink))); -+ -+ /* long long func (short, short) */ -+ longlong_ftype_short_short -+ = build_function_type (long_long_integer_type_node, -+ tree_cons (NULL_TREE, short_integer_type_node, -+ short_endlink)); -+ -+ /* int func (int, int) */ -+ int_ftype_int_int -+ = build_function_type (integer_type_node, -+ tree_cons (NULL_TREE, integer_type_node, -+ int_endlink)); -+ -+ /* long long func (int, int) */ -+ longlong_ftype_int_int -+ = build_function_type (long_long_integer_type_node, -+ tree_cons (NULL_TREE, integer_type_node, -+ int_endlink)); -+ -+ /* long long int func (long long, int, short) */ -+ longlong_ftype_longlong_int_short -+ = build_function_type (long_long_integer_type_node, -+ tree_cons (NULL_TREE, long_long_integer_type_node, -+ tree_cons (NULL_TREE, integer_type_node, -+ short_endlink))); -+ -+ /* long long int func (int, short) */ -+ longlong_ftype_int_short -+ = build_function_type (long_long_integer_type_node, -+ tree_cons (NULL_TREE, integer_type_node, -+ short_endlink)); -+ -+ /* int func (int, short, short) */ -+ int_ftype_int_short_short -+ = build_function_type (integer_type_node, -+ tree_cons (NULL_TREE, integer_type_node, -+ tree_cons (NULL_TREE, -+ short_integer_type_node, -+ short_endlink))); -+ -+ /* int func (short, short) */ -+ int_ftype_short_short -+ = build_function_type (integer_type_node, -+ tree_cons (NULL_TREE, short_integer_type_node, -+ short_endlink)); -+ -+ /* int func (int, short) */ -+ int_ftype_int_short -+ = build_function_type (integer_type_node, -+ tree_cons (NULL_TREE, integer_type_node, -+ short_endlink)); -+ -+ /* void func (int, int) */ -+ void_ftype_int_int -+ = build_function_type (void_type_node, -+ tree_cons (NULL_TREE, integer_type_node, -+ int_endlink)); -+ -+ /* void func (int, int, int) */ -+ void_ftype_int_int_int -+ = build_function_type (void_type_node, -+ tree_cons (NULL_TREE, integer_type_node, -+ tree_cons (NULL_TREE, integer_type_node, -+ int_endlink))); -+ -+ /* void func (int, int, long long) */ -+ void_ftype_int_int_longlong -+ = build_function_type (void_type_node, -+ tree_cons (NULL_TREE, integer_type_node, -+ tree_cons (NULL_TREE, integer_type_node, -+ longlong_endlink))); -+ -+ /* void func (int, int, int, int, int) */ -+ void_ftype_int_int_int_int_int -+ = build_function_type (void_type_node, -+ tree_cons (NULL_TREE, integer_type_node, -+ tree_cons (NULL_TREE, integer_type_node, -+ tree_cons (NULL_TREE, -+ integer_type_node, -+ tree_cons -+ (NULL_TREE, -+ integer_type_node, -+ int_endlink))))); -+ -+ /* void func (void *, int) */ -+ void_ftype_ptr_int -+ = build_function_type (void_type_node, -+ tree_cons (NULL_TREE, ptr_type_node, int_endlink)); -+ -+ /* void func (int) */ -+ void_ftype_int = build_function_type (void_type_node, int_endlink); -+ -+ /* void func (ulong) */ -+ void_ftype_ulong = build_function_type_list (void_type_node, -+ long_unsigned_type_node, NULL_TREE); -+ -+ /* void func (void) */ -+ void_ftype_void = build_function_type (void_type_node, void_endlink); -+ -+ /* int func (void) */ -+ int_ftype_void = build_function_type (integer_type_node, void_endlink); -+ -+ /* int func (void *, int) */ -+ int_ftype_ptr_int -+ = build_function_type (integer_type_node, -+ tree_cons (NULL_TREE, ptr_type_node, int_endlink)); -+ -+ /* int func (int, int, int) */ -+ int_ftype_int_int_int -+ = build_function_type (integer_type_node, -+ tree_cons (NULL_TREE, integer_type_node, -+ tree_cons (NULL_TREE, integer_type_node, -+ int_endlink))); -+ -+ /* Initialize avr32 builtins. */ -+ def_builtin ("__builtin_mfsr", int_ftype_int, AVR32_BUILTIN_MFSR); -+ def_builtin ("__builtin_mtsr", void_ftype_int_int, AVR32_BUILTIN_MTSR); -+ def_builtin ("__builtin_mfdr", int_ftype_int, AVR32_BUILTIN_MFDR); -+ def_builtin ("__builtin_mtdr", void_ftype_int_int, AVR32_BUILTIN_MTDR); -+ def_builtin ("__builtin_cache", void_ftype_ptr_int, AVR32_BUILTIN_CACHE); -+ def_builtin ("__builtin_sync", void_ftype_int, AVR32_BUILTIN_SYNC); -+ def_builtin ("__builtin_ssrf", void_ftype_int, AVR32_BUILTIN_SSRF); -+ def_builtin ("__builtin_csrf", void_ftype_int, AVR32_BUILTIN_CSRF); -+ def_builtin ("__builtin_tlbr", void_ftype_void, AVR32_BUILTIN_TLBR); -+ def_builtin ("__builtin_tlbs", void_ftype_void, AVR32_BUILTIN_TLBS); -+ def_builtin ("__builtin_tlbw", void_ftype_void, AVR32_BUILTIN_TLBW); -+ def_builtin ("__builtin_breakpoint", void_ftype_void, -+ AVR32_BUILTIN_BREAKPOINT); -+ def_builtin ("__builtin_xchg", int_ftype_ptr_int, AVR32_BUILTIN_XCHG); -+ def_builtin ("__builtin_ldxi", int_ftype_ptr_int, AVR32_BUILTIN_LDXI); -+ def_builtin ("__builtin_bswap_16", short_ftype_short, -+ AVR32_BUILTIN_BSWAP16); -+ def_builtin ("__builtin_bswap_32", int_ftype_int, AVR32_BUILTIN_BSWAP32); -+ def_builtin ("__builtin_cop", void_ftype_int_int_int_int_int, -+ AVR32_BUILTIN_COP); -+ def_builtin ("__builtin_mvcr_w", int_ftype_int_int, AVR32_BUILTIN_MVCR_W); -+ def_builtin ("__builtin_mvrc_w", void_ftype_int_int_int, -+ AVR32_BUILTIN_MVRC_W); -+ def_builtin ("__builtin_mvcr_d", longlong_ftype_int_int, -+ AVR32_BUILTIN_MVCR_D); -+ def_builtin ("__builtin_mvrc_d", void_ftype_int_int_longlong, -+ AVR32_BUILTIN_MVRC_D); -+ def_builtin ("__builtin_sats", int_ftype_int_int_int, AVR32_BUILTIN_SATS); -+ def_builtin ("__builtin_satu", int_ftype_int_int_int, AVR32_BUILTIN_SATU); -+ def_builtin ("__builtin_satrnds", int_ftype_int_int_int, -+ AVR32_BUILTIN_SATRNDS); -+ def_builtin ("__builtin_satrndu", int_ftype_int_int_int, -+ AVR32_BUILTIN_SATRNDU); -+ def_builtin ("__builtin_musfr", void_ftype_int, AVR32_BUILTIN_MUSFR); -+ def_builtin ("__builtin_mustr", int_ftype_void, AVR32_BUILTIN_MUSTR); -+ def_builtin ("__builtin_macsathh_w", int_ftype_int_short_short, -+ AVR32_BUILTIN_MACSATHH_W); -+ def_builtin ("__builtin_macwh_d", longlong_ftype_longlong_int_short, -+ AVR32_BUILTIN_MACWH_D); -+ def_builtin ("__builtin_machh_d", longlong_ftype_longlong_short_short, -+ AVR32_BUILTIN_MACHH_D); -+ def_builtin ("__builtin_mems", void_ftype_ptr_int, AVR32_BUILTIN_MEMS); -+ def_builtin ("__builtin_memt", void_ftype_ptr_int, AVR32_BUILTIN_MEMT); -+ def_builtin ("__builtin_memc", void_ftype_ptr_int, AVR32_BUILTIN_MEMC); -+ def_builtin ("__builtin_sleep", void_ftype_int, AVR32_BUILTIN_SLEEP); -+ def_builtin ("__builtin_avr32_delay_cycles", void_ftype_int, AVR32_BUILTIN_DELAY_CYCLES); -+ -+ /* Add all builtins that are more or less simple operations on two -+ operands. */ -+ for (i = 0, d = bdesc_2arg; i < ARRAY_SIZE (bdesc_2arg); i++, d++) -+ { -+ /* Use one of the operands; the target can have a different mode for -+ mask-generating compares. */ -+ -+ if (d->name == 0) -+ continue; -+ -+ def_mbuiltin (d->mask, d->name, *(d->ftype), d->code); -+ } -+} -+ -+ -+/* Subroutine of avr32_expand_builtin to take care of binop insns. */ -+static rtx -+avr32_expand_binop_builtin (enum insn_code icode, tree exp, rtx target) -+{ -+ rtx pat; -+ tree arg0 = CALL_EXPR_ARG (exp,0); -+ tree arg1 = CALL_EXPR_ARG (exp,1); -+ rtx op0 = expand_normal (arg0); -+ rtx op1 = expand_normal (arg1); -+ enum machine_mode tmode = insn_data[icode].operand[0].mode; -+ enum machine_mode mode0 = insn_data[icode].operand[1].mode; -+ enum machine_mode mode1 = insn_data[icode].operand[2].mode; -+ -+ if (!target -+ || GET_MODE (target) != tmode -+ || !(*insn_data[icode].operand[0].predicate) (target, tmode)) -+ target = gen_reg_rtx (tmode); -+ -+ /* In case the insn wants input operands in modes different from the -+ result, abort. */ -+ if (!(*insn_data[icode].operand[1].predicate) (op0, mode0)) -+ { -+ /* If op0 is already a reg we must cast it to the correct mode. */ -+ if (REG_P (op0)) -+ op0 = convert_to_mode (mode0, op0, 1); -+ else -+ op0 = copy_to_mode_reg (mode0, op0); -+ } -+ if (!(*insn_data[icode].operand[2].predicate) (op1, mode1)) -+ { -+ /* If op1 is already a reg we must cast it to the correct mode. */ -+ if (REG_P (op1)) -+ op1 = convert_to_mode (mode1, op1, 1); -+ else -+ op1 = copy_to_mode_reg (mode1, op1); -+ } -+ pat = GEN_FCN (icode) (target, op0, op1); -+ if (!pat) -+ return 0; -+ emit_insn (pat); -+ return target; -+} -+ -+ -+/* Expand an expression EXP that calls a built-in function, -+ with result going to TARGET if that's convenient -+ (and in mode MODE if that's convenient). -+ SUBTARGET may be used as the target for computing one of EXP's operands. -+ IGNORE is nonzero if the value is to be ignored. */ -+rtx -+avr32_expand_builtin (tree exp, -+ rtx target, -+ rtx subtarget ATTRIBUTE_UNUSED, -+ enum machine_mode mode ATTRIBUTE_UNUSED, -+ int ignore ATTRIBUTE_UNUSED) -+{ -+ const struct builtin_description *d; -+ unsigned int i; -+ enum insn_code icode = 0; -+ tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0); -+ tree arg0, arg1, arg2; -+ rtx op0, op1, op2, pat; -+ enum machine_mode tmode, mode0, mode1; -+ enum machine_mode arg0_mode; -+ int fcode = DECL_FUNCTION_CODE (fndecl); -+ -+ switch (fcode) -+ { -+ default: -+ break; -+ -+ case AVR32_BUILTIN_SATS: -+ case AVR32_BUILTIN_SATU: -+ case AVR32_BUILTIN_SATRNDS: -+ case AVR32_BUILTIN_SATRNDU: -+ { -+ const char *fname; -+ switch (fcode) -+ { -+ default: -+ case AVR32_BUILTIN_SATS: -+ icode = CODE_FOR_sats; -+ fname = "sats"; -+ break; -+ case AVR32_BUILTIN_SATU: -+ icode = CODE_FOR_satu; -+ fname = "satu"; -+ break; -+ case AVR32_BUILTIN_SATRNDS: -+ icode = CODE_FOR_satrnds; -+ fname = "satrnds"; -+ break; -+ case AVR32_BUILTIN_SATRNDU: -+ icode = CODE_FOR_satrndu; -+ fname = "satrndu"; -+ break; -+ } -+ -+ arg0 = CALL_EXPR_ARG (exp,0); -+ arg1 = CALL_EXPR_ARG (exp,1); -+ arg2 = CALL_EXPR_ARG (exp,2); -+ op0 = expand_normal (arg0); -+ op1 = expand_normal (arg1); -+ op2 = expand_normal (arg2); -+ -+ tmode = insn_data[icode].operand[0].mode; -+ -+ -+ if (target == 0 -+ || GET_MODE (target) != tmode -+ || !(*insn_data[icode].operand[0].predicate) (target, tmode)) -+ target = gen_reg_rtx (tmode); -+ -+ -+ if (!(*insn_data[icode].operand[0].predicate) (op0, GET_MODE (op0))) -+ { -+ op0 = copy_to_mode_reg (insn_data[icode].operand[0].mode, op0); -+ } -+ -+ if (!(*insn_data[icode].operand[1].predicate) (op1, SImode)) -+ { -+ error ("Parameter 2 to __builtin_%s should be a constant number.", -+ fname); -+ return NULL_RTX; -+ } -+ -+ if (!(*insn_data[icode].operand[1].predicate) (op2, SImode)) -+ { -+ error ("Parameter 3 to __builtin_%s should be a constant number.", -+ fname); -+ return NULL_RTX; -+ } -+ -+ emit_move_insn (target, op0); -+ pat = GEN_FCN (icode) (target, op1, op2); -+ if (!pat) -+ return 0; -+ emit_insn (pat); -+ -+ return target; -+ } -+ case AVR32_BUILTIN_MUSTR: -+ icode = CODE_FOR_mustr; -+ tmode = insn_data[icode].operand[0].mode; -+ -+ if (target == 0 -+ || GET_MODE (target) != tmode -+ || !(*insn_data[icode].operand[0].predicate) (target, tmode)) -+ target = gen_reg_rtx (tmode); -+ pat = GEN_FCN (icode) (target); -+ if (!pat) -+ return 0; -+ emit_insn (pat); -+ return target; -+ -+ case AVR32_BUILTIN_MFSR: -+ icode = CODE_FOR_mfsr; -+ arg0 = CALL_EXPR_ARG (exp,0); -+ op0 = expand_normal (arg0); -+ tmode = insn_data[icode].operand[0].mode; -+ mode0 = insn_data[icode].operand[1].mode; -+ -+ if (!(*insn_data[icode].operand[1].predicate) (op0, mode0)) -+ { -+ error ("Parameter 1 to __builtin_mfsr must be a constant number"); -+ } -+ -+ if (target == 0 -+ || GET_MODE (target) != tmode -+ || !(*insn_data[icode].operand[0].predicate) (target, tmode)) -+ target = gen_reg_rtx (tmode); -+ pat = GEN_FCN (icode) (target, op0); -+ if (!pat) -+ return 0; -+ emit_insn (pat); -+ return target; -+ case AVR32_BUILTIN_MTSR: -+ icode = CODE_FOR_mtsr; -+ arg0 = CALL_EXPR_ARG (exp,0); -+ arg1 = CALL_EXPR_ARG (exp,1); -+ op0 = expand_normal (arg0); -+ op1 = expand_normal (arg1); -+ mode0 = insn_data[icode].operand[0].mode; -+ mode1 = insn_data[icode].operand[1].mode; -+ -+ if (!(*insn_data[icode].operand[0].predicate) (op0, mode0)) -+ { -+ error ("Parameter 1 to __builtin_mtsr must be a constant number"); -+ return gen_reg_rtx (mode0); -+ } -+ if (!(*insn_data[icode].operand[1].predicate) (op1, mode1)) -+ op1 = copy_to_mode_reg (mode1, op1); -+ pat = GEN_FCN (icode) (op0, op1); -+ if (!pat) -+ return 0; -+ emit_insn (pat); -+ return NULL_RTX; -+ case AVR32_BUILTIN_MFDR: -+ icode = CODE_FOR_mfdr; -+ arg0 = CALL_EXPR_ARG (exp,0); -+ op0 = expand_normal (arg0); -+ tmode = insn_data[icode].operand[0].mode; -+ mode0 = insn_data[icode].operand[1].mode; -+ -+ if (!(*insn_data[icode].operand[1].predicate) (op0, mode0)) -+ { -+ error ("Parameter 1 to __builtin_mfdr must be a constant number"); -+ } -+ -+ if (target == 0 -+ || GET_MODE (target) != tmode -+ || !(*insn_data[icode].operand[0].predicate) (target, tmode)) -+ target = gen_reg_rtx (tmode); -+ pat = GEN_FCN (icode) (target, op0); -+ if (!pat) -+ return 0; -+ emit_insn (pat); -+ return target; -+ case AVR32_BUILTIN_MTDR: -+ icode = CODE_FOR_mtdr; -+ arg0 = CALL_EXPR_ARG (exp,0); -+ arg1 = CALL_EXPR_ARG (exp,1); -+ op0 = expand_normal (arg0); -+ op1 = expand_normal (arg1); -+ mode0 = insn_data[icode].operand[0].mode; -+ mode1 = insn_data[icode].operand[1].mode; -+ -+ if (!(*insn_data[icode].operand[0].predicate) (op0, mode0)) -+ { -+ error ("Parameter 1 to __builtin_mtdr must be a constant number"); -+ return gen_reg_rtx (mode0); -+ } -+ if (!(*insn_data[icode].operand[1].predicate) (op1, mode1)) -+ op1 = copy_to_mode_reg (mode1, op1); -+ pat = GEN_FCN (icode) (op0, op1); -+ if (!pat) -+ return 0; -+ emit_insn (pat); -+ return NULL_RTX; -+ case AVR32_BUILTIN_CACHE: -+ icode = CODE_FOR_cache; -+ arg0 = CALL_EXPR_ARG (exp,0); -+ arg1 = CALL_EXPR_ARG (exp,1); -+ op0 = expand_normal (arg0); -+ op1 = expand_normal (arg1); -+ mode0 = insn_data[icode].operand[0].mode; -+ mode1 = insn_data[icode].operand[1].mode; -+ -+ if (!(*insn_data[icode].operand[1].predicate) (op1, mode1)) -+ { -+ error ("Parameter 2 to __builtin_cache must be a constant number"); -+ return gen_reg_rtx (mode1); -+ } -+ -+ if (!(*insn_data[icode].operand[0].predicate) (op0, mode0)) -+ op0 = copy_to_mode_reg (mode0, op0); -+ -+ pat = GEN_FCN (icode) (op0, op1); -+ if (!pat) -+ return 0; -+ emit_insn (pat); -+ return NULL_RTX; -+ case AVR32_BUILTIN_SYNC: -+ case AVR32_BUILTIN_MUSFR: -+ case AVR32_BUILTIN_SSRF: -+ case AVR32_BUILTIN_CSRF: -+ { -+ const char *fname; -+ switch (fcode) -+ { -+ default: -+ case AVR32_BUILTIN_SYNC: -+ icode = CODE_FOR_sync; -+ fname = "sync"; -+ break; -+ case AVR32_BUILTIN_MUSFR: -+ icode = CODE_FOR_musfr; -+ fname = "musfr"; -+ break; -+ case AVR32_BUILTIN_SSRF: -+ icode = CODE_FOR_ssrf; -+ fname = "ssrf"; -+ break; -+ case AVR32_BUILTIN_CSRF: -+ icode = CODE_FOR_csrf; -+ fname = "csrf"; -+ break; -+ } -+ -+ arg0 = CALL_EXPR_ARG (exp,0); -+ op0 = expand_normal (arg0); -+ mode0 = insn_data[icode].operand[0].mode; -+ -+ if (!(*insn_data[icode].operand[0].predicate) (op0, mode0)) -+ { -+ if (icode == CODE_FOR_musfr) -+ op0 = copy_to_mode_reg (mode0, op0); -+ else -+ { -+ error ("Parameter to __builtin_%s is illegal.", fname); -+ return gen_reg_rtx (mode0); -+ } -+ } -+ pat = GEN_FCN (icode) (op0); -+ if (!pat) -+ return 0; -+ emit_insn (pat); -+ return NULL_RTX; -+ } -+ case AVR32_BUILTIN_TLBR: -+ icode = CODE_FOR_tlbr; -+ pat = GEN_FCN (icode) (NULL_RTX); -+ if (!pat) -+ return 0; -+ emit_insn (pat); -+ return NULL_RTX; -+ case AVR32_BUILTIN_TLBS: -+ icode = CODE_FOR_tlbs; -+ pat = GEN_FCN (icode) (NULL_RTX); -+ if (!pat) -+ return 0; -+ emit_insn (pat); -+ return NULL_RTX; -+ case AVR32_BUILTIN_TLBW: -+ icode = CODE_FOR_tlbw; -+ pat = GEN_FCN (icode) (NULL_RTX); -+ if (!pat) -+ return 0; -+ emit_insn (pat); -+ return NULL_RTX; -+ case AVR32_BUILTIN_BREAKPOINT: -+ icode = CODE_FOR_breakpoint; -+ pat = GEN_FCN (icode) (NULL_RTX); -+ if (!pat) -+ return 0; -+ emit_insn (pat); -+ return NULL_RTX; -+ case AVR32_BUILTIN_XCHG: -+ icode = CODE_FOR_sync_lock_test_and_setsi; -+ arg0 = CALL_EXPR_ARG (exp,0); -+ arg1 = CALL_EXPR_ARG (exp,1); -+ op0 = expand_normal (arg0); -+ op1 = expand_normal (arg1); -+ tmode = insn_data[icode].operand[0].mode; -+ mode0 = insn_data[icode].operand[1].mode; -+ mode1 = insn_data[icode].operand[2].mode; -+ -+ if (!(*insn_data[icode].operand[2].predicate) (op1, mode1)) -+ { -+ op1 = copy_to_mode_reg (mode1, op1); -+ } -+ -+ op0 = force_reg (GET_MODE (op0), op0); -+ op0 = gen_rtx_MEM (GET_MODE (op0), op0); -+ if (!(*insn_data[icode].operand[1].predicate) (op0, mode0)) -+ { -+ error -+ ("Parameter 1 to __builtin_xchg must be a pointer to an integer."); -+ } -+ -+ if (target == 0 -+ || GET_MODE (target) != tmode -+ || !(*insn_data[icode].operand[0].predicate) (target, tmode)) -+ target = gen_reg_rtx (tmode); -+ pat = GEN_FCN (icode) (target, op0, op1); -+ if (!pat) -+ return 0; -+ emit_insn (pat); -+ return target; -+ case AVR32_BUILTIN_LDXI: -+ icode = CODE_FOR_ldxi; -+ arg0 = CALL_EXPR_ARG (exp,0); -+ arg1 = CALL_EXPR_ARG (exp,1); -+ arg2 = CALL_EXPR_ARG (exp,2); -+ op0 = expand_normal (arg0); -+ op1 = expand_normal (arg1); -+ op2 = expand_normal (arg2); -+ tmode = insn_data[icode].operand[0].mode; -+ mode0 = insn_data[icode].operand[1].mode; -+ mode1 = insn_data[icode].operand[2].mode; -+ -+ if (!(*insn_data[icode].operand[1].predicate) (op0, mode0)) -+ { -+ op0 = copy_to_mode_reg (mode0, op0); -+ } -+ -+ if (!(*insn_data[icode].operand[2].predicate) (op1, mode1)) -+ { -+ op1 = copy_to_mode_reg (mode1, op1); -+ } -+ -+ if (!(*insn_data[icode].operand[3].predicate) (op2, SImode)) -+ { -+ error -+ ("Parameter 3 to __builtin_ldxi must be a valid extract shift operand: (0|8|16|24)"); -+ return gen_reg_rtx (mode0); -+ } -+ -+ if (target == 0 -+ || GET_MODE (target) != tmode -+ || !(*insn_data[icode].operand[0].predicate) (target, tmode)) -+ target = gen_reg_rtx (tmode); -+ pat = GEN_FCN (icode) (target, op0, op1, op2); -+ if (!pat) -+ return 0; -+ emit_insn (pat); -+ return target; -+ case AVR32_BUILTIN_BSWAP16: -+ { -+ icode = CODE_FOR_bswap_16; -+ arg0 = CALL_EXPR_ARG (exp,0); -+ arg0_mode = TYPE_MODE (TREE_TYPE (arg0)); -+ mode0 = insn_data[icode].operand[1].mode; -+ if (arg0_mode != mode0) -+ arg0 = build1 (NOP_EXPR, -+ (*lang_hooks.types.type_for_mode) (mode0, 0), arg0); -+ -+ op0 = expand_expr (arg0, NULL_RTX, HImode, 0); -+ tmode = insn_data[icode].operand[0].mode; -+ -+ -+ if (!(*insn_data[icode].operand[1].predicate) (op0, mode0)) -+ { -+ if ( CONST_INT_P (op0) ) -+ { -+ HOST_WIDE_INT val = ( ((INTVAL (op0)&0x00ff) << 8) | -+ ((INTVAL (op0)&0xff00) >> 8) ); -+ /* Sign extend 16-bit value to host wide int */ -+ val <<= (HOST_BITS_PER_WIDE_INT - 16); -+ val >>= (HOST_BITS_PER_WIDE_INT - 16); -+ op0 = GEN_INT(val); -+ if (target == 0 -+ || GET_MODE (target) != tmode -+ || !(*insn_data[icode].operand[0].predicate) (target, tmode)) -+ target = gen_reg_rtx (tmode); -+ emit_move_insn(target, op0); -+ return target; -+ } -+ else -+ op0 = copy_to_mode_reg (mode0, op0); -+ } -+ -+ if (target == 0 -+ || GET_MODE (target) != tmode -+ || !(*insn_data[icode].operand[0].predicate) (target, tmode)) -+ { -+ target = gen_reg_rtx (tmode); -+ } -+ -+ -+ pat = GEN_FCN (icode) (target, op0); -+ if (!pat) -+ return 0; -+ emit_insn (pat); -+ -+ return target; -+ } -+ case AVR32_BUILTIN_BSWAP32: -+ { -+ icode = CODE_FOR_bswap_32; -+ arg0 = CALL_EXPR_ARG (exp,0); -+ op0 = expand_normal (arg0); -+ tmode = insn_data[icode].operand[0].mode; -+ mode0 = insn_data[icode].operand[1].mode; -+ -+ if (!(*insn_data[icode].operand[1].predicate) (op0, mode0)) -+ { -+ if ( CONST_INT_P (op0) ) -+ { -+ HOST_WIDE_INT val = ( ((INTVAL (op0)&0x000000ff) << 24) | -+ ((INTVAL (op0)&0x0000ff00) << 8) | -+ ((INTVAL (op0)&0x00ff0000) >> 8) | -+ ((INTVAL (op0)&0xff000000) >> 24) ); -+ /* Sign extend 32-bit value to host wide int */ -+ val <<= (HOST_BITS_PER_WIDE_INT - 32); -+ val >>= (HOST_BITS_PER_WIDE_INT - 32); -+ op0 = GEN_INT(val); -+ if (target == 0 -+ || GET_MODE (target) != tmode -+ || !(*insn_data[icode].operand[0].predicate) (target, tmode)) -+ target = gen_reg_rtx (tmode); -+ emit_move_insn(target, op0); -+ return target; -+ } -+ else -+ op0 = copy_to_mode_reg (mode0, op0); -+ } -+ -+ if (target == 0 -+ || GET_MODE (target) != tmode -+ || !(*insn_data[icode].operand[0].predicate) (target, tmode)) -+ target = gen_reg_rtx (tmode); -+ -+ -+ pat = GEN_FCN (icode) (target, op0); -+ if (!pat) -+ return 0; -+ emit_insn (pat); -+ -+ return target; -+ } -+ case AVR32_BUILTIN_MVCR_W: -+ case AVR32_BUILTIN_MVCR_D: -+ { -+ arg0 = CALL_EXPR_ARG (exp,0); -+ arg1 = CALL_EXPR_ARG (exp,1); -+ op0 = expand_normal (arg0); -+ op1 = expand_normal (arg1); -+ -+ if (fcode == AVR32_BUILTIN_MVCR_W) -+ icode = CODE_FOR_mvcrsi; -+ else -+ icode = CODE_FOR_mvcrdi; -+ -+ tmode = insn_data[icode].operand[0].mode; -+ -+ if (target == 0 -+ || GET_MODE (target) != tmode -+ || !(*insn_data[icode].operand[0].predicate) (target, tmode)) -+ target = gen_reg_rtx (tmode); -+ -+ if (!(*insn_data[icode].operand[1].predicate) (op0, SImode)) -+ { -+ error -+ ("Parameter 1 to __builtin_cop is not a valid coprocessor number."); -+ error ("Number should be between 0 and 7."); -+ return NULL_RTX; -+ } -+ -+ if (!(*insn_data[icode].operand[2].predicate) (op1, SImode)) -+ { -+ error -+ ("Parameter 2 to __builtin_cop is not a valid coprocessor register number."); -+ error ("Number should be between 0 and 15."); -+ return NULL_RTX; -+ } -+ -+ pat = GEN_FCN (icode) (target, op0, op1); -+ if (!pat) -+ return 0; -+ emit_insn (pat); -+ -+ return target; -+ } -+ case AVR32_BUILTIN_MACSATHH_W: -+ case AVR32_BUILTIN_MACWH_D: -+ case AVR32_BUILTIN_MACHH_D: -+ { -+ arg0 = CALL_EXPR_ARG (exp,0); -+ arg1 = CALL_EXPR_ARG (exp,1); -+ arg2 = CALL_EXPR_ARG (exp,2); -+ op0 = expand_normal (arg0); -+ op1 = expand_normal (arg1); -+ op2 = expand_normal (arg2); -+ -+ icode = ((fcode == AVR32_BUILTIN_MACSATHH_W) ? CODE_FOR_macsathh_w : -+ (fcode == AVR32_BUILTIN_MACWH_D) ? CODE_FOR_macwh_d : -+ CODE_FOR_machh_d); -+ -+ tmode = insn_data[icode].operand[0].mode; -+ mode0 = insn_data[icode].operand[1].mode; -+ mode1 = insn_data[icode].operand[2].mode; -+ -+ -+ if (!target -+ || GET_MODE (target) != tmode -+ || !(*insn_data[icode].operand[0].predicate) (target, tmode)) -+ target = gen_reg_rtx (tmode); -+ -+ if (!(*insn_data[icode].operand[0].predicate) (op0, tmode)) -+ { -+ /* If op0 is already a reg we must cast it to the correct mode. */ -+ if (REG_P (op0)) -+ op0 = convert_to_mode (tmode, op0, 1); -+ else -+ op0 = copy_to_mode_reg (tmode, op0); -+ } -+ -+ if (!(*insn_data[icode].operand[1].predicate) (op1, mode0)) -+ { -+ /* If op1 is already a reg we must cast it to the correct mode. */ -+ if (REG_P (op1)) -+ op1 = convert_to_mode (mode0, op1, 1); -+ else -+ op1 = copy_to_mode_reg (mode0, op1); -+ } -+ -+ if (!(*insn_data[icode].operand[2].predicate) (op2, mode1)) -+ { -+ /* If op1 is already a reg we must cast it to the correct mode. */ -+ if (REG_P (op2)) -+ op2 = convert_to_mode (mode1, op2, 1); -+ else -+ op2 = copy_to_mode_reg (mode1, op2); -+ } -+ -+ emit_move_insn (target, op0); -+ -+ pat = GEN_FCN (icode) (target, op1, op2); -+ if (!pat) -+ return 0; -+ emit_insn (pat); -+ return target; -+ } -+ case AVR32_BUILTIN_MVRC_W: -+ case AVR32_BUILTIN_MVRC_D: -+ { -+ arg0 = CALL_EXPR_ARG (exp,0); -+ arg1 = CALL_EXPR_ARG (exp,1); -+ arg2 = CALL_EXPR_ARG (exp,2); -+ op0 = expand_normal (arg0); -+ op1 = expand_normal (arg1); -+ op2 = expand_normal (arg2); -+ -+ if (fcode == AVR32_BUILTIN_MVRC_W) -+ icode = CODE_FOR_mvrcsi; -+ else -+ icode = CODE_FOR_mvrcdi; -+ -+ if (!(*insn_data[icode].operand[0].predicate) (op0, SImode)) -+ { -+ error ("Parameter 1 is not a valid coprocessor number."); -+ error ("Number should be between 0 and 7."); -+ return NULL_RTX; -+ } -+ -+ if (!(*insn_data[icode].operand[1].predicate) (op1, SImode)) -+ { -+ error ("Parameter 2 is not a valid coprocessor register number."); -+ error ("Number should be between 0 and 15."); -+ return NULL_RTX; -+ } -+ -+ if (GET_CODE (op2) == CONST_INT -+ || GET_CODE (op2) == CONST -+ || GET_CODE (op2) == SYMBOL_REF || GET_CODE (op2) == LABEL_REF) -+ { -+ op2 = force_const_mem (insn_data[icode].operand[2].mode, op2); -+ } -+ -+ if (!(*insn_data[icode].operand[2].predicate) (op2, GET_MODE (op2))) -+ op2 = copy_to_mode_reg (insn_data[icode].operand[2].mode, op2); -+ -+ -+ pat = GEN_FCN (icode) (op0, op1, op2); -+ if (!pat) -+ return 0; -+ emit_insn (pat); -+ -+ return NULL_RTX; -+ } -+ case AVR32_BUILTIN_COP: -+ { -+ rtx op3, op4; -+ tree arg3, arg4; -+ icode = CODE_FOR_cop; -+ arg0 = CALL_EXPR_ARG (exp,0); -+ arg1 = CALL_EXPR_ARG (exp,1); -+ arg2 = CALL_EXPR_ARG (exp,2); -+ arg3 = CALL_EXPR_ARG (exp,3); -+ arg4 = CALL_EXPR_ARG (exp,4); -+ op0 = expand_normal (arg0); -+ op1 = expand_normal (arg1); -+ op2 = expand_normal (arg2); -+ op3 = expand_normal (arg3); -+ op4 = expand_normal (arg4); -+ -+ if (!(*insn_data[icode].operand[0].predicate) (op0, SImode)) -+ { -+ error -+ ("Parameter 1 to __builtin_cop is not a valid coprocessor number."); -+ error ("Number should be between 0 and 7."); -+ return NULL_RTX; -+ } -+ -+ if (!(*insn_data[icode].operand[1].predicate) (op1, SImode)) -+ { -+ error -+ ("Parameter 2 to __builtin_cop is not a valid coprocessor register number."); -+ error ("Number should be between 0 and 15."); -+ return NULL_RTX; -+ } -+ -+ if (!(*insn_data[icode].operand[2].predicate) (op2, SImode)) -+ { -+ error -+ ("Parameter 3 to __builtin_cop is not a valid coprocessor register number."); -+ error ("Number should be between 0 and 15."); -+ return NULL_RTX; -+ } -+ -+ if (!(*insn_data[icode].operand[3].predicate) (op3, SImode)) -+ { -+ error -+ ("Parameter 4 to __builtin_cop is not a valid coprocessor register number."); -+ error ("Number should be between 0 and 15."); -+ return NULL_RTX; -+ } -+ -+ if (!(*insn_data[icode].operand[4].predicate) (op4, SImode)) -+ { -+ error -+ ("Parameter 5 to __builtin_cop is not a valid coprocessor operation."); -+ error ("Number should be between 0 and 127."); -+ return NULL_RTX; -+ } -+ -+ pat = GEN_FCN (icode) (op0, op1, op2, op3, op4); -+ if (!pat) -+ return 0; -+ emit_insn (pat); -+ -+ return target; -+ } -+ -+ case AVR32_BUILTIN_MEMS: -+ case AVR32_BUILTIN_MEMC: -+ case AVR32_BUILTIN_MEMT: -+ { -+ if (!TARGET_RMW) -+ error ("Trying to use __builtin_mem(s/c/t) when target does not support RMW insns."); -+ -+ switch (fcode) { -+ case AVR32_BUILTIN_MEMS: -+ icode = CODE_FOR_iorsi3; -+ break; -+ case AVR32_BUILTIN_MEMC: -+ icode = CODE_FOR_andsi3; -+ break; -+ case AVR32_BUILTIN_MEMT: -+ icode = CODE_FOR_xorsi3; -+ break; -+ } -+ arg0 = CALL_EXPR_ARG (exp,0); -+ arg1 = CALL_EXPR_ARG (exp,1); -+ op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0); -+ if ( GET_CODE (op0) == SYMBOL_REF ) -+ // This symbol must be RMW addressable -+ SYMBOL_REF_FLAGS (op0) |= (1 << SYMBOL_FLAG_RMW_ADDR_SHIFT); -+ op0 = gen_rtx_MEM(SImode, op0); -+ op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0); -+ mode0 = insn_data[icode].operand[1].mode; -+ -+ -+ if (!(*insn_data[icode].operand[1].predicate) (op0, mode0)) -+ { -+ error ("Parameter 1 to __builtin_mem(s/c/t) must be a Ks15<<2 address or a rmw addressable symbol."); -+ } -+ -+ if ( !CONST_INT_P (op1) -+ || INTVAL (op1) > 31 -+ || INTVAL (op1) < 0 ) -+ error ("Parameter 2 to __builtin_mem(s/c/t) must be a constant between 0 and 31."); -+ -+ if ( fcode == AVR32_BUILTIN_MEMC ) -+ op1 = GEN_INT((~(1 << INTVAL(op1)))&0xffffffff); -+ else -+ op1 = GEN_INT((1 << INTVAL(op1))&0xffffffff); -+ pat = GEN_FCN (icode) (op0, op0, op1); -+ if (!pat) -+ return 0; -+ emit_insn (pat); -+ return op0; -+ } -+ -+ case AVR32_BUILTIN_SLEEP: -+ { -+ arg0 = CALL_EXPR_ARG (exp, 0); -+ op0 = expand_normal (arg0); -+ int intval = INTVAL(op0); -+ -+ /* Check if the argument if integer and if the value of integer -+ is greater than 0. */ -+ -+ if (!CONSTANT_P (op0)) -+ error ("Parameter 1 to __builtin_sleep() is not a valid integer."); -+ if (intval < 0 ) -+ error ("Parameter 1 to __builtin_sleep() should be an integer greater than 0."); -+ -+ int strncmpval = strncmp (avr32_part_name,"uc3l", 4); -+ -+ /* Check if op0 is less than 7 for uc3l* and less than 6 for other -+ devices. By this check we are avoiding if operand is less than -+ 256. For more devices, add more such checks. */ -+ -+ if ( strncmpval == 0 && intval >= 7) -+ error ("Parameter 1 to __builtin_sleep() should be less than or equal to 7."); -+ else if ( strncmp != 0 && intval >= 6) -+ error ("Parameter 1 to __builtin_sleep() should be less than or equal to 6."); -+ -+ emit_insn (gen_sleep(op0)); -+ return target; -+ -+ } -+ case AVR32_BUILTIN_DELAY_CYCLES: -+ { -+ arg0 = CALL_EXPR_ARG (exp, 0); -+ op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0); -+ -+ if (TARGET_ARCH_AP) -+ error (" __builtin_avr32_delay_cycles() not supported for \'%s\' architecture.", avr32_arch_name); -+ if (!CONSTANT_P (op0)) -+ error ("Parameter 1 to __builtin_avr32_delay_cycles() should be an integer."); -+ emit_insn (gen_delay_cycles (op0)); -+ return 0; -+ -+ } -+ -+ } -+ -+ for (i = 0, d = bdesc_2arg; i < ARRAY_SIZE (bdesc_2arg); i++, d++) -+ if (d->code == fcode) -+ return avr32_expand_binop_builtin (d->icode, exp, target); -+ -+ -+ /* @@@ Should really do something sensible here. */ -+ return NULL_RTX; -+} -+ -+ -+/* Handle an "interrupt" or "isr" attribute; -+ arguments as in struct attribute_spec.handler. */ -+static tree -+avr32_handle_isr_attribute (tree * node, tree name, tree args, -+ int flags, bool * no_add_attrs) -+{ -+ if (DECL_P (*node)) -+ { -+ if (TREE_CODE (*node) != FUNCTION_DECL) -+ { -+ warning (OPT_Wattributes,"`%s' attribute only applies to functions", -+ IDENTIFIER_POINTER (name)); -+ *no_add_attrs = true; -+ } -+ /* FIXME: the argument if any is checked for type attributes; should it -+ be checked for decl ones? */ -+ } -+ else -+ { -+ if (TREE_CODE (*node) == FUNCTION_TYPE -+ || TREE_CODE (*node) == METHOD_TYPE) -+ { -+ if (avr32_isr_value (args) == AVR32_FT_UNKNOWN) -+ { -+ warning (OPT_Wattributes,"`%s' attribute ignored", IDENTIFIER_POINTER (name)); -+ *no_add_attrs = true; -+ } -+ } -+ else if (TREE_CODE (*node) == POINTER_TYPE -+ && (TREE_CODE (TREE_TYPE (*node)) == FUNCTION_TYPE -+ || TREE_CODE (TREE_TYPE (*node)) == METHOD_TYPE) -+ && avr32_isr_value (args) != AVR32_FT_UNKNOWN) -+ { -+ *node = build_variant_type_copy (*node); -+ TREE_TYPE (*node) = build_type_attribute_variant -+ (TREE_TYPE (*node), -+ tree_cons (name, args, TYPE_ATTRIBUTES (TREE_TYPE (*node)))); -+ *no_add_attrs = true; -+ } -+ else -+ { -+ /* Possibly pass this attribute on from the type to a decl. */ -+ if (flags & ((int) ATTR_FLAG_DECL_NEXT -+ | (int) ATTR_FLAG_FUNCTION_NEXT -+ | (int) ATTR_FLAG_ARRAY_NEXT)) -+ { -+ *no_add_attrs = true; -+ return tree_cons (name, args, NULL_TREE); -+ } -+ else -+ { -+ warning (OPT_Wattributes,"`%s' attribute ignored", IDENTIFIER_POINTER (name)); -+ } -+ } -+ } -+ -+ return NULL_TREE; -+} -+ -+ -+/* Handle an attribute requiring a FUNCTION_DECL; -+ arguments as in struct attribute_spec.handler. */ -+static tree -+avr32_handle_fndecl_attribute (tree * node, tree name, -+ tree args, -+ int flags ATTRIBUTE_UNUSED, -+ bool * no_add_attrs) -+{ -+ if (TREE_CODE (*node) != FUNCTION_DECL) -+ { -+ warning (OPT_Wattributes,"%qs attribute only applies to functions", -+ IDENTIFIER_POINTER (name)); -+ *no_add_attrs = true; -+ return NULL_TREE; -+ } -+ -+ fndecl_attribute_args = args; -+ if (args == NULL_TREE) -+ return NULL_TREE; -+ -+ tree value = TREE_VALUE (args); -+ if (TREE_CODE (value) != INTEGER_CST) -+ { -+ warning (OPT_Wattributes, -+ "argument of %qs attribute is not an integer constant", -+ IDENTIFIER_POINTER (name)); -+ *no_add_attrs = true; -+ } -+ -+ return NULL_TREE; -+} -+ -+ -+/* Handle an acall attribute; -+ arguments as in struct attribute_spec.handler. */ -+ -+static tree -+avr32_handle_acall_attribute (tree * node, tree name, -+ tree args ATTRIBUTE_UNUSED, -+ int flags ATTRIBUTE_UNUSED, bool * no_add_attrs) -+{ -+ if (TREE_CODE (*node) == FUNCTION_TYPE || TREE_CODE (*node) == METHOD_TYPE) -+ { -+ warning (OPT_Wattributes,"`%s' attribute not yet supported...", -+ IDENTIFIER_POINTER (name)); -+ *no_add_attrs = true; -+ return NULL_TREE; -+ } -+ -+ warning (OPT_Wattributes,"`%s' attribute only applies to functions", -+ IDENTIFIER_POINTER (name)); -+ *no_add_attrs = true; -+ return NULL_TREE; -+} -+ -+ -+bool -+avr32_flashvault_call(tree decl) -+{ -+ tree attributes; -+ tree fv_attribute; -+ tree vector_tree; -+ unsigned int vector; -+ -+ if (decl && TREE_CODE (decl) == FUNCTION_DECL) -+ { -+ attributes = DECL_ATTRIBUTES(decl); -+ fv_attribute = lookup_attribute ("flashvault", attributes); -+ if (fv_attribute != NULL_TREE) -+ { -+ /* Get attribute parameter, for the function vector number. */ -+ /* -+ There is probably an easier, standard way to retrieve the -+ attribute parameter which needs to be done here. -+ */ -+ vector_tree = TREE_VALUE(fv_attribute); -+ if (vector_tree != NULL_TREE) -+ { -+ vector = (unsigned int)TREE_INT_CST_LOW(TREE_VALUE(vector_tree)); -+ fprintf (asm_out_file, -+ "\tmov\tr8, lo(%i)\t# Load vector number for sscall.\n", -+ vector); -+ } -+ -+ fprintf (asm_out_file, -+ "\tsscall\t# Secure system call.\n"); -+ -+ return true; -+ } -+ } -+ -+ return false; -+} -+ -+ -+static bool has_attribute_p (tree decl, const char *name) -+{ -+ if (decl && TREE_CODE (decl) == FUNCTION_DECL) -+ { -+ return (lookup_attribute (name, DECL_ATTRIBUTES(decl)) != NULL_TREE); -+ } -+ return NULL_TREE; -+} -+ -+ -+/* Return 0 if the attributes for two types are incompatible, 1 if they -+ are compatible, and 2 if they are nearly compatible (which causes a -+ warning to be generated). */ -+static int -+avr32_comp_type_attributes (tree type1, tree type2) -+{ -+ bool acall1, acall2, isr1, isr2, naked1, naked2, fv1, fv2, fvimpl1, fvimpl2; -+ -+ /* Check for mismatch of non-default calling convention. */ -+ if (TREE_CODE (type1) != FUNCTION_TYPE) -+ return 1; -+ -+ /* Check for mismatched call attributes. */ -+ acall1 = lookup_attribute ("acall", TYPE_ATTRIBUTES (type1)) != NULL; -+ acall2 = lookup_attribute ("acall", TYPE_ATTRIBUTES (type2)) != NULL; -+ naked1 = lookup_attribute ("naked", TYPE_ATTRIBUTES (type1)) != NULL; -+ naked2 = lookup_attribute ("naked", TYPE_ATTRIBUTES (type2)) != NULL; -+ fv1 = lookup_attribute ("flashvault", TYPE_ATTRIBUTES (type1)) != NULL; -+ fv2 = lookup_attribute ("flashvault", TYPE_ATTRIBUTES (type2)) != NULL; -+ fvimpl1 = lookup_attribute ("flashvault_impl", TYPE_ATTRIBUTES (type1)) != NULL; -+ fvimpl2 = lookup_attribute ("flashvault_impl", TYPE_ATTRIBUTES (type2)) != NULL; -+ isr1 = lookup_attribute ("isr", TYPE_ATTRIBUTES (type1)) != NULL; -+ if (!isr1) -+ isr1 = lookup_attribute ("interrupt", TYPE_ATTRIBUTES (type1)) != NULL; -+ -+ isr2 = lookup_attribute ("isr", TYPE_ATTRIBUTES (type2)) != NULL; -+ if (!isr2) -+ isr2 = lookup_attribute ("interrupt", TYPE_ATTRIBUTES (type2)) != NULL; -+ -+ if ((acall1 && isr2) -+ || (acall2 && isr1) -+ || (naked1 && isr2) -+ || (naked2 && isr1) -+ || (fv1 && isr2) -+ || (fv2 && isr1) -+ || (fvimpl1 && isr2) -+ || (fvimpl2 && isr1) -+ || (fv1 && fvimpl2) -+ || (fv2 && fvimpl1) -+ ) -+ return 0; -+ -+ return 1; -+} -+ -+ -+/* Computes the type of the current function. */ -+static unsigned long -+avr32_compute_func_type (void) -+{ -+ unsigned long type = AVR32_FT_UNKNOWN; -+ tree a; -+ tree attr; -+ -+ if (TREE_CODE (current_function_decl) != FUNCTION_DECL) -+ abort (); -+ -+ /* Decide if the current function is volatile. Such functions never -+ return, and many memory cycles can be saved by not storing register -+ values that will never be needed again. This optimization was added to -+ speed up context switching in a kernel application. */ -+ if (optimize > 0 -+ && TREE_NOTHROW (current_function_decl) -+ && TREE_THIS_VOLATILE (current_function_decl)) -+ type |= AVR32_FT_VOLATILE; -+ -+ if (cfun->static_chain_decl != NULL) -+ type |= AVR32_FT_NESTED; -+ -+ attr = DECL_ATTRIBUTES (current_function_decl); -+ -+ a = lookup_attribute ("isr", attr); -+ if (a == NULL_TREE) -+ a = lookup_attribute ("interrupt", attr); -+ -+ if (a == NULL_TREE) -+ type |= AVR32_FT_NORMAL; -+ else -+ type |= avr32_isr_value (TREE_VALUE (a)); -+ -+ -+ a = lookup_attribute ("acall", attr); -+ if (a != NULL_TREE) -+ type |= AVR32_FT_ACALL; -+ -+ a = lookup_attribute ("naked", attr); -+ if (a != NULL_TREE) -+ type |= AVR32_FT_NAKED; -+ -+ a = lookup_attribute ("flashvault", attr); -+ if (a != NULL_TREE) -+ type |= AVR32_FT_FLASHVAULT; -+ -+ a = lookup_attribute ("flashvault_impl", attr); -+ if (a != NULL_TREE) -+ type |= AVR32_FT_FLASHVAULT_IMPL; -+ -+ return type; -+} -+ -+ -+/* Returns the type of the current function. */ -+static unsigned long -+avr32_current_func_type (void) -+{ -+ if (AVR32_FUNC_TYPE (cfun->machine->func_type) == AVR32_FT_UNKNOWN) -+ cfun->machine->func_type = avr32_compute_func_type (); -+ -+ return cfun->machine->func_type; -+} -+ -+ -+/* -+This target hook should return true if we should not pass type solely -+in registers. The file expr.h defines a definition that is usually appropriate, -+refer to expr.h for additional documentation. -+*/ -+bool -+avr32_must_pass_in_stack (enum machine_mode mode ATTRIBUTE_UNUSED, tree type) -+{ -+ if (type && AGGREGATE_TYPE_P (type) -+ /* If the alignment is less than the size then pass in the struct on -+ the stack. */ -+ && ((unsigned int) TYPE_ALIGN_UNIT (type) < -+ (unsigned int) int_size_in_bytes (type)) -+ /* If we support unaligned word accesses then structs of size 4 and 8 -+ can have any alignment and still be passed in registers. */ -+ && !(TARGET_UNALIGNED_WORD -+ && (int_size_in_bytes (type) == 4 -+ || int_size_in_bytes (type) == 8)) -+ /* Double word structs need only a word alignment. */ -+ && !(int_size_in_bytes (type) == 8 && TYPE_ALIGN_UNIT (type) >= 4)) -+ return true; -+ -+ if (type && AGGREGATE_TYPE_P (type) -+ /* Structs of size 3,5,6,7 are always passed in registers. */ -+ && (int_size_in_bytes (type) == 3 -+ || int_size_in_bytes (type) == 5 -+ || int_size_in_bytes (type) == 6 || int_size_in_bytes (type) == 7)) -+ return true; -+ -+ -+ return (type && TREE_ADDRESSABLE (type)); -+} -+ -+ -+bool -+avr32_strict_argument_naming (CUMULATIVE_ARGS * ca ATTRIBUTE_UNUSED) -+{ -+ return true; -+} -+ -+ -+/* -+ This target hook should return true if an argument at the position indicated -+ by cum should be passed by reference. This predicate is queried after target -+ independent reasons for being passed by reference, such as TREE_ADDRESSABLE (type). -+ -+ If the hook returns true, 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. -+*/ -+bool -+avr32_pass_by_reference (CUMULATIVE_ARGS * cum ATTRIBUTE_UNUSED, -+ enum machine_mode mode ATTRIBUTE_UNUSED, -+ tree type, bool named ATTRIBUTE_UNUSED) -+{ -+ return (type && (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)); -+} -+ -+ -+static int -+avr32_arg_partial_bytes (CUMULATIVE_ARGS * pcum ATTRIBUTE_UNUSED, -+ enum machine_mode mode ATTRIBUTE_UNUSED, -+ tree type ATTRIBUTE_UNUSED, -+ bool named ATTRIBUTE_UNUSED) -+{ -+ return 0; -+} -+ -+ -+struct gcc_target targetm = TARGET_INITIALIZER; -+ -+/* -+ Table used to convert from register number in the assembler instructions and -+ the register numbers used in gcc. -+*/ -+const int avr32_function_arg_reglist[] = { -+ INTERNAL_REGNUM (12), -+ INTERNAL_REGNUM (11), -+ INTERNAL_REGNUM (10), -+ INTERNAL_REGNUM (9), -+ INTERNAL_REGNUM (8) -+}; -+ -+ -+rtx avr32_compare_op0 = NULL_RTX; -+rtx avr32_compare_op1 = NULL_RTX; -+rtx avr32_compare_operator = NULL_RTX; -+rtx avr32_acc_cache = NULL_RTX; -+ -+ -+/* -+ Returns nonzero if it is allowed to store a value of mode mode in hard -+ register number regno. -+*/ -+int -+avr32_hard_regno_mode_ok (int regnr, enum machine_mode mode) -+{ -+ switch (mode) -+ { -+ case DImode: /* long long */ -+ case DFmode: /* double */ -+ case SCmode: /* __complex__ float */ -+ case CSImode: /* __complex__ int */ -+ if (regnr < 4) -+ { /* long long int not supported in r12, sp, lr or pc. */ -+ return 0; -+ } -+ else -+ { -+ /* long long int has to be referred in even registers. */ -+ if (regnr % 2) -+ return 0; -+ else -+ return 1; -+ } -+ case CDImode: /* __complex__ long long */ -+ case DCmode: /* __complex__ double */ -+ case TImode: /* 16 bytes */ -+ if (regnr < 7) -+ return 0; -+ else if (regnr % 2) -+ return 0; -+ else -+ return 1; -+ default: -+ return 1; -+ } -+} -+ -+ -+int -+avr32_rnd_operands (rtx add, rtx shift) -+{ -+ if (GET_CODE (shift) == CONST_INT && -+ GET_CODE (add) == CONST_INT && INTVAL (shift) > 0) -+ { -+ if ((1 << (INTVAL (shift) - 1)) == INTVAL (add)) -+ return TRUE; -+ } -+ -+ return FALSE; -+} -+ -+ -+int -+avr32_const_ok_for_constraint_p (HOST_WIDE_INT value, char c, const char *str) -+{ -+ switch (c) -+ { -+ case 'K': -+ case 'I': -+ { -+ HOST_WIDE_INT min_value = 0, max_value = 0; -+ char size_str[3]; -+ int const_size; -+ -+ size_str[0] = str[2]; -+ size_str[1] = str[3]; -+ size_str[2] = '\0'; -+ const_size = atoi (size_str); -+ -+ if (toupper (str[1]) == 'U') -+ { -+ min_value = 0; -+ max_value = (1 << const_size) - 1; -+ } -+ else if (toupper (str[1]) == 'S') -+ { -+ min_value = -(1 << (const_size - 1)); -+ max_value = (1 << (const_size - 1)) - 1; -+ } -+ -+ if (c == 'I') -+ { -+ value = -value; -+ } -+ -+ if (value >= min_value && value <= max_value) -+ { -+ return 1; -+ } -+ break; -+ } -+ case 'M': -+ return avr32_mask_upper_bits_operand (GEN_INT (value), VOIDmode); -+ case 'J': -+ return avr32_hi16_immediate_operand (GEN_INT (value), VOIDmode); -+ case 'O': -+ return one_bit_set_operand (GEN_INT (value), VOIDmode); -+ case 'N': -+ return one_bit_cleared_operand (GEN_INT (value), VOIDmode); -+ case 'L': -+ /* The lower 16-bits are set. */ -+ return ((value & 0xffff) == 0xffff) ; -+ } -+ -+ return 0; -+} -+ -+ -+/* Compute mask of registers which needs saving upon function entry. */ -+static unsigned long -+avr32_compute_save_reg_mask (int push) -+{ -+ unsigned long func_type; -+ unsigned int save_reg_mask = 0; -+ unsigned int reg; -+ -+ func_type = avr32_current_func_type (); -+ -+ if (IS_INTERRUPT (func_type)) -+ { -+ unsigned int max_reg = 12; -+ -+ /* Get the banking scheme for the interrupt */ -+ switch (func_type) -+ { -+ case AVR32_FT_ISR_FULL: -+ max_reg = 0; -+ break; -+ case AVR32_FT_ISR_HALF: -+ max_reg = 7; -+ break; -+ case AVR32_FT_ISR_NONE: -+ max_reg = 12; -+ break; -+ } -+ -+ /* Interrupt functions must not corrupt any registers, even call -+ clobbered ones. If this is a leaf function we can just examine the -+ registers used by the RTL, but otherwise we have to assume that -+ whatever function is called might clobber anything, and so we have -+ to save all the call-clobbered registers as well. */ -+ -+ /* Need not push the registers r8-r12 for AVR32A architectures, as this -+ is automatially done in hardware. We also do not have any shadow -+ registers. */ -+ if (TARGET_UARCH_AVR32A) -+ { -+ max_reg = 7; -+ func_type = AVR32_FT_ISR_NONE; -+ } -+ -+ /* All registers which are used and are not shadowed must be saved. */ -+ for (reg = 0; reg <= max_reg; reg++) -+ if (df_regs_ever_live_p (INTERNAL_REGNUM (reg)) -+ || (!current_function_is_leaf -+ && call_used_regs[INTERNAL_REGNUM (reg)])) -+ save_reg_mask |= (1 << reg); -+ -+ /* Check LR */ -+ if ((df_regs_ever_live_p (LR_REGNUM) -+ || !current_function_is_leaf || frame_pointer_needed) -+ /* Only non-shadowed register models */ -+ && (func_type == AVR32_FT_ISR_NONE)) -+ save_reg_mask |= (1 << ASM_REGNUM (LR_REGNUM)); -+ -+ /* Make sure that the GOT register is pushed. */ -+ if (max_reg >= ASM_REGNUM (PIC_OFFSET_TABLE_REGNUM) -+ && current_function_uses_pic_offset_table) -+ save_reg_mask |= (1 << ASM_REGNUM (PIC_OFFSET_TABLE_REGNUM)); -+ -+ } -+ else -+ { -+ int use_pushm = optimize_size; -+ -+ /* In the normal case we only need to save those registers which are -+ call saved and which are used by this function. */ -+ for (reg = 0; reg <= 7; reg++) -+ if (df_regs_ever_live_p (INTERNAL_REGNUM (reg)) -+ && !call_used_regs[INTERNAL_REGNUM (reg)]) -+ save_reg_mask |= (1 << reg); -+ -+ /* Make sure that the GOT register is pushed. */ -+ if (current_function_uses_pic_offset_table) -+ save_reg_mask |= (1 << ASM_REGNUM (PIC_OFFSET_TABLE_REGNUM)); -+ -+ -+ /* If we optimize for size and do not have anonymous arguments: use -+ pushm/popm always. */ -+ if (use_pushm) -+ { -+ if ((save_reg_mask & (1 << 0)) -+ || (save_reg_mask & (1 << 1)) -+ || (save_reg_mask & (1 << 2)) || (save_reg_mask & (1 << 3))) -+ save_reg_mask |= 0xf; -+ -+ if ((save_reg_mask & (1 << 4)) -+ || (save_reg_mask & (1 << 5)) -+ || (save_reg_mask & (1 << 6)) || (save_reg_mask & (1 << 7))) -+ save_reg_mask |= 0xf0; -+ -+ if ((save_reg_mask & (1 << 8)) || (save_reg_mask & (1 << 9))) -+ save_reg_mask |= 0x300; -+ } -+ -+ -+ /* Check LR */ -+ if ((df_regs_ever_live_p (LR_REGNUM) -+ || !current_function_is_leaf -+ || (optimize_size -+ && save_reg_mask -+ && !current_function_calls_eh_return) -+ || frame_pointer_needed) -+ && !IS_FLASHVAULT (func_type)) -+ { -+ if (push -+ /* Never pop LR into PC for functions which -+ calls __builtin_eh_return, since we need to -+ fix the SP after the restoring of the registers -+ and before returning. */ -+ || current_function_calls_eh_return) -+ { -+ /* Push/Pop LR */ -+ save_reg_mask |= (1 << ASM_REGNUM (LR_REGNUM)); -+ } -+ else -+ { -+ /* Pop PC */ -+ save_reg_mask |= (1 << ASM_REGNUM (PC_REGNUM)); -+ } -+ } -+ } -+ -+ -+ /* Save registers so the exception handler can modify them. */ -+ if (current_function_calls_eh_return) -+ { -+ unsigned int i; -+ -+ for (i = 0;; i++) -+ { -+ reg = EH_RETURN_DATA_REGNO (i); -+ if (reg == INVALID_REGNUM) -+ break; -+ save_reg_mask |= 1 << ASM_REGNUM (reg); -+ } -+ } -+ -+ return save_reg_mask; -+} -+ -+ -+/* Compute total size in bytes of all saved registers. */ -+static int -+avr32_get_reg_mask_size (int reg_mask) -+{ -+ int reg, size; -+ size = 0; -+ -+ for (reg = 0; reg <= 15; reg++) -+ if (reg_mask & (1 << reg)) -+ size += 4; -+ -+ return size; -+} -+ -+ -+/* Get a register from one of the registers which are saved onto the stack -+ upon function entry. */ -+static int -+avr32_get_saved_reg (int save_reg_mask) -+{ -+ unsigned int reg; -+ -+ /* Find the first register which is saved in the saved_reg_mask */ -+ for (reg = 0; reg <= 15; reg++) -+ if (save_reg_mask & (1 << reg)) -+ return reg; -+ -+ return -1; -+} -+ -+ -+/* Return 1 if it is possible to return using a single instruction. */ -+int -+avr32_use_return_insn (int iscond) -+{ -+ unsigned int func_type = avr32_current_func_type (); -+ unsigned long saved_int_regs; -+ -+ /* Never use a return instruction before reload has run. */ -+ if (!reload_completed) -+ return 0; -+ -+ /* Must adjust the stack for vararg functions. */ -+ if (current_function_args_info.uses_anonymous_args) -+ return 0; -+ -+ /* If there a stack adjstment. */ -+ if (get_frame_size ()) -+ return 0; -+ -+ saved_int_regs = avr32_compute_save_reg_mask (TRUE); -+ -+ /* Conditional returns can not be performed in one instruction if we need -+ to restore registers from the stack */ -+ if (iscond && saved_int_regs) -+ return 0; -+ -+ /* Conditional return can not be used for interrupt handlers. */ -+ if (iscond && IS_INTERRUPT (func_type)) -+ return 0; -+ -+ /* For interrupt handlers which needs to pop registers */ -+ if (saved_int_regs && IS_INTERRUPT (func_type)) -+ return 0; -+ -+ -+ /* If there are saved registers but the LR isn't saved, then we need two -+ instructions for the return. */ -+ if (saved_int_regs && !(saved_int_regs & (1 << ASM_REGNUM (LR_REGNUM)))) -+ return 0; -+ -+ -+ return 1; -+} -+ -+ -+/* Generate some function prologue info in the assembly file. */ -+void -+avr32_target_asm_function_prologue (FILE * f, HOST_WIDE_INT frame_size) -+{ -+ unsigned long func_type = avr32_current_func_type (); -+ -+ if (IS_NAKED (func_type)) -+ fprintf (f, -+ "\t# Function is naked: Prologue and epilogue provided by programmer\n"); -+ -+ if (IS_FLASHVAULT (func_type)) -+ { -+ fprintf(f, -+ "\t.ident \"flashvault\"\n\t# Function is defined with flashvault attribute.\n"); -+ } -+ -+ if (IS_FLASHVAULT_IMPL (func_type)) -+ { -+ fprintf(f, -+ "\t.ident \"flashvault\"\n\t# Function is defined with flashvault_impl attribute.\n"); -+ -+ /* Save information on flashvault function declaration. */ -+ tree fv_attribute = lookup_attribute ("flashvault_impl", DECL_ATTRIBUTES(current_function_decl)); -+ if (fv_attribute != NULL_TREE) -+ { -+ tree vector_tree = TREE_VALUE(fv_attribute); -+ if (vector_tree != NULL_TREE) -+ { -+ unsigned int vector_num; -+ const char * name; -+ -+ vector_num = (unsigned int) TREE_INT_CST_LOW (TREE_VALUE (vector_tree)); -+ -+ name = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0); -+ -+ flashvault_decl_list_add (vector_num, name); -+ } -+ } -+ } -+ -+ if (IS_INTERRUPT (func_type)) -+ { -+ switch (func_type) -+ { -+ case AVR32_FT_ISR_FULL: -+ fprintf (f, -+ "\t# Interrupt Function: Fully shadowed register file\n"); -+ break; -+ case AVR32_FT_ISR_HALF: -+ fprintf (f, -+ "\t# Interrupt Function: Half shadowed register file\n"); -+ break; -+ default: -+ case AVR32_FT_ISR_NONE: -+ fprintf (f, "\t# Interrupt Function: No shadowed register file\n"); -+ break; -+ } -+ } -+ -+ -+ fprintf (f, "\t# args = %i, frame = %li, pretend = %i\n", -+ current_function_args_size, frame_size, -+ current_function_pretend_args_size); -+ -+ fprintf (f, "\t# frame_needed = %i, leaf_function = %i\n", -+ frame_pointer_needed, current_function_is_leaf); -+ -+ fprintf (f, "\t# uses_anonymous_args = %i\n", -+ current_function_args_info.uses_anonymous_args); -+ -+ if (current_function_calls_eh_return) -+ fprintf (f, "\t# Calls __builtin_eh_return.\n"); -+ -+} -+ -+ -+/* Generate and emit an insn that we will recognize as a pushm or stm. -+ Unfortunately, since this insn does not reflect very well the actual -+ semantics of the operation, we need to annotate the insn for the benefit -+ of DWARF2 frame unwind information. */ -+ -+int avr32_convert_to_reglist16 (int reglist8_vect); -+ -+static rtx -+emit_multi_reg_push (int reglist, int usePUSHM) -+{ -+ rtx insn; -+ rtx dwarf; -+ rtx tmp; -+ rtx reg; -+ int i; -+ int nr_regs; -+ int index = 0; -+ -+ if (usePUSHM) -+ { -+ insn = emit_insn (gen_pushm (gen_rtx_CONST_INT (SImode, reglist))); -+ reglist = avr32_convert_to_reglist16 (reglist); -+ } -+ else -+ { -+ insn = emit_insn (gen_stm (stack_pointer_rtx, -+ gen_rtx_CONST_INT (SImode, reglist), -+ gen_rtx_CONST_INT (SImode, 1))); -+ } -+ -+ nr_regs = avr32_get_reg_mask_size (reglist) / 4; -+ dwarf = gen_rtx_SEQUENCE (VOIDmode, rtvec_alloc (nr_regs + 1)); -+ -+ for (i = 15; i >= 0; i--) -+ { -+ if (reglist & (1 << i)) -+ { -+ reg = gen_rtx_REG (SImode, INTERNAL_REGNUM (i)); -+ tmp = gen_rtx_SET (VOIDmode, -+ gen_rtx_MEM (SImode, -+ plus_constant (stack_pointer_rtx, -+ 4 * index)), reg); -+ RTX_FRAME_RELATED_P (tmp) = 1; -+ XVECEXP (dwarf, 0, 1 + index++) = tmp; -+ } -+ } -+ -+ tmp = gen_rtx_SET (SImode, -+ stack_pointer_rtx, -+ gen_rtx_PLUS (SImode, -+ stack_pointer_rtx, -+ GEN_INT (-4 * nr_regs))); -+ RTX_FRAME_RELATED_P (tmp) = 1; -+ XVECEXP (dwarf, 0, 0) = tmp; -+ REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, dwarf, -+ REG_NOTES (insn)); -+ return insn; -+} -+ -+rtx -+avr32_gen_load_multiple (rtx * regs, int count, rtx from, -+ int write_back, int in_struct_p, int scalar_p) -+{ -+ -+ rtx result; -+ int i = 0, j; -+ -+ result = -+ gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + (write_back ? 1 : 0))); -+ -+ if (write_back) -+ { -+ XVECEXP (result, 0, 0) -+ = gen_rtx_SET (GET_MODE (from), from, -+ plus_constant (from, count * 4)); -+ i = 1; -+ count++; -+ } -+ -+ -+ for (j = 0; i < count; i++, j++) -+ { -+ rtx unspec; -+ rtx mem = gen_rtx_MEM (SImode, plus_constant (from, j * 4)); -+ MEM_IN_STRUCT_P (mem) = in_struct_p; -+ MEM_SCALAR_P (mem) = scalar_p; -+ unspec = gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, mem), UNSPEC_LDM); -+ XVECEXP (result, 0, i) = gen_rtx_SET (VOIDmode, regs[j], unspec); -+ } -+ -+ return result; -+} -+ -+ -+rtx -+avr32_gen_store_multiple (rtx * regs, int count, rtx to, -+ int in_struct_p, int scalar_p) -+{ -+ rtx result; -+ int i = 0, j; -+ -+ result = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count)); -+ -+ for (j = 0; i < count; i++, j++) -+ { -+ rtx mem = gen_rtx_MEM (SImode, plus_constant (to, j * 4)); -+ MEM_IN_STRUCT_P (mem) = in_struct_p; -+ MEM_SCALAR_P (mem) = scalar_p; -+ XVECEXP (result, 0, i) -+ = gen_rtx_SET (VOIDmode, mem, -+ gen_rtx_UNSPEC (VOIDmode, -+ gen_rtvec (1, regs[j]), -+ UNSPEC_STORE_MULTIPLE)); -+ } -+ -+ return result; -+} -+ -+ -+/* Move a block of memory if it is word aligned or we support unaligned -+ word memory accesses. The size must be maximum 64 bytes. */ -+int -+avr32_gen_movmemsi (rtx * operands) -+{ -+ HOST_WIDE_INT bytes_to_go; -+ rtx src, dst; -+ rtx st_src, st_dst; -+ int src_offset = 0, dst_offset = 0; -+ int block_size; -+ int dst_in_struct_p, src_in_struct_p; -+ int dst_scalar_p, src_scalar_p; -+ int unaligned; -+ -+ if (GET_CODE (operands[2]) != CONST_INT -+ || GET_CODE (operands[3]) != CONST_INT -+ || INTVAL (operands[2]) > 64 -+ || ((INTVAL (operands[3]) & 3) && !TARGET_UNALIGNED_WORD)) -+ return 0; -+ -+ unaligned = (INTVAL (operands[3]) & 3) != 0; -+ -+ block_size = 4; -+ -+ st_dst = XEXP (operands[0], 0); -+ st_src = XEXP (operands[1], 0); -+ -+ dst_in_struct_p = MEM_IN_STRUCT_P (operands[0]); -+ dst_scalar_p = MEM_SCALAR_P (operands[0]); -+ src_in_struct_p = MEM_IN_STRUCT_P (operands[1]); -+ src_scalar_p = MEM_SCALAR_P (operands[1]); -+ -+ dst = copy_to_mode_reg (SImode, st_dst); -+ src = copy_to_mode_reg (SImode, st_src); -+ -+ bytes_to_go = INTVAL (operands[2]); -+ -+ while (bytes_to_go) -+ { -+ enum machine_mode move_mode; -+ /* (Seems to be a problem with reloads for the movti pattern so this is -+ disabled until that problem is resolved) -+ UPDATE: Problem seems to be solved now.... */ -+ if (bytes_to_go >= GET_MODE_SIZE (TImode) && !unaligned -+ /* Do not emit ldm/stm for UC3 as ld.d/st.d is more optimal. */ -+ && !TARGET_ARCH_UC) -+ move_mode = TImode; -+ else if ((bytes_to_go >= GET_MODE_SIZE (DImode)) && !unaligned) -+ move_mode = DImode; -+ else if (bytes_to_go >= GET_MODE_SIZE (SImode)) -+ move_mode = SImode; -+ else -+ move_mode = QImode; -+ -+ { -+ rtx src_mem; -+ rtx dst_mem = gen_rtx_MEM (move_mode, -+ gen_rtx_PLUS (SImode, dst, -+ GEN_INT (dst_offset))); -+ dst_offset += GET_MODE_SIZE (move_mode); -+ if ( 0 /* This causes an error in GCC. Think there is -+ something wrong in the gcse pass which causes REQ_EQUIV notes -+ to be wrong so disabling it for now. */ -+ && move_mode == TImode -+ && INTVAL (operands[2]) > GET_MODE_SIZE (TImode) ) -+ { -+ src_mem = gen_rtx_MEM (move_mode, -+ gen_rtx_POST_INC (SImode, src)); -+ } -+ else -+ { -+ src_mem = gen_rtx_MEM (move_mode, -+ gen_rtx_PLUS (SImode, src, -+ GEN_INT (src_offset))); -+ src_offset += GET_MODE_SIZE (move_mode); -+ } -+ -+ bytes_to_go -= GET_MODE_SIZE (move_mode); -+ -+ MEM_IN_STRUCT_P (dst_mem) = dst_in_struct_p; -+ MEM_SCALAR_P (dst_mem) = dst_scalar_p; -+ -+ MEM_IN_STRUCT_P (src_mem) = src_in_struct_p; -+ MEM_SCALAR_P (src_mem) = src_scalar_p; -+ emit_move_insn (dst_mem, src_mem); -+ -+ } -+ } -+ -+ return 1; -+} -+ -+ -+/* Expand the prologue instruction. */ -+void -+avr32_expand_prologue (void) -+{ -+ rtx insn, dwarf; -+ unsigned long saved_reg_mask; -+ int reglist8 = 0; -+ -+ /* Naked functions do not have a prologue. */ -+ if (IS_NAKED (avr32_current_func_type ())) -+ return; -+ -+ saved_reg_mask = avr32_compute_save_reg_mask (TRUE); -+ -+ if (saved_reg_mask) -+ { -+ /* Must push used registers. */ -+ -+ /* Should we use POPM or LDM? */ -+ int usePUSHM = TRUE; -+ reglist8 = 0; -+ if (((saved_reg_mask & (1 << 0)) || -+ (saved_reg_mask & (1 << 1)) || -+ (saved_reg_mask & (1 << 2)) || (saved_reg_mask & (1 << 3)))) -+ { -+ /* One of R0-R3 should at least be pushed. */ -+ if (((saved_reg_mask & (1 << 0)) && -+ (saved_reg_mask & (1 << 1)) && -+ (saved_reg_mask & (1 << 2)) && (saved_reg_mask & (1 << 3)))) -+ { -+ /* All should be pushed. */ -+ reglist8 |= 0x01; -+ } -+ else -+ { -+ usePUSHM = FALSE; -+ } -+ } -+ -+ if (((saved_reg_mask & (1 << 4)) || -+ (saved_reg_mask & (1 << 5)) || -+ (saved_reg_mask & (1 << 6)) || (saved_reg_mask & (1 << 7)))) -+ { -+ /* One of R4-R7 should at least be pushed */ -+ if (((saved_reg_mask & (1 << 4)) && -+ (saved_reg_mask & (1 << 5)) && -+ (saved_reg_mask & (1 << 6)) && (saved_reg_mask & (1 << 7)))) -+ { -+ if (usePUSHM) -+ /* All should be pushed */ -+ reglist8 |= 0x02; -+ } -+ else -+ { -+ usePUSHM = FALSE; -+ } -+ } -+ -+ if (((saved_reg_mask & (1 << 8)) || (saved_reg_mask & (1 << 9)))) -+ { -+ /* One of R8-R9 should at least be pushed. */ -+ if (((saved_reg_mask & (1 << 8)) && (saved_reg_mask & (1 << 9)))) -+ { -+ if (usePUSHM) -+ /* All should be pushed. */ -+ reglist8 |= 0x04; -+ } -+ else -+ { -+ usePUSHM = FALSE; -+ } -+ } -+ -+ if (saved_reg_mask & (1 << 10)) -+ reglist8 |= 0x08; -+ -+ if (saved_reg_mask & (1 << 11)) -+ reglist8 |= 0x10; -+ -+ if (saved_reg_mask & (1 << 12)) -+ reglist8 |= 0x20; -+ -+ if ((saved_reg_mask & (1 << ASM_REGNUM (LR_REGNUM))) -+ && !IS_FLASHVAULT (avr32_current_func_type ())) -+ { -+ /* Push LR */ -+ reglist8 |= 0x40; -+ } -+ -+ if (usePUSHM) -+ { -+ insn = emit_multi_reg_push (reglist8, TRUE); -+ } -+ else -+ { -+ insn = emit_multi_reg_push (saved_reg_mask, FALSE); -+ } -+ RTX_FRAME_RELATED_P (insn) = 1; -+ -+ /* Prevent this instruction from being scheduled after any other -+ instructions. */ -+ emit_insn (gen_blockage ()); -+ } -+ -+ /* Set frame pointer */ -+ if (frame_pointer_needed) -+ { -+ insn = emit_move_insn (frame_pointer_rtx, stack_pointer_rtx); -+ RTX_FRAME_RELATED_P (insn) = 1; -+ } -+ -+ if (get_frame_size () > 0) -+ { -+ if (avr32_const_ok_for_constraint_p (get_frame_size (), 'K', "Ks21")) -+ { -+ insn = emit_insn (gen_rtx_SET (SImode, -+ stack_pointer_rtx, -+ gen_rtx_PLUS (SImode, -+ stack_pointer_rtx, -+ gen_rtx_CONST_INT -+ (SImode, -+ -get_frame_size -+ ())))); -+ RTX_FRAME_RELATED_P (insn) = 1; -+ } -+ else -+ { -+ /* Immediate is larger than k21 We must either check if we can use -+ one of the pushed reegisters as temporary storage or we must -+ make us a temp register by pushing a register to the stack. */ -+ rtx temp_reg, const_pool_entry, insn; -+ if (saved_reg_mask) -+ { -+ temp_reg = -+ gen_rtx_REG (SImode, -+ INTERNAL_REGNUM (avr32_get_saved_reg -+ (saved_reg_mask))); -+ } -+ else -+ { -+ temp_reg = gen_rtx_REG (SImode, INTERNAL_REGNUM (7)); -+ emit_move_insn (gen_rtx_MEM -+ (SImode, -+ gen_rtx_PRE_DEC (SImode, stack_pointer_rtx)), -+ temp_reg); -+ } -+ -+ const_pool_entry = -+ force_const_mem (SImode, -+ gen_rtx_CONST_INT (SImode, get_frame_size ())); -+ emit_move_insn (temp_reg, const_pool_entry); -+ -+ insn = emit_insn (gen_rtx_SET (SImode, -+ stack_pointer_rtx, -+ gen_rtx_MINUS (SImode, -+ stack_pointer_rtx, -+ temp_reg))); -+ -+ dwarf = gen_rtx_SET (VOIDmode, stack_pointer_rtx, -+ gen_rtx_PLUS (SImode, stack_pointer_rtx, -+ GEN_INT (-get_frame_size ()))); -+ REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, -+ dwarf, REG_NOTES (insn)); -+ RTX_FRAME_RELATED_P (insn) = 1; -+ -+ if (!saved_reg_mask) -+ { -+ insn = -+ emit_move_insn (temp_reg, -+ gen_rtx_MEM (SImode, -+ gen_rtx_POST_INC (SImode, -+ gen_rtx_REG -+ (SImode, -+ 13)))); -+ } -+ -+ /* Mark the temp register as dead */ -+ REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_DEAD, temp_reg, -+ REG_NOTES (insn)); -+ -+ -+ } -+ -+ /* Prevent the the stack adjustment to be scheduled after any -+ instructions using the frame pointer. */ -+ emit_insn (gen_blockage ()); -+ } -+ -+ /* Load GOT */ -+ if (flag_pic) -+ { -+ avr32_load_pic_register (); -+ -+ /* gcc does not know that load or call instructions might use the pic -+ register so it might schedule these instructions before the loading -+ of the pic register. To avoid this emit a barrier for now. TODO! -+ Find out a better way to let gcc know which instructions might use -+ the pic register. */ -+ emit_insn (gen_blockage ()); -+ } -+ return; -+} -+ -+ -+void -+avr32_set_return_address (rtx source, rtx scratch) -+{ -+ rtx addr; -+ unsigned long saved_regs; -+ -+ saved_regs = avr32_compute_save_reg_mask (TRUE); -+ -+ if (!(saved_regs & (1 << ASM_REGNUM (LR_REGNUM)))) -+ emit_move_insn (gen_rtx_REG (Pmode, LR_REGNUM), source); -+ else -+ { -+ if (frame_pointer_needed) -+ addr = gen_rtx_REG (Pmode, FRAME_POINTER_REGNUM); -+ else -+ if (avr32_const_ok_for_constraint_p (get_frame_size (), 'K', "Ks16")) -+ { -+ addr = plus_constant (stack_pointer_rtx, get_frame_size ()); -+ } -+ else -+ { -+ emit_insn (gen_movsi (scratch, GEN_INT (get_frame_size ()))); -+ addr = scratch; -+ } -+ emit_move_insn (gen_rtx_MEM (Pmode, addr), source); -+ } -+} -+ -+ -+/* Return the length of INSN. LENGTH is the initial length computed by -+ attributes in the machine-description file. */ -+int -+avr32_adjust_insn_length (rtx insn ATTRIBUTE_UNUSED, -+ int length ATTRIBUTE_UNUSED) -+{ -+ return length; -+} -+ -+ -+void -+avr32_output_return_instruction (int single_ret_inst ATTRIBUTE_UNUSED, -+ int iscond ATTRIBUTE_UNUSED, -+ rtx cond ATTRIBUTE_UNUSED, rtx r12_imm) -+{ -+ -+ unsigned long saved_reg_mask; -+ int insert_ret = TRUE; -+ int reglist8 = 0; -+ int stack_adjustment = get_frame_size (); -+ unsigned int func_type = avr32_current_func_type (); -+ FILE *f = asm_out_file; -+ -+ /* Naked functions does not have an epilogue */ -+ if (IS_NAKED (func_type)) -+ return; -+ -+ saved_reg_mask = avr32_compute_save_reg_mask (FALSE); -+ -+ /* Reset frame pointer */ -+ if (stack_adjustment > 0) -+ { -+ if (avr32_const_ok_for_constraint_p (stack_adjustment, 'I', "Is21")) -+ { -+ fprintf (f, "\tsub\tsp, %i # Reset Frame Pointer\n", -+ -stack_adjustment); -+ } -+ else -+ { -+ /* TODO! Is it safe to use r8 as scratch?? */ -+ fprintf (f, "\tmov\tr8, lo(%i) # Reset Frame Pointer\n", -+ -stack_adjustment); -+ fprintf (f, "\torh\tr8, hi(%i) # Reset Frame Pointer\n", -+ -stack_adjustment); -+ fprintf (f, "\tadd\tsp, r8 # Reset Frame Pointer\n"); -+ } -+ } -+ -+ if (saved_reg_mask) -+ { -+ /* Must pop used registers */ -+ -+ /* Should we use POPM or LDM? */ -+ int usePOPM = TRUE; -+ if (((saved_reg_mask & (1 << 0)) || -+ (saved_reg_mask & (1 << 1)) || -+ (saved_reg_mask & (1 << 2)) || (saved_reg_mask & (1 << 3)))) -+ { -+ /* One of R0-R3 should at least be popped */ -+ if (((saved_reg_mask & (1 << 0)) && -+ (saved_reg_mask & (1 << 1)) && -+ (saved_reg_mask & (1 << 2)) && (saved_reg_mask & (1 << 3)))) -+ { -+ /* All should be popped */ -+ reglist8 |= 0x01; -+ } -+ else -+ { -+ usePOPM = FALSE; -+ } -+ } -+ -+ if (((saved_reg_mask & (1 << 4)) || -+ (saved_reg_mask & (1 << 5)) || -+ (saved_reg_mask & (1 << 6)) || (saved_reg_mask & (1 << 7)))) -+ { -+ /* One of R0-R3 should at least be popped */ -+ if (((saved_reg_mask & (1 << 4)) && -+ (saved_reg_mask & (1 << 5)) && -+ (saved_reg_mask & (1 << 6)) && (saved_reg_mask & (1 << 7)))) -+ { -+ if (usePOPM) -+ /* All should be popped */ -+ reglist8 |= 0x02; -+ } -+ else -+ { -+ usePOPM = FALSE; -+ } -+ } -+ -+ if (((saved_reg_mask & (1 << 8)) || (saved_reg_mask & (1 << 9)))) -+ { -+ /* One of R8-R9 should at least be pushed */ -+ if (((saved_reg_mask & (1 << 8)) && (saved_reg_mask & (1 << 9)))) -+ { -+ if (usePOPM) -+ /* All should be pushed */ -+ reglist8 |= 0x04; -+ } -+ else -+ { -+ usePOPM = FALSE; -+ } -+ } -+ -+ if (saved_reg_mask & (1 << 10)) -+ reglist8 |= 0x08; -+ -+ if (saved_reg_mask & (1 << 11)) -+ reglist8 |= 0x10; -+ -+ if (saved_reg_mask & (1 << 12)) -+ reglist8 |= 0x20; -+ -+ if (saved_reg_mask & (1 << ASM_REGNUM (LR_REGNUM))) -+ /* Pop LR */ -+ reglist8 |= 0x40; -+ -+ if ((saved_reg_mask & (1 << ASM_REGNUM (PC_REGNUM))) -+ && !IS_FLASHVAULT_IMPL (func_type)) -+ /* Pop LR into PC. */ -+ reglist8 |= 0x80; -+ -+ if (usePOPM) -+ { -+ char reglist[64]; /* 64 bytes should be enough... */ -+ avr32_make_reglist8 (reglist8, (char *) reglist); -+ -+ if (reglist8 & 0x80) -+ /* This instruction is also a return */ -+ insert_ret = FALSE; -+ -+ if (r12_imm && !insert_ret) -+ fprintf (f, "\tpopm\t%s, r12=%li\n", reglist, INTVAL (r12_imm)); -+ else -+ fprintf (f, "\tpopm\t%s\n", reglist); -+ -+ } -+ else -+ { -+ char reglist[64]; /* 64 bytes should be enough... */ -+ avr32_make_reglist16 (saved_reg_mask, (char *) reglist); -+ if (saved_reg_mask & (1 << ASM_REGNUM (PC_REGNUM))) -+ /* This instruction is also a return */ -+ insert_ret = FALSE; -+ -+ if (r12_imm && !insert_ret) -+ fprintf (f, "\tldm\tsp++, %s, r12=%li\n", reglist, -+ INTVAL (r12_imm)); -+ else -+ fprintf (f, "\tldm\tsp++, %s\n", reglist); -+ -+ } -+ -+ } -+ -+ /* Stack adjustment for exception handler. */ -+ if (current_function_calls_eh_return) -+ fprintf (f, "\tadd\tsp, r%d\n", ASM_REGNUM (EH_RETURN_STACKADJ_REGNO)); -+ -+ -+ if (IS_INTERRUPT (func_type)) -+ { -+ fprintf (f, "\trete\n"); -+ } -+ else if (IS_FLASHVAULT (func_type)) -+ { -+ /* Normal return from Secure System call, increment SS_RAR before -+ returning. Use R8 as scratch. */ -+ fprintf (f, -+ "\t# Normal return from sscall.\n" -+ "\t# Increment SS_RAR before returning.\n" -+ "\t# Use R8 as scratch.\n" -+ "\tmfsr\tr8, 440\n" -+ "\tsub\tr8, -2\n" -+ "\tmtsr\t440, r8\n" -+ "\tretss\n"); -+ } -+ else if (insert_ret) -+ { -+ if (r12_imm) -+ fprintf (f, "\tretal\t%li\n", INTVAL (r12_imm)); -+ else -+ fprintf (f, "\tretal\tr12\n"); -+ } -+} -+ -+void -+avr32_make_reglist16 (int reglist16_vect, char *reglist16_string) -+{ -+ int i; -+ bool first_reg = true; -+ /* Make sure reglist16_string is empty. */ -+ reglist16_string[0] = '\0'; -+ -+ for (i = 0; i < 16; ++i) -+ { -+ if (reglist16_vect & (1 << i)) -+ { -+ first_reg == true ? first_reg = false : strcat(reglist16_string,", "); -+ strcat (reglist16_string, reg_names[INTERNAL_REGNUM (i)]); -+ } -+ } -+} -+ -+int -+avr32_convert_to_reglist16 (int reglist8_vect) -+{ -+ int reglist16_vect = 0; -+ if (reglist8_vect & 0x1) -+ reglist16_vect |= 0xF; -+ if (reglist8_vect & 0x2) -+ reglist16_vect |= 0xF0; -+ if (reglist8_vect & 0x4) -+ reglist16_vect |= 0x300; -+ if (reglist8_vect & 0x8) -+ reglist16_vect |= 0x400; -+ if (reglist8_vect & 0x10) -+ reglist16_vect |= 0x800; -+ if (reglist8_vect & 0x20) -+ reglist16_vect |= 0x1000; -+ if (reglist8_vect & 0x40) -+ reglist16_vect |= 0x4000; -+ if (reglist8_vect & 0x80) -+ reglist16_vect |= 0x8000; -+ -+ return reglist16_vect; -+} -+ -+void -+avr32_make_reglist8 (int reglist8_vect, char *reglist8_string) -+{ -+ /* Make sure reglist8_string is empty. */ -+ reglist8_string[0] = '\0'; -+ -+ if (reglist8_vect & 0x1) -+ strcpy (reglist8_string, "r0-r3"); -+ if (reglist8_vect & 0x2) -+ strlen (reglist8_string) ? strcat (reglist8_string, ", r4-r7") : -+ strcpy (reglist8_string, "r4-r7"); -+ if (reglist8_vect & 0x4) -+ strlen (reglist8_string) ? strcat (reglist8_string, ", r8-r9") : -+ strcpy (reglist8_string, "r8-r9"); -+ if (reglist8_vect & 0x8) -+ strlen (reglist8_string) ? strcat (reglist8_string, ", r10") : -+ strcpy (reglist8_string, "r10"); -+ if (reglist8_vect & 0x10) -+ strlen (reglist8_string) ? strcat (reglist8_string, ", r11") : -+ strcpy (reglist8_string, "r11"); -+ if (reglist8_vect & 0x20) -+ strlen (reglist8_string) ? strcat (reglist8_string, ", r12") : -+ strcpy (reglist8_string, "r12"); -+ if (reglist8_vect & 0x40) -+ strlen (reglist8_string) ? strcat (reglist8_string, ", lr") : -+ strcpy (reglist8_string, "lr"); -+ if (reglist8_vect & 0x80) -+ strlen (reglist8_string) ? strcat (reglist8_string, ", pc") : -+ strcpy (reglist8_string, "pc"); -+} -+ -+ -+int -+avr32_eh_return_data_regno (int n) -+{ -+ if (n >= 0 && n <= 3) -+ return 8 + n; -+ else -+ return INVALID_REGNUM; -+} -+ -+ -+/* Compute the distance from register FROM to register TO. -+ These can be the arg pointer, the frame pointer or -+ the stack pointer. -+ Typical stack layout looks like this: -+ -+ old stack pointer -> | | -+ ---- -+ | | \ -+ | | saved arguments for -+ | | vararg functions -+ arg_pointer -> | | / -+ -- -+ | | \ -+ | | call saved -+ | | registers -+ | | / -+ frame ptr -> -- -+ | | \ -+ | | local -+ | | variables -+ stack ptr --> | | / -+ -- -+ | | \ -+ | | outgoing -+ | | arguments -+ | | / -+ -- -+ -+ For a given funciton some or all of these stack compomnents -+ may not be needed, giving rise to the possibility of -+ eliminating some of the registers. -+ -+ The values returned by this function must reflect the behaviour -+ of avr32_expand_prologue() and avr32_compute_save_reg_mask(). -+ -+ The sign of the number returned reflects the direction of stack -+ growth, so the values are positive for all eliminations except -+ from the soft frame pointer to the hard frame pointer. */ -+int -+avr32_initial_elimination_offset (int from, int to) -+{ -+ int i; -+ int call_saved_regs = 0; -+ unsigned long saved_reg_mask; -+ unsigned int local_vars = get_frame_size (); -+ -+ saved_reg_mask = avr32_compute_save_reg_mask (TRUE); -+ -+ for (i = 0; i < 16; ++i) -+ { -+ if (saved_reg_mask & (1 << i)) -+ call_saved_regs += 4; -+ } -+ -+ switch (from) -+ { -+ case ARG_POINTER_REGNUM: -+ switch (to) -+ { -+ case STACK_POINTER_REGNUM: -+ return call_saved_regs + local_vars; -+ case FRAME_POINTER_REGNUM: -+ return call_saved_regs; -+ default: -+ abort (); -+ } -+ case FRAME_POINTER_REGNUM: -+ switch (to) -+ { -+ case STACK_POINTER_REGNUM: -+ return local_vars; -+ default: -+ abort (); -+ } -+ default: -+ abort (); -+ } -+} -+ -+ -+/* -+ Returns a rtx used when passing the next argument to a function. -+ avr32_init_cumulative_args() and avr32_function_arg_advance() sets which -+ register to use. -+*/ -+rtx -+avr32_function_arg (CUMULATIVE_ARGS * cum, enum machine_mode mode, -+ tree type, int named) -+{ -+ int index = -1; -+ //unsigned long func_type = avr32_current_func_type (); -+ //int last_reg_index = (IS_FLASHVAULT(func_type) || IS_FLASHVAULT_IMPL(func_type) || cum->flashvault_func ? LAST_CUM_REG_INDEX - 1 : LAST_CUM_REG_INDEX); -+ int last_reg_index = (cum->flashvault_func ? LAST_CUM_REG_INDEX - 1 : LAST_CUM_REG_INDEX); -+ -+ HOST_WIDE_INT arg_size, arg_rsize; -+ if (type) -+ { -+ arg_size = int_size_in_bytes (type); -+ } -+ else -+ { -+ arg_size = GET_MODE_SIZE (mode); -+ } -+ arg_rsize = PUSH_ROUNDING (arg_size); -+ -+ /* -+ The last time this macro is called, it is called with mode == VOIDmode, -+ and its result is passed to the call or call_value pattern as operands 2 -+ and 3 respectively. */ -+ if (mode == VOIDmode) -+ { -+ return gen_rtx_CONST_INT (SImode, 22); /* ToDo: fixme. */ -+ } -+ -+ if ((*targetm.calls.must_pass_in_stack) (mode, type) || !named) -+ { -+ return NULL_RTX; -+ } -+ -+ if (arg_rsize == 8) -+ { -+ /* use r11:r10 or r9:r8. */ -+ if (!(GET_USED_INDEX (cum, 1) || GET_USED_INDEX (cum, 2))) -+ index = 1; -+ else if ((last_reg_index == 4) && -+ !(GET_USED_INDEX (cum, 3) || GET_USED_INDEX (cum, 4))) -+ index = 3; -+ else -+ index = -1; -+ } -+ else if (arg_rsize == 4) -+ { /* Use first available register */ -+ index = 0; -+ while (index <= last_reg_index && GET_USED_INDEX (cum, index)) -+ index++; -+ if (index > last_reg_index) -+ index = -1; -+ } -+ -+ SET_REG_INDEX (cum, index); -+ -+ if (GET_REG_INDEX (cum) >= 0) -+ return gen_rtx_REG (mode, avr32_function_arg_reglist[GET_REG_INDEX (cum)]); -+ -+ return NULL_RTX; -+} -+ -+ -+/* Set the register used for passing the first argument to a function. */ -+void -+avr32_init_cumulative_args (CUMULATIVE_ARGS * cum, -+ tree fntype ATTRIBUTE_UNUSED, -+ rtx libname ATTRIBUTE_UNUSED, -+ tree fndecl) -+{ -+ /* Set all registers as unused. */ -+ SET_INDEXES_UNUSED (cum); -+ -+ /* Reset uses_anonymous_args */ -+ cum->uses_anonymous_args = 0; -+ -+ /* Reset size of stack pushed arguments */ -+ cum->stack_pushed_args_size = 0; -+ -+ cum->flashvault_func = (fndecl && (has_attribute_p (fndecl,"flashvault") || has_attribute_p (fndecl,"flashvault_impl"))); -+} -+ -+ -+/* -+ Set register used for passing the next argument to a function. Only the -+ Scratch Registers are used. -+ -+ number name -+ 15 r15 PC -+ 14 r14 LR -+ 13 r13 _SP_________ -+ FIRST_CUM_REG 12 r12 _||_ -+ 10 r11 || -+ 11 r10 _||_ Scratch Registers -+ 8 r9 || -+ LAST_SCRATCH_REG 9 r8 _\/_________ -+ 6 r7 /\ -+ 7 r6 || -+ 4 r5 || -+ 5 r4 || -+ 2 r3 || -+ 3 r2 || -+ 0 r1 || -+ 1 r0 _||_________ -+ -+*/ -+void -+avr32_function_arg_advance (CUMULATIVE_ARGS * cum, enum machine_mode mode, -+ tree type, int named ATTRIBUTE_UNUSED) -+{ -+ HOST_WIDE_INT arg_size, arg_rsize; -+ -+ if (type) -+ { -+ arg_size = int_size_in_bytes (type); -+ } -+ else -+ { -+ arg_size = GET_MODE_SIZE (mode); -+ } -+ arg_rsize = PUSH_ROUNDING (arg_size); -+ -+ /* If the argument had to be passed in stack, no register is used. */ -+ if ((*targetm.calls.must_pass_in_stack) (mode, type)) -+ { -+ cum->stack_pushed_args_size += PUSH_ROUNDING (int_size_in_bytes (type)); -+ return; -+ } -+ -+ /* Mark the used registers as "used". */ -+ if (GET_REG_INDEX (cum) >= 0) -+ { -+ SET_USED_INDEX (cum, GET_REG_INDEX (cum)); -+ if (arg_rsize == 8) -+ { -+ SET_USED_INDEX (cum, (GET_REG_INDEX (cum) + 1)); -+ } -+ } -+ else -+ { -+ /* Had to use stack */ -+ cum->stack_pushed_args_size += arg_rsize; -+ } -+} -+ -+ -+/* -+ Defines witch direction to go to find the next register to use if the -+ argument is larger then one register or for arguments shorter than an -+ int which is not promoted, such as the last part of structures with -+ size not a multiple of 4. */ -+enum direction -+avr32_function_arg_padding (enum machine_mode mode ATTRIBUTE_UNUSED, -+ tree type) -+{ -+ /* Pad upward for all aggregates except byte and halfword sized aggregates -+ which can be passed in registers. */ -+ if (type -+ && AGGREGATE_TYPE_P (type) -+ && (int_size_in_bytes (type) != 1) -+ && !((int_size_in_bytes (type) == 2) -+ && TYPE_ALIGN_UNIT (type) >= 2) -+ && (int_size_in_bytes (type) & 0x3)) -+ { -+ return upward; -+ } -+ -+ return downward; -+} -+ -+ -+/* Return a rtx used for the return value from a function call. */ -+rtx -+avr32_function_value (tree type, tree func, bool outgoing ATTRIBUTE_UNUSED) -+{ -+ if (avr32_return_in_memory (type, func)) -+ return NULL_RTX; -+ -+ if (int_size_in_bytes (type) <= 4) -+ { -+ enum machine_mode mode = TYPE_MODE (type); -+ int unsignedp = 0; -+ PROMOTE_FUNCTION_MODE (mode, unsignedp, type); -+ return gen_rtx_REG (mode, RET_REGISTER); -+ } -+ else if (int_size_in_bytes (type) <= 8) -+ return gen_rtx_REG (TYPE_MODE (type), INTERNAL_REGNUM (11)); -+ -+ return NULL_RTX; -+} -+ -+ -+/* Return a rtx used for the return value from a library function call. */ -+rtx -+avr32_libcall_value (enum machine_mode mode) -+{ -+ -+ if (GET_MODE_SIZE (mode) <= 4) -+ return gen_rtx_REG (mode, RET_REGISTER); -+ else if (GET_MODE_SIZE (mode) <= 8) -+ return gen_rtx_REG (mode, INTERNAL_REGNUM (11)); -+ else -+ return NULL_RTX; -+} -+ -+ -+/* Return TRUE if X references a SYMBOL_REF. */ -+int -+symbol_mentioned_p (rtx x) -+{ -+ const char *fmt; -+ int i; -+ -+ if (GET_CODE (x) == SYMBOL_REF) -+ return 1; -+ -+ fmt = GET_RTX_FORMAT (GET_CODE (x)); -+ -+ for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--) -+ { -+ if (fmt[i] == 'E') -+ { -+ int j; -+ -+ for (j = XVECLEN (x, i) - 1; j >= 0; j--) -+ if (symbol_mentioned_p (XVECEXP (x, i, j))) -+ return 1; -+ } -+ else if (fmt[i] == 'e' && symbol_mentioned_p (XEXP (x, i))) -+ return 1; -+ } -+ -+ return 0; -+} -+ -+ -+/* Return TRUE if X references a LABEL_REF. */ -+int -+label_mentioned_p (rtx x) -+{ -+ const char *fmt; -+ int i; -+ -+ if (GET_CODE (x) == LABEL_REF) -+ return 1; -+ -+ fmt = GET_RTX_FORMAT (GET_CODE (x)); -+ for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--) -+ { -+ if (fmt[i] == 'E') -+ { -+ int j; -+ -+ for (j = XVECLEN (x, i) - 1; j >= 0; j--) -+ if (label_mentioned_p (XVECEXP (x, i, j))) -+ return 1; -+ } -+ else if (fmt[i] == 'e' && label_mentioned_p (XEXP (x, i))) -+ return 1; -+ } -+ -+ return 0; -+} -+ -+ -+/* Return TRUE if X contains a MEM expression. */ -+int -+mem_mentioned_p (rtx x) -+{ -+ const char *fmt; -+ int i; -+ -+ if (MEM_P (x)) -+ return 1; -+ -+ fmt = GET_RTX_FORMAT (GET_CODE (x)); -+ for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--) -+ { -+ if (fmt[i] == 'E') -+ { -+ int j; -+ -+ for (j = XVECLEN (x, i) - 1; j >= 0; j--) -+ if (mem_mentioned_p (XVECEXP (x, i, j))) -+ return 1; -+ } -+ else if (fmt[i] == 'e' && mem_mentioned_p (XEXP (x, i))) -+ return 1; -+ } -+ -+ return 0; -+} -+ -+ -+int -+avr32_legitimate_pic_operand_p (rtx x) -+{ -+ -+ /* We can't have const, this must be broken down to a symbol. */ -+ if (GET_CODE (x) == CONST) -+ return FALSE; -+ -+ /* Can't access symbols or labels via the constant pool either */ -+ if ((GET_CODE (x) == SYMBOL_REF -+ && CONSTANT_POOL_ADDRESS_P (x) -+ && (symbol_mentioned_p (get_pool_constant (x)) -+ || label_mentioned_p (get_pool_constant (x))))) -+ return FALSE; -+ -+ return TRUE; -+} -+ -+ -+rtx -+legitimize_pic_address (rtx orig, enum machine_mode mode ATTRIBUTE_UNUSED, -+ rtx reg) -+{ -+ -+ if (GET_CODE (orig) == SYMBOL_REF || GET_CODE (orig) == LABEL_REF) -+ { -+ int subregs = 0; -+ -+ if (reg == 0) -+ { -+ if (!can_create_pseudo_p ()) -+ abort (); -+ else -+ reg = gen_reg_rtx (Pmode); -+ -+ subregs = 1; -+ } -+ -+ emit_move_insn (reg, orig); -+ -+ /* Only set current function as using pic offset table if flag_pic is -+ set. This is because this function is also used if -+ TARGET_HAS_ASM_ADDR_PSEUDOS is set. */ -+ if (flag_pic) -+ current_function_uses_pic_offset_table = 1; -+ -+ /* Put a REG_EQUAL note on this insn, so that it can be optimized by -+ loop. */ -+ return reg; -+ } -+ else if (GET_CODE (orig) == CONST) -+ { -+ rtx base, offset; -+ -+ if (flag_pic -+ && GET_CODE (XEXP (orig, 0)) == PLUS -+ && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx) -+ return orig; -+ -+ if (reg == 0) -+ { -+ if (!can_create_pseudo_p ()) -+ abort (); -+ else -+ reg = gen_reg_rtx (Pmode); -+ } -+ -+ if (GET_CODE (XEXP (orig, 0)) == PLUS) -+ { -+ base = -+ legitimize_pic_address (XEXP (XEXP (orig, 0), 0), Pmode, reg); -+ offset = -+ legitimize_pic_address (XEXP (XEXP (orig, 0), 1), Pmode, -+ base == reg ? 0 : reg); -+ } -+ else -+ abort (); -+ -+ if (GET_CODE (offset) == CONST_INT) -+ { -+ /* The base register doesn't really matter, we only want to test -+ the index for the appropriate mode. */ -+ if (!avr32_const_ok_for_constraint_p (INTVAL (offset), 'I', "Is21")) -+ { -+ if (can_create_pseudo_p ()) -+ offset = force_reg (Pmode, offset); -+ else -+ abort (); -+ } -+ -+ if (GET_CODE (offset) == CONST_INT) -+ return plus_constant (base, INTVAL (offset)); -+ } -+ -+ return gen_rtx_PLUS (Pmode, base, offset); -+ } -+ -+ return orig; -+} -+ -+ -+/* Generate code to load the PIC register. */ -+void -+avr32_load_pic_register (void) -+{ -+ rtx l1, pic_tmp; -+ rtx global_offset_table; -+ -+ if ((current_function_uses_pic_offset_table == 0) || TARGET_NO_INIT_GOT) -+ return; -+ -+ if (!flag_pic) -+ abort (); -+ -+ l1 = gen_label_rtx (); -+ -+ global_offset_table = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_"); -+ pic_tmp = -+ gen_rtx_CONST (Pmode, -+ gen_rtx_MINUS (SImode, gen_rtx_LABEL_REF (Pmode, l1), -+ global_offset_table)); -+ emit_insn (gen_pic_load_addr -+ (pic_offset_table_rtx, force_const_mem (SImode, pic_tmp))); -+ emit_insn (gen_pic_compute_got_from_pc (pic_offset_table_rtx, l1)); -+ -+ /* Need to emit this whether or not we obey regdecls, since setjmp/longjmp -+ can cause life info to screw up. */ -+ emit_insn (gen_rtx_USE (VOIDmode, pic_offset_table_rtx)); -+} -+ -+ -+/* This hook should return true if values of type type are returned at the most -+ significant end of a register (in other words, if they are padded at the -+ least significant end). You can assume that type is returned in a register; -+ the caller is required to check this. Note that the register provided by -+ FUNCTION_VALUE must be able to hold the complete return value. For example, -+ if a 1-, 2- or 3-byte structure is returned at the most significant end of a -+ 4-byte register, FUNCTION_VALUE should provide an SImode rtx. */ -+bool -+avr32_return_in_msb (tree type ATTRIBUTE_UNUSED) -+{ -+ /* if ( AGGREGATE_TYPE_P (type) ) if ((int_size_in_bytes(type) == 1) || -+ ((int_size_in_bytes(type) == 2) && TYPE_ALIGN_UNIT(type) >= 2)) return -+ false; else return true; */ -+ -+ return false; -+} -+ -+ -+/* -+ Returns one if a certain function value is going to be returned in memory -+ and zero if it is going to be returned in a register. -+ -+ BLKmode and all other modes that is larger than 64 bits are returned in -+ memory. -+*/ -+bool -+avr32_return_in_memory (tree type, tree fntype ATTRIBUTE_UNUSED) -+{ -+ if (TYPE_MODE (type) == VOIDmode) -+ return false; -+ -+ if (int_size_in_bytes (type) > (2 * UNITS_PER_WORD) -+ || int_size_in_bytes (type) == -1) -+ { -+ return true; -+ } -+ -+ /* If we have an aggregate then use the same mechanism as when checking if -+ it should be passed on the stack. */ -+ if (type -+ && AGGREGATE_TYPE_P (type) -+ && (*targetm.calls.must_pass_in_stack) (TYPE_MODE (type), type)) -+ return true; -+ -+ return false; -+} -+ -+ -+/* Output the constant part of the trampoline. -+ lddpc r0, pc[0x8:e] ; load static chain register -+ lddpc pc, pc[0x8:e] ; jump to subrutine -+ .long 0 ; Address to static chain, -+ ; filled in by avr32_initialize_trampoline() -+ .long 0 ; Address to subrutine, -+ ; filled in by avr32_initialize_trampoline() -+*/ -+void -+avr32_trampoline_template (FILE * file) -+{ -+ fprintf (file, "\tlddpc r0, pc[8]\n"); -+ fprintf (file, "\tlddpc pc, pc[8]\n"); -+ /* make room for the address of the static chain. */ -+ fprintf (file, "\t.long\t0\n"); -+ /* make room for the address to the subrutine. */ -+ fprintf (file, "\t.long\t0\n"); -+} -+ -+ -+/* Initialize the variable parts of a trampoline. */ -+void -+avr32_initialize_trampoline (rtx addr, rtx fnaddr, rtx static_chain) -+{ -+ /* Store the address to the static chain. */ -+ emit_move_insn (gen_rtx_MEM -+ (SImode, plus_constant (addr, TRAMPOLINE_SIZE - 4)), -+ static_chain); -+ -+ /* Store the address to the function. */ -+ emit_move_insn (gen_rtx_MEM (SImode, plus_constant (addr, TRAMPOLINE_SIZE)), -+ fnaddr); -+ -+ emit_insn (gen_cache (gen_rtx_REG (SImode, 13), -+ gen_rtx_CONST_INT (SImode, -+ AVR32_CACHE_INVALIDATE_ICACHE))); -+} -+ -+ -+/* Return nonzero if X is valid as an addressing register. */ -+int -+avr32_address_register_rtx_p (rtx x, int strict_p) -+{ -+ int regno; -+ -+ if (!register_operand(x, GET_MODE(x))) -+ return 0; -+ -+ /* If strict we require the register to be a hard register. */ -+ if (strict_p -+ && !REG_P(x)) -+ return 0; -+ -+ regno = REGNO (x); -+ -+ if (strict_p) -+ return REGNO_OK_FOR_BASE_P (regno); -+ -+ return (regno <= LAST_REGNUM || regno >= FIRST_PSEUDO_REGISTER); -+} -+ -+ -+/* Return nonzero if INDEX is valid for an address index operand. */ -+int -+avr32_legitimate_index_p (enum machine_mode mode, rtx index, int strict_p) -+{ -+ enum rtx_code code = GET_CODE (index); -+ -+ if (GET_MODE_SIZE (mode) > 8) -+ return 0; -+ -+ /* Standard coprocessor addressing modes. */ -+ if (code == CONST_INT) -+ { -+ return CONST_OK_FOR_CONSTRAINT_P (INTVAL (index), 'K', "Ks16"); -+ } -+ -+ if (avr32_address_register_rtx_p (index, strict_p)) -+ return 1; -+ -+ if (code == MULT) -+ { -+ rtx xiop0 = XEXP (index, 0); -+ rtx xiop1 = XEXP (index, 1); -+ return ((avr32_address_register_rtx_p (xiop0, strict_p) -+ && power_of_two_operand (xiop1, SImode) -+ && (INTVAL (xiop1) <= 8)) -+ || (avr32_address_register_rtx_p (xiop1, strict_p) -+ && power_of_two_operand (xiop0, SImode) -+ && (INTVAL (xiop0) <= 8))); -+ } -+ else if (code == ASHIFT) -+ { -+ rtx op = XEXP (index, 1); -+ -+ return (avr32_address_register_rtx_p (XEXP (index, 0), strict_p) -+ && GET_CODE (op) == CONST_INT -+ && INTVAL (op) > 0 && INTVAL (op) <= 3); -+ } -+ -+ return 0; -+} -+ -+ -+/* -+ Used in the GO_IF_LEGITIMATE_ADDRESS macro. Returns a nonzero value if -+ the RTX x is a legitimate memory address. -+ -+ Returns NO_REGS if the address is not legatime, GENERAL_REGS or ALL_REGS -+ if it is. -+*/ -+ -+ -+/* Forward declaration */ -+int is_minipool_label (rtx label); -+ -+int -+avr32_legitimate_address (enum machine_mode mode, rtx x, int strict) -+{ -+ -+ switch (GET_CODE (x)) -+ { -+ case REG: -+ return avr32_address_register_rtx_p (x, strict); -+ case CONST_INT: -+ return ((mode==SImode) && TARGET_RMW_ADDRESSABLE_DATA -+ && CONST_OK_FOR_CONSTRAINT_P(INTVAL(x), 'K', "Ks17")); -+ case CONST: -+ { -+ rtx label = avr32_find_symbol (x); -+ if (label -+ && -+ (/* -+ If we enable (const (plus (symbol_ref ...))) type constant -+ pool entries we must add support for it in the predicates and -+ in the minipool generation in avr32_reorg(). -+ (CONSTANT_POOL_ADDRESS_P (label) -+ && !(flag_pic -+ && (symbol_mentioned_p (get_pool_constant (label)) -+ || label_mentioned_p (get_pool_constant (label))))) -+ ||*/ -+ ((GET_CODE (label) == LABEL_REF) -+ && GET_CODE (XEXP (label, 0)) == CODE_LABEL -+ && is_minipool_label (XEXP (label, 0))) -+ /*|| ((GET_CODE (label) == SYMBOL_REF) -+ && mode == SImode -+ && SYMBOL_REF_RMW_ADDR(label))*/)) -+ { -+ return TRUE; -+ } -+ } -+ break; -+ case LABEL_REF: -+ if (GET_CODE (XEXP (x, 0)) == CODE_LABEL -+ && is_minipool_label (XEXP (x, 0))) -+ { -+ return TRUE; -+ } -+ break; -+ case SYMBOL_REF: -+ { -+ if (CONSTANT_POOL_ADDRESS_P (x) -+ && !(flag_pic -+ && (symbol_mentioned_p (get_pool_constant (x)) -+ || label_mentioned_p (get_pool_constant (x))))) -+ return TRUE; -+ else if (SYMBOL_REF_RCALL_FUNCTION_P (x) -+ || (mode == SImode -+ && SYMBOL_REF_RMW_ADDR (x))) -+ return TRUE; -+ break; -+ } -+ case PRE_DEC: /* (pre_dec (...)) */ -+ case POST_INC: /* (post_inc (...)) */ -+ return avr32_address_register_rtx_p (XEXP (x, 0), strict); -+ case PLUS: /* (plus (...) (...)) */ -+ { -+ rtx xop0 = XEXP (x, 0); -+ rtx xop1 = XEXP (x, 1); -+ -+ return ((avr32_address_register_rtx_p (xop0, strict) -+ && avr32_legitimate_index_p (mode, xop1, strict)) -+ || (avr32_address_register_rtx_p (xop1, strict) -+ && avr32_legitimate_index_p (mode, xop0, strict))); -+ } -+ default: -+ break; -+ } -+ -+ return FALSE; -+} -+ -+ -+int -+avr32_const_ok_for_move (HOST_WIDE_INT c) -+{ -+ if ( TARGET_V2_INSNS ) -+ return ( avr32_const_ok_for_constraint_p (c, 'K', "Ks21") -+ /* movh instruction */ -+ || avr32_hi16_immediate_operand (GEN_INT(c), VOIDmode) ); -+ else -+ return avr32_const_ok_for_constraint_p (c, 'K', "Ks21"); -+} -+ -+ -+int -+avr32_const_double_immediate (rtx value) -+{ -+ HOST_WIDE_INT hi, lo; -+ -+ if (GET_CODE (value) != CONST_DOUBLE) -+ return FALSE; -+ -+ if (SCALAR_FLOAT_MODE_P (GET_MODE (value))) -+ { -+ HOST_WIDE_INT target_float[2]; -+ hi = lo = 0; -+ real_to_target (target_float, CONST_DOUBLE_REAL_VALUE (value), -+ GET_MODE (value)); -+ lo = target_float[0]; -+ hi = target_float[1]; -+ } -+ else -+ { -+ hi = CONST_DOUBLE_HIGH (value); -+ lo = CONST_DOUBLE_LOW (value); -+ } -+ -+ if (avr32_const_ok_for_constraint_p (lo, 'K', "Ks21") -+ && (GET_MODE (value) == SFmode -+ || avr32_const_ok_for_constraint_p (hi, 'K', "Ks21"))) -+ { -+ return TRUE; -+ } -+ -+ return FALSE; -+} -+ -+ -+int -+avr32_legitimate_constant_p (rtx x) -+{ -+ switch (GET_CODE (x)) -+ { -+ case CONST_INT: -+ /* Check if we should put large immediate into constant pool -+ or load them directly with mov/orh.*/ -+ if (!avr32_imm_in_const_pool) -+ return 1; -+ -+ return avr32_const_ok_for_move (INTVAL (x)); -+ case CONST_DOUBLE: -+ /* Check if we should put large immediate into constant pool -+ or load them directly with mov/orh.*/ -+ if (!avr32_imm_in_const_pool) -+ return 1; -+ -+ if (GET_MODE (x) == SFmode -+ || GET_MODE (x) == DFmode || GET_MODE (x) == DImode) -+ return avr32_const_double_immediate (x); -+ else -+ return 0; -+ case LABEL_REF: -+ case SYMBOL_REF: -+ return avr32_find_symbol (x) && (flag_pic || TARGET_HAS_ASM_ADDR_PSEUDOS); -+ case CONST: -+ case HIGH: -+ case CONST_VECTOR: -+ return 0; -+ default: -+ printf ("%s():\n", __FUNCTION__); -+ debug_rtx (x); -+ return 1; -+ } -+} -+ -+ -+/* Strip any special encoding from labels */ -+const char * -+avr32_strip_name_encoding (const char *name) -+{ -+ const char *stripped = name; -+ -+ while (1) -+ { -+ switch (stripped[0]) -+ { -+ case '#': -+ stripped = strchr (name + 1, '#') + 1; -+ break; -+ case '*': -+ stripped = &stripped[1]; -+ break; -+ default: -+ return stripped; -+ } -+ } -+} -+ -+ -+ -+/* Do anything needed before RTL is emitted for each function. */ -+static struct machine_function * -+avr32_init_machine_status (void) -+{ -+ struct machine_function *machine; -+ machine = -+ (machine_function *) ggc_alloc_cleared (sizeof (machine_function)); -+ -+#if AVR32_FT_UNKNOWN != 0 -+ machine->func_type = AVR32_FT_UNKNOWN; -+#endif -+ -+ machine->minipool_label_head = 0; -+ machine->minipool_label_tail = 0; -+ machine->ifcvt_after_reload = 0; -+ return machine; -+} -+ -+ -+void -+avr32_init_expanders (void) -+{ -+ /* Arrange to initialize and mark the machine per-function status. */ -+ init_machine_status = avr32_init_machine_status; -+} -+ -+ -+/* Return an RTX indicating where the return address to the -+ calling function can be found. */ -+rtx -+avr32_return_addr (int count, rtx frame ATTRIBUTE_UNUSED) -+{ -+ if (count != 0) -+ return NULL_RTX; -+ -+ return get_hard_reg_initial_val (Pmode, LR_REGNUM); -+} -+ -+ -+void -+avr32_encode_section_info (tree decl, rtx rtl, int first) -+{ -+ default_encode_section_info(decl, rtl, first); -+ -+ if ( TREE_CODE (decl) == VAR_DECL -+ && (GET_CODE (XEXP (rtl, 0)) == SYMBOL_REF) -+ && (lookup_attribute ("rmw_addressable", DECL_ATTRIBUTES (decl)) -+ || TARGET_RMW_ADDRESSABLE_DATA) ){ -+ if ( !TARGET_RMW || flag_pic ) -+ return; -+ // { -+ // warning ("Using RMW addressable data with an arch that does not support RMW instructions."); -+ // return; -+ // } -+ // -+ //if ( flag_pic ) -+ // { -+ // warning ("Using RMW addressable data with together with -fpic switch. Can not use RMW instruction when compiling with -fpic."); -+ // return; -+ // } -+ SYMBOL_REF_FLAGS (XEXP (rtl, 0)) |= (1 << SYMBOL_FLAG_RMW_ADDR_SHIFT); -+ } -+} -+ -+ -+void -+avr32_asm_output_label (FILE * stream, const char *name) -+{ -+ name = avr32_strip_name_encoding (name); -+ -+ /* Print the label. */ -+ assemble_name (stream, name); -+ fprintf (stream, ":\n"); -+} -+ -+ -+void -+avr32_asm_weaken_label (FILE * stream, const char *name) -+{ -+ fprintf (stream, "\t.weak "); -+ assemble_name (stream, name); -+ fprintf (stream, "\n"); -+} -+ -+ -+/* -+ Checks if a labelref is equal to a reserved word in the assembler. If it is, -+ insert a '_' before the label name. -+*/ -+void -+avr32_asm_output_labelref (FILE * stream, const char *name) -+{ -+ int verbatim = FALSE; -+ const char *stripped = name; -+ int strip_finished = FALSE; -+ -+ while (!strip_finished) -+ { -+ switch (stripped[0]) -+ { -+ case '#': -+ stripped = strchr (name + 1, '#') + 1; -+ break; -+ case '*': -+ stripped = &stripped[1]; -+ verbatim = TRUE; -+ break; -+ default: -+ strip_finished = TRUE; -+ break; -+ } -+ } -+ -+ if (verbatim) -+ fputs (stripped, stream); -+ else -+ asm_fprintf (stream, "%U%s", stripped); -+} -+ -+ -+/* -+ Check if the comparison in compare_exp is redundant -+ for the condition given in next_cond given that the -+ needed flags are already set by an earlier instruction. -+ Uses cc_prev_status to check this. -+ -+ Returns NULL_RTX if the compare is not redundant -+ or the new condition to use in the conditional -+ instruction if the compare is redundant. -+*/ -+static rtx -+is_compare_redundant (rtx compare_exp, rtx next_cond) -+{ -+ int z_flag_valid = FALSE; -+ int n_flag_valid = FALSE; -+ rtx new_cond; -+ -+ if (GET_CODE (compare_exp) != COMPARE -+ && GET_CODE (compare_exp) != AND) -+ return NULL_RTX; -+ -+ -+ if (rtx_equal_p (cc_prev_status.mdep.value, compare_exp)) -+ { -+ /* cc0 already contains the correct comparison -> delete cmp insn */ -+ return next_cond; -+ } -+ -+ if (GET_MODE (compare_exp) != SImode) -+ return NULL_RTX; -+ -+ switch (cc_prev_status.mdep.flags) -+ { -+ case CC_SET_VNCZ: -+ case CC_SET_NCZ: -+ n_flag_valid = TRUE; -+ case CC_SET_CZ: -+ case CC_SET_Z: -+ z_flag_valid = TRUE; -+ } -+ -+ if (cc_prev_status.mdep.value -+ && GET_CODE (compare_exp) == COMPARE -+ && REG_P (XEXP (compare_exp, 0)) -+ && REGNO (XEXP (compare_exp, 0)) == REGNO (cc_prev_status.mdep.value) -+ && GET_CODE (XEXP (compare_exp, 1)) == CONST_INT -+ && next_cond != NULL_RTX) -+ { -+ if (INTVAL (XEXP (compare_exp, 1)) == 0 -+ && z_flag_valid -+ && (GET_CODE (next_cond) == EQ || GET_CODE (next_cond) == NE)) -+ /* We can skip comparison Z flag is already reflecting ops[0] */ -+ return next_cond; -+ else if (n_flag_valid -+ && ((INTVAL (XEXP (compare_exp, 1)) == 0 -+ && (GET_CODE (next_cond) == GE -+ || GET_CODE (next_cond) == LT)) -+ || (INTVAL (XEXP (compare_exp, 1)) == -1 -+ && (GET_CODE (next_cond) == GT -+ || GET_CODE (next_cond) == LE)))) -+ { -+ /* We can skip comparison N flag is already reflecting ops[0], -+ which means that we can use the mi/pl conditions to check if -+ ops[0] is GE or LT 0. */ -+ if ((GET_CODE (next_cond) == GE) || (GET_CODE (next_cond) == GT)) -+ new_cond = -+ gen_rtx_UNSPEC (GET_MODE (next_cond), gen_rtvec (2, cc0_rtx, const0_rtx), -+ UNSPEC_COND_PL); -+ else -+ new_cond = -+ gen_rtx_UNSPEC (GET_MODE (next_cond), gen_rtvec (2, cc0_rtx, const0_rtx), -+ UNSPEC_COND_MI); -+ return new_cond; -+ } -+ } -+ return NULL_RTX; -+} -+ -+ -+/* Updates cc_status. */ -+void -+avr32_notice_update_cc (rtx exp, rtx insn) -+{ -+ enum attr_cc attr_cc = get_attr_cc (insn); -+ -+ if ( attr_cc == CC_SET_Z_IF_NOT_V2 ) -+ { -+ if (TARGET_V2_INSNS) -+ attr_cc = CC_NONE; -+ else -+ attr_cc = CC_SET_Z; -+ } -+ -+ switch (attr_cc) -+ { -+ case CC_CALL_SET: -+ CC_STATUS_INIT; -+ /* Check if the function call returns a value in r12 */ -+ if (REG_P (recog_data.operand[0]) -+ && REGNO (recog_data.operand[0]) == RETVAL_REGNUM) -+ { -+ cc_status.flags = 0; -+ cc_status.mdep.value = -+ gen_rtx_COMPARE (SImode, recog_data.operand[0], const0_rtx); -+ cc_status.mdep.flags = CC_SET_VNCZ; -+ cc_status.mdep.cond_exec_cmp_clobbered = 0; -+ -+ } -+ break; -+ case CC_COMPARE: -+ { -+ /* Check that compare will not be optimized away if so nothing should -+ be done */ -+ rtx compare_exp = SET_SRC (exp); -+ /* Check if we have a tst expression. If so convert it to a -+ compare with 0. */ -+ if ( REG_P (SET_SRC (exp)) ) -+ compare_exp = gen_rtx_COMPARE (GET_MODE (SET_SRC (exp)), -+ SET_SRC (exp), -+ const0_rtx); -+ -+ if (!next_insn_emits_cmp (insn) -+ && (is_compare_redundant (compare_exp, get_next_insn_cond (insn)) == NULL_RTX)) -+ { -+ -+ /* Reset the nonstandard flag */ -+ CC_STATUS_INIT; -+ cc_status.flags = 0; -+ cc_status.mdep.value = compare_exp; -+ cc_status.mdep.flags = CC_SET_VNCZ; -+ cc_status.mdep.cond_exec_cmp_clobbered = 0; -+ } -+ } -+ break; -+ case CC_CMP_COND_INSN: -+ { -+ /* Conditional insn that emit the compare itself. */ -+ rtx cmp; -+ rtx cmp_op0, cmp_op1; -+ rtx cond; -+ rtx dest; -+ rtx next_insn = next_nonnote_insn (insn); -+ -+ if ( GET_CODE (exp) == COND_EXEC ) -+ { -+ cmp_op0 = XEXP (COND_EXEC_TEST (exp), 0); -+ cmp_op1 = XEXP (COND_EXEC_TEST (exp), 1); -+ cond = COND_EXEC_TEST (exp); -+ dest = SET_DEST (COND_EXEC_CODE (exp)); -+ } -+ else -+ { -+ /* If then else conditional. compare operands are in operands -+ 4 and 5. */ -+ cmp_op0 = recog_data.operand[4]; -+ cmp_op1 = recog_data.operand[5]; -+ cond = recog_data.operand[1]; -+ dest = SET_DEST (exp); -+ } -+ -+ if ( GET_CODE (cmp_op0) == AND ) -+ cmp = cmp_op0; -+ else -+ cmp = gen_rtx_COMPARE (GET_MODE (cmp_op0), -+ cmp_op0, -+ cmp_op1); -+ -+ /* Check if the conditional insns updates a register present -+ in the comparison, if so then we must reset the cc_status. */ -+ if (REG_P (dest) -+ && (reg_mentioned_p (dest, cmp_op0) -+ || reg_mentioned_p (dest, cmp_op1)) -+ && GET_CODE (exp) != COND_EXEC ) -+ { -+ CC_STATUS_INIT; -+ } -+ else if (is_compare_redundant (cmp, cond) == NULL_RTX) -+ { -+ /* Reset the nonstandard flag */ -+ CC_STATUS_INIT; -+ if ( GET_CODE (cmp_op0) == AND ) -+ { -+ cc_status.flags = CC_INVERTED; -+ cc_status.mdep.flags = CC_SET_Z; -+ } -+ else -+ { -+ cc_status.flags = 0; -+ cc_status.mdep.flags = CC_SET_VNCZ; -+ } -+ cc_status.mdep.value = cmp; -+ cc_status.mdep.cond_exec_cmp_clobbered = 0; -+ } -+ -+ -+ /* Check if we have a COND_EXEC insn which updates one -+ of the registers in the compare status. */ -+ if (REG_P (dest) -+ && (reg_mentioned_p (dest, cmp_op0) -+ || reg_mentioned_p (dest, cmp_op1)) -+ && GET_CODE (exp) == COND_EXEC ) -+ cc_status.mdep.cond_exec_cmp_clobbered = 1; -+ -+ if ( cc_status.mdep.cond_exec_cmp_clobbered -+ && GET_CODE (exp) == COND_EXEC -+ && next_insn != NULL -+ && INSN_P (next_insn) -+ && !(GET_CODE (PATTERN (next_insn)) == COND_EXEC -+ && rtx_equal_p (XEXP (COND_EXEC_TEST (PATTERN (next_insn)), 0), cmp_op0) -+ && rtx_equal_p (XEXP (COND_EXEC_TEST (PATTERN (next_insn)), 1), cmp_op1) -+ && (GET_CODE (COND_EXEC_TEST (PATTERN (next_insn))) == GET_CODE (cond) -+ || GET_CODE (COND_EXEC_TEST (PATTERN (next_insn))) == reverse_condition (GET_CODE (cond)))) ) -+ { -+ /* We have a sequence of conditional insns where the compare status has been clobbered -+ since the compare no longer reflects the content of the values to compare. */ -+ CC_STATUS_INIT; -+ cc_status.mdep.cond_exec_cmp_clobbered = 1; -+ } -+ -+ } -+ break; -+ case CC_BLD: -+ /* Bit load is kind of like an inverted testsi, because the Z flag is -+ inverted */ -+ CC_STATUS_INIT; -+ cc_status.flags = CC_INVERTED; -+ cc_status.mdep.value = SET_SRC (exp); -+ cc_status.mdep.flags = CC_SET_Z; -+ cc_status.mdep.cond_exec_cmp_clobbered = 0; -+ break; -+ case CC_NONE: -+ /* Insn does not affect CC at all. Check if the instruction updates -+ some of the register currently reflected in cc0 */ -+ -+ if ((GET_CODE (exp) == SET) -+ && (cc_status.value1 || cc_status.value2 || cc_status.mdep.value) -+ && (reg_mentioned_p (SET_DEST (exp), cc_status.value1) -+ || reg_mentioned_p (SET_DEST (exp), cc_status.value2) -+ || reg_mentioned_p (SET_DEST (exp), cc_status.mdep.value))) -+ { -+ CC_STATUS_INIT; -+ } -+ -+ /* If this is a parallel we must step through each of the parallel -+ expressions */ -+ if (GET_CODE (exp) == PARALLEL) -+ { -+ int i; -+ for (i = 0; i < XVECLEN (exp, 0); ++i) -+ { -+ rtx vec_exp = XVECEXP (exp, 0, i); -+ if ((GET_CODE (vec_exp) == SET) -+ && (cc_status.value1 || cc_status.value2 -+ || cc_status.mdep.value) -+ && (reg_mentioned_p (SET_DEST (vec_exp), cc_status.value1) -+ || reg_mentioned_p (SET_DEST (vec_exp), -+ cc_status.value2) -+ || reg_mentioned_p (SET_DEST (vec_exp), -+ cc_status.mdep.value))) -+ { -+ CC_STATUS_INIT; -+ } -+ } -+ } -+ -+ /* Check if we have memory opartions with post_inc or pre_dec on the -+ register currently reflected in cc0 */ -+ if (GET_CODE (exp) == SET -+ && GET_CODE (SET_SRC (exp)) == MEM -+ && (GET_CODE (XEXP (SET_SRC (exp), 0)) == POST_INC -+ || GET_CODE (XEXP (SET_SRC (exp), 0)) == PRE_DEC) -+ && -+ (reg_mentioned_p -+ (XEXP (XEXP (SET_SRC (exp), 0), 0), cc_status.value1) -+ || reg_mentioned_p (XEXP (XEXP (SET_SRC (exp), 0), 0), -+ cc_status.value2) -+ || reg_mentioned_p (XEXP (XEXP (SET_SRC (exp), 0), 0), -+ cc_status.mdep.value))) -+ CC_STATUS_INIT; -+ -+ if (GET_CODE (exp) == SET -+ && GET_CODE (SET_DEST (exp)) == MEM -+ && (GET_CODE (XEXP (SET_DEST (exp), 0)) == POST_INC -+ || GET_CODE (XEXP (SET_DEST (exp), 0)) == PRE_DEC) -+ && -+ (reg_mentioned_p -+ (XEXP (XEXP (SET_DEST (exp), 0), 0), cc_status.value1) -+ || reg_mentioned_p (XEXP (XEXP (SET_DEST (exp), 0), 0), -+ cc_status.value2) -+ || reg_mentioned_p (XEXP (XEXP (SET_DEST (exp), 0), 0), -+ cc_status.mdep.value))) -+ CC_STATUS_INIT; -+ break; -+ -+ case CC_SET_VNCZ: -+ CC_STATUS_INIT; -+ cc_status.mdep.value = recog_data.operand[0]; -+ cc_status.mdep.flags = CC_SET_VNCZ; -+ cc_status.mdep.cond_exec_cmp_clobbered = 0; -+ break; -+ -+ case CC_SET_NCZ: -+ CC_STATUS_INIT; -+ cc_status.mdep.value = recog_data.operand[0]; -+ cc_status.mdep.flags = CC_SET_NCZ; -+ cc_status.mdep.cond_exec_cmp_clobbered = 0; -+ break; -+ -+ case CC_SET_CZ: -+ CC_STATUS_INIT; -+ cc_status.mdep.value = recog_data.operand[0]; -+ cc_status.mdep.flags = CC_SET_CZ; -+ cc_status.mdep.cond_exec_cmp_clobbered = 0; -+ break; -+ -+ case CC_SET_Z: -+ CC_STATUS_INIT; -+ cc_status.mdep.value = recog_data.operand[0]; -+ cc_status.mdep.flags = CC_SET_Z; -+ cc_status.mdep.cond_exec_cmp_clobbered = 0; -+ break; -+ -+ case CC_CLOBBER: -+ CC_STATUS_INIT; -+ break; -+ -+ default: -+ CC_STATUS_INIT; -+ } -+} -+ -+ -+/* -+ Outputs to stdio stream stream the assembler syntax for an instruction -+ operand x. x is an RTL expression. -+*/ -+void -+avr32_print_operand (FILE * stream, rtx x, int code) -+{ -+ int error = 0; -+ -+ if ( code == '?' ) -+ { -+ /* Predicable instruction, print condition code */ -+ -+ /* If the insn should not be conditional then do nothing. */ -+ if ( current_insn_predicate == NULL_RTX ) -+ return; -+ -+ /* Set x to the predicate to force printing -+ the condition later on. */ -+ x = current_insn_predicate; -+ -+ /* Reverse condition if useing bld insn. */ -+ if ( GET_CODE (XEXP(current_insn_predicate,0)) == AND ) -+ x = reversed_condition (current_insn_predicate); -+ } -+ else if ( code == '!' ) -+ { -+ /* Output compare for conditional insn if needed. */ -+ rtx new_cond; -+ gcc_assert ( current_insn_predicate != NULL_RTX ); -+ new_cond = avr32_output_cmp(current_insn_predicate, -+ GET_MODE(XEXP(current_insn_predicate,0)), -+ XEXP(current_insn_predicate,0), -+ XEXP(current_insn_predicate,1)); -+ -+ /* Check if the new condition is a special avr32 condition -+ specified using UNSPECs. If so we must handle it differently. */ -+ if ( GET_CODE (new_cond) == UNSPEC ) -+ { -+ current_insn_predicate = -+ gen_rtx_UNSPEC (CCmode, -+ gen_rtvec (2, -+ XEXP(current_insn_predicate,0), -+ XEXP(current_insn_predicate,1)), -+ XINT (new_cond, 1)); -+ } -+ else -+ { -+ PUT_CODE(current_insn_predicate, GET_CODE(new_cond)); -+ } -+ return; -+ } -+ -+ switch (GET_CODE (x)) -+ { -+ case UNSPEC: -+ switch (XINT (x, 1)) -+ { -+ case UNSPEC_COND_PL: -+ if (code == 'i') -+ fputs ("mi", stream); -+ else -+ fputs ("pl", stream); -+ break; -+ case UNSPEC_COND_MI: -+ if (code == 'i') -+ fputs ("pl", stream); -+ else -+ fputs ("mi", stream); -+ break; -+ default: -+ error = 1; -+ } -+ break; -+ case EQ: -+ if (code == 'i') -+ fputs ("ne", stream); -+ else -+ fputs ("eq", stream); -+ break; -+ case NE: -+ if (code == 'i') -+ fputs ("eq", stream); -+ else -+ fputs ("ne", stream); -+ break; -+ case GT: -+ if (code == 'i') -+ fputs ("le", stream); -+ else -+ fputs ("gt", stream); -+ break; -+ case GTU: -+ if (code == 'i') -+ fputs ("ls", stream); -+ else -+ fputs ("hi", stream); -+ break; -+ case LT: -+ if (code == 'i') -+ fputs ("ge", stream); -+ else -+ fputs ("lt", stream); -+ break; -+ case LTU: -+ if (code == 'i') -+ fputs ("hs", stream); -+ else -+ fputs ("lo", stream); -+ break; -+ case GE: -+ if (code == 'i') -+ fputs ("lt", stream); -+ else -+ fputs ("ge", stream); -+ break; -+ case GEU: -+ if (code == 'i') -+ fputs ("lo", stream); -+ else -+ fputs ("hs", stream); -+ break; -+ case LE: -+ if (code == 'i') -+ fputs ("gt", stream); -+ else -+ fputs ("le", stream); -+ break; -+ case LEU: -+ if (code == 'i') -+ fputs ("hi", stream); -+ else -+ fputs ("ls", stream); -+ break; -+ case CONST_INT: -+ { -+ HOST_WIDE_INT value = INTVAL (x); -+ -+ switch (code) -+ { -+ case 'm': -+ if ( HOST_BITS_PER_WIDE_INT > BITS_PER_WORD ) -+ { -+ /* A const_int can be used to represent DImode constants. */ -+ value >>= BITS_PER_WORD; -+ } -+ /* We might get a const_int immediate for setting a DI register, -+ we then must then return the correct sign extended DI. The most -+ significant word is just a sign extension. */ -+ else if (value < 0) -+ value = -1; -+ else -+ value = 0; -+ break; -+ case 'i': -+ value++; -+ break; -+ case 'p': -+ { -+ /* Set to bit position of first bit set in immediate */ -+ int i, bitpos = 32; -+ for (i = 0; i < 32; i++) -+ if (value & (1 << i)) -+ { -+ bitpos = i; -+ break; -+ } -+ value = bitpos; -+ } -+ break; -+ case 'z': -+ { -+ /* Set to bit position of first bit cleared in immediate */ -+ int i, bitpos = 32; -+ for (i = 0; i < 32; i++) -+ if (!(value & (1 << i))) -+ { -+ bitpos = i; -+ break; -+ } -+ value = bitpos; -+ } -+ break; -+ case 'r': -+ { -+ /* Reglist 8 */ -+ char op[50]; -+ op[0] = '\0'; -+ -+ if (value & 0x01) -+ strcpy (op, "r0-r3"); -+ if (value & 0x02) -+ strlen (op) ? strcat (op, ", r4-r7") : strcpy (op,"r4-r7"); -+ if (value & 0x04) -+ strlen (op) ? strcat (op, ", r8-r9") : strcpy (op,"r8-r9"); -+ if (value & 0x08) -+ strlen (op) ? strcat (op, ", r10") : strcpy (op,"r10"); -+ if (value & 0x10) -+ strlen (op) ? strcat (op, ", r11") : strcpy (op,"r11"); -+ if (value & 0x20) -+ strlen (op) ? strcat (op, ", r12") : strcpy (op,"r12"); -+ if (value & 0x40) -+ strlen (op) ? strcat (op, ", lr") : strcpy (op, "lr"); -+ if (value & 0x80) -+ strlen (op) ? strcat (op, ", pc") : strcpy (op, "pc"); -+ -+ fputs (op, stream); -+ return; -+ } -+ case 's': -+ { -+ /* Reglist 16 */ -+ char reglist16_string[100]; -+ int i; -+ bool first_reg = true; -+ reglist16_string[0] = '\0'; -+ -+ for (i = 0; i < 16; ++i) -+ { -+ if (value & (1 << i)) -+ { -+ first_reg == true ? first_reg = false : strcat(reglist16_string,", "); -+ strcat(reglist16_string,reg_names[INTERNAL_REGNUM(i)]); -+ } -+ } -+ fputs (reglist16_string, stream); -+ return; -+ } -+ case 'h': -+ /* Print halfword part of word */ -+ fputs (value ? "b" : "t", stream); -+ return; -+ } -+ -+ /* Print Value */ -+ fprintf (stream, "%d", value); -+ break; -+ } -+ case CONST_DOUBLE: -+ { -+ HOST_WIDE_INT hi, lo; -+ if (SCALAR_FLOAT_MODE_P (GET_MODE (x))) -+ { -+ HOST_WIDE_INT target_float[2]; -+ hi = lo = 0; -+ real_to_target (target_float, CONST_DOUBLE_REAL_VALUE (x), -+ GET_MODE (x)); -+ /* For doubles the most significant part starts at index 0. */ -+ if (GET_MODE_SIZE (GET_MODE (x)) > UNITS_PER_WORD) -+ { -+ hi = target_float[0]; -+ lo = target_float[1]; -+ } -+ else -+ { -+ lo = target_float[0]; -+ } -+ } -+ else -+ { -+ hi = CONST_DOUBLE_HIGH (x); -+ lo = CONST_DOUBLE_LOW (x); -+ } -+ -+ if (code == 'm') -+ fprintf (stream, "%ld", hi); -+ else -+ fprintf (stream, "%ld", lo); -+ -+ break; -+ } -+ case CONST: -+ output_addr_const (stream, XEXP (XEXP (x, 0), 0)); -+ fprintf (stream, "+%ld", INTVAL (XEXP (XEXP (x, 0), 1))); -+ break; -+ case REG: -+ /* Swap register name if the register is DImode or DFmode. */ -+ if (GET_MODE (x) == DImode || GET_MODE (x) == DFmode) -+ { -+ /* Double register must have an even numbered address */ -+ gcc_assert (!(REGNO (x) % 2)); -+ if (code == 'm') -+ fputs (reg_names[true_regnum (x)], stream); -+ else -+ fputs (reg_names[true_regnum (x) + 1], stream); -+ } -+ else if (GET_MODE (x) == TImode) -+ { -+ switch (code) -+ { -+ case 'T': -+ fputs (reg_names[true_regnum (x)], stream); -+ break; -+ case 'U': -+ fputs (reg_names[true_regnum (x) + 1], stream); -+ break; -+ case 'L': -+ fputs (reg_names[true_regnum (x) + 2], stream); -+ break; -+ case 'B': -+ fputs (reg_names[true_regnum (x) + 3], stream); -+ break; -+ default: -+ fprintf (stream, "%s, %s, %s, %s", -+ reg_names[true_regnum (x) + 3], -+ reg_names[true_regnum (x) + 2], -+ reg_names[true_regnum (x) + 1], -+ reg_names[true_regnum (x)]); -+ break; -+ } -+ } -+ else -+ { -+ fputs (reg_names[true_regnum (x)], stream); -+ } -+ break; -+ case CODE_LABEL: -+ case LABEL_REF: -+ case SYMBOL_REF: -+ output_addr_const (stream, x); -+ break; -+ case MEM: -+ switch (GET_CODE (XEXP (x, 0))) -+ { -+ case LABEL_REF: -+ case SYMBOL_REF: -+ output_addr_const (stream, XEXP (x, 0)); -+ break; -+ case MEM: -+ switch (GET_CODE (XEXP (XEXP (x, 0), 0))) -+ { -+ case SYMBOL_REF: -+ output_addr_const (stream, XEXP (XEXP (x, 0), 0)); -+ break; -+ default: -+ error = 1; -+ break; -+ } -+ break; -+ case REG: -+ avr32_print_operand (stream, XEXP (x, 0), 0); -+ if (code != 'p') -+ fputs ("[0]", stream); -+ break; -+ case PRE_DEC: -+ fputs ("--", stream); -+ avr32_print_operand (stream, XEXP (XEXP (x, 0), 0), 0); -+ break; -+ case POST_INC: -+ avr32_print_operand (stream, XEXP (XEXP (x, 0), 0), 0); -+ fputs ("++", stream); -+ break; -+ case PLUS: -+ { -+ rtx op0 = XEXP (XEXP (x, 0), 0); -+ rtx op1 = XEXP (XEXP (x, 0), 1); -+ rtx base = NULL_RTX, offset = NULL_RTX; -+ -+ if (avr32_address_register_rtx_p (op0, 1)) -+ { -+ base = op0; -+ offset = op1; -+ } -+ else if (avr32_address_register_rtx_p (op1, 1)) -+ { -+ /* Operands are switched. */ -+ base = op1; -+ offset = op0; -+ } -+ -+ gcc_assert (base && offset -+ && avr32_address_register_rtx_p (base, 1) -+ && avr32_legitimate_index_p (GET_MODE (x), offset, -+ 1)); -+ -+ avr32_print_operand (stream, base, 0); -+ fputs ("[", stream); -+ avr32_print_operand (stream, offset, 0); -+ fputs ("]", stream); -+ break; -+ } -+ case CONST: -+ output_addr_const (stream, XEXP (XEXP (XEXP (x, 0), 0), 0)); -+ fprintf (stream, " + %ld", -+ INTVAL (XEXP (XEXP (XEXP (x, 0), 0), 1))); -+ break; -+ case CONST_INT: -+ avr32_print_operand (stream, XEXP (x, 0), 0); -+ break; -+ default: -+ error = 1; -+ } -+ break; -+ case MULT: -+ { -+ int value = INTVAL (XEXP (x, 1)); -+ -+ /* Convert immediate in multiplication into a shift immediate */ -+ switch (value) -+ { -+ case 2: -+ value = 1; -+ break; -+ case 4: -+ value = 2; -+ break; -+ case 8: -+ value = 3; -+ break; -+ default: -+ value = 0; -+ } -+ fprintf (stream, "%s << %i", reg_names[true_regnum (XEXP (x, 0))], -+ value); -+ break; -+ } -+ case ASHIFT: -+ if (GET_CODE (XEXP (x, 1)) == CONST_INT) -+ fprintf (stream, "%s << %i", reg_names[true_regnum (XEXP (x, 0))], -+ (int) INTVAL (XEXP (x, 1))); -+ else if (REG_P (XEXP (x, 1))) -+ fprintf (stream, "%s << %s", reg_names[true_regnum (XEXP (x, 0))], -+ reg_names[true_regnum (XEXP (x, 1))]); -+ else -+ { -+ error = 1; -+ } -+ break; -+ case LSHIFTRT: -+ if (GET_CODE (XEXP (x, 1)) == CONST_INT) -+ fprintf (stream, "%s >> %i", reg_names[true_regnum (XEXP (x, 0))], -+ (int) INTVAL (XEXP (x, 1))); -+ else if (REG_P (XEXP (x, 1))) -+ fprintf (stream, "%s >> %s", reg_names[true_regnum (XEXP (x, 0))], -+ reg_names[true_regnum (XEXP (x, 1))]); -+ else -+ { -+ error = 1; -+ } -+ fprintf (stream, ">>"); -+ break; -+ case PARALLEL: -+ { -+ /* Load store multiple */ -+ int i; -+ int count = XVECLEN (x, 0); -+ int reglist16 = 0; -+ char reglist16_string[100]; -+ -+ for (i = 0; i < count; ++i) -+ { -+ rtx vec_elm = XVECEXP (x, 0, i); -+ if (GET_MODE (vec_elm) != SET) -+ { -+ debug_rtx (vec_elm); -+ internal_error ("Unknown element in parallel expression!"); -+ } -+ if (GET_MODE (XEXP (vec_elm, 0)) == REG) -+ { -+ /* Load multiple */ -+ reglist16 |= 1 << ASM_REGNUM (REGNO (XEXP (vec_elm, 0))); -+ } -+ else -+ { -+ /* Store multiple */ -+ reglist16 |= 1 << ASM_REGNUM (REGNO (XEXP (vec_elm, 1))); -+ } -+ } -+ -+ avr32_make_reglist16 (reglist16, reglist16_string); -+ fputs (reglist16_string, stream); -+ -+ break; -+ } -+ -+ case PLUS: -+ { -+ rtx op0 = XEXP (x, 0); -+ rtx op1 = XEXP (x, 1); -+ rtx base = NULL_RTX, offset = NULL_RTX; -+ -+ if (avr32_address_register_rtx_p (op0, 1)) -+ { -+ base = op0; -+ offset = op1; -+ } -+ else if (avr32_address_register_rtx_p (op1, 1)) -+ { -+ /* Operands are switched. */ -+ base = op1; -+ offset = op0; -+ } -+ -+ gcc_assert (base && offset -+ && avr32_address_register_rtx_p (base, 1) -+ && avr32_legitimate_index_p (GET_MODE (x), offset, 1)); -+ -+ avr32_print_operand (stream, base, 0); -+ fputs ("[", stream); -+ avr32_print_operand (stream, offset, 0); -+ fputs ("]", stream); -+ break; -+ } -+ -+ default: -+ error = 1; -+ } -+ -+ if (error) -+ { -+ debug_rtx (x); -+ internal_error ("Illegal expression for avr32_print_operand"); -+ } -+} -+ -+rtx -+avr32_get_note_reg_equiv (rtx insn) -+{ -+ rtx note; -+ -+ note = find_reg_note (insn, REG_EQUIV, NULL_RTX); -+ -+ if (note != NULL_RTX) -+ return XEXP (note, 0); -+ else -+ return NULL_RTX; -+} -+ -+ -+/* -+ Outputs to stdio stream stream the assembler syntax for an instruction -+ operand that is a memory reference whose address is x. x is an RTL -+ expression. -+ -+ ToDo: fixme. -+*/ -+void -+avr32_print_operand_address (FILE * stream, rtx x) -+{ -+ fprintf (stream, "(%d) /* address */", REGNO (x)); -+} -+ -+ -+/* Return true if _GLOBAL_OFFSET_TABLE_ symbol is mentioned. */ -+bool -+avr32_got_mentioned_p (rtx addr) -+{ -+ if (GET_CODE (addr) == MEM) -+ addr = XEXP (addr, 0); -+ while (GET_CODE (addr) == CONST) -+ addr = XEXP (addr, 0); -+ if (GET_CODE (addr) == SYMBOL_REF) -+ { -+ return streq (XSTR (addr, 0), "_GLOBAL_OFFSET_TABLE_"); -+ } -+ if (GET_CODE (addr) == PLUS || GET_CODE (addr) == MINUS) -+ { -+ bool l1, l2; -+ -+ l1 = avr32_got_mentioned_p (XEXP (addr, 0)); -+ l2 = avr32_got_mentioned_p (XEXP (addr, 1)); -+ return l1 || l2; -+ } -+ return false; -+} -+ -+ -+/* Find the symbol in an address expression. */ -+rtx -+avr32_find_symbol (rtx addr) -+{ -+ if (GET_CODE (addr) == MEM) -+ addr = XEXP (addr, 0); -+ -+ while (GET_CODE (addr) == CONST) -+ addr = XEXP (addr, 0); -+ -+ if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == LABEL_REF) -+ return addr; -+ if (GET_CODE (addr) == PLUS) -+ { -+ rtx l1, l2; -+ -+ l1 = avr32_find_symbol (XEXP (addr, 0)); -+ l2 = avr32_find_symbol (XEXP (addr, 1)); -+ if (l1 != NULL_RTX && l2 == NULL_RTX) -+ return l1; -+ else if (l1 == NULL_RTX && l2 != NULL_RTX) -+ return l2; -+ } -+ -+ return NULL_RTX; -+} -+ -+ -+/* Routines for manipulation of the constant pool. */ -+ -+/* AVR32 instructions cannot load a large constant directly into a -+ register; they have to come from a pc relative load. The constant -+ must therefore be placed in the addressable range of the pc -+ relative load. Depending on the precise pc relative load -+ instruction the range is somewhere between 256 bytes and 4k. This -+ means that we often have to dump a constant inside a function, and -+ generate code to branch around it. -+ -+ It is important to minimize this, since the branches will slow -+ things down and make the code larger. -+ -+ Normally we can hide the table after an existing unconditional -+ branch so that there is no interruption of the flow, but in the -+ worst case the code looks like this: -+ -+ lddpc rn, L1 -+ ... -+ rjmp L2 -+ align -+ L1: .long value -+ L2: -+ ... -+ -+ lddpc rn, L3 -+ ... -+ rjmp L4 -+ align -+ L3: .long value -+ L4: -+ ... -+ -+ We fix this by performing a scan after scheduling, which notices -+ which instructions need to have their operands fetched from the -+ constant table and builds the table. -+ -+ The algorithm starts by building a table of all the constants that -+ need fixing up and all the natural barriers in the function (places -+ where a constant table can be dropped without breaking the flow). -+ For each fixup we note how far the pc-relative replacement will be -+ able to reach and the offset of the instruction into the function. -+ -+ Having built the table we then group the fixes together to form -+ tables that are as large as possible (subject to addressing -+ constraints) and emit each table of constants after the last -+ barrier that is within range of all the instructions in the group. -+ If a group does not contain a barrier, then we forcibly create one -+ by inserting a jump instruction into the flow. Once the table has -+ been inserted, the insns are then modified to reference the -+ relevant entry in the pool. -+ -+ Possible enhancements to the algorithm (not implemented) are: -+ -+ 1) For some processors and object formats, there may be benefit in -+ aligning the pools to the start of cache lines; this alignment -+ would need to be taken into account when calculating addressability -+ of a pool. */ -+ -+/* These typedefs are located at the start of this file, so that -+ they can be used in the prototypes there. This comment is to -+ remind readers of that fact so that the following structures -+ can be understood more easily. -+ -+ typedef struct minipool_node Mnode; -+ typedef struct minipool_fixup Mfix; */ -+ -+struct minipool_node -+{ -+ /* Doubly linked chain of entries. */ -+ Mnode *next; -+ Mnode *prev; -+ /* The maximum offset into the code that this entry can be placed. While -+ pushing fixes for forward references, all entries are sorted in order of -+ increasing max_address. */ -+ HOST_WIDE_INT max_address; -+ /* Similarly for an entry inserted for a backwards ref. */ -+ HOST_WIDE_INT min_address; -+ /* The number of fixes referencing this entry. This can become zero if we -+ "unpush" an entry. In this case we ignore the entry when we come to -+ emit the code. */ -+ int refcount; -+ /* The offset from the start of the minipool. */ -+ HOST_WIDE_INT offset; -+ /* The value in table. */ -+ rtx value; -+ /* The mode of value. */ -+ enum machine_mode mode; -+ /* The size of the value. */ -+ int fix_size; -+}; -+ -+ -+struct minipool_fixup -+{ -+ Mfix *next; -+ rtx insn; -+ HOST_WIDE_INT address; -+ rtx *loc; -+ enum machine_mode mode; -+ int fix_size; -+ rtx value; -+ Mnode *minipool; -+ HOST_WIDE_INT forwards; -+ HOST_WIDE_INT backwards; -+}; -+ -+ -+/* Fixes less than a word need padding out to a word boundary. */ -+#define MINIPOOL_FIX_SIZE(mode, value) \ -+ (IS_FORCE_MINIPOOL(value) ? 0 : \ -+ (GET_MODE_SIZE ((mode)) >= 4 ? GET_MODE_SIZE ((mode)) : 4)) -+ -+#define IS_FORCE_MINIPOOL(x) \ -+ (GET_CODE(x) == UNSPEC && \ -+ XINT(x, 1) == UNSPEC_FORCE_MINIPOOL) -+ -+static Mnode *minipool_vector_head; -+static Mnode *minipool_vector_tail; -+ -+/* The linked list of all minipool fixes required for this function. */ -+Mfix *minipool_fix_head; -+Mfix *minipool_fix_tail; -+/* The fix entry for the current minipool, once it has been placed. */ -+Mfix *minipool_barrier; -+ -+ -+/* Determines if INSN is the start of a jump table. Returns the end -+ of the TABLE or NULL_RTX. */ -+static rtx -+is_jump_table (rtx insn) -+{ -+ rtx table; -+ -+ if (GET_CODE (insn) == JUMP_INSN -+ && JUMP_LABEL (insn) != NULL -+ && ((table = next_real_insn (JUMP_LABEL (insn))) -+ == next_real_insn (insn)) -+ && table != NULL -+ && GET_CODE (table) == JUMP_INSN -+ && (GET_CODE (PATTERN (table)) == ADDR_VEC -+ || GET_CODE (PATTERN (table)) == ADDR_DIFF_VEC)) -+ return table; -+ -+ return NULL_RTX; -+} -+ -+ -+static HOST_WIDE_INT -+get_jump_table_size (rtx insn) -+{ -+ /* ADDR_VECs only take room if read-only data does into the text section. */ -+ if (JUMP_TABLES_IN_TEXT_SECTION -+#if !defined(READONLY_DATA_SECTION_ASM_OP) -+ || 1 -+#endif -+ ) -+ { -+ rtx body = PATTERN (insn); -+ int elt = GET_CODE (body) == ADDR_DIFF_VEC ? 1 : 0; -+ -+ return GET_MODE_SIZE (GET_MODE (body)) * XVECLEN (body, elt); -+ } -+ -+ return 0; -+} -+ -+ -+/* Move a minipool fix MP from its current location to before MAX_MP. -+ If MAX_MP is NULL, then MP doesn't need moving, but the addressing -+ constraints may need updating. */ -+static Mnode * -+move_minipool_fix_forward_ref (Mnode * mp, Mnode * max_mp, -+ HOST_WIDE_INT max_address) -+{ -+ /* This should never be true and the code below assumes these are -+ different. */ -+ if (mp == max_mp) -+ abort (); -+ -+ if (max_mp == NULL) -+ { -+ if (max_address < mp->max_address) -+ mp->max_address = max_address; -+ } -+ else -+ { -+ if (max_address > max_mp->max_address - mp->fix_size) -+ mp->max_address = max_mp->max_address - mp->fix_size; -+ else -+ mp->max_address = max_address; -+ -+ /* Unlink MP from its current position. Since max_mp is non-null, -+ mp->prev must be non-null. */ -+ mp->prev->next = mp->next; -+ if (mp->next != NULL) -+ mp->next->prev = mp->prev; -+ else -+ minipool_vector_tail = mp->prev; -+ -+ /* Re-insert it before MAX_MP. */ -+ mp->next = max_mp; -+ mp->prev = max_mp->prev; -+ max_mp->prev = mp; -+ -+ if (mp->prev != NULL) -+ mp->prev->next = mp; -+ else -+ minipool_vector_head = mp; -+ } -+ -+ /* Save the new entry. */ -+ max_mp = mp; -+ -+ /* Scan over the preceding entries and adjust their addresses as required. -+ */ -+ while (mp->prev != NULL -+ && mp->prev->max_address > mp->max_address - mp->prev->fix_size) -+ { -+ mp->prev->max_address = mp->max_address - mp->prev->fix_size; -+ mp = mp->prev; -+ } -+ -+ return max_mp; -+} -+ -+ -+/* Add a constant to the minipool for a forward reference. Returns the -+ node added or NULL if the constant will not fit in this pool. */ -+static Mnode * -+add_minipool_forward_ref (Mfix * fix) -+{ -+ /* If set, max_mp is the first pool_entry that has a lower constraint than -+ the one we are trying to add. */ -+ Mnode *max_mp = NULL; -+ HOST_WIDE_INT max_address = fix->address + fix->forwards; -+ Mnode *mp; -+ -+ /* If this fix's address is greater than the address of the first entry, -+ then we can't put the fix in this pool. We subtract the size of the -+ current fix to ensure that if the table is fully packed we still have -+ enough room to insert this value by suffling the other fixes forwards. */ -+ if (minipool_vector_head && -+ fix->address >= minipool_vector_head->max_address - fix->fix_size) -+ return NULL; -+ -+ /* Scan the pool to see if a constant with the same value has already been -+ added. While we are doing this, also note the location where we must -+ insert the constant if it doesn't already exist. */ -+ for (mp = minipool_vector_head; mp != NULL; mp = mp->next) -+ { -+ if (GET_CODE (fix->value) == GET_CODE (mp->value) -+ && fix->mode == mp->mode -+ && (GET_CODE (fix->value) != CODE_LABEL -+ || (CODE_LABEL_NUMBER (fix->value) -+ == CODE_LABEL_NUMBER (mp->value))) -+ && rtx_equal_p (fix->value, mp->value)) -+ { -+ /* More than one fix references this entry. */ -+ mp->refcount++; -+ return move_minipool_fix_forward_ref (mp, max_mp, max_address); -+ } -+ -+ /* Note the insertion point if necessary. */ -+ if (max_mp == NULL && mp->max_address > max_address) -+ max_mp = mp; -+ -+ } -+ -+ /* The value is not currently in the minipool, so we need to create a new -+ entry for it. If MAX_MP is NULL, the entry will be put on the end of -+ the list since the placement is less constrained than any existing -+ entry. Otherwise, we insert the new fix before MAX_MP and, if -+ necessary, adjust the constraints on the other entries. */ -+ mp = xmalloc (sizeof (*mp)); -+ mp->fix_size = fix->fix_size; -+ mp->mode = fix->mode; -+ mp->value = fix->value; -+ mp->refcount = 1; -+ /* Not yet required for a backwards ref. */ -+ mp->min_address = -65536; -+ -+ if (max_mp == NULL) -+ { -+ mp->max_address = max_address; -+ mp->next = NULL; -+ mp->prev = minipool_vector_tail; -+ -+ if (mp->prev == NULL) -+ { -+ minipool_vector_head = mp; -+ minipool_vector_label = gen_label_rtx (); -+ } -+ else -+ mp->prev->next = mp; -+ -+ minipool_vector_tail = mp; -+ } -+ else -+ { -+ if (max_address > max_mp->max_address - mp->fix_size) -+ mp->max_address = max_mp->max_address - mp->fix_size; -+ else -+ mp->max_address = max_address; -+ -+ mp->next = max_mp; -+ mp->prev = max_mp->prev; -+ max_mp->prev = mp; -+ if (mp->prev != NULL) -+ mp->prev->next = mp; -+ else -+ minipool_vector_head = mp; -+ } -+ -+ /* Save the new entry. */ -+ max_mp = mp; -+ -+ /* Scan over the preceding entries and adjust their addresses as required. -+ */ -+ while (mp->prev != NULL -+ && mp->prev->max_address > mp->max_address - mp->prev->fix_size) -+ { -+ mp->prev->max_address = mp->max_address - mp->prev->fix_size; -+ mp = mp->prev; -+ } -+ -+ return max_mp; -+} -+ -+ -+static Mnode * -+move_minipool_fix_backward_ref (Mnode * mp, Mnode * min_mp, -+ HOST_WIDE_INT min_address) -+{ -+ HOST_WIDE_INT offset; -+ -+ /* This should never be true, and the code below assumes these are -+ different. */ -+ if (mp == min_mp) -+ abort (); -+ -+ if (min_mp == NULL) -+ { -+ if (min_address > mp->min_address) -+ mp->min_address = min_address; -+ } -+ else -+ { -+ /* We will adjust this below if it is too loose. */ -+ mp->min_address = min_address; -+ -+ /* Unlink MP from its current position. Since min_mp is non-null, -+ mp->next must be non-null. */ -+ mp->next->prev = mp->prev; -+ if (mp->prev != NULL) -+ mp->prev->next = mp->next; -+ else -+ minipool_vector_head = mp->next; -+ -+ /* Reinsert it after MIN_MP. */ -+ mp->prev = min_mp; -+ mp->next = min_mp->next; -+ min_mp->next = mp; -+ if (mp->next != NULL) -+ mp->next->prev = mp; -+ else -+ minipool_vector_tail = mp; -+ } -+ -+ min_mp = mp; -+ -+ offset = 0; -+ for (mp = minipool_vector_head; mp != NULL; mp = mp->next) -+ { -+ mp->offset = offset; -+ if (mp->refcount > 0) -+ offset += mp->fix_size; -+ -+ if (mp->next && mp->next->min_address < mp->min_address + mp->fix_size) -+ mp->next->min_address = mp->min_address + mp->fix_size; -+ } -+ -+ return min_mp; -+} -+ -+ -+/* Add a constant to the minipool for a backward reference. Returns the -+ node added or NULL if the constant will not fit in this pool. -+ -+ Note that the code for insertion for a backwards reference can be -+ somewhat confusing because the calculated offsets for each fix do -+ not take into account the size of the pool (which is still under -+ construction. */ -+static Mnode * -+add_minipool_backward_ref (Mfix * fix) -+{ -+ /* If set, min_mp is the last pool_entry that has a lower constraint than -+ the one we are trying to add. */ -+ Mnode *min_mp = NULL; -+ /* This can be negative, since it is only a constraint. */ -+ HOST_WIDE_INT min_address = fix->address - fix->backwards; -+ Mnode *mp; -+ -+ /* If we can't reach the current pool from this insn, or if we can't insert -+ this entry at the end of the pool without pushing other fixes out of -+ range, then we don't try. This ensures that we can't fail later on. */ -+ if (min_address >= minipool_barrier->address -+ || (minipool_vector_tail->min_address + fix->fix_size -+ >= minipool_barrier->address)) -+ return NULL; -+ -+ /* Scan the pool to see if a constant with the same value has already been -+ added. While we are doing this, also note the location where we must -+ insert the constant if it doesn't already exist. */ -+ for (mp = minipool_vector_tail; mp != NULL; mp = mp->prev) -+ { -+ if (GET_CODE (fix->value) == GET_CODE (mp->value) -+ && fix->mode == mp->mode -+ && (GET_CODE (fix->value) != CODE_LABEL -+ || (CODE_LABEL_NUMBER (fix->value) -+ == CODE_LABEL_NUMBER (mp->value))) -+ && rtx_equal_p (fix->value, mp->value) -+ /* Check that there is enough slack to move this entry to the end -+ of the table (this is conservative). */ -+ && (mp->max_address -+ > (minipool_barrier->address -+ + minipool_vector_tail->offset -+ + minipool_vector_tail->fix_size))) -+ { -+ mp->refcount++; -+ return move_minipool_fix_backward_ref (mp, min_mp, min_address); -+ } -+ -+ if (min_mp != NULL) -+ mp->min_address += fix->fix_size; -+ else -+ { -+ /* Note the insertion point if necessary. */ -+ if (mp->min_address < min_address) -+ { -+ min_mp = mp; -+ } -+ else if (mp->max_address -+ < minipool_barrier->address + mp->offset + fix->fix_size) -+ { -+ /* Inserting before this entry would push the fix beyond its -+ maximum address (which can happen if we have re-located a -+ forwards fix); force the new fix to come after it. */ -+ min_mp = mp; -+ min_address = mp->min_address + fix->fix_size; -+ } -+ } -+ } -+ -+ /* We need to create a new entry. */ -+ mp = xmalloc (sizeof (*mp)); -+ mp->fix_size = fix->fix_size; -+ mp->mode = fix->mode; -+ mp->value = fix->value; -+ mp->refcount = 1; -+ mp->max_address = minipool_barrier->address + 65536; -+ -+ mp->min_address = min_address; -+ -+ if (min_mp == NULL) -+ { -+ mp->prev = NULL; -+ mp->next = minipool_vector_head; -+ -+ if (mp->next == NULL) -+ { -+ minipool_vector_tail = mp; -+ minipool_vector_label = gen_label_rtx (); -+ } -+ else -+ mp->next->prev = mp; -+ -+ minipool_vector_head = mp; -+ } -+ else -+ { -+ mp->next = min_mp->next; -+ mp->prev = min_mp; -+ min_mp->next = mp; -+ -+ if (mp->next != NULL) -+ mp->next->prev = mp; -+ else -+ minipool_vector_tail = mp; -+ } -+ -+ /* Save the new entry. */ -+ min_mp = mp; -+ -+ if (mp->prev) -+ mp = mp->prev; -+ else -+ mp->offset = 0; -+ -+ /* Scan over the following entries and adjust their offsets. */ -+ while (mp->next != NULL) -+ { -+ if (mp->next->min_address < mp->min_address + mp->fix_size) -+ mp->next->min_address = mp->min_address + mp->fix_size; -+ -+ if (mp->refcount) -+ mp->next->offset = mp->offset + mp->fix_size; -+ else -+ mp->next->offset = mp->offset; -+ -+ mp = mp->next; -+ } -+ -+ return min_mp; -+} -+ -+ -+static void -+assign_minipool_offsets (Mfix * barrier) -+{ -+ HOST_WIDE_INT offset = 0; -+ Mnode *mp; -+ -+ minipool_barrier = barrier; -+ -+ for (mp = minipool_vector_head; mp != NULL; mp = mp->next) -+ { -+ mp->offset = offset; -+ -+ if (mp->refcount > 0) -+ offset += mp->fix_size; -+ } -+} -+ -+ -+/* Print a symbolic form of X to the debug file, F. */ -+static void -+avr32_print_value (FILE * f, rtx x) -+{ -+ switch (GET_CODE (x)) -+ { -+ case CONST_INT: -+ fprintf (f, "0x%x", (int) INTVAL (x)); -+ return; -+ -+ case CONST_DOUBLE: -+ fprintf (f, "<0x%lx,0x%lx>", (long) XWINT (x, 2), (long) XWINT (x, 3)); -+ return; -+ -+ case CONST_VECTOR: -+ { -+ int i; -+ -+ fprintf (f, "<"); -+ for (i = 0; i < CONST_VECTOR_NUNITS (x); i++) -+ { -+ fprintf (f, "0x%x", (int) INTVAL (CONST_VECTOR_ELT (x, i))); -+ if (i < (CONST_VECTOR_NUNITS (x) - 1)) -+ fputc (',', f); -+ } -+ fprintf (f, ">"); -+ } -+ return; -+ -+ case CONST_STRING: -+ fprintf (f, "\"%s\"", XSTR (x, 0)); -+ return; -+ -+ case SYMBOL_REF: -+ fprintf (f, "`%s'", XSTR (x, 0)); -+ return; -+ -+ case LABEL_REF: -+ fprintf (f, "L%d", INSN_UID (XEXP (x, 0))); -+ return; -+ -+ case CONST: -+ avr32_print_value (f, XEXP (x, 0)); -+ return; -+ -+ case PLUS: -+ avr32_print_value (f, XEXP (x, 0)); -+ fprintf (f, "+"); -+ avr32_print_value (f, XEXP (x, 1)); -+ return; -+ -+ case PC: -+ fprintf (f, "pc"); -+ return; -+ -+ default: -+ fprintf (f, "????"); -+ return; -+ } -+} -+ -+ -+int -+is_minipool_label (rtx label) -+{ -+ minipool_labels *cur_mp_label = cfun->machine->minipool_label_head; -+ -+ if (GET_CODE (label) != CODE_LABEL) -+ return FALSE; -+ -+ while (cur_mp_label) -+ { -+ if (CODE_LABEL_NUMBER (label) -+ == CODE_LABEL_NUMBER (cur_mp_label->label)) -+ return TRUE; -+ cur_mp_label = cur_mp_label->next; -+ } -+ return FALSE; -+} -+ -+ -+static void -+new_minipool_label (rtx label) -+{ -+ if (!cfun->machine->minipool_label_head) -+ { -+ cfun->machine->minipool_label_head = -+ ggc_alloc (sizeof (minipool_labels)); -+ cfun->machine->minipool_label_tail = cfun->machine->minipool_label_head; -+ cfun->machine->minipool_label_head->label = label; -+ cfun->machine->minipool_label_head->next = 0; -+ cfun->machine->minipool_label_head->prev = 0; -+ } -+ else -+ { -+ cfun->machine->minipool_label_tail->next = -+ ggc_alloc (sizeof (minipool_labels)); -+ cfun->machine->minipool_label_tail->next->label = label; -+ cfun->machine->minipool_label_tail->next->next = 0; -+ cfun->machine->minipool_label_tail->next->prev = -+ cfun->machine->minipool_label_tail; -+ cfun->machine->minipool_label_tail = -+ cfun->machine->minipool_label_tail->next; -+ } -+} -+ -+ -+/* Output the literal table */ -+static void -+dump_minipool (rtx scan) -+{ -+ Mnode *mp; -+ Mnode *nmp; -+ -+ if (dump_file) -+ fprintf (dump_file, -+ ";; Emitting minipool after insn %u; address %ld; align %d (bytes)\n", -+ INSN_UID (scan), (unsigned long) minipool_barrier->address, 4); -+ -+ scan = emit_insn_after (gen_consttable_start (), scan); -+ scan = emit_insn_after (gen_align_4 (), scan); -+ scan = emit_label_after (minipool_vector_label, scan); -+ new_minipool_label (minipool_vector_label); -+ -+ for (mp = minipool_vector_head; mp != NULL; mp = nmp) -+ { -+ if (mp->refcount > 0) -+ { -+ if (dump_file) -+ { -+ fprintf (dump_file, -+ ";; Offset %u, min %ld, max %ld ", -+ (unsigned) mp->offset, (unsigned long) mp->min_address, -+ (unsigned long) mp->max_address); -+ avr32_print_value (dump_file, mp->value); -+ fputc ('\n', dump_file); -+ } -+ -+ switch (mp->fix_size) -+ { -+#ifdef HAVE_consttable_4 -+ case 4: -+ scan = emit_insn_after (gen_consttable_4 (mp->value), scan); -+ break; -+ -+#endif -+#ifdef HAVE_consttable_8 -+ case 8: -+ scan = emit_insn_after (gen_consttable_8 (mp->value), scan); -+ break; -+ -+#endif -+#ifdef HAVE_consttable_16 -+ case 16: -+ scan = emit_insn_after (gen_consttable_16 (mp->value), scan); -+ break; -+ -+#endif -+ case 0: -+ /* This can happen for force-minipool entries which just are -+ there to force the minipool to be generate. */ -+ break; -+ default: -+ abort (); -+ break; -+ } -+ } -+ -+ nmp = mp->next; -+ free (mp); -+ } -+ -+ minipool_vector_head = minipool_vector_tail = NULL; -+ scan = emit_insn_after (gen_consttable_end (), scan); -+ scan = emit_barrier_after (scan); -+} -+ -+ -+/* Return the cost of forcibly inserting a barrier after INSN. */ -+static int -+avr32_barrier_cost (rtx insn) -+{ -+ /* Basing the location of the pool on the loop depth is preferable, but at -+ the moment, the basic block information seems to be corrupt by this -+ stage of the compilation. */ -+ int base_cost = 50; -+ rtx next = next_nonnote_insn (insn); -+ -+ if (next != NULL && GET_CODE (next) == CODE_LABEL) -+ base_cost -= 20; -+ -+ switch (GET_CODE (insn)) -+ { -+ case CODE_LABEL: -+ /* It will always be better to place the table before the label, rather -+ than after it. */ -+ return 50; -+ -+ case INSN: -+ case CALL_INSN: -+ return base_cost; -+ -+ case JUMP_INSN: -+ return base_cost - 10; -+ -+ default: -+ return base_cost + 10; -+ } -+} -+ -+ -+/* Find the best place in the insn stream in the range -+ (FIX->address,MAX_ADDRESS) to forcibly insert a minipool barrier. -+ Create the barrier by inserting a jump and add a new fix entry for -+ it. */ -+static Mfix * -+create_fix_barrier (Mfix * fix, HOST_WIDE_INT max_address) -+{ -+ HOST_WIDE_INT count = 0; -+ rtx barrier; -+ rtx from = fix->insn; -+ rtx selected = from; -+ int selected_cost; -+ HOST_WIDE_INT selected_address; -+ Mfix *new_fix; -+ HOST_WIDE_INT max_count = max_address - fix->address; -+ rtx label = gen_label_rtx (); -+ -+ selected_cost = avr32_barrier_cost (from); -+ selected_address = fix->address; -+ -+ while (from && count < max_count) -+ { -+ rtx tmp; -+ int new_cost; -+ -+ /* This code shouldn't have been called if there was a natural barrier -+ within range. */ -+ if (GET_CODE (from) == BARRIER) -+ abort (); -+ -+ /* Count the length of this insn. */ -+ count += get_attr_length (from); -+ -+ /* If there is a jump table, add its length. */ -+ tmp = is_jump_table (from); -+ if (tmp != NULL) -+ { -+ count += get_jump_table_size (tmp); -+ -+ /* Jump tables aren't in a basic block, so base the cost on the -+ dispatch insn. If we select this location, we will still put -+ the pool after the table. */ -+ new_cost = avr32_barrier_cost (from); -+ -+ if (count < max_count && new_cost <= selected_cost) -+ { -+ selected = tmp; -+ selected_cost = new_cost; -+ selected_address = fix->address + count; -+ } -+ -+ /* Continue after the dispatch table. */ -+ from = NEXT_INSN (tmp); -+ continue; -+ } -+ -+ new_cost = avr32_barrier_cost (from); -+ -+ if (count < max_count && new_cost <= selected_cost) -+ { -+ selected = from; -+ selected_cost = new_cost; -+ selected_address = fix->address + count; -+ } -+ -+ from = NEXT_INSN (from); -+ } -+ -+ /* Create a new JUMP_INSN that branches around a barrier. */ -+ from = emit_jump_insn_after (gen_jump (label), selected); -+ JUMP_LABEL (from) = label; -+ barrier = emit_barrier_after (from); -+ emit_label_after (label, barrier); -+ -+ /* Create a minipool barrier entry for the new barrier. */ -+ new_fix = (Mfix *) obstack_alloc (&minipool_obstack, sizeof (*new_fix)); -+ new_fix->insn = barrier; -+ new_fix->address = selected_address; -+ new_fix->next = fix->next; -+ fix->next = new_fix; -+ -+ return new_fix; -+} -+ -+ -+/* Record that there is a natural barrier in the insn stream at -+ ADDRESS. */ -+static void -+push_minipool_barrier (rtx insn, HOST_WIDE_INT address) -+{ -+ Mfix *fix = (Mfix *) obstack_alloc (&minipool_obstack, sizeof (*fix)); -+ -+ fix->insn = insn; -+ fix->address = address; -+ -+ fix->next = NULL; -+ if (minipool_fix_head != NULL) -+ minipool_fix_tail->next = fix; -+ else -+ minipool_fix_head = fix; -+ -+ minipool_fix_tail = fix; -+} -+ -+ -+/* Record INSN, which will need fixing up to load a value from the -+ minipool. ADDRESS is the offset of the insn since the start of the -+ function; LOC is a pointer to the part of the insn which requires -+ fixing; VALUE is the constant that must be loaded, which is of type -+ MODE. */ -+static void -+push_minipool_fix (rtx insn, HOST_WIDE_INT address, rtx * loc, -+ enum machine_mode mode, rtx value) -+{ -+ Mfix *fix = (Mfix *) obstack_alloc (&minipool_obstack, sizeof (*fix)); -+ rtx body = PATTERN (insn); -+ -+ fix->insn = insn; -+ fix->address = address; -+ fix->loc = loc; -+ fix->mode = mode; -+ fix->fix_size = MINIPOOL_FIX_SIZE (mode, value); -+ fix->value = value; -+ -+ if (GET_CODE (body) == PARALLEL) -+ { -+ /* Mcall : Ks16 << 2 */ -+ fix->forwards = ((1 << 15) - 1) << 2; -+ fix->backwards = (1 << 15) << 2; -+ } -+ else if (GET_CODE (body) == SET -+ && GET_MODE_SIZE (GET_MODE (SET_DEST (body))) == 4) -+ { -+ if (optimize_size) -+ { -+ /* Lddpc : Ku7 << 2 */ -+ fix->forwards = ((1 << 7) - 1) << 2; -+ fix->backwards = 0; -+ } -+ else -+ { -+ /* Ld.w : Ks16 */ -+ fix->forwards = ((1 << 15) - 4); -+ fix->backwards = (1 << 15); -+ } -+ } -+ else if (GET_CODE (body) == SET -+ && GET_MODE_SIZE (GET_MODE (SET_DEST (body))) == 8) -+ { -+ /* Ld.d : Ks16 */ -+ fix->forwards = ((1 << 15) - 4); -+ fix->backwards = (1 << 15); -+ } -+ else if (GET_CODE (body) == UNSPEC_VOLATILE -+ && XINT (body, 1) == VUNSPEC_MVRC) -+ { -+ /* Coprocessor load */ -+ /* Ldc : Ku8 << 2 */ -+ fix->forwards = ((1 << 8) - 1) << 2; -+ fix->backwards = 0; -+ } -+ else -+ { -+ /* Assume worst case which is lddpc insn. */ -+ fix->forwards = ((1 << 7) - 1) << 2; -+ fix->backwards = 0; -+ } -+ -+ fix->minipool = NULL; -+ -+ /* If an insn doesn't have a range defined for it, then it isn't expecting -+ to be reworked by this code. Better to abort now than to generate duff -+ assembly code. */ -+ if (fix->forwards == 0 && fix->backwards == 0) -+ abort (); -+ -+ if (dump_file) -+ { -+ fprintf (dump_file, -+ ";; %smode fixup for i%d; addr %lu, range (%ld,%ld): ", -+ GET_MODE_NAME (mode), -+ INSN_UID (insn), (unsigned long) address, -+ -1 * (long) fix->backwards, (long) fix->forwards); -+ avr32_print_value (dump_file, fix->value); -+ fprintf (dump_file, "\n"); -+ } -+ -+ /* Add it to the chain of fixes. */ -+ fix->next = NULL; -+ -+ if (minipool_fix_head != NULL) -+ minipool_fix_tail->next = fix; -+ else -+ minipool_fix_head = fix; -+ -+ minipool_fix_tail = fix; -+} -+ -+ -+/* Scan INSN and note any of its operands that need fixing. -+ If DO_PUSHES is false we do not actually push any of the fixups -+ needed. The function returns TRUE is any fixups were needed/pushed. -+ This is used by avr32_memory_load_p() which needs to know about loads -+ of constants that will be converted into minipool loads. */ -+static bool -+note_invalid_constants (rtx insn, HOST_WIDE_INT address, int do_pushes) -+{ -+ bool result = false; -+ int opno; -+ -+ extract_insn (insn); -+ -+ if (!constrain_operands (1)) -+ fatal_insn_not_found (insn); -+ -+ if (recog_data.n_alternatives == 0) -+ return false; -+ -+ /* Fill in recog_op_alt with information about the constraints of this -+ insn. */ -+ preprocess_constraints (); -+ -+ for (opno = 0; opno < recog_data.n_operands; opno++) -+ { -+ rtx op; -+ -+ /* Things we need to fix can only occur in inputs. */ -+ if (recog_data.operand_type[opno] != OP_IN) -+ continue; -+ -+ op = recog_data.operand[opno]; -+ -+ if (avr32_const_pool_ref_operand (op, GET_MODE (op))) -+ { -+ if (do_pushes) -+ { -+ rtx cop = avoid_constant_pool_reference (op); -+ -+ /* Casting the address of something to a mode narrower than a -+ word can cause avoid_constant_pool_reference() to return the -+ pool reference itself. That's no good to us here. Lets -+ just hope that we can use the constant pool value directly. -+ */ -+ if (op == cop) -+ cop = get_pool_constant (XEXP (op, 0)); -+ -+ push_minipool_fix (insn, address, -+ recog_data.operand_loc[opno], -+ recog_data.operand_mode[opno], cop); -+ } -+ -+ result = true; -+ } -+ else if (TARGET_HAS_ASM_ADDR_PSEUDOS -+ && avr32_address_operand (op, GET_MODE (op))) -+ { -+ /* Handle pseudo instructions using a direct address. These pseudo -+ instructions might need entries in the constant pool and we must -+ therefor create a constant pool for them, in case the -+ assembler/linker needs to insert entries. */ -+ if (do_pushes) -+ { -+ /* Push a dummy constant pool entry so that the .cpool -+ directive should be inserted on the appropriate place in the -+ code even if there are no real constant pool entries. This -+ is used by the assembler and linker to know where to put -+ generated constant pool entries. */ -+ push_minipool_fix (insn, address, -+ recog_data.operand_loc[opno], -+ recog_data.operand_mode[opno], -+ gen_rtx_UNSPEC (VOIDmode, -+ gen_rtvec (1, const0_rtx), -+ UNSPEC_FORCE_MINIPOOL)); -+ result = true; -+ } -+ } -+ } -+ return result; -+} -+ -+ -+static int -+avr32_insn_is_cast (rtx insn) -+{ -+ -+ if (NONJUMP_INSN_P (insn) -+ && GET_CODE (PATTERN (insn)) == SET -+ && (GET_CODE (SET_SRC (PATTERN (insn))) == ZERO_EXTEND -+ || GET_CODE (SET_SRC (PATTERN (insn))) == SIGN_EXTEND) -+ && REG_P (XEXP (SET_SRC (PATTERN (insn)), 0)) -+ && REG_P (SET_DEST (PATTERN (insn)))) -+ return true; -+ return false; -+} -+ -+ -+/* Replace all occurances of reg FROM with reg TO in X. */ -+rtx -+avr32_replace_reg (rtx x, rtx from, rtx to) -+{ -+ int i, j; -+ const char *fmt; -+ -+ gcc_assert ( REG_P (from) && REG_P (to) ); -+ -+ /* Allow this function to make replacements in EXPR_LISTs. */ -+ if (x == 0) -+ return 0; -+ -+ if (rtx_equal_p (x, from)) -+ return to; -+ -+ if (GET_CODE (x) == SUBREG) -+ { -+ rtx new = avr32_replace_reg (SUBREG_REG (x), from, to); -+ -+ if (GET_CODE (new) == CONST_INT) -+ { -+ x = simplify_subreg (GET_MODE (x), new, -+ GET_MODE (SUBREG_REG (x)), -+ SUBREG_BYTE (x)); -+ gcc_assert (x); -+ } -+ else -+ SUBREG_REG (x) = new; -+ -+ return x; -+ } -+ else if (GET_CODE (x) == ZERO_EXTEND) -+ { -+ rtx new = avr32_replace_reg (XEXP (x, 0), from, to); -+ -+ if (GET_CODE (new) == CONST_INT) -+ { -+ x = simplify_unary_operation (ZERO_EXTEND, GET_MODE (x), -+ new, GET_MODE (XEXP (x, 0))); -+ gcc_assert (x); -+ } -+ else -+ XEXP (x, 0) = new; -+ -+ return x; -+ } -+ -+ fmt = GET_RTX_FORMAT (GET_CODE (x)); -+ for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--) -+ { -+ if (fmt[i] == 'e') -+ XEXP (x, i) = avr32_replace_reg (XEXP (x, i), from, to); -+ else if (fmt[i] == 'E') -+ for (j = XVECLEN (x, i) - 1; j >= 0; j--) -+ XVECEXP (x, i, j) = avr32_replace_reg (XVECEXP (x, i, j), from, to); -+ } -+ -+ return x; -+} -+ -+ -+/* FIXME: The level of nesting in this function is way too deep. It needs to be -+ torn apart. */ -+static void -+avr32_reorg_optimization (void) -+{ -+ rtx first = get_first_nonnote_insn (); -+ rtx insn; -+ -+ if (TARGET_MD_REORG_OPTIMIZATION && (optimize_size || (optimize > 0))) -+ { -+ -+ /* Scan through all insns looking for cast operations. */ -+ if (dump_file) -+ { -+ fprintf (dump_file, ";; Deleting redundant cast operations:\n"); -+ } -+ for (insn = first; insn; insn = NEXT_INSN (insn)) -+ { -+ rtx reg, src_reg, scan; -+ enum machine_mode mode; -+ int unused_cast; -+ rtx label_ref; -+ -+ if (avr32_insn_is_cast (insn) -+ && (GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 0)) == QImode -+ || GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 0)) == HImode)) -+ { -+ mode = GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 0)); -+ reg = SET_DEST (PATTERN (insn)); -+ src_reg = XEXP (SET_SRC (PATTERN (insn)), 0); -+ } -+ else -+ { -+ continue; -+ } -+ -+ unused_cast = false; -+ label_ref = NULL_RTX; -+ for (scan = NEXT_INSN (insn); scan; scan = NEXT_INSN (scan)) -+ { -+ /* Check if we have reached the destination of a simple -+ conditional jump which we have already scanned past. If so, -+ we can safely continue scanning. */ -+ if (LABEL_P (scan) && label_ref != NULL_RTX) -+ { -+ if (CODE_LABEL_NUMBER (scan) == -+ CODE_LABEL_NUMBER (XEXP (label_ref, 0))) -+ label_ref = NULL_RTX; -+ else -+ break; -+ } -+ -+ if (!INSN_P (scan)) -+ continue; -+ -+ /* For conditional jumps we can manage to keep on scanning if -+ we meet the destination label later on before any new jump -+ insns occure. */ -+ if (GET_CODE (scan) == JUMP_INSN) -+ { -+ if (any_condjump_p (scan) && label_ref == NULL_RTX) -+ label_ref = condjump_label (scan); -+ else -+ break; -+ } -+ -+ /* Check if we have a call and the register is used as an argument. */ -+ if (CALL_P (scan) -+ && find_reg_fusage (scan, USE, reg) ) -+ break; -+ -+ if (!reg_mentioned_p (reg, PATTERN (scan))) -+ continue; -+ -+ /* Check if casted register is used in this insn */ -+ if ((regno_use_in (REGNO (reg), PATTERN (scan)) != NULL_RTX) -+ && (GET_MODE (regno_use_in (REGNO (reg), PATTERN (scan))) == -+ GET_MODE (reg))) -+ { -+ /* If not used in the source to the set or in a memory -+ expression in the destiantion then the register is used -+ as a destination and is really dead. */ -+ if (single_set (scan) -+ && GET_CODE (PATTERN (scan)) == SET -+ && REG_P (SET_DEST (PATTERN (scan))) -+ && !regno_use_in (REGNO (reg), SET_SRC (PATTERN (scan))) -+ && label_ref == NULL_RTX) -+ { -+ unused_cast = true; -+ } -+ break; -+ } -+ -+ /* Check if register is dead or set in this insn */ -+ if (dead_or_set_p (scan, reg)) -+ { -+ unused_cast = true; -+ break; -+ } -+ } -+ -+ /* Check if we have unresolved conditional jumps */ -+ if (label_ref != NULL_RTX) -+ continue; -+ -+ if (unused_cast) -+ { -+ if (REGNO (reg) == REGNO (XEXP (SET_SRC (PATTERN (insn)), 0))) -+ { -+ /* One operand cast, safe to delete */ -+ if (dump_file) -+ { -+ fprintf (dump_file, -+ ";; INSN %i removed, casted register %i value not used.\n", -+ INSN_UID (insn), REGNO (reg)); -+ } -+ SET_INSN_DELETED (insn); -+ /* Force the instruction to be recognized again */ -+ INSN_CODE (insn) = -1; -+ } -+ else -+ { -+ /* Two operand cast, which really could be substituted with -+ a move, if the source register is dead after the cast -+ insn and then the insn which sets the source register -+ could instead directly set the destination register for -+ the cast. As long as there are no insns in between which -+ uses the register. */ -+ rtx link = NULL_RTX; -+ rtx set; -+ rtx src_reg = XEXP (SET_SRC (PATTERN (insn)), 0); -+ unused_cast = false; -+ -+ if (!find_reg_note (insn, REG_DEAD, src_reg)) -+ continue; -+ -+ /* Search for the insn which sets the source register */ -+ for (scan = PREV_INSN (insn); -+ scan && GET_CODE (scan) != CODE_LABEL; -+ scan = PREV_INSN (scan)) -+ { -+ if (! INSN_P (scan)) -+ continue; -+ -+ set = single_set (scan); -+ // Fix for bug #11763 : the following if condition -+ // has been modified and else part is included to -+ // set the link to NULL_RTX. -+ // if (set && rtx_equal_p (src_reg, SET_DEST (set))) -+ if (set && (REGNO(src_reg) == REGNO(SET_DEST(set)))) -+ { -+ if (rtx_equal_p (src_reg, SET_DEST (set))) -+ { -+ link = scan; -+ break; -+ } -+ else -+ { -+ link = NULL_RTX; -+ break; -+ } -+ } -+ } -+ -+ -+ /* Found no link or link is a call insn where we can not -+ change the destination register */ -+ if (link == NULL_RTX || CALL_P (link)) -+ continue; -+ -+ /* Scan through all insn between link and insn */ -+ for (scan = NEXT_INSN (link); scan; scan = NEXT_INSN (scan)) -+ { -+ /* Don't try to trace forward past a CODE_LABEL if we -+ haven't seen INSN yet. Ordinarily, we will only -+ find the setting insn in LOG_LINKS if it is in the -+ same basic block. However, cross-jumping can insert -+ code labels in between the load and the call, and -+ can result in situations where a single call insn -+ may have two targets depending on where we came -+ from. */ -+ -+ if (GET_CODE (scan) == CODE_LABEL) -+ break; -+ -+ if (!INSN_P (scan)) -+ continue; -+ -+ /* Don't try to trace forward past a JUMP. To optimize -+ safely, we would have to check that all the -+ instructions at the jump destination did not use REG. -+ */ -+ -+ if (GET_CODE (scan) == JUMP_INSN) -+ { -+ break; -+ } -+ -+ if (!reg_mentioned_p (src_reg, PATTERN (scan))) -+ continue; -+ -+ /* We have reached the cast insn */ -+ if (scan == insn) -+ { -+ /* We can remove cast and replace the destination -+ register of the link insn with the destination -+ of the cast */ -+ if (dump_file) -+ { -+ fprintf (dump_file, -+ ";; INSN %i removed, casted value unused. " -+ "Destination of removed cast operation: register %i, folded into INSN %i.\n", -+ INSN_UID (insn), REGNO (reg), -+ INSN_UID (link)); -+ } -+ /* Update link insn */ -+ SET_DEST (PATTERN (link)) = -+ gen_rtx_REG (mode, REGNO (reg)); -+ /* Force the instruction to be recognized again */ -+ INSN_CODE (link) = -1; -+ -+ /* Delete insn */ -+ SET_INSN_DELETED (insn); -+ /* Force the instruction to be recognized again */ -+ INSN_CODE (insn) = -1; -+ break; -+ } -+ } -+ } -+ } -+ } -+ } -+ -+ if (TARGET_MD_REORG_OPTIMIZATION && (optimize_size || (optimize > 0))) -+ { -+ -+ /* Scan through all insns looking for shifted add operations */ -+ if (dump_file) -+ { -+ fprintf (dump_file, -+ ";; Deleting redundant shifted add operations:\n"); -+ } -+ for (insn = first; insn; insn = NEXT_INSN (insn)) -+ { -+ rtx reg, mem_expr, scan, op0, op1; -+ int add_only_used_as_pointer; -+ -+ if (INSN_P (insn) -+ && GET_CODE (PATTERN (insn)) == SET -+ && GET_CODE (SET_SRC (PATTERN (insn))) == PLUS -+ && (GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 0)) == MULT -+ || GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 0)) == ASHIFT) -+ && GET_CODE (XEXP (XEXP (SET_SRC (PATTERN (insn)), 0), 1)) == -+ CONST_INT && REG_P (SET_DEST (PATTERN (insn))) -+ && REG_P (XEXP (SET_SRC (PATTERN (insn)), 1)) -+ && REG_P (XEXP (XEXP (SET_SRC (PATTERN (insn)), 0), 0))) -+ { -+ reg = SET_DEST (PATTERN (insn)); -+ mem_expr = SET_SRC (PATTERN (insn)); -+ op0 = XEXP (XEXP (mem_expr, 0), 0); -+ op1 = XEXP (mem_expr, 1); -+ } -+ else -+ { -+ continue; -+ } -+ -+ /* Scan forward the check if the result of the shifted add -+ operation is only used as an address in memory operations and -+ that the operands to the shifted add are not clobbered. */ -+ add_only_used_as_pointer = false; -+ for (scan = NEXT_INSN (insn); scan; scan = NEXT_INSN (scan)) -+ { -+ if (!INSN_P (scan)) -+ continue; -+ -+ /* Don't try to trace forward past a JUMP or CALL. To optimize -+ safely, we would have to check that all the instructions at -+ the jump destination did not use REG. */ -+ -+ if (GET_CODE (scan) == JUMP_INSN) -+ { -+ break; -+ } -+ -+ /* If used in a call insn then we cannot optimize it away */ -+ if (CALL_P (scan) && find_regno_fusage (scan, USE, REGNO (reg))) -+ break; -+ -+ /* If any of the operands of the shifted add are clobbered we -+ cannot optimize the shifted adda away */ -+ if ((reg_set_p (op0, scan) && (REGNO (op0) != REGNO (reg))) -+ || (reg_set_p (op1, scan) && (REGNO (op1) != REGNO (reg)))) -+ break; -+ -+ if (!reg_mentioned_p (reg, PATTERN (scan))) -+ continue; -+ -+ /* If used any other place than as a pointer or as the -+ destination register we failed */ -+ if (!(single_set (scan) -+ && GET_CODE (PATTERN (scan)) == SET -+ && ((MEM_P (SET_DEST (PATTERN (scan))) -+ && REG_P (XEXP (SET_DEST (PATTERN (scan)), 0)) -+ && REGNO (XEXP (SET_DEST (PATTERN (scan)), 0)) == REGNO (reg)) -+ || (MEM_P (SET_SRC (PATTERN (scan))) -+ && REG_P (XEXP (SET_SRC (PATTERN (scan)), 0)) -+ && REGNO (XEXP -+ (SET_SRC (PATTERN (scan)), 0)) == REGNO (reg)))) -+ && !(GET_CODE (PATTERN (scan)) == SET -+ && REG_P (SET_DEST (PATTERN (scan))) -+ && !regno_use_in (REGNO (reg), -+ SET_SRC (PATTERN (scan))))) -+ break; -+ -+ /* We cannot replace the pointer in TImode insns -+ as these has a differene addressing mode than the other -+ memory insns. */ -+ if ( GET_MODE (SET_DEST (PATTERN (scan))) == TImode ) -+ break; -+ -+ /* Check if register is dead or set in this insn */ -+ if (dead_or_set_p (scan, reg)) -+ { -+ add_only_used_as_pointer = true; -+ break; -+ } -+ } -+ -+ if (add_only_used_as_pointer) -+ { -+ /* Lets delete the add insn and replace all memory references -+ which uses the pointer with the full expression. */ -+ if (dump_file) -+ { -+ fprintf (dump_file, -+ ";; Deleting INSN %i since address expression can be folded into all " -+ "memory references using this expression\n", -+ INSN_UID (insn)); -+ } -+ SET_INSN_DELETED (insn); -+ /* Force the instruction to be recognized again */ -+ INSN_CODE (insn) = -1; -+ -+ for (scan = NEXT_INSN (insn); scan; scan = NEXT_INSN (scan)) -+ { -+ if (!INSN_P (scan)) -+ continue; -+ -+ if (!reg_mentioned_p (reg, PATTERN (scan))) -+ continue; -+ -+ /* If used any other place than as a pointer or as the -+ destination register we failed */ -+ if ((single_set (scan) -+ && GET_CODE (PATTERN (scan)) == SET -+ && ((MEM_P (SET_DEST (PATTERN (scan))) -+ && REG_P (XEXP (SET_DEST (PATTERN (scan)), 0)) -+ && REGNO (XEXP (SET_DEST (PATTERN (scan)), 0)) == -+ REGNO (reg)) || (MEM_P (SET_SRC (PATTERN (scan))) -+ && -+ REG_P (XEXP -+ (SET_SRC (PATTERN (scan)), -+ 0)) -+ && -+ REGNO (XEXP -+ (SET_SRC (PATTERN (scan)), -+ 0)) == REGNO (reg))))) -+ { -+ if (dump_file) -+ { -+ fprintf (dump_file, -+ ";; Register %i replaced by indexed address in INSN %i\n", -+ REGNO (reg), INSN_UID (scan)); -+ } -+ if (MEM_P (SET_DEST (PATTERN (scan)))) -+ XEXP (SET_DEST (PATTERN (scan)), 0) = mem_expr; -+ else -+ XEXP (SET_SRC (PATTERN (scan)), 0) = mem_expr; -+ } -+ -+ /* Check if register is dead or set in this insn */ -+ if (dead_or_set_p (scan, reg)) -+ { -+ break; -+ } -+ -+ } -+ } -+ } -+ } -+ -+ -+ if (TARGET_MD_REORG_OPTIMIZATION && (optimize_size || (optimize > 0))) -+ { -+ -+ /* Scan through all insns looking for conditional register to -+ register move operations */ -+ if (dump_file) -+ { -+ fprintf (dump_file, -+ ";; Folding redundant conditional move operations:\n"); -+ } -+ for (insn = first; insn; insn = next_nonnote_insn (insn)) -+ { -+ rtx src_reg, dst_reg, scan, test; -+ -+ if (INSN_P (insn) -+ && GET_CODE (PATTERN (insn)) == COND_EXEC -+ && GET_CODE (COND_EXEC_CODE (PATTERN (insn))) == SET -+ && REG_P (SET_SRC (COND_EXEC_CODE (PATTERN (insn)))) -+ && REG_P (SET_DEST (COND_EXEC_CODE (PATTERN (insn)))) -+ && find_reg_note (insn, REG_DEAD, SET_SRC (COND_EXEC_CODE (PATTERN (insn))))) -+ { -+ src_reg = SET_SRC (COND_EXEC_CODE (PATTERN (insn))); -+ dst_reg = SET_DEST (COND_EXEC_CODE (PATTERN (insn))); -+ test = COND_EXEC_TEST (PATTERN (insn)); -+ } -+ else -+ { -+ continue; -+ } -+ -+ /* Scan backward through the rest of insns in this if-then or if-else -+ block and check if we can fold the move into another of the conditional -+ insns in the same block. */ -+ scan = prev_nonnote_insn (insn); -+ while (INSN_P (scan) -+ && GET_CODE (PATTERN (scan)) == COND_EXEC -+ && rtx_equal_p (COND_EXEC_TEST (PATTERN (scan)), test)) -+ { -+ rtx pattern = COND_EXEC_CODE (PATTERN (scan)); -+ if ( GET_CODE (pattern) == PARALLEL ) -+ pattern = XVECEXP (pattern, 0, 0); -+ -+ if ( reg_set_p (src_reg, pattern) ) -+ { -+ /* Fold in the destination register for the cond. move -+ into this insn. */ -+ SET_DEST (pattern) = dst_reg; -+ if (dump_file) -+ { -+ fprintf (dump_file, -+ ";; Deleting INSN %i since this operation can be folded into INSN %i\n", -+ INSN_UID (insn), INSN_UID (scan)); -+ } -+ -+ /* Scan and check if any of the insns in between uses the src_reg. We -+ must then replace it with the dst_reg. */ -+ while ( (scan = next_nonnote_insn (scan)) != insn ){ -+ avr32_replace_reg (scan, src_reg, dst_reg); -+ } -+ /* Delete the insn. */ -+ SET_INSN_DELETED (insn); -+ -+ /* Force the instruction to be recognized again */ -+ INSN_CODE (insn) = -1; -+ break; -+ } -+ -+ /* If the destination register is used but not set in this insn -+ we cannot fold. */ -+ if ( reg_mentioned_p (dst_reg, pattern) ) -+ break; -+ -+ scan = prev_nonnote_insn (scan); -+ } -+ } -+ } -+ -+} -+ -+ -+/* Exported to toplev.c. -+ -+ Do a final pass over the function, just before delayed branch -+ scheduling. */ -+static void -+avr32_reorg (void) -+{ -+ rtx insn; -+ HOST_WIDE_INT address = 0; -+ Mfix *fix; -+ -+ minipool_fix_head = minipool_fix_tail = NULL; -+ -+ /* The first insn must always be a note, or the code below won't scan it -+ properly. */ -+ insn = get_insns (); -+ if (GET_CODE (insn) != NOTE) -+ abort (); -+ -+ /* Scan all the insns and record the operands that will need fixing. */ -+ for (insn = next_nonnote_insn (insn); insn; insn = next_nonnote_insn (insn)) -+ { -+ if (GET_CODE (insn) == BARRIER) -+ push_minipool_barrier (insn, address); -+ else if (INSN_P (insn)) -+ { -+ rtx table; -+ -+ note_invalid_constants (insn, address, true); -+ address += get_attr_length (insn); -+ -+ /* If the insn is a vector jump, add the size of the table and skip -+ the table. */ -+ if ((table = is_jump_table (insn)) != NULL) -+ { -+ address += get_jump_table_size (table); -+ insn = table; -+ } -+ } -+ } -+ -+ fix = minipool_fix_head; -+ -+ /* Now scan the fixups and perform the required changes. */ -+ while (fix) -+ { -+ Mfix *ftmp; -+ Mfix *fdel; -+ Mfix *last_added_fix; -+ Mfix *last_barrier = NULL; -+ Mfix *this_fix; -+ -+ /* Skip any further barriers before the next fix. */ -+ while (fix && GET_CODE (fix->insn) == BARRIER) -+ fix = fix->next; -+ -+ /* No more fixes. */ -+ if (fix == NULL) -+ break; -+ -+ last_added_fix = NULL; -+ -+ for (ftmp = fix; ftmp; ftmp = ftmp->next) -+ { -+ if (GET_CODE (ftmp->insn) == BARRIER) -+ { -+ if (ftmp->address >= minipool_vector_head->max_address) -+ break; -+ -+ last_barrier = ftmp; -+ } -+ else if ((ftmp->minipool = add_minipool_forward_ref (ftmp)) == NULL) -+ break; -+ -+ last_added_fix = ftmp; /* Keep track of the last fix added. -+ */ -+ } -+ -+ /* If we found a barrier, drop back to that; any fixes that we could -+ have reached but come after the barrier will now go in the next -+ mini-pool. */ -+ if (last_barrier != NULL) -+ { -+ /* Reduce the refcount for those fixes that won't go into this pool -+ after all. */ -+ for (fdel = last_barrier->next; -+ fdel && fdel != ftmp; fdel = fdel->next) -+ { -+ fdel->minipool->refcount--; -+ fdel->minipool = NULL; -+ } -+ -+ ftmp = last_barrier; -+ } -+ else -+ { -+ /* ftmp is first fix that we can't fit into this pool and there no -+ natural barriers that we could use. Insert a new barrier in the -+ code somewhere between the previous fix and this one, and -+ arrange to jump around it. */ -+ HOST_WIDE_INT max_address; -+ -+ /* The last item on the list of fixes must be a barrier, so we can -+ never run off the end of the list of fixes without last_barrier -+ being set. */ -+ if (ftmp == NULL) -+ abort (); -+ -+ max_address = minipool_vector_head->max_address; -+ /* Check that there isn't another fix that is in range that we -+ couldn't fit into this pool because the pool was already too -+ large: we need to put the pool before such an instruction. */ -+ if (ftmp->address < max_address) -+ max_address = ftmp->address; -+ -+ last_barrier = create_fix_barrier (last_added_fix, max_address); -+ } -+ -+ assign_minipool_offsets (last_barrier); -+ -+ while (ftmp) -+ { -+ if (GET_CODE (ftmp->insn) != BARRIER -+ && ((ftmp->minipool = add_minipool_backward_ref (ftmp)) -+ == NULL)) -+ break; -+ -+ ftmp = ftmp->next; -+ } -+ -+ /* Scan over the fixes we have identified for this pool, fixing them up -+ and adding the constants to the pool itself. */ -+ for (this_fix = fix; this_fix && ftmp != this_fix; -+ this_fix = this_fix->next) -+ if (GET_CODE (this_fix->insn) != BARRIER -+ /* Do nothing for entries present just to force the insertion of -+ a minipool. */ -+ && !IS_FORCE_MINIPOOL (this_fix->value)) -+ { -+ rtx addr = plus_constant (gen_rtx_LABEL_REF (VOIDmode, -+ minipool_vector_label), -+ this_fix->minipool->offset); -+ *this_fix->loc = gen_rtx_MEM (this_fix->mode, addr); -+ } -+ -+ dump_minipool (last_barrier->insn); -+ fix = ftmp; -+ } -+ -+ /* Free the minipool memory. */ -+ obstack_free (&minipool_obstack, minipool_startobj); -+ -+ avr32_reorg_optimization (); -+} -+ -+ -+/* Hook for doing some final scanning of instructions. Does nothing yet...*/ -+void -+avr32_final_prescan_insn (rtx insn ATTRIBUTE_UNUSED, -+ rtx * opvec ATTRIBUTE_UNUSED, -+ int noperands ATTRIBUTE_UNUSED) -+{ -+ return; -+} -+ -+ -+/* Function for changing the condition on the next instruction, -+ should be used when emmiting compare instructions and -+ the condition of the next instruction needs to change. -+*/ -+int -+set_next_insn_cond (rtx cur_insn, rtx new_cond) -+{ -+ rtx next_insn = next_nonnote_insn (cur_insn); -+ if ((next_insn != NULL_RTX) -+ && (INSN_P (next_insn))) -+ { -+ if ((GET_CODE (PATTERN (next_insn)) == SET) -+ && (GET_CODE (SET_SRC (PATTERN (next_insn))) == IF_THEN_ELSE)) -+ { -+ /* Branch instructions */ -+ XEXP (SET_SRC (PATTERN (next_insn)), 0) = new_cond; -+ /* Force the instruction to be recognized again */ -+ INSN_CODE (next_insn) = -1; -+ return TRUE; -+ } -+ else if ((GET_CODE (PATTERN (next_insn)) == SET) -+ && avr32_comparison_operator (SET_SRC (PATTERN (next_insn)), -+ GET_MODE (SET_SRC (PATTERN (next_insn))))) -+ { -+ /* scc with no compare */ -+ SET_SRC (PATTERN (next_insn)) = new_cond; -+ /* Force the instruction to be recognized again */ -+ INSN_CODE (next_insn) = -1; -+ return TRUE; -+ } -+ else if (GET_CODE (PATTERN (next_insn)) == COND_EXEC) -+ { -+ if ( GET_CODE (new_cond) == UNSPEC ) -+ { -+ COND_EXEC_TEST (PATTERN (next_insn)) = -+ gen_rtx_UNSPEC (CCmode, -+ gen_rtvec (2, -+ XEXP (COND_EXEC_TEST (PATTERN (next_insn)), 0), -+ XEXP (COND_EXEC_TEST (PATTERN (next_insn)), 1)), -+ XINT (new_cond, 1)); -+ } -+ else -+ { -+ PUT_CODE(COND_EXEC_TEST (PATTERN (next_insn)), GET_CODE(new_cond)); -+ } -+ } -+ } -+ -+ return FALSE; -+} -+ -+ -+/* Function for obtaining the condition for the next instruction after cur_insn. -+*/ -+rtx -+get_next_insn_cond (rtx cur_insn) -+{ -+ rtx next_insn = next_nonnote_insn (cur_insn); -+ rtx cond = NULL_RTX; -+ if (next_insn != NULL_RTX -+ && INSN_P (next_insn)) -+ { -+ if ((GET_CODE (PATTERN (next_insn)) == SET) -+ && (GET_CODE (SET_SRC (PATTERN (next_insn))) == IF_THEN_ELSE)) -+ { -+ /* Branch and cond if then else instructions */ -+ cond = XEXP (SET_SRC (PATTERN (next_insn)), 0); -+ } -+ else if ((GET_CODE (PATTERN (next_insn)) == SET) -+ && avr32_comparison_operator (SET_SRC (PATTERN (next_insn)), -+ GET_MODE (SET_SRC (PATTERN (next_insn))))) -+ { -+ /* scc with no compare */ -+ cond = SET_SRC (PATTERN (next_insn)); -+ } -+ else if (GET_CODE (PATTERN (next_insn)) == COND_EXEC) -+ { -+ cond = COND_EXEC_TEST (PATTERN (next_insn)); -+ } -+ } -+ return cond; -+} -+ -+ -+/* Check if the next insn is a conditional insn that will emit a compare -+ for itself. -+*/ -+rtx -+next_insn_emits_cmp (rtx cur_insn) -+{ -+ rtx next_insn = next_nonnote_insn (cur_insn); -+ rtx cond = NULL_RTX; -+ if (next_insn != NULL_RTX -+ && INSN_P (next_insn)) -+ { -+ if ( ((GET_CODE (PATTERN (next_insn)) == SET) -+ && (GET_CODE (SET_SRC (PATTERN (next_insn))) == IF_THEN_ELSE) -+ && (XEXP (XEXP (SET_SRC (PATTERN (next_insn)), 0),0) != cc0_rtx)) -+ || GET_CODE (PATTERN (next_insn)) == COND_EXEC ) -+ return TRUE; -+ } -+ return FALSE; -+} -+ -+ -+rtx -+avr32_output_cmp (rtx cond, enum machine_mode mode, rtx op0, rtx op1) -+{ -+ -+ rtx new_cond = NULL_RTX; -+ rtx ops[2]; -+ rtx compare_pattern; -+ ops[0] = op0; -+ ops[1] = op1; -+ -+ if ( GET_CODE (op0) == AND ) -+ compare_pattern = op0; -+ else -+ compare_pattern = gen_rtx_COMPARE (mode, op0, op1); -+ -+ new_cond = is_compare_redundant (compare_pattern, cond); -+ -+ if (new_cond != NULL_RTX) -+ return new_cond; -+ -+ /* Check if we are inserting a bit-load instead of a compare. */ -+ if ( GET_CODE (op0) == AND ) -+ { -+ ops[0] = XEXP (op0, 0); -+ ops[1] = XEXP (op0, 1); -+ output_asm_insn ("bld\t%0, %p1", ops); -+ return cond; -+ } -+ -+ /* Insert compare */ -+ switch (mode) -+ { -+ case QImode: -+ output_asm_insn ("cp.b\t%0, %1", ops); -+ break; -+ case HImode: -+ output_asm_insn ("cp.h\t%0, %1", ops); -+ break; -+ case SImode: -+ output_asm_insn ("cp.w\t%0, %1", ops); -+ break; -+ case DImode: -+ if (GET_CODE (op1) != REG) -+ output_asm_insn ("cp.w\t%0, %1\ncpc\t%m0", ops); -+ else -+ output_asm_insn ("cp.w\t%0, %1\ncpc\t%m0, %m1", ops); -+ break; -+ default: -+ internal_error ("Unknown comparison mode"); -+ break; -+ } -+ -+ return cond; -+} -+ -+ -+int -+avr32_load_multiple_operation (rtx op, -+ enum machine_mode mode ATTRIBUTE_UNUSED) -+{ -+ int count = XVECLEN (op, 0); -+ unsigned int dest_regno; -+ rtx src_addr; -+ rtx elt; -+ int i = 1, base = 0; -+ -+ if (count <= 1 || GET_CODE (XVECEXP (op, 0, 0)) != SET) -+ return 0; -+ -+ /* Check to see if this might be a write-back. */ -+ if (GET_CODE (SET_SRC (elt = XVECEXP (op, 0, 0))) == PLUS) -+ { -+ i++; -+ base = 1; -+ -+ /* Now check it more carefully. */ -+ if (GET_CODE (SET_DEST (elt)) != REG -+ || GET_CODE (XEXP (SET_SRC (elt), 0)) != REG -+ || GET_CODE (XEXP (SET_SRC (elt), 1)) != CONST_INT -+ || INTVAL (XEXP (SET_SRC (elt), 1)) != (count - 1) * 4) -+ return 0; -+ } -+ -+ /* Perform a quick check so we don't blow up below. */ -+ if (count <= 1 -+ || GET_CODE (XVECEXP (op, 0, i - 1)) != SET -+ || GET_CODE (SET_DEST (XVECEXP (op, 0, i - 1))) != REG -+ || GET_CODE (SET_SRC (XVECEXP (op, 0, i - 1))) != UNSPEC) -+ return 0; -+ -+ dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, i - 1))); -+ src_addr = XEXP (SET_SRC (XVECEXP (op, 0, i - 1)), 0); -+ -+ for (; i < count; i++) -+ { -+ elt = XVECEXP (op, 0, i); -+ -+ if (GET_CODE (elt) != SET -+ || GET_CODE (SET_DEST (elt)) != REG -+ || GET_MODE (SET_DEST (elt)) != SImode -+ || GET_CODE (SET_SRC (elt)) != UNSPEC) -+ return 0; -+ } -+ -+ return 1; -+} -+ -+ -+int -+avr32_store_multiple_operation (rtx op, -+ enum machine_mode mode ATTRIBUTE_UNUSED) -+{ -+ int count = XVECLEN (op, 0); -+ int src_regno; -+ rtx dest_addr; -+ rtx elt; -+ int i = 1; -+ -+ if (count <= 1 || GET_CODE (XVECEXP (op, 0, 0)) != SET) -+ return 0; -+ -+ /* Perform a quick check so we don't blow up below. */ -+ if (count <= i -+ || GET_CODE (XVECEXP (op, 0, i - 1)) != SET -+ || GET_CODE (SET_DEST (XVECEXP (op, 0, i - 1))) != MEM -+ || GET_CODE (SET_SRC (XVECEXP (op, 0, i - 1))) != UNSPEC) -+ return 0; -+ -+ src_regno = REGNO (SET_SRC (XVECEXP (op, 0, i - 1))); -+ dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, i - 1)), 0); -+ -+ for (; i < count; i++) -+ { -+ elt = XVECEXP (op, 0, i); -+ -+ if (GET_CODE (elt) != SET -+ || GET_CODE (SET_DEST (elt)) != MEM -+ || GET_MODE (SET_DEST (elt)) != SImode -+ || GET_CODE (SET_SRC (elt)) != UNSPEC) -+ return 0; -+ } -+ -+ return 1; -+} -+ -+ -+int -+avr32_valid_macmac_bypass (rtx insn_out, rtx insn_in) -+{ -+ /* Check if they use the same accumulator */ -+ if (rtx_equal_p -+ (SET_DEST (PATTERN (insn_out)), SET_DEST (PATTERN (insn_in)))) -+ { -+ return TRUE; -+ } -+ -+ return FALSE; -+} -+ -+ -+int -+avr32_valid_mulmac_bypass (rtx insn_out, rtx insn_in) -+{ -+ /* -+ Check if the mul instruction produces the accumulator for the mac -+ instruction. */ -+ if (rtx_equal_p -+ (SET_DEST (PATTERN (insn_out)), SET_DEST (PATTERN (insn_in)))) -+ { -+ return TRUE; -+ } -+ return FALSE; -+} -+ -+ -+int -+avr32_store_bypass (rtx insn_out, rtx insn_in) -+{ -+ /* Only valid bypass if the output result is used as an src in the store -+ instruction, NOT if used as a pointer or base. */ -+ if (rtx_equal_p -+ (SET_DEST (PATTERN (insn_out)), SET_SRC (PATTERN (insn_in)))) -+ { -+ return TRUE; -+ } -+ -+ return FALSE; -+} -+ -+ -+int -+avr32_mul_waw_bypass (rtx insn_out, rtx insn_in) -+{ -+ /* Check if the register holding the result from the mul instruction is -+ used as a result register in the input instruction. */ -+ if (rtx_equal_p -+ (SET_DEST (PATTERN (insn_out)), SET_DEST (PATTERN (insn_in)))) -+ { -+ return TRUE; -+ } -+ -+ return FALSE; -+} -+ -+ -+int -+avr32_valid_load_double_bypass (rtx insn_out, rtx insn_in) -+{ -+ /* Check if the first loaded word in insn_out is used in insn_in. */ -+ rtx dst_reg; -+ rtx second_loaded_reg; -+ -+ /* If this is a double alu operation then the bypass is not valid */ -+ if ((get_attr_type (insn_in) == TYPE_ALU -+ || get_attr_type (insn_in) == TYPE_ALU2) -+ && (GET_MODE_SIZE (GET_MODE (SET_DEST (PATTERN (insn_out)))) > 4)) -+ return FALSE; -+ -+ /* Get the destination register in the load */ -+ if (!REG_P (SET_DEST (PATTERN (insn_out)))) -+ return FALSE; -+ -+ dst_reg = SET_DEST (PATTERN (insn_out)); -+ second_loaded_reg = gen_rtx_REG (SImode, REGNO (dst_reg) + 1); -+ -+ if (!reg_mentioned_p (second_loaded_reg, PATTERN (insn_in))) -+ return TRUE; -+ -+ return FALSE; -+} -+ -+ -+int -+avr32_valid_load_quad_bypass (rtx insn_out, rtx insn_in) -+{ -+ /* -+ Check if the two first loaded word in insn_out are used in insn_in. */ -+ rtx dst_reg; -+ rtx third_loaded_reg, fourth_loaded_reg; -+ -+ /* Get the destination register in the load */ -+ if (!REG_P (SET_DEST (PATTERN (insn_out)))) -+ return FALSE; -+ -+ dst_reg = SET_DEST (PATTERN (insn_out)); -+ third_loaded_reg = gen_rtx_REG (SImode, REGNO (dst_reg) + 2); -+ fourth_loaded_reg = gen_rtx_REG (SImode, REGNO (dst_reg) + 3); -+ -+ if (!reg_mentioned_p (third_loaded_reg, PATTERN (insn_in)) -+ && !reg_mentioned_p (fourth_loaded_reg, PATTERN (insn_in))) -+ { -+ return TRUE; -+ } -+ -+ return FALSE; -+} -+ -+ -+rtx -+avr32_ifcvt_modify_test (ce_if_block_t *ce_info, rtx test ) -+{ -+ rtx branch_insn; -+ rtx cmp_test; -+ rtx compare_op0; -+ rtx compare_op1; -+ -+ -+ if ( !ce_info -+ || test == NULL_RTX -+ || !reg_mentioned_p (cc0_rtx, test)) -+ return test; -+ -+ branch_insn = BB_END (ce_info->test_bb); -+ cmp_test = PATTERN(prev_nonnote_insn (branch_insn)); -+ -+ if (GET_CODE(cmp_test) != SET -+ || !CC0_P(XEXP(cmp_test, 0)) ) -+ return cmp_test; -+ -+ if ( GET_CODE(SET_SRC(cmp_test)) == COMPARE ){ -+ compare_op0 = XEXP(SET_SRC(cmp_test), 0); -+ compare_op1 = XEXP(SET_SRC(cmp_test), 1); -+ } else { -+ compare_op0 = SET_SRC(cmp_test); -+ compare_op1 = const0_rtx; -+ } -+ -+ return gen_rtx_fmt_ee (GET_CODE(test), GET_MODE (compare_op0), -+ compare_op0, compare_op1); -+} -+ -+ -+rtx -+avr32_ifcvt_modify_insn (ce_if_block_t *ce_info, rtx pattern, rtx insn, -+ int *num_true_changes) -+{ -+ rtx test = COND_EXEC_TEST(pattern); -+ rtx op = COND_EXEC_CODE(pattern); -+ rtx cmp_insn; -+ rtx cond_exec_insn; -+ int inputs_set_outside_ifblock = 1; -+ basic_block current_bb = BLOCK_FOR_INSN (insn); -+ rtx bb_insn ; -+ enum machine_mode mode = GET_MODE (XEXP (op, 0)); -+ -+ if (CC0_P(XEXP(test, 0))) -+ test = avr32_ifcvt_modify_test (ce_info, -+ test ); -+ -+ /* We do not support multiple tests. */ -+ if ( ce_info -+ && ce_info->num_multiple_test_blocks > 0 ) -+ return NULL_RTX; -+ -+ pattern = gen_rtx_COND_EXEC (VOIDmode, test, op); -+ -+ if ( !reload_completed ) -+ { -+ rtx start; -+ int num_insns; -+ int max_insns = MAX_CONDITIONAL_EXECUTE; -+ -+ if ( !ce_info ) -+ return op; -+ -+ /* Check if the insn is not suitable for conditional -+ execution. */ -+ start_sequence (); -+ cond_exec_insn = emit_insn (pattern); -+ if ( recog_memoized (cond_exec_insn) < 0 -+ && can_create_pseudo_p () ) -+ { -+ /* Insn is not suitable for conditional execution, try -+ to fix it up by using an extra scratch register or -+ by pulling the operation outside the if-then-else -+ and then emiting a conditional move inside the if-then-else. */ -+ end_sequence (); -+ if ( GET_CODE (op) != SET -+ || !REG_P (SET_DEST (op)) -+ || GET_CODE (SET_SRC (op)) == IF_THEN_ELSE -+ || GET_MODE_SIZE (mode) > UNITS_PER_WORD ) -+ return NULL_RTX; -+ -+ /* Check if any of the input operands to the insn is set inside the -+ current block. */ -+ if ( current_bb->index == ce_info->then_bb->index ) -+ start = PREV_INSN (BB_HEAD (ce_info->then_bb)); -+ else -+ start = PREV_INSN (BB_HEAD (ce_info->else_bb)); -+ -+ -+ for ( bb_insn = next_nonnote_insn (start); bb_insn != insn; bb_insn = next_nonnote_insn (bb_insn) ) -+ { -+ rtx set = single_set (bb_insn); -+ -+ if ( set && reg_mentioned_p (SET_DEST (set), SET_SRC (op))) -+ { -+ inputs_set_outside_ifblock = 0; -+ break; -+ } -+ } -+ -+ cmp_insn = prev_nonnote_insn (BB_END (ce_info->test_bb)); -+ -+ -+ /* Check if we can insert more insns. */ -+ num_insns = ( ce_info->num_then_insns + -+ ce_info->num_else_insns + -+ ce_info->num_cond_clobber_insns + -+ ce_info->num_extra_move_insns ); -+ -+ if ( ce_info->num_else_insns != 0 ) -+ max_insns *=2; -+ -+ if ( num_insns >= max_insns ) -+ return NULL_RTX; -+ -+ /* Check if we have an instruction which might be converted to -+ conditional form if we give it a scratch register to clobber. */ -+ { -+ rtx clobber_insn; -+ rtx scratch_reg = gen_reg_rtx (mode); -+ rtx new_pattern = copy_rtx (pattern); -+ rtx set_src = SET_SRC (COND_EXEC_CODE (new_pattern)); -+ -+ rtx clobber = gen_rtx_CLOBBER (mode, scratch_reg); -+ rtx vec[2] = { COND_EXEC_CODE (new_pattern), clobber }; -+ COND_EXEC_CODE (new_pattern) = gen_rtx_PARALLEL (mode, gen_rtvec_v (2, vec)); -+ -+ start_sequence (); -+ clobber_insn = emit_insn (new_pattern); -+ -+ if ( recog_memoized (clobber_insn) >= 0 -+ && ( ( GET_RTX_LENGTH (GET_CODE (set_src)) == 2 -+ && CONST_INT_P (XEXP (set_src, 1)) -+ && avr32_const_ok_for_constraint_p (INTVAL (XEXP (set_src, 1)), 'K', "Ks08") ) -+ || !ce_info->else_bb -+ || current_bb->index == ce_info->else_bb->index )) -+ { -+ end_sequence (); -+ /* Force the insn to be recognized again. */ -+ INSN_CODE (insn) = -1; -+ -+ /* If this is the first change in this IF-block then -+ signal that we have made a change. */ -+ if ( ce_info->num_cond_clobber_insns == 0 -+ && ce_info->num_extra_move_insns == 0 ) -+ *num_true_changes += 1; -+ -+ ce_info->num_cond_clobber_insns++; -+ -+ if (dump_file) -+ fprintf (dump_file, -+ "\nReplacing INSN %d with an insn using a scratch register for later ifcvt passes...\n", -+ INSN_UID (insn)); -+ -+ return COND_EXEC_CODE (new_pattern); -+ } -+ end_sequence (); -+ } -+ -+ if ( inputs_set_outside_ifblock ) -+ { -+ /* Check if the insn before the cmp is an and which used -+ together with the cmp can be optimized into a bld. If -+ so then we should try to put the insn before the and -+ so that we can catch the bld peephole. */ -+ rtx set; -+ rtx insn_before_cmp_insn = prev_nonnote_insn (cmp_insn); -+ if (insn_before_cmp_insn -+ && (set = single_set (insn_before_cmp_insn)) -+ && GET_CODE (SET_SRC (set)) == AND -+ && one_bit_set_operand (XEXP (SET_SRC (set), 1), SImode) -+ /* Also make sure that the insn does not set any -+ of the input operands to the insn we are pulling out. */ -+ && !reg_mentioned_p (SET_DEST (set), SET_SRC (op)) ) -+ cmp_insn = prev_nonnote_insn (cmp_insn); -+ -+ /* We can try to put the operation outside the if-then-else -+ blocks and insert a move. */ -+ if ( !insn_invalid_p (insn) -+ /* Do not allow conditional insns to be moved outside the -+ if-then-else. */ -+ && !reg_mentioned_p (cc0_rtx, insn) -+ /* We cannot move memory loads outside of the if-then-else -+ since the memory access should not be perfomed if the -+ condition is not met. */ -+ && !mem_mentioned_p (SET_SRC (op)) ) -+ { -+ rtx scratch_reg = gen_reg_rtx (mode); -+ rtx op_pattern = copy_rtx (op); -+ rtx new_insn, seq; -+ rtx link, prev_link; -+ op = copy_rtx (op); -+ /* Emit the operation to a temp reg before the compare, -+ and emit a move inside the if-then-else, hoping that the -+ whole if-then-else can be converted to conditional -+ execution. */ -+ SET_DEST (op_pattern) = scratch_reg; -+ start_sequence (); -+ new_insn = emit_insn (op_pattern); -+ seq = get_insns(); -+ end_sequence (); -+ -+ /* Check again that the insn is valid. For some insns the insn might -+ become invalid if the destination register is changed. Ie. for mulacc -+ operations. */ -+ if ( insn_invalid_p (new_insn) ) -+ return NULL_RTX; -+ -+ emit_insn_before_setloc (seq, cmp_insn, INSN_LOCATOR (insn)); -+ -+ if (dump_file) -+ fprintf (dump_file, -+ "\nMoving INSN %d out of IF-block by adding INSN %d...\n", -+ INSN_UID (insn), INSN_UID (new_insn)); -+ -+ ce_info->extra_move_insns[ce_info->num_extra_move_insns] = insn; -+ ce_info->moved_insns[ce_info->num_extra_move_insns] = new_insn; -+ XEXP (op, 1) = scratch_reg; -+ /* Force the insn to be recognized again. */ -+ INSN_CODE (insn) = -1; -+ -+ /* Move REG_DEAD notes to the moved insn. */ -+ prev_link = NULL_RTX; -+ for (link = REG_NOTES (insn); link; link = XEXP (link, 1)) -+ { -+ if (REG_NOTE_KIND (link) == REG_DEAD) -+ { -+ /* Add the REG_DEAD note to the new insn. */ -+ rtx dead_reg = XEXP (link, 0); -+ REG_NOTES (new_insn) = gen_rtx_EXPR_LIST (REG_DEAD, dead_reg, REG_NOTES (new_insn)); -+ /* Remove the REG_DEAD note from the insn we convert to a move. */ -+ if ( prev_link ) -+ XEXP (prev_link, 1) = XEXP (link, 1); -+ else -+ REG_NOTES (insn) = XEXP (link, 1); -+ } -+ else -+ { -+ prev_link = link; -+ } -+ } -+ /* Add a REG_DEAD note to signal that the scratch register is dead. */ -+ REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_DEAD, scratch_reg, REG_NOTES (insn)); -+ -+ /* If this is the first change in this IF-block then -+ signal that we have made a change. */ -+ if ( ce_info->num_cond_clobber_insns == 0 -+ && ce_info->num_extra_move_insns == 0 ) -+ *num_true_changes += 1; -+ -+ ce_info->num_extra_move_insns++; -+ return op; -+ } -+ } -+ -+ /* We failed to fixup the insns, so this if-then-else can not be made -+ conditional. Just return NULL_RTX so that the if-then-else conversion -+ for this if-then-else will be cancelled. */ -+ return NULL_RTX; -+ } -+ end_sequence (); -+ return op; -+ } -+ -+ /* Signal that we have started if conversion after reload, which means -+ that it should be safe to split all the predicable clobber insns which -+ did not become cond_exec back into a simpler form if possible. */ -+ cfun->machine->ifcvt_after_reload = 1; -+ -+ return pattern; -+} -+ -+ -+void -+avr32_ifcvt_modify_cancel ( ce_if_block_t *ce_info, int *num_true_changes) -+{ -+ int n; -+ -+ if ( ce_info->num_extra_move_insns > 0 -+ && ce_info->num_cond_clobber_insns == 0) -+ /* Signal that we did not do any changes after all. */ -+ *num_true_changes -= 1; -+ -+ /* Remove any inserted move insns. */ -+ for ( n = 0; n < ce_info->num_extra_move_insns; n++ ) -+ { -+ rtx link, prev_link; -+ -+ /* Remove REG_DEAD note since we are not needing the scratch register anyway. */ -+ prev_link = NULL_RTX; -+ for (link = REG_NOTES (ce_info->extra_move_insns[n]); link; link = XEXP (link, 1)) -+ { -+ if (REG_NOTE_KIND (link) == REG_DEAD) -+ { -+ if ( prev_link ) -+ XEXP (prev_link, 1) = XEXP (link, 1); -+ else -+ REG_NOTES (ce_info->extra_move_insns[n]) = XEXP (link, 1); -+ } -+ else -+ { -+ prev_link = link; -+ } -+ } -+ -+ /* Revert all reg_notes for the moved insn. */ -+ for (link = REG_NOTES (ce_info->moved_insns[n]); link; link = XEXP (link, 1)) -+ { -+ REG_NOTES (ce_info->extra_move_insns[n]) = gen_rtx_EXPR_LIST (REG_NOTE_KIND (link), -+ XEXP (link, 0), -+ REG_NOTES (ce_info->extra_move_insns[n])); -+ } -+ -+ /* Remove the moved insn. */ -+ remove_insn ( ce_info->moved_insns[n] ); -+ } -+} -+ -+ -+/* Function returning TRUE if INSN with OPERANDS is a splittable -+ conditional immediate clobber insn. We assume that the insn is -+ already a conditional immediate clobber insns and do not check -+ for that. */ -+int -+avr32_cond_imm_clobber_splittable (rtx insn, rtx operands[]) -+{ -+ if ( REGNO (operands[0]) == REGNO (operands[1]) ) -+ { -+ if ( (GET_CODE (SET_SRC (XVECEXP (PATTERN (insn),0,0))) == PLUS -+ && !avr32_const_ok_for_constraint_p (INTVAL (operands[2]), 'I', "Is21")) -+ || (GET_CODE (SET_SRC (XVECEXP (PATTERN (insn),0,0))) == MINUS -+ && !avr32_const_ok_for_constraint_p (INTVAL (operands[2]), 'K', "Ks21"))) -+ return FALSE; -+ } -+ else if ( (logical_binary_operator (SET_SRC (XVECEXP (PATTERN (insn),0,0)), VOIDmode) -+ || (GET_CODE (SET_SRC (XVECEXP (PATTERN (insn),0,0))) == PLUS -+ && !avr32_const_ok_for_constraint_p (INTVAL (operands[2]), 'I', "Is16")) -+ || (GET_CODE (SET_SRC (XVECEXP (PATTERN (insn),0,0))) == MINUS -+ && !avr32_const_ok_for_constraint_p (INTVAL (operands[2]), 'K', "Ks16"))) ) -+ return FALSE; -+ -+ return TRUE; -+} -+ -+ -+/* Function for getting an integer value from a const_int or const_double -+ expression regardless of the HOST_WIDE_INT size. Each target cpu word -+ will be put into the val array where the LSW will be stored at the lowest -+ address and so forth. Assumes that const_expr is either a const_int or -+ const_double. Only valid for modes which have sizes that are a multiple -+ of the word size. -+*/ -+void -+avr32_get_intval (enum machine_mode mode, rtx const_expr, HOST_WIDE_INT *val) -+{ -+ int words_in_mode = GET_MODE_SIZE (mode)/UNITS_PER_WORD; -+ const int words_in_const_int = HOST_BITS_PER_WIDE_INT / BITS_PER_WORD; -+ -+ if ( GET_CODE(const_expr) == CONST_DOUBLE ){ -+ HOST_WIDE_INT hi = CONST_DOUBLE_HIGH(const_expr); -+ HOST_WIDE_INT lo = CONST_DOUBLE_LOW(const_expr); -+ /* Evaluate hi and lo values of const_double. */ -+ avr32_get_intval (mode_for_size (HOST_BITS_PER_WIDE_INT, MODE_INT, 0), -+ GEN_INT (lo), -+ &val[0]); -+ avr32_get_intval (mode_for_size (HOST_BITS_PER_WIDE_INT, MODE_INT, 0), -+ GEN_INT (hi), -+ &val[words_in_const_int]); -+ } else if ( GET_CODE(const_expr) == CONST_INT ){ -+ HOST_WIDE_INT value = INTVAL(const_expr); -+ int word; -+ for ( word = 0; (word < words_in_mode) && (word < words_in_const_int); word++ ){ -+ /* Shift word up to the MSW and shift down again to extract the -+ word and sign-extend. */ -+ int lshift = (words_in_const_int - word - 1) * BITS_PER_WORD; -+ int rshift = (words_in_const_int-1) * BITS_PER_WORD; -+ val[word] = (value << lshift) >> rshift; -+ } -+ -+ for ( ; word < words_in_mode; word++ ){ -+ /* Just put the sign bits in the remaining words. */ -+ val[word] = value < 0 ? -1 : 0; -+ } -+ } -+} -+ -+ -+void -+avr32_split_const_expr (enum machine_mode mode, enum machine_mode new_mode, -+ rtx expr, rtx *split_expr) -+{ -+ int i, word; -+ int words_in_intval = GET_MODE_SIZE (mode)/UNITS_PER_WORD; -+ int words_in_split_values = GET_MODE_SIZE (new_mode)/UNITS_PER_WORD; -+ const int words_in_const_int = HOST_BITS_PER_WIDE_INT / BITS_PER_WORD; -+ HOST_WIDE_INT *val = alloca (words_in_intval * UNITS_PER_WORD); -+ -+ avr32_get_intval (mode, expr, val); -+ -+ for ( i=0; i < (words_in_intval/words_in_split_values); i++ ) -+ { -+ HOST_WIDE_INT value_lo = 0, value_hi = 0; -+ for ( word = 0; word < words_in_split_values; word++ ) -+ { -+ if ( word >= words_in_const_int ) -+ value_hi |= ((val[i * words_in_split_values + word] & -+ (((HOST_WIDE_INT)1 << BITS_PER_WORD)-1)) -+ << (BITS_PER_WORD * (word - words_in_const_int))); -+ else -+ value_lo |= ((val[i * words_in_split_values + word] & -+ (((HOST_WIDE_INT)1 << BITS_PER_WORD)-1)) -+ << (BITS_PER_WORD * word)); -+ } -+ split_expr[i] = immed_double_const(value_lo, value_hi, new_mode); -+ } -+} -+ -+ -+/* Set up library functions to comply to AVR32 ABI */ -+static void -+avr32_init_libfuncs (void) -+{ -+ /* Convert gcc run-time function names to AVR32 ABI names */ -+ -+ /* Double-precision floating-point arithmetic. */ -+ set_optab_libfunc (neg_optab, DFmode, NULL); -+ -+ /* Double-precision comparisons. */ -+ set_optab_libfunc (eq_optab, DFmode, "__avr32_f64_cmp_eq"); -+ set_optab_libfunc (ne_optab, DFmode, NULL); -+ set_optab_libfunc (lt_optab, DFmode, "__avr32_f64_cmp_lt"); -+ set_optab_libfunc (le_optab, DFmode, NULL); -+ set_optab_libfunc (ge_optab, DFmode, "__avr32_f64_cmp_ge"); -+ set_optab_libfunc (gt_optab, DFmode, NULL); -+ -+ /* Single-precision floating-point arithmetic. */ -+ set_optab_libfunc (smul_optab, SFmode, "__avr32_f32_mul"); -+ set_optab_libfunc (neg_optab, SFmode, NULL); -+ -+ /* Single-precision comparisons. */ -+ set_optab_libfunc (eq_optab, SFmode, "__avr32_f32_cmp_eq"); -+ set_optab_libfunc (ne_optab, SFmode, NULL); -+ set_optab_libfunc (lt_optab, SFmode, "__avr32_f32_cmp_lt"); -+ set_optab_libfunc (le_optab, SFmode, NULL); -+ set_optab_libfunc (ge_optab, SFmode, "__avr32_f32_cmp_ge"); -+ set_optab_libfunc (gt_optab, SFmode, NULL); -+ -+ /* Floating-point to integer conversions. */ -+ set_conv_libfunc (sfix_optab, SImode, DFmode, "__avr32_f64_to_s32"); -+ set_conv_libfunc (ufix_optab, SImode, DFmode, "__avr32_f64_to_u32"); -+ set_conv_libfunc (sfix_optab, DImode, DFmode, "__avr32_f64_to_s64"); -+ set_conv_libfunc (ufix_optab, DImode, DFmode, "__avr32_f64_to_u64"); -+ set_conv_libfunc (sfix_optab, SImode, SFmode, "__avr32_f32_to_s32"); -+ set_conv_libfunc (ufix_optab, SImode, SFmode, "__avr32_f32_to_u32"); -+ set_conv_libfunc (sfix_optab, DImode, SFmode, "__avr32_f32_to_s64"); -+ set_conv_libfunc (ufix_optab, DImode, SFmode, "__avr32_f32_to_u64"); -+ -+ /* Conversions between floating types. */ -+ set_conv_libfunc (trunc_optab, SFmode, DFmode, "__avr32_f64_to_f32"); -+ set_conv_libfunc (sext_optab, DFmode, SFmode, "__avr32_f32_to_f64"); -+ -+ /* Integer to floating-point conversions. Table 8. */ -+ set_conv_libfunc (sfloat_optab, DFmode, SImode, "__avr32_s32_to_f64"); -+ set_conv_libfunc (sfloat_optab, DFmode, DImode, "__avr32_s64_to_f64"); -+ set_conv_libfunc (sfloat_optab, SFmode, SImode, "__avr32_s32_to_f32"); -+ set_conv_libfunc (sfloat_optab, SFmode, DImode, "__avr32_s64_to_f32"); -+ set_conv_libfunc (ufloat_optab, DFmode, SImode, "__avr32_u32_to_f64"); -+ set_conv_libfunc (ufloat_optab, SFmode, SImode, "__avr32_u32_to_f32"); -+ /* TODO: Add these to gcc library functions */ -+ //set_conv_libfunc (ufloat_optab, DFmode, DImode, NULL); -+ //set_conv_libfunc (ufloat_optab, SFmode, DImode, NULL); -+ -+ /* Long long. Table 9. */ -+ set_optab_libfunc (smul_optab, DImode, "__avr32_mul64"); -+ set_optab_libfunc (sdiv_optab, DImode, "__avr32_sdiv64"); -+ set_optab_libfunc (udiv_optab, DImode, "__avr32_udiv64"); -+ set_optab_libfunc (smod_optab, DImode, "__avr32_smod64"); -+ set_optab_libfunc (umod_optab, DImode, "__avr32_umod64"); -+ set_optab_libfunc (ashl_optab, DImode, "__avr32_lsl64"); -+ set_optab_libfunc (lshr_optab, DImode, "__avr32_lsr64"); -+ set_optab_libfunc (ashr_optab, DImode, "__avr32_asr64"); -+ -+ /* Floating point library functions which have fast versions. */ -+ if ( TARGET_FAST_FLOAT ) -+ { -+ set_optab_libfunc (sdiv_optab, DFmode, "__avr32_f64_div_fast"); -+ set_optab_libfunc (smul_optab, DFmode, "__avr32_f64_mul_fast"); -+ set_optab_libfunc (add_optab, DFmode, "__avr32_f64_add_fast"); -+ set_optab_libfunc (sub_optab, DFmode, "__avr32_f64_sub_fast"); -+ set_optab_libfunc (add_optab, SFmode, "__avr32_f32_add_fast"); -+ set_optab_libfunc (sub_optab, SFmode, "__avr32_f32_sub_fast"); -+ set_optab_libfunc (sdiv_optab, SFmode, "__avr32_f32_div_fast"); -+ } -+ else -+ { -+ set_optab_libfunc (sdiv_optab, DFmode, "__avr32_f64_div"); -+ set_optab_libfunc (smul_optab, DFmode, "__avr32_f64_mul"); -+ set_optab_libfunc (add_optab, DFmode, "__avr32_f64_add"); -+ set_optab_libfunc (sub_optab, DFmode, "__avr32_f64_sub"); -+ set_optab_libfunc (add_optab, SFmode, "__avr32_f32_add"); -+ set_optab_libfunc (sub_optab, SFmode, "__avr32_f32_sub"); -+ set_optab_libfunc (sdiv_optab, SFmode, "__avr32_f32_div"); -+ } -+} -+ -+ -+/* Record a flashvault declaration. */ -+static void -+flashvault_decl_list_add (unsigned int vector_num, const char *name) -+{ -+ struct flashvault_decl_list *p; -+ -+ p = (struct flashvault_decl_list *) -+ xmalloc (sizeof (struct flashvault_decl_list)); -+ p->next = flashvault_decl_list_head; -+ p->name = name; -+ p->vector_num = vector_num; -+ flashvault_decl_list_head = p; -+} -+ -+ -+static void -+avr32_file_end (void) -+{ -+ struct flashvault_decl_list *p; -+ unsigned int num_entries = 0; -+ -+ /* Check if a list of flashvault declarations exists. */ -+ if (flashvault_decl_list_head != NULL) -+ { -+ /* Calculate the number of entries in the table. */ -+ for (p = flashvault_decl_list_head; p != NULL; p = p->next) -+ { -+ num_entries++; -+ } -+ -+ /* Generate the beginning of the flashvault data table. */ -+ fputs ("\t.global __fv_table\n" -+ "\t.data\n" -+ "\t.align 2\n" -+ "\t.set .LFVTABLE, . + 0\n" -+ "\t.type __fv_table, @object\n", asm_out_file); -+ /* Each table entry is 8 bytes. */ -+ fprintf (asm_out_file, "\t.size __fv_table, %u\n", (num_entries * 8)); -+ -+ fputs("__fv_table:\n", asm_out_file); -+ -+ for (p = flashvault_decl_list_head; p != NULL; p = p->next) -+ { -+ /* Output table entry. */ -+ fprintf (asm_out_file, -+ "\t.align 2\n" -+ "\t.int %u\n", p->vector_num); -+ fprintf (asm_out_file, -+ "\t.align 2\n" -+ "\t.int %s\n", p->name); -+ } -+ } -+} ---- /dev/null -+++ b/gcc/config/avr32/avr32-elf.h -@@ -0,0 +1,91 @@ -+/* -+ Elf specific definitions. -+ Copyright 2003,2004,2005,2006,2007,2008,2009 Atmel Corporation. -+ -+ This file is part of GCC. -+ -+ 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 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 this program; if not, write to the Free Software -+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -+ -+ -+/***************************************************************************** -+ * Controlling the Compiler Driver, 'gcc' -+ *****************************************************************************/ -+ -+/* Run-time Target Specification. */ -+#undef TARGET_VERSION -+#define TARGET_VERSION fputs (" (AVR32 GNU with ELF)", stderr); -+ -+/* -+Another C string constant used much like LINK_SPEC. The -+difference between the two is that STARTFILE_SPEC is used at -+the very beginning of the command given to the linker. -+ -+If this macro is not defined, a default is provided that loads the -+standard C startup file from the usual place. See gcc.c. -+*/ -+#if 0 -+#undef STARTFILE_SPEC -+#define STARTFILE_SPEC "crt0%O%s crti%O%s crtbegin%O%s" -+#endif -+#undef STARTFILE_SPEC -+#define STARTFILE_SPEC "%{mflashvault: crtfv.o%s} %{!mflashvault: crt0.o%s} \ -+ crti.o%s crtbegin.o%s" -+ -+#undef LINK_SPEC -+#define LINK_SPEC "%{muse-oscall:--defsym __do_not_use_oscall_coproc__=0} %{mrelax|O*:%{mno-relax|O0|O1: ;:--relax}} %{mpart=uc3a3revd:-mavr32elf_uc3a3256s;:%{mpart=*:-mavr32elf_%*}} %{mcpu=*:-mavr32elf_%*}" -+ -+ -+/* -+Another C string constant used much like LINK_SPEC. The -+difference between the two is that ENDFILE_SPEC is used at -+the very end of the command given to the linker. -+ -+Do not define this macro if it does not need to do anything. -+*/ -+#undef ENDFILE_SPEC -+#define ENDFILE_SPEC "crtend%O%s crtn%O%s" -+ -+ -+/* Target CPU builtins. */ -+#define TARGET_CPU_CPP_BUILTINS() \ -+ do \ -+ { \ -+ builtin_define ("__avr32__"); \ -+ builtin_define ("__AVR32__"); \ -+ builtin_define ("__AVR32_ELF__"); \ -+ builtin_define (avr32_part->macro); \ -+ builtin_define (avr32_arch->macro); \ -+ if (avr32_arch->uarch_type == UARCH_TYPE_AVR32A) \ -+ builtin_define ("__AVR32_AVR32A__"); \ -+ else \ -+ builtin_define ("__AVR32_AVR32B__"); \ -+ if (TARGET_UNALIGNED_WORD) \ -+ builtin_define ("__AVR32_HAS_UNALIGNED_WORD__"); \ -+ if (TARGET_SIMD) \ -+ builtin_define ("__AVR32_HAS_SIMD__"); \ -+ if (TARGET_DSP) \ -+ builtin_define ("__AVR32_HAS_DSP__"); \ -+ if (TARGET_RMW) \ -+ builtin_define ("__AVR32_HAS_RMW__"); \ -+ if (TARGET_BRANCH_PRED) \ -+ builtin_define ("__AVR32_HAS_BRANCH_PRED__"); \ -+ if (TARGET_FAST_FLOAT) \ -+ builtin_define ("__AVR32_FAST_FLOAT__"); \ -+ if (TARGET_FLASHVAULT) \ -+ builtin_define ("__AVR32_FLASHVAULT__"); \ -+ if (TARGET_NO_MUL_INSNS) \ -+ builtin_define ("__AVR32_NO_MUL__"); \ -+ } \ -+ while (0) ---- /dev/null -+++ b/gcc/config/avr32/avr32.h -@@ -0,0 +1,3274 @@ -+/* -+ Definitions of target machine for AVR32. -+ Copyright 2003,2004,2005,2006,2007,2008,2009,2010 Atmel Corporation. -+ -+ This file is part of GCC. -+ -+ 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 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 this program; if not, write to the Free Software -+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -+ -+#ifndef GCC_AVR32_H -+#define GCC_AVR32_H -+ -+ -+#ifndef OBJECT_FORMAT_ELF -+#error avr32.h included before elfos.h -+#endif -+ -+#ifndef LOCAL_LABEL_PREFIX -+#define LOCAL_LABEL_PREFIX "." -+#endif -+ -+#ifndef SUBTARGET_CPP_SPEC -+#define SUBTARGET_CPP_SPEC "-D__ELF__" -+#endif -+ -+ -+extern struct rtx_def *avr32_compare_op0; -+extern struct rtx_def *avr32_compare_op1; -+ -+ -+extern struct rtx_def *avr32_acc_cache; -+ -+/* cache instruction op5 codes */ -+#define AVR32_CACHE_INVALIDATE_ICACHE 1 -+ -+/* -+These bits describe the different types of function supported by the AVR32 -+backend. They are exclusive, e.g. a function cannot be both a normal function -+and an interworked function. Knowing the type of a function is important for -+determining its prologue and epilogue sequences. Note value 7 is currently -+unassigned. Also note that the interrupt function types all have bit 2 set, -+so that they can be tested for easily. Note that 0 is deliberately chosen for -+AVR32_FT_UNKNOWN so that when the machine_function structure is initialized -+(to zero) func_type will default to unknown. This will force the first use of -+avr32_current_func_type to call avr32_compute_func_type. -+*/ -+#define AVR32_FT_UNKNOWN 0 /* Type has not yet been determined. */ -+#define AVR32_FT_NORMAL 1 /* Normal function. */ -+#define AVR32_FT_ACALL 2 /* An acall function. */ -+#define AVR32_FT_EXCEPTION_HANDLER 3 /* A C++ exception handler. */ -+#define AVR32_FT_ISR_FULL 4 /* A fully shadowed interrupt mode. */ -+#define AVR32_FT_ISR_HALF 5 /* A half shadowed interrupt mode. */ -+#define AVR32_FT_ISR_NONE 6 /* No shadow registers. */ -+ -+#define AVR32_FT_TYPE_MASK ((1 << 3) - 1) -+ -+/* In addition functions can have several type modifiers, outlined by these bit masks: */ -+#define AVR32_FT_INTERRUPT (1 << 2) /* Note overlap with FT_ISR and above. */ -+#define AVR32_FT_NAKED (1 << 3) /* No prologue or epilogue. */ -+#define AVR32_FT_VOLATILE (1 << 4) /* Does not return. */ -+#define AVR32_FT_NESTED (1 << 5) /* Embedded inside another func. */ -+#define AVR32_FT_FLASHVAULT (1 << 6) /* Flashvault function call. */ -+#define AVR32_FT_FLASHVAULT_IMPL (1 << 7) /* Function definition in FlashVault. */ -+ -+ -+/* Some macros to test these flags. */ -+#define AVR32_FUNC_TYPE(t) (t & AVR32_FT_TYPE_MASK) -+#define IS_INTERRUPT(t) (t & AVR32_FT_INTERRUPT) -+#define IS_NAKED(t) (t & AVR32_FT_NAKED) -+#define IS_VOLATILE(t) (t & AVR32_FT_VOLATILE) -+#define IS_NESTED(t) (t & AVR32_FT_NESTED) -+#define IS_FLASHVAULT(t) (t & AVR32_FT_FLASHVAULT) -+#define IS_FLASHVAULT_IMPL(t) (t & AVR32_FT_FLASHVAULT_IMPL) -+ -+#define SYMBOL_FLAG_RMW_ADDR_SHIFT SYMBOL_FLAG_MACH_DEP_SHIFT -+#define SYMBOL_REF_RMW_ADDR(RTX) \ -+ ((SYMBOL_REF_FLAGS (RTX) & (1 << SYMBOL_FLAG_RMW_ADDR_SHIFT)) != 0) -+ -+ -+typedef struct minipool_labels -+GTY ((chain_next ("%h.next"), chain_prev ("%h.prev"))) -+{ -+ rtx label; -+ struct minipool_labels *prev; -+ struct minipool_labels *next; -+} minipool_labels; -+ -+/* A C structure for machine-specific, per-function data. -+ This is added to the cfun structure. */ -+ -+typedef struct machine_function -+GTY (()) -+{ -+ /* Records the type of the current function. */ -+ unsigned long func_type; -+ /* List of minipool labels, use for checking if code label is valid in a -+ memory expression */ -+ minipool_labels *minipool_label_head; -+ minipool_labels *minipool_label_tail; -+ int ifcvt_after_reload; -+} machine_function; -+ -+/* Initialize data used by insn expanders. This is called from insn_emit, -+ once for every function before code is generated. */ -+#define INIT_EXPANDERS avr32_init_expanders () -+ -+/****************************************************************************** -+ * SPECS -+ *****************************************************************************/ -+ -+#ifndef ASM_SPEC -+#define ASM_SPEC "%{fpic:--pic} %{mrelax|O*:%{mno-relax|O0|O1: ;:--linkrelax}} %{march=ucr2nomul:-march=ucr2;:%{march=*:-march=%*}} %{mpart=uc3a3revd:-mpart=uc3a3256s;:%{mpart=*:-mpart=%*}}" -+#endif -+ -+#ifndef MULTILIB_DEFAULTS -+#define MULTILIB_DEFAULTS { "march=ap", "" } -+#endif -+ -+/****************************************************************************** -+ * Run-time Target Specification -+ *****************************************************************************/ -+#ifndef TARGET_VERSION -+#define TARGET_VERSION fprintf(stderr, " (AVR32, GNU assembler syntax)"); -+#endif -+ -+ -+/* Part types. Keep this in sync with the order of avr32_part_types in avr32.c*/ -+enum part_type -+{ -+ PART_TYPE_AVR32_NONE, -+ PART_TYPE_AVR32_AP7000, -+ PART_TYPE_AVR32_AP7001, -+ PART_TYPE_AVR32_AP7002, -+ PART_TYPE_AVR32_AP7200, -+ PART_TYPE_AVR32_UC3A0128, -+ PART_TYPE_AVR32_UC3A0256, -+ PART_TYPE_AVR32_UC3A0512, -+ PART_TYPE_AVR32_UC3A0512ES, -+ PART_TYPE_AVR32_UC3A1128, -+ PART_TYPE_AVR32_UC3A1256, -+ PART_TYPE_AVR32_UC3A1512, -+ PART_TYPE_AVR32_UC3A1512ES, -+ PART_TYPE_AVR32_UC3A3REVD, -+ PART_TYPE_AVR32_UC3A364, -+ PART_TYPE_AVR32_UC3A364S, -+ PART_TYPE_AVR32_UC3A3128, -+ PART_TYPE_AVR32_UC3A3128S, -+ PART_TYPE_AVR32_UC3A3256, -+ PART_TYPE_AVR32_UC3A3256S, -+ PART_TYPE_AVR32_UC3B064, -+ PART_TYPE_AVR32_UC3B0128, -+ PART_TYPE_AVR32_UC3B0256, -+ PART_TYPE_AVR32_UC3B0256ES, -+ PART_TYPE_AVR32_UC3B0512, -+ PART_TYPE_AVR32_UC3B0512REVC, -+ PART_TYPE_AVR32_UC3B164, -+ PART_TYPE_AVR32_UC3B1128, -+ PART_TYPE_AVR32_UC3B1256, -+ PART_TYPE_AVR32_UC3B1256ES, -+ PART_TYPE_AVR32_UC3B1512, -+ PART_TYPE_AVR32_UC3B1512REVC, -+ PART_TYPE_AVR32_UC3C0512CREVC, -+ PART_TYPE_AVR32_UC3C1512CREVC, -+ PART_TYPE_AVR32_UC3C2512CREVC, -+ PART_TYPE_AVR32_UC3L0256, -+ PART_TYPE_AVR32_UC3L0128, -+ PART_TYPE_AVR32_UC3L064, -+ PART_TYPE_AVR32_UC3L032, -+ PART_TYPE_AVR32_UC3L016, -+ PART_TYPE_AVR32_UC3C064C, -+ PART_TYPE_AVR32_UC3C0128C, -+ PART_TYPE_AVR32_UC3C0256C, -+ PART_TYPE_AVR32_UC3C0512C, -+ PART_TYPE_AVR32_UC3C164C, -+ PART_TYPE_AVR32_UC3C1128C, -+ PART_TYPE_AVR32_UC3C1256C, -+ PART_TYPE_AVR32_UC3C1512C, -+ PART_TYPE_AVR32_UC3C264C, -+ PART_TYPE_AVR32_UC3C2128C, -+ PART_TYPE_AVR32_UC3C2256C, -+ PART_TYPE_AVR32_UC3C2512C, -+ PART_TYPE_AVR32_MXT768E -+}; -+ -+/* Microarchitectures. */ -+enum microarchitecture_type -+{ -+ UARCH_TYPE_AVR32A, -+ UARCH_TYPE_AVR32B, -+ UARCH_TYPE_NONE -+}; -+ -+/* Architectures types which specifies the pipeline. -+ Keep this in sync with avr32_arch_types in avr32.c -+ and the pipeline attribute in avr32.md */ -+enum architecture_type -+{ -+ ARCH_TYPE_AVR32_AP, -+ ARCH_TYPE_AVR32_UCR1, -+ ARCH_TYPE_AVR32_UCR2, -+ ARCH_TYPE_AVR32_UCR2NOMUL, -+ ARCH_TYPE_AVR32_UCR3, -+ ARCH_TYPE_AVR32_UCR3FP, -+ ARCH_TYPE_AVR32_NONE -+}; -+ -+/* Flag specifying if the cpu has support for DSP instructions.*/ -+#define FLAG_AVR32_HAS_DSP (1 << 0) -+/* Flag specifying if the cpu has support for Read-Modify-Write -+ instructions.*/ -+#define FLAG_AVR32_HAS_RMW (1 << 1) -+/* Flag specifying if the cpu has support for SIMD instructions. */ -+#define FLAG_AVR32_HAS_SIMD (1 << 2) -+/* Flag specifying if the cpu has support for unaligned memory word access. */ -+#define FLAG_AVR32_HAS_UNALIGNED_WORD (1 << 3) -+/* Flag specifying if the cpu has support for branch prediction. */ -+#define FLAG_AVR32_HAS_BRANCH_PRED (1 << 4) -+/* Flag specifying if the cpu has support for a return stack. */ -+#define FLAG_AVR32_HAS_RETURN_STACK (1 << 5) -+/* Flag specifying if the cpu has caches. */ -+#define FLAG_AVR32_HAS_CACHES (1 << 6) -+/* Flag specifying if the cpu has support for v2 insns. */ -+#define FLAG_AVR32_HAS_V2_INSNS (1 << 7) -+/* Flag specifying that the cpu has buggy mul insns. */ -+#define FLAG_AVR32_HAS_NO_MUL_INSNS (1 << 8) -+/* Flag specifying that the device has FPU instructions according -+ to AVR32002 specifications*/ -+#define FLAG_AVR32_HAS_FPU (1 << 9) -+ -+/* Structure for holding information about different avr32 CPUs/parts */ -+struct part_type_s -+{ -+ const char *const name; -+ enum part_type part_type; -+ enum architecture_type arch_type; -+ /* Must lie outside user's namespace. NULL == no macro. */ -+ const char *const macro; -+}; -+ -+/* Structure for holding information about different avr32 pipeline -+ architectures. */ -+struct arch_type_s -+{ -+ const char *const name; -+ enum architecture_type arch_type; -+ enum microarchitecture_type uarch_type; -+ const unsigned long feature_flags; -+ /* Must lie outside user's namespace. NULL == no macro. */ -+ const char *const macro; -+}; -+ -+extern const struct part_type_s *avr32_part; -+extern const struct arch_type_s *avr32_arch; -+ -+#define TARGET_SIMD (avr32_arch->feature_flags & FLAG_AVR32_HAS_SIMD) -+#define TARGET_DSP (avr32_arch->feature_flags & FLAG_AVR32_HAS_DSP) -+#define TARGET_RMW (avr32_arch->feature_flags & FLAG_AVR32_HAS_RMW) -+#define TARGET_UNALIGNED_WORD (avr32_arch->feature_flags & FLAG_AVR32_HAS_UNALIGNED_WORD) -+#define TARGET_BRANCH_PRED (avr32_arch->feature_flags & FLAG_AVR32_HAS_BRANCH_PRED) -+#define TARGET_RETURN_STACK (avr32_arch->feature_flags & FLAG_AVR32_HAS_RETURN_STACK) -+#define TARGET_V2_INSNS (avr32_arch->feature_flags & FLAG_AVR32_HAS_V2_INSNS) -+#define TARGET_CACHES (avr32_arch->feature_flags & FLAG_AVR32_HAS_CACHES) -+#define TARGET_NO_MUL_INSNS (avr32_arch->feature_flags & FLAG_AVR32_HAS_NO_MUL_INSNS) -+#define TARGET_ARCH_AP (avr32_arch->arch_type == ARCH_TYPE_AVR32_AP) -+#define TARGET_ARCH_UCR1 (avr32_arch->arch_type == ARCH_TYPE_AVR32_UCR1) -+#define TARGET_ARCH_UCR2 (avr32_arch->arch_type == ARCH_TYPE_AVR32_UCR2) -+#define TARGET_ARCH_UC (TARGET_ARCH_UCR1 || TARGET_ARCH_UCR2) -+#define TARGET_UARCH_AVR32A (avr32_arch->uarch_type == UARCH_TYPE_AVR32A) -+#define TARGET_UARCH_AVR32B (avr32_arch->uarch_type == UARCH_TYPE_AVR32B) -+#define TARGET_ARCH_FPU (avr32_arch->feature_flags & FLAG_AVR32_HAS_FPU) -+ -+#define CAN_DEBUG_WITHOUT_FP -+ -+ -+ -+ -+/****************************************************************************** -+ * Storage Layout -+ *****************************************************************************/ -+ -+/* -+Define this macro to have the value 1 if the most significant bit in a -+byte has the lowest number; otherwise define it to have the value zero. -+This means that bit-field instructions count from the most significant -+bit. If the machine has no bit-field instructions, then this must still -+be defined, but it doesn't matter which value it is defined to. This -+macro need not be a constant. -+ -+This macro does not affect the way structure fields are packed into -+bytes or words; that is controlled by BYTES_BIG_ENDIAN. -+*/ -+#define BITS_BIG_ENDIAN 0 -+ -+/* -+Define this macro to have the value 1 if the most significant byte in a -+word has the lowest number. This macro need not be a constant. -+*/ -+/* -+ Data is stored in an big-endian way. -+*/ -+#define BYTES_BIG_ENDIAN 1 -+ -+/* -+Define this macro to have the value 1 if, in a multiword object, the -+most significant word has the lowest number. This applies to both -+memory locations and registers; GCC fundamentally assumes that the -+order of words in memory is the same as the order in registers. This -+macro need not be a constant. -+*/ -+/* -+ Data is stored in an bin-endian way. -+*/ -+#define WORDS_BIG_ENDIAN 1 -+ -+/* -+Define this macro if WORDS_BIG_ENDIAN is not constant. This must be a -+constant value with the same meaning as WORDS_BIG_ENDIAN, which will be -+used only when compiling libgcc2.c. Typically the value will be set -+based on preprocessor defines. -+*/ -+#define LIBGCC2_WORDS_BIG_ENDIAN WORDS_BIG_ENDIAN -+ -+/* -+Define this macro to have the value 1 if DFmode, XFmode or -+TFmode floating point numbers are stored in memory with the word -+containing the sign bit at the lowest address; otherwise define it to -+have the value 0. This macro need not be a constant. -+ -+You need not define this macro if the ordering is the same as for -+multi-word integers. -+*/ -+/* #define FLOAT_WORDS_BIG_ENDIAN 1 */ -+ -+/* -+Define this macro to be the number of bits in an addressable storage -+unit (byte); normally 8. -+*/ -+#define BITS_PER_UNIT 8 -+ -+/* -+Number of bits in a word; normally 32. -+*/ -+#define BITS_PER_WORD 32 -+ -+/* -+Maximum number of bits in a word. If this is undefined, the default is -+BITS_PER_WORD. Otherwise, it is the constant value that is the -+largest value that BITS_PER_WORD can have at run-time. -+*/ -+/* MAX_BITS_PER_WORD not defined*/ -+ -+/* -+Number of storage units in a word; normally 4. -+*/ -+#define UNITS_PER_WORD 4 -+ -+/* -+Minimum number of units in a word. If this is undefined, the default is -+UNITS_PER_WORD. Otherwise, it is the constant value that is the -+smallest value that UNITS_PER_WORD can have at run-time. -+*/ -+/* MIN_UNITS_PER_WORD not defined */ -+ -+/* -+Width of a pointer, in bits. You must specify a value no wider than the -+width of Pmode. If it is not equal to the width of Pmode, -+you must define POINTERS_EXTEND_UNSIGNED. -+*/ -+#define POINTER_SIZE 32 -+ -+/* -+A C expression whose value is greater than zero if pointers that need to be -+extended from being POINTER_SIZE bits wide to Pmode are to -+be zero-extended and zero if they are to be sign-extended. If the value -+is less then zero then there must be an "ptr_extend" instruction that -+extends a pointer from POINTER_SIZE to Pmode. -+ -+You need not define this macro if the POINTER_SIZE is equal -+to the width of Pmode. -+*/ -+/* #define POINTERS_EXTEND_UNSIGNED */ -+ -+/* -+A Macro to update M and UNSIGNEDP when an object whose type -+is TYPE and which has the specified mode and signedness is to be -+stored in a register. This macro is only called when TYPE is a -+scalar type. -+ -+On most RISC machines, which only have operations that operate on a full -+register, define this macro to set M to word_mode if -+M is an integer mode narrower than BITS_PER_WORD. In most -+cases, only integer modes should be widened because wider-precision -+floating-point operations are usually more expensive than their narrower -+counterparts. -+ -+For most machines, the macro definition does not change UNSIGNEDP. -+However, some machines, have instructions that preferentially handle -+either signed or unsigned quantities of certain modes. For example, on -+the DEC Alpha, 32-bit loads from memory and 32-bit add instructions -+sign-extend the result to 64 bits. On such machines, set -+UNSIGNEDP according to which kind of extension is more efficient. -+ -+Do not define this macro if it would never modify M. -+*/ -+#define PROMOTE_MODE(M, UNSIGNEDP, TYPE) \ -+ { \ -+ if (!AGGREGATE_TYPE_P (TYPE) \ -+ && GET_MODE_CLASS (mode) == MODE_INT \ -+ && GET_MODE_SIZE (mode) < 4) \ -+ { \ -+ if (M == QImode) \ -+ (UNSIGNEDP) = 1; \ -+ else if (M == HImode) \ -+ (UNSIGNEDP) = 0; \ -+ (M) = SImode; \ -+ } \ -+ } -+ -+#define PROMOTE_FUNCTION_MODE(M, UNSIGNEDP, TYPE) \ -+ PROMOTE_MODE(M, UNSIGNEDP, TYPE) -+ -+/* Define if operations between registers always perform the operation -+ on the full register even if a narrower mode is specified. */ -+#define WORD_REGISTER_OPERATIONS -+ -+/* Define if loading in MODE, an integral mode narrower than BITS_PER_WORD -+ will either zero-extend or sign-extend. The value of this macro should -+ be the code that says which one of the two operations is implicitly -+ done, UNKNOWN if not known. */ -+#define LOAD_EXTEND_OP(MODE) \ -+ (((MODE) == QImode) ? ZERO_EXTEND \ -+ : ((MODE) == HImode) ? SIGN_EXTEND : UNKNOWN) -+ -+ -+/* -+Normal alignment required for function parameters on the stack, in -+bits. All stack parameters receive at least this much alignment -+regardless of data type. On most machines, this is the same as the -+size of an integer. -+*/ -+#define PARM_BOUNDARY 32 -+ -+/* -+Define this macro to the minimum alignment enforced by hardware for the -+stack pointer on this machine. The definition is a C expression for the -+desired alignment (measured in bits). This value is used as a default -+if PREFERRED_STACK_BOUNDARY is not defined. On most machines, -+this should be the same as PARM_BOUNDARY. -+*/ -+#define STACK_BOUNDARY 32 -+ -+/* -+Define this macro if you wish to preserve a certain alignment for the -+stack pointer, greater than what the hardware enforces. The definition -+is a C expression for the desired alignment (measured in bits). This -+macro must evaluate to a value equal to or larger than -+STACK_BOUNDARY. -+*/ -+#define PREFERRED_STACK_BOUNDARY (TARGET_FORCE_DOUBLE_ALIGN ? 64 : 32 ) -+ -+/* -+Alignment required for a function entry point, in bits. -+*/ -+#define FUNCTION_BOUNDARY 16 -+ -+/* -+Biggest alignment that any data type can require on this machine, in bits. -+*/ -+#define BIGGEST_ALIGNMENT (TARGET_FORCE_DOUBLE_ALIGN ? 64 : 32 ) -+ -+/* -+If defined, the smallest alignment, in bits, that can be given to an -+object that can be referenced in one operation, without disturbing any -+nearby object. Normally, this is BITS_PER_UNIT, but may be larger -+on machines that don't have byte or half-word store operations. -+*/ -+#define MINIMUM_ATOMIC_ALIGNMENT BITS_PER_UNIT -+ -+ -+/* -+An integer expression for the size in bits of the largest integer machine mode that -+should actually be used. All integer machine modes of this size or smaller can be -+used for structures and unions with the appropriate sizes. If this macro is undefined, -+GET_MODE_BITSIZE (DImode) is assumed.*/ -+#define MAX_FIXED_MODE_SIZE GET_MODE_BITSIZE (DImode) -+ -+ -+/* -+If defined, a C expression to compute the alignment given to a constant -+that is being placed in memory. CONSTANT is the constant and -+BASIC_ALIGN is the alignment that the object would ordinarily -+have. The value of this macro is used instead of that alignment to -+align the object. -+ -+If this macro is not defined, then BASIC_ALIGN is used. -+ -+The typical use of this macro is to increase alignment for string -+constants to be word aligned so that strcpy calls that copy -+constants can be done inline. -+*/ -+#define CONSTANT_ALIGNMENT(CONSTANT, BASIC_ALIGN) \ -+ ((TREE_CODE(CONSTANT) == STRING_CST) ? BITS_PER_WORD : BASIC_ALIGN) -+ -+/* Try to align string to a word. */ -+#define DATA_ALIGNMENT(TYPE, ALIGN) \ -+ ({(TREE_CODE (TYPE) == ARRAY_TYPE \ -+ && TYPE_MODE (TREE_TYPE (TYPE)) == QImode \ -+ && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN));}) -+ -+/* Try to align local store strings to a word. */ -+#define LOCAL_ALIGNMENT(TYPE, ALIGN) \ -+ ({(TREE_CODE (TYPE) == ARRAY_TYPE \ -+ && TYPE_MODE (TREE_TYPE (TYPE)) == QImode \ -+ && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN));}) -+ -+/* -+Define this macro to be the value 1 if instructions will fail to work -+if given data not on the nominal alignment. If instructions will merely -+go slower in that case, define this macro as 0. -+*/ -+#define STRICT_ALIGNMENT 1 -+ -+/* -+Define this if you wish to imitate the way many other C compilers handle -+alignment of bit-fields and the structures that contain them. -+ -+The behavior is that the type written for a bit-field (int, -+short, or other integer type) imposes an alignment for the -+entire structure, as if the structure really did contain an ordinary -+field of that type. In addition, the bit-field is placed within the -+structure so that it would fit within such a field, not crossing a -+boundary for it. -+ -+Thus, on most machines, a bit-field whose type is written as int -+would not cross a four-byte boundary, and would force four-byte -+alignment for the whole structure. (The alignment used may not be four -+bytes; it is controlled by the other alignment parameters.) -+ -+If the macro is defined, its definition should be a C expression; -+a nonzero value for the expression enables this behavior. -+ -+Note that if this macro is not defined, or its value is zero, some -+bit-fields may cross more than one alignment boundary. The compiler can -+support such references if there are insv, extv, and -+extzv insns that can directly reference memory. -+ -+The other known way of making bit-fields work is to define -+STRUCTURE_SIZE_BOUNDARY as large as BIGGEST_ALIGNMENT. -+Then every structure can be accessed with fullwords. -+ -+Unless the machine has bit-field instructions or you define -+STRUCTURE_SIZE_BOUNDARY that way, you must define -+PCC_BITFIELD_TYPE_MATTERS to have a nonzero value. -+ -+If your aim is to make GCC use the same conventions for laying out -+bit-fields as are used by another compiler, here is how to investigate -+what the other compiler does. Compile and run this program: -+ -+struct foo1 -+{ -+ char x; -+ char :0; -+ char y; -+}; -+ -+struct foo2 -+{ -+ char x; -+ int :0; -+ char y; -+}; -+ -+main () -+{ -+ printf ("Size of foo1 is %d\n", -+ sizeof (struct foo1)); -+ printf ("Size of foo2 is %d\n", -+ sizeof (struct foo2)); -+ exit (0); -+} -+ -+If this prints 2 and 5, then the compiler's behavior is what you would -+get from PCC_BITFIELD_TYPE_MATTERS. -+*/ -+#define PCC_BITFIELD_TYPE_MATTERS 1 -+ -+ -+/****************************************************************************** -+ * Layout of Source Language Data Types -+ *****************************************************************************/ -+ -+/* -+A C expression for the size in bits of the type int on the -+target machine. If you don't define this, the default is one word. -+*/ -+#define INT_TYPE_SIZE 32 -+ -+/* -+A C expression for the size in bits of the type short on the -+target machine. If you don't define this, the default is half a word. (If -+this would be less than one storage unit, it is rounded up to one unit.) -+*/ -+#define SHORT_TYPE_SIZE 16 -+ -+/* -+A C expression for the size in bits of the type long on the -+target machine. If you don't define this, the default is one word. -+*/ -+#define LONG_TYPE_SIZE 32 -+ -+ -+/* -+A C expression for the size in bits of the type long long on the -+target machine. If you don't define this, the default is two -+words. If you want to support GNU Ada on your machine, the value of this -+macro must be at least 64. -+*/ -+#define LONG_LONG_TYPE_SIZE 64 -+ -+/* -+A C expression for the size in bits of the type char on the -+target machine. If you don't define this, the default is -+BITS_PER_UNIT. -+*/ -+#define CHAR_TYPE_SIZE 8 -+ -+ -+/* -+A C expression for the size in bits of the C++ type bool and -+C99 type _Bool on the target machine. If you don't define -+this, and you probably shouldn't, the default is CHAR_TYPE_SIZE. -+*/ -+#define BOOL_TYPE_SIZE 8 -+ -+ -+/* -+An expression whose value is 1 or 0, according to whether the type -+char should be signed or unsigned by default. The user can -+always override this default with the options -fsigned-char -+and -funsigned-char. -+*/ -+/* We are using unsigned char */ -+#define DEFAULT_SIGNED_CHAR 0 -+ -+ -+/* -+A C expression for a string describing the name of the data type to use -+for size values. The typedef name size_t is defined using the -+contents of the string. -+ -+The string can contain more than one keyword. If so, separate them with -+spaces, and write first any length keyword, then unsigned if -+appropriate, and finally int. The string must exactly match one -+of the data type names defined in the function -+init_decl_processing in the file c-decl.c. You may not -+omit int or change the order - that would cause the compiler to -+crash on startup. -+ -+If you don't define this macro, the default is "long unsigned int". -+*/ -+#define SIZE_TYPE "long unsigned int" -+ -+/* -+A C expression for a string describing the name of the data type to use -+for the result of subtracting two pointers. The typedef name -+ptrdiff_t is defined using the contents of the string. See -+SIZE_TYPE above for more information. -+ -+If you don't define this macro, the default is "long int". -+*/ -+#define PTRDIFF_TYPE "long int" -+ -+ -+/* -+A C expression for the size in bits of the data type for wide -+characters. This is used in cpp, which cannot make use of -+WCHAR_TYPE. -+*/ -+#define WCHAR_TYPE_SIZE 32 -+ -+ -+/* -+A C expression for a string describing the name of the data type to -+use for wide characters passed to printf and returned from -+getwc. The typedef name wint_t is defined using the -+contents of the string. See SIZE_TYPE above for more -+information. -+ -+If you don't define this macro, the default is "unsigned int". -+*/ -+#define WINT_TYPE "unsigned int" -+ -+/* -+A C expression for a string describing the name of the data type that -+can represent any value of any standard or extended signed integer type. -+The typedef name intmax_t is defined using the contents of the -+string. See SIZE_TYPE above for more information. -+ -+If you don't define this macro, the default is the first of -+"int", "long int", or "long long int" that has as -+much precision as long long int. -+*/ -+#define INTMAX_TYPE "long long int" -+ -+/* -+A C expression for a string describing the name of the data type that -+can represent any value of any standard or extended unsigned integer -+type. The typedef name uintmax_t is defined using the contents -+of the string. See SIZE_TYPE above for more information. -+ -+If you don't define this macro, the default is the first of -+"unsigned int", "long unsigned int", or "long long unsigned int" -+that has as much precision as long long unsigned int. -+*/ -+#define UINTMAX_TYPE "long long unsigned int" -+ -+ -+/****************************************************************************** -+ * Register Usage -+ *****************************************************************************/ -+ -+/* Convert from gcc internal register number to register number -+ used in assembly code */ -+#define ASM_REGNUM(reg) (LAST_REGNUM - (reg)) -+ -+/* Convert between register number used in assembly to gcc -+ internal register number */ -+#define INTERNAL_REGNUM(reg) (LAST_REGNUM - (reg)) -+ -+/** Basic Characteristics of Registers **/ -+ -+/* -+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 (LAST_REGNUM + 1) -+ -+#define FIRST_REGNUM 0 -+#define LAST_REGNUM 15 -+ -+/* -+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]. -+*/ -+ -+/* The internal gcc register numbers are reversed -+ compared to the real register numbers since -+ gcc expects data types stored over multiple -+ registers in the register file to be big endian -+ if the memory layout is big endian. But this -+ is not the case for avr32 so we fake a big -+ endian register file. */ -+ -+#define FIXED_REGISTERS { \ -+ 1, /* Program Counter */ \ -+ 0, /* Link Register */ \ -+ 1, /* Stack Pointer */ \ -+ 0, /* r12 */ \ -+ 0, /* r11 */ \ -+ 0, /* r10 */ \ -+ 0, /* r9 */ \ -+ 0, /* r8 */ \ -+ 0, /* r7 */ \ -+ 0, /* r6 */ \ -+ 0, /* r5 */ \ -+ 0, /* r4 */ \ -+ 0, /* r3 */ \ -+ 0, /* r2 */ \ -+ 0, /* r1 */ \ -+ 0, /* r0 */ \ -+} -+ -+/* -+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, /* Program Counter */ \ -+ 0, /* Link Register */ \ -+ 1, /* Stack Pointer */ \ -+ 1, /* r12 */ \ -+ 1, /* r11 */ \ -+ 1, /* r10 */ \ -+ 1, /* r9 */ \ -+ 1, /* r8 */ \ -+ 0, /* r7 */ \ -+ 0, /* r6 */ \ -+ 0, /* r5 */ \ -+ 0, /* r4 */ \ -+ 0, /* r3 */ \ -+ 0, /* r2 */ \ -+ 0, /* r1 */ \ -+ 0, /* r0 */ \ -+} -+ -+/* Interrupt functions can only use registers that have already been -+ saved by the prologue, even if they would normally be -+ call-clobbered. */ -+#define HARD_REGNO_RENAME_OK(SRC, DST) \ -+ (! IS_INTERRUPT (cfun->machine->func_type) || \ -+ df_regs_ever_live_p (DST)) -+ -+ -+/* -+Zero or more C statements that may conditionally modify five variables -+fixed_regs, call_used_regs, global_regs, -+reg_names, and reg_class_contents, to take into account -+any dependence of these register sets on target flags. The first three -+of these are of type char [] (interpreted as Boolean vectors). -+global_regs is a const char *[], and -+reg_class_contents is a HARD_REG_SET. Before the macro is -+called, fixed_regs, call_used_regs, -+reg_class_contents, and reg_names have been initialized -+from FIXED_REGISTERS, CALL_USED_REGISTERS, -+REG_CLASS_CONTENTS, and REGISTER_NAMES, respectively. -+global_regs has been cleared, and any -ffixed-[reg], -+-fcall-used-[reg] and -fcall-saved-[reg] -+command options have been applied. -+ -+You need not define this macro if it has no work to do. -+ -+If the usage of an entire class of registers depends on the target -+flags, you may indicate this to GCC by using this macro to modify -+fixed_regs and call_used_regs to 1 for each of the -+registers in the classes which should not be used by GCC. Also define -+the macro REG_CLASS_FROM_LETTER to return NO_REGS if it -+is called with a letter for a class that shouldn't be used. -+ -+ (However, if this class is not included in GENERAL_REGS and all -+of the insn patterns whose constraints permit this class are -+controlled by target switches, then GCC will automatically avoid using -+these registers when the target switches are opposed to them.) -+*/ -+#define CONDITIONAL_REGISTER_USAGE \ -+ do \ -+ { \ -+ if (flag_pic) \ -+ { \ -+ fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \ -+ call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \ -+ } \ -+ } \ -+ while (0) -+ -+ -+/* -+If the program counter has a register number, define this as that -+register number. Otherwise, do not define it. -+*/ -+ -+#define LAST_AVR32_REGNUM 16 -+ -+ -+/** 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 GCC should prefer -+to use them (from most preferred to least). -+ -+If this macro is not defined, registers are used lowest numbered first -+(all else being equal). -+ -+One use of this macro is on machines where the highest numbered -+registers must always be saved and the save-multiple-registers -+instruction supports only sequences of consecutive registers. On such -+machines, define REG_ALLOC_ORDER to be an initializer that lists -+the highest numbered allocable register first. -+*/ -+#define REG_ALLOC_ORDER \ -+{ \ -+ INTERNAL_REGNUM(8), \ -+ INTERNAL_REGNUM(9), \ -+ INTERNAL_REGNUM(10), \ -+ INTERNAL_REGNUM(11), \ -+ INTERNAL_REGNUM(12), \ -+ LR_REGNUM, \ -+ INTERNAL_REGNUM(7), \ -+ INTERNAL_REGNUM(6), \ -+ INTERNAL_REGNUM(5), \ -+ INTERNAL_REGNUM(4), \ -+ INTERNAL_REGNUM(3), \ -+ INTERNAL_REGNUM(2), \ -+ INTERNAL_REGNUM(1), \ -+ INTERNAL_REGNUM(0), \ -+ SP_REGNUM, \ -+ PC_REGNUM \ -+} -+ -+ -+/** How Values Fit in Registers **/ -+ -+/* -+A C expression for the number of consecutive hard registers, starting -+at register number REGNO, required to hold a value of mode -+MODE. -+ -+On a machine where all registers are exactly one word, a suitable -+definition of this macro is -+ -+#define HARD_REGNO_NREGS(REGNO, MODE) \ -+ ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) \ -+ / UNITS_PER_WORD) -+*/ -+#define HARD_REGNO_NREGS(REGNO, MODE) \ -+ ((unsigned int)((GET_MODE_SIZE(MODE) + UNITS_PER_WORD -1 ) / UNITS_PER_WORD)) -+ -+/* -+A C expression that is nonzero if it is permissible to store a value -+of mode MODE in hard register number REGNO (or in several -+registers starting with that one). For a machine where all registers -+are equivalent, a suitable definition is -+ -+ #define HARD_REGNO_MODE_OK(REGNO, MODE) 1 -+ -+You need not include code to check for the numbers of fixed registers, -+because the allocation mechanism considers them to be always occupied. -+ -+On some machines, double-precision values must be kept in even/odd -+register pairs. You can implement that by defining this macro to reject -+odd register numbers for such modes. -+ -+The minimum requirement for a mode to be OK in a register is that the -+mov[mode] instruction pattern support moves between the -+register and other hard register in the same class and that moving a -+value into the register and back out not alter it. -+ -+Since the same instruction used to move word_mode will work for -+all narrower integer modes, it is not necessary on any machine for -+HARD_REGNO_MODE_OK to distinguish between these modes, provided -+you define patterns movhi, etc., to take advantage of this. This -+is useful because of the interaction between HARD_REGNO_MODE_OK -+and MODES_TIEABLE_P; it is very desirable for all integer modes -+to be tieable. -+ -+Many machines have special registers for floating point arithmetic. -+Often people assume that floating point machine modes are allowed only -+in floating point registers. This is not true. Any registers that -+can hold integers can safely hold a floating point machine -+mode, whether or not floating arithmetic can be done on it in those -+registers. Integer move instructions can be used to move the values. -+ -+On some machines, though, the converse is true: fixed-point machine -+modes may not go in floating registers. This is true if the floating -+registers normalize any value stored in them, because storing a -+non-floating value there would garble it. In this case, -+HARD_REGNO_MODE_OK should reject fixed-point machine modes in -+floating registers. But if the floating registers do not automatically -+normalize, if you can store any bit pattern in one and retrieve it -+unchanged without a trap, then any machine mode may go in a floating -+register, so you can define this macro to say so. -+ -+The primary significance of special floating registers is rather that -+they are the registers acceptable in floating point arithmetic -+instructions. However, this is of no concern to -+HARD_REGNO_MODE_OK. You handle it by writing the proper -+constraints for those instructions. -+ -+On some machines, the floating registers are especially slow to access, -+so that it is better to store a value in a stack frame than in such a -+register if floating point arithmetic is not being done. As long as the -+floating registers are not in class GENERAL_REGS, they will not -+be used unless some pattern's constraint asks for one. -+*/ -+#define HARD_REGNO_MODE_OK(REGNO, MODE) avr32_hard_regno_mode_ok(REGNO, MODE) -+ -+/* -+A C expression that is nonzero if a value of mode -+MODE1 is accessible in mode MODE2 without copying. -+ -+If HARD_REGNO_MODE_OK(R, MODE1) and -+HARD_REGNO_MODE_OK(R, MODE2) are always the same for -+any R, then MODES_TIEABLE_P(MODE1, MODE2) -+should be nonzero. If they differ for any R, you should define -+this macro to return zero unless some other mechanism ensures the -+accessibility of the value in a narrower mode. -+ -+You should define this macro to return nonzero in as many cases as -+possible since doing so will allow GCC to perform better register -+allocation. -+*/ -+#define MODES_TIEABLE_P(MODE1, MODE2) \ -+ (GET_MODE_CLASS (MODE1) == GET_MODE_CLASS (MODE2)) -+ -+ -+ -+/****************************************************************************** -+ * Register Classes -+ *****************************************************************************/ -+ -+/* -+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, -+ GENERAL_REGS, -+ ALL_REGS, -+ LIM_REG_CLASSES -+}; -+ -+/* -+The number of distinct register classes, defined as follows: -+ #define N_REG_CLASSES (int) LIM_REG_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", \ -+ "GENERAL_REGS", \ -+ "ALL_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. -+In this situation, the first integer in each sub-initializer corresponds to -+registers 0 through 31, the second integer to registers 32 through 63, and -+so on. -+*/ -+#define REG_CLASS_CONTENTS { \ -+ {0x00000000}, /* NO_REGS */ \ -+ {0x0000FFFF}, /* GENERAL_REGS */ \ -+ {0x7FFFFFFF}, /* ALL_REGS */ \ -+} -+ -+ -+/* -+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) (GENERAL_REGS) -+ -+/* -+A macro whose definition is the name of the class to which a valid -+base register must belong. A base register is one used in an address -+which is the register value plus a displacement. -+*/ -+#define BASE_REG_CLASS GENERAL_REGS -+ -+/* -+This is a variation of the BASE_REG_CLASS macro which allows -+the selection of a base register in a mode depenedent manner. If -+mode is VOIDmode then it should return the same value as -+BASE_REG_CLASS. -+*/ -+#define MODE_BASE_REG_CLASS(MODE) BASE_REG_CLASS -+ -+/* -+A macro whose definition is the name of the class to which a valid -+index register must belong. An index register is one used in an -+address where its value is either multiplied by a scale factor or -+added to another register (as well as added to a displacement). -+*/ -+#define INDEX_REG_CLASS BASE_REG_CLASS -+ -+/* -+A C expression which defines the machine-dependent operand constraint -+letters for register classes. If CHAR is such a letter, the -+value should be the register class corresponding to it. Otherwise, -+the value should be NO_REGS. The register letter r, -+corresponding to class GENERAL_REGS, will not be passed -+to this macro; you do not need to handle it. -+*/ -+#define REG_CLASS_FROM_LETTER(CHAR) NO_REGS -+ -+/* 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. */ -+#define TEST_REGNO(R, TEST, VALUE) \ -+ ((R TEST VALUE) || ((unsigned) reg_renumber[R] TEST VALUE)) -+ -+/* -+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. -+*/ -+#define REGNO_OK_FOR_BASE_P(NUM) TEST_REGNO(NUM, <=, LAST_REGNUM) -+ -+/* -+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. -+*/ -+#define REGNO_OK_FOR_INDEX_P(NUM) TEST_REGNO(NUM, <=, LAST_REGNUM) -+ -+/* -+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. -+*/ -+#define PREFERRED_RELOAD_CLASS(X, CLASS) CLASS -+ -+ -+ -+/* -+A C expression for the maximum number of consecutive registers -+of class CLASS needed to hold a value of mode MODE. -+ -+This is closely related to the macro HARD_REGNO_NREGS. In fact, -+the value of the macro CLASS_MAX_NREGS(CLASS, MODE) -+should be the maximum value of HARD_REGNO_NREGS(REGNO, MODE) -+for all REGNO values in the class CLASS. -+ -+This macro helps control the handling of multiple-word values -+in the reload pass. -+*/ -+#define CLASS_MAX_NREGS(CLASS, MODE) /* ToDo:fixme */ \ -+ (unsigned int)((GET_MODE_SIZE(MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) -+ -+ -+/* -+ Using CONST_OK_FOR_CONSTRAINT_P instead of CONS_OK_FOR_LETTER_P -+ in order to support constraints with more than one letter. -+ Only two letters are then used for constant constraints, -+ the letter 'K' and the letter 'I'. The constraint starting with -+ these letters must consist of four characters. The character following -+ 'K' or 'I' must be either 'u' (unsigned) or 's' (signed) to specify -+ if the constant is zero or sign extended. The last two characters specify -+ the length in bits of the constant. The base constraint letter 'I' means -+ that this is an negated constant, meaning that actually -VAL should be -+ checked to lie withing the valid range instead of VAL which is used when -+ 'K' is the base constraint letter. -+ -+*/ -+ -+#define CONSTRAINT_LEN(C, STR) \ -+ ( ((C) == 'K' || (C) == 'I') ? 4 : \ -+ ((C) == 'R') ? 5 : \ -+ ((C) == 'P') ? -1 : \ -+ DEFAULT_CONSTRAINT_LEN((C), (STR)) ) -+ -+#define CONST_OK_FOR_CONSTRAINT_P(VALUE, C, STR) \ -+ avr32_const_ok_for_constraint_p(VALUE, C, STR) -+ -+/* -+A C expression that defines the machine-dependent operand constraint -+letters that specify particular ranges of const_double values ('G' or 'H'). -+ -+If C is one of those letters, the expression should check that -+VALUE, an RTX of code const_double, is in the appropriate -+range and return 1 if so, 0 otherwise. If C is not one of those -+letters, the value should be 0 regardless of VALUE. -+ -+const_double is used for all floating-point constants and for -+DImode fixed-point constants. A given letter can accept either -+or both kinds of values. It can use GET_MODE to distinguish -+between these kinds. -+*/ -+#define CONST_DOUBLE_OK_FOR_LETTER_P(OP, C) \ -+ ((C) == 'G' ? avr32_const_double_immediate(OP) : 0) -+ -+/* -+A C expression that defines the optional machine-dependent constraint -+letters that can be used to segregate specific types of operands, usually -+memory references, for the target machine. Any letter that is not -+elsewhere defined and not matched by REG_CLASS_FROM_LETTER -+may be used. Normally this macro will not be defined. -+ -+If it is required for a particular target machine, it should return 1 -+if VALUE corresponds to the operand type represented by the -+constraint letter C. If C is not defined as an extra -+constraint, the value returned should be 0 regardless of VALUE. -+ -+For example, on the ROMP, load instructions cannot have their output -+in r0 if the memory reference contains a symbolic address. Constraint -+letter 'Q' is defined as representing a memory address that does -+not contain a symbolic address. An alternative is specified with -+a 'Q' constraint on the input and 'r' on the output. The next -+alternative specifies 'm' on the input and a register class that -+does not include r0 on the output. -+*/ -+#define EXTRA_CONSTRAINT_STR(OP, C, STR) \ -+ ((C) == 'W' ? avr32_address_operand(OP, GET_MODE(OP)) : \ -+ (C) == 'R' ? (avr32_indirect_register_operand(OP, GET_MODE(OP)) || \ -+ (avr32_imm_disp_memory_operand(OP, GET_MODE(OP)) \ -+ && avr32_const_ok_for_constraint_p( \ -+ INTVAL(XEXP(XEXP(OP, 0), 1)), \ -+ (STR)[1], &(STR)[1]))) : \ -+ (C) == 'S' ? avr32_indexed_memory_operand(OP, GET_MODE(OP)) : \ -+ (C) == 'T' ? avr32_const_pool_ref_operand(OP, GET_MODE(OP)) : \ -+ (C) == 'U' ? SYMBOL_REF_RCALL_FUNCTION_P(OP) : \ -+ (C) == 'Z' ? avr32_cop_memory_operand(OP, GET_MODE(OP)) : \ -+ (C) == 'Q' ? avr32_non_rmw_memory_operand(OP, GET_MODE(OP)) : \ -+ (C) == 'Y' ? avr32_rmw_memory_operand(OP, GET_MODE(OP)) : \ -+ 0) -+ -+ -+#define EXTRA_MEMORY_CONSTRAINT(C, STR) ( ((C) == 'R') || \ -+ ((C) == 'Q') || \ -+ ((C) == 'S') || \ -+ ((C) == 'Y') || \ -+ ((C) == 'Z') ) -+ -+ -+/* Returns nonzero if op is a function SYMBOL_REF which -+ can be called using an rcall instruction */ -+#define SYMBOL_REF_RCALL_FUNCTION_P(op) \ -+ ( GET_CODE(op) == SYMBOL_REF \ -+ && SYMBOL_REF_FUNCTION_P(op) \ -+ && SYMBOL_REF_LOCAL_P(op) \ -+ && !SYMBOL_REF_EXTERNAL_P(op) \ -+ && !TARGET_HAS_ASM_ADDR_PSEUDOS ) -+ -+/****************************************************************************** -+ * Stack Layout and Calling Conventions -+ *****************************************************************************/ -+ -+/** Basic Stack Layout **/ -+ -+/* -+Define this macro if pushing a word onto the stack moves the stack -+pointer to a smaller address. -+ -+When we say, ``define this macro if ...,'' it means that the -+compiler checks this macro only with #ifdef so the precise -+definition used does not matter. -+*/ -+/* pushm decrece SP: *(--SP) <-- Rx */ -+#define STACK_GROWS_DOWNWARD -+ -+/* -+This macro defines the operation used when something is pushed -+on the stack. In RTL, a push operation will be -+(set (mem (STACK_PUSH_CODE (reg sp))) ...) -+ -+The choices are PRE_DEC, POST_DEC, PRE_INC, -+and POST_INC. Which of these is correct depends on -+the stack direction and on whether the stack pointer points -+to the last item on the stack or whether it points to the -+space for the next item on the stack. -+ -+The default is PRE_DEC when STACK_GROWS_DOWNWARD is -+defined, which is almost always right, and PRE_INC otherwise, -+which is often wrong. -+*/ -+/* pushm: *(--SP) <-- Rx */ -+#define STACK_PUSH_CODE PRE_DEC -+ -+/* Define this to nonzero if the nominal address of the stack frame -+ is at the high-address end of the local variables; -+ that is, each additional local variable allocated -+ goes at a more negative offset in the frame. */ -+#define FRAME_GROWS_DOWNWARD 1 -+ -+ -+/* -+Offset from the frame pointer to the first local variable slot to be allocated. -+ -+If FRAME_GROWS_DOWNWARD, find the next slot's offset by -+subtracting the first slot's length from STARTING_FRAME_OFFSET. -+Otherwise, it is found by adding the length of the first slot to the -+value STARTING_FRAME_OFFSET. -+ (i'm not sure if the above is still correct.. had to change it to get -+ rid of an overfull. --mew 2feb93 ) -+*/ -+#define STARTING_FRAME_OFFSET 0 -+ -+/* -+Offset from the stack pointer register to the first location at which -+outgoing arguments are placed. If not specified, the default value of -+zero is used. This is the proper value for most machines. -+ -+If ARGS_GROW_DOWNWARD, this is the offset to the location above -+the first location at which outgoing arguments are placed. -+*/ -+#define STACK_POINTER_OFFSET 0 -+ -+/* -+Offset from the argument pointer register to the first argument's -+address. On some machines it may depend on the data type of the -+function. -+ -+If ARGS_GROW_DOWNWARD, this is the offset to the location above -+the first argument's address. -+*/ -+#define FIRST_PARM_OFFSET(FUNDECL) 0 -+ -+ -+/* -+A C expression whose value is RTL representing the address in a stack -+frame where the pointer to the caller's frame is stored. Assume that -+FRAMEADDR is an RTL expression for the address of the stack frame -+itself. -+ -+If you don't define this macro, the default is to return the value -+of FRAMEADDR - that is, the stack frame address is also the -+address of the stack word that points to the previous frame. -+*/ -+#define DYNAMIC_CHAIN_ADDRESS(FRAMEADDR) plus_constant ((FRAMEADDR), 4) -+ -+ -+/* -+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, FRAMEADDR) avr32_return_addr(COUNT, FRAMEADDR) -+ -+ -+/* -+A C expression whose value is RTL representing the location of the -+incoming return address at the beginning of any function, before the -+prologue. This RTL is either a REG, indicating that the return -+value is saved in 'REG', or a MEM representing a location in -+the stack. -+ -+You only need to define this macro if you want to support call frame -+debugging information like that provided by DWARF 2. -+ -+If this RTL is a REG, you should also define -+DWARF_FRAME_RETURN_COLUMN to DWARF_FRAME_REGNUM (REGNO). -+*/ -+#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (Pmode, LR_REGNUM) -+ -+/* -+A C expression whose value is an integer giving the offset, in bytes, -+from the value of the stack pointer register to the top of the stack -+frame at the beginning of any function, before the prologue. The top of -+the frame is defined to be the value of the stack pointer in the -+previous frame, just before the call instruction. -+ -+You only need to define this macro if you want to support call frame -+debugging information like that provided by DWARF 2. -+*/ -+#define INCOMING_FRAME_SP_OFFSET 0 -+ -+ -+/** Exception Handling Support **/ -+ -+/* Use setjump/longjump for exception handling. */ -+#define DWARF2_UNWIND_INFO 0 -+#define MUST_USE_SJLJ_EXCEPTIONS 1 -+ -+/* -+A C expression whose value is the Nth register number used for -+data by exception handlers, or INVALID_REGNUM if fewer than -+N registers are usable. -+ -+The exception handling library routines communicate with the exception -+handlers via a set of agreed upon registers. Ideally these registers -+should be call-clobbered; it is possible to use call-saved registers, -+but may negatively impact code size. The target must support at least -+2 data registers, but should define 4 if there are enough free registers. -+ -+You must define this macro if you want to support call frame exception -+handling like that provided by DWARF 2. -+*/ -+/* -+ Use r9-r11 -+*/ -+#define EH_RETURN_DATA_REGNO(N) \ -+ ((N<3) ? INTERNAL_REGNUM(N+9) : INVALID_REGNUM) -+ -+/* -+A C expression whose value is RTL representing a location in which -+to store a stack adjustment to be applied before function return. -+This is used to unwind the stack to an exception handler's call frame. -+It will be assigned zero on code paths that return normally. -+ -+Typically this is a call-clobbered hard register that is otherwise -+untouched by the epilogue, but could also be a stack slot. -+ -+You must define this macro if you want to support call frame exception -+handling like that provided by DWARF 2. -+*/ -+/* -+ Use r8 -+*/ -+#define EH_RETURN_STACKADJ_REGNO INTERNAL_REGNUM(8) -+#define EH_RETURN_STACKADJ_RTX gen_rtx_REG(SImode, EH_RETURN_STACKADJ_REGNO) -+ -+/* -+A C expression whose value is RTL representing a location in which -+to store the address of an exception handler to which we should -+return. It will not be assigned on code paths that return normally. -+ -+Typically this is the location in the call frame at which the normal -+return address is stored. For targets that return by popping an -+address off the stack, this might be a memory address just below -+the target call frame rather than inside the current call -+frame. EH_RETURN_STACKADJ_RTX will have already been assigned, -+so it may be used to calculate the location of the target call frame. -+ -+Some targets have more complex requirements than storing to an -+address calculable during initial code generation. In that case -+the eh_return instruction pattern should be used instead. -+ -+If you want to support call frame exception handling, you must -+define either this macro or the eh_return instruction pattern. -+*/ -+/* -+ We define the eh_return instruction pattern, so this isn't needed. -+*/ -+/* #define EH_RETURN_HANDLER_RTX gen_rtx_REG(Pmode, RET_REGISTER) */ -+ -+/* -+ This macro chooses the encoding of pointers embedded in the -+ exception handling sections. If at all possible, this should be -+ defined such that the exception handling section will not require -+ dynamic relocations, and so may be read-only. -+ -+ code is 0 for data, 1 for code labels, 2 for function -+ pointers. global is true if the symbol may be affected by dynamic -+ relocations. The macro should return a combination of the DW_EH_PE_* -+ defines as found in dwarf2.h. -+ -+ If this macro is not defined, pointers will not be encoded but -+ represented directly. -+*/ -+#define ASM_PREFERRED_EH_DATA_FORMAT(CODE, GLOBAL) \ -+ ((flag_pic && (GLOBAL) ? DW_EH_PE_indirect : 0) \ -+ | (flag_pic ? DW_EH_PE_pcrel : DW_EH_PE_absptr) \ -+ | DW_EH_PE_sdata4) -+ -+/* ToDo: The rest of this subsection */ -+ -+/** Specifying How Stack Checking is Done **/ -+/* ToDo: All in this subsection */ -+ -+/** Registers That Address the Stack Frame **/ -+ -+/* -+The register number of the stack pointer register, which must also be a -+fixed register according to FIXED_REGISTERS. On most machines, -+the hardware determines which register this is. -+*/ -+/* Using r13 as stack pointer. */ -+#define STACK_POINTER_REGNUM INTERNAL_REGNUM(13) -+ -+/* -+The register number of the frame pointer register, which is used to -+access automatic variables in the stack frame. On some machines, the -+hardware determines which register this is. On other machines, you can -+choose any register you wish for this purpose. -+*/ -+/* Use r7 */ -+#define FRAME_POINTER_REGNUM INTERNAL_REGNUM(7) -+ -+/* -+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 (see Section -+10.10.5 [Elimination], page 224). -+*/ -+/* Using r5 */ -+#define ARG_POINTER_REGNUM INTERNAL_REGNUM(4) -+ -+ -+/* -+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. -+*/ -+/* Using r0 */ -+#define STATIC_CHAIN_REGNUM INTERNAL_REGNUM(0) -+ -+/** Eliminating Frame Pointer and Arg Pointer **/ -+ -+/* -+A C expression which is nonzero if a function must have and use a frame -+pointer. This expression is evaluated in the reload pass. If its value is -+nonzero the function will have a frame pointer. -+ -+The expression can in principle examine the current function and decide -+according to the facts, but on most machines the constant 0 or the -+constant 1 suffices. Use 0 when the machine allows code to be generated -+with no frame pointer, and doing so saves some time or space. Use 1 -+when there is no possible advantage to avoiding a frame pointer. -+ -+In certain cases, the compiler does not know how to produce valid code -+without a frame pointer. The compiler recognizes those cases and -+automatically gives the function a frame pointer regardless of what -+FRAME_POINTER_REQUIRED says. You don't need to worry about -+them. -+ -+In a function that does not require a frame pointer, the frame pointer -+register can be allocated for ordinary usage, unless you mark it as a -+fixed register. See FIXED_REGISTERS for more information. -+*/ -+/* We need the frame pointer when compiling for profiling */ -+#define FRAME_POINTER_REQUIRED (current_function_profile) -+ -+/* -+A C statement to store in the variable DEPTH_VAR the difference -+between the frame pointer and the stack pointer values immediately after -+the function prologue. The value would be computed from information -+such as the result of get_frame_size () and the tables of -+registers regs_ever_live and call_used_regs. -+ -+If ELIMINABLE_REGS is defined, this macro will be not be used and -+need not be defined. Otherwise, it must be defined even if -+FRAME_POINTER_REQUIRED is defined to always be true; in that -+case, you may set DEPTH_VAR to anything. -+*/ -+#define INITIAL_FRAME_POINTER_OFFSET(DEPTH_VAR) ((DEPTH_VAR) = get_frame_size()) -+ -+/* -+If defined, this macro specifies a table of register pairs used to -+eliminate unneeded registers that point into the stack frame. If it is not -+defined, the only elimination attempted by the compiler is to replace -+references to the frame pointer with references to the stack pointer. -+ -+The definition of this macro is a list of structure initializations, each -+of which specifies an original and replacement register. -+ -+On some machines, the position of the argument pointer is not known until -+the compilation is completed. In such a case, a separate hard register -+must be used for the argument pointer. This register can be eliminated by -+replacing it with either the frame pointer or the argument pointer, -+depending on whether or not the frame pointer has been eliminated. -+ -+In this case, you might specify: -+ #define ELIMINABLE_REGS \ -+ {{ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \ -+ {ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM}, \ -+ {FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}} -+ -+Note that the elimination of the argument pointer with the stack pointer is -+specified first since that is the preferred elimination. -+*/ -+#define ELIMINABLE_REGS \ -+{ \ -+ { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM }, \ -+ { ARG_POINTER_REGNUM, STACK_POINTER_REGNUM }, \ -+ { ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM } \ -+} -+ -+/* -+A C expression that returns nonzero if the compiler is allowed to try -+to replace register number FROM with register number -+TO. This macro need only be defined if ELIMINABLE_REGS -+is defined, and will usually be the constant 1, since most of the cases -+preventing register elimination are things that the compiler already -+knows about. -+*/ -+#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) = avr32_initial_elimination_offset(FROM, TO)) -+ -+/** Passing Function Arguments on the Stack **/ -+ -+ -+/* -+A C expression. If nonzero, push insns will be used to pass -+outgoing arguments. -+If the target machine does not have a push instruction, set it to zero. -+That directs GCC to use an alternate strategy: to -+allocate the entire argument block and then store the arguments into -+it. When PUSH_ARGS is nonzero, PUSH_ROUNDING must be defined too. -+*/ -+#define PUSH_ARGS 1 -+ -+/* -+A C expression that is the number of bytes actually pushed onto the -+stack when an instruction attempts to push NPUSHED bytes. -+ -+On some machines, the definition -+ -+ #define PUSH_ROUNDING(BYTES) (BYTES) -+ -+will suffice. But on other machines, instructions that appear -+to push one byte actually push two bytes in an attempt to maintain -+alignment. Then the definition should be -+ -+ #define PUSH_ROUNDING(BYTES) (((BYTES) + 1) & ~1) -+*/ -+/* Push 4 bytes at the time. */ -+#define PUSH_ROUNDING(NPUSHED) (((NPUSHED) + 3) & ~3) -+ -+/* -+A C expression. If nonzero, 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. -+ -+Setting both PUSH_ARGS and ACCUMULATE_OUTGOING_ARGS is not proper. -+*/ -+#define ACCUMULATE_OUTGOING_ARGS 0 -+ -+/* -+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 you can obtain the DECL_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, FUNDECL -+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 -+ -+ -+/*Return true if this function can we use a single return instruction*/ -+#define USE_RETURN_INSN(ISCOND) avr32_use_return_insn(ISCOND) -+ -+/* -+A C expression that should indicate the number of bytes a call sequence -+pops off the stack. It is added to the value of RETURN_POPS_ARGS -+when compiling a function call. -+ -+CUM is the variable in which all arguments to the called function -+have been accumulated. -+ -+On certain architectures, such as the SH5, a call trampoline is used -+that pops certain registers off the stack, depending on the arguments -+that have been passed to the function. Since this is a property of the -+call site, not of the called function, RETURN_POPS_ARGS is not -+appropriate. -+*/ -+#define CALL_POPS_ARGS(CUM) 0 -+ -+/* Passing Arguments in Registers */ -+ -+/* -+A C expression that controls whether a function argument is passed -+in a register, and which register. -+ -+The arguments are CUM, which summarizes all the previous -+arguments; 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. -+TYPE can be an incomplete type if a syntax error has previously -+occurred. -+ -+The value of the expression is usually either 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 value of the expression can also be a parallel RTX. This is -+used when an argument is passed in multiple locations. The mode of the -+of the parallel should be the mode of the entire argument. The -+parallel holds any number of expr_list pairs; each one -+describes where part of the argument is passed. In each -+expr_list the first operand must be a reg RTX for the hard -+register in which to pass this part of the argument, and the mode of the -+register RTX indicates how large this part of the argument is. The -+second operand of the expr_list is a const_int which gives -+the offset in bytes into the entire argument of where this part starts. -+As a special exception the first expr_list in the parallel -+RTX may have a first operand of zero. This indicates that the entire -+argument is also stored on the stack. -+ -+The last time this macro is called, it is called with MODE == VOIDmode, -+and its result is passed to the call or call_value -+pattern as operands 2 and 3 respectively. -+ -+The usual way to make the ISO 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 nonzero 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) \ -+ avr32_function_arg(&(CUM), MODE, TYPE, NAMED) -+ -+/* -+A C type for declaring a variable that is used as the first argument of -+FUNCTION_ARG and other related values. For some target machines, -+the type 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. -+*/ -+typedef struct avr32_args -+{ -+ /* Index representing the argument register the current function argument -+ will occupy */ -+ int index; -+ /* A mask with bits representing the argument registers: if a bit is set -+ then this register is used for an argument */ -+ int used_index; -+ /* TRUE if this function has anonymous arguments */ -+ int uses_anonymous_args; -+ /* The size in bytes of the named arguments pushed on the stack */ -+ int stack_pushed_args_size; -+ /* Set to true if this function needs a Return Value Pointer */ -+ int use_rvp; -+ /* Set to true if function is a flashvault function. */ -+ int flashvault_func; -+ -+} CUMULATIVE_ARGS; -+ -+ -+#define FIRST_CUM_REG_INDEX 0 -+#define LAST_CUM_REG_INDEX 4 -+#define GET_REG_INDEX(CUM) ((CUM)->index) -+#define SET_REG_INDEX(CUM, INDEX) ((CUM)->index = (INDEX)); -+#define GET_USED_INDEX(CUM, INDEX) ((CUM)->used_index & (1 << (INDEX))) -+#define SET_USED_INDEX(CUM, INDEX) \ -+ do \ -+ { \ -+ if (INDEX >= 0) \ -+ (CUM)->used_index |= (1 << (INDEX)); \ -+ } \ -+ while (0) -+#define SET_INDEXES_UNUSED(CUM) ((CUM)->used_index = 0) -+ -+/* -+ 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. For direct calls that are not libcalls, FNDECL -+ contain the declaration node of the function. FNDECL is also set when -+ INIT_CUMULATIVE_ARGS is used to find arguments for the function being -+ compiled. N_NAMED_ARGS is set to the number of named arguments, including a -+ structure return address if it is passed as a parameter, when making a call. -+ When processing incoming arguments, N_NAMED_ARGS is set to -1. -+ -+ 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, FNDECL, N_NAMED_ARGS) \ -+ avr32_init_cumulative_args(&(CUM), FNTYPE, LIBNAME, FNDECL) -+ -+/* -+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) \ -+ avr32_function_arg_advance(&(CUM), MODE, TYPE, NAMED) -+ -+/* -+If defined, a C expression which determines whether, and in which direction, -+to pad out an argument with extra space. The value should be of type -+enum direction: either 'upward' to pad above the argument, -+'downward' to pad below, or 'none' to inhibit padding. -+ -+The amount of padding is always just enough to reach the next -+multiple of FUNCTION_ARG_BOUNDARY; this macro does not control -+it. -+ -+This macro has a default definition which is right for most systems. -+For little-endian machines, the default is to pad upward. For -+big-endian machines, the default is to pad downward for an argument of -+constant size shorter than an int, and upward otherwise. -+*/ -+#define FUNCTION_ARG_PADDING(MODE, TYPE) \ -+ avr32_function_arg_padding(MODE, TYPE) -+ -+/* -+ Specify padding for the last element of a block move between registers -+ and memory. First is nonzero if this is the only element. Defining -+ this macro allows better control of register function parameters on -+ big-endian machines, without using PARALLEL rtl. In particular, -+ MUST_PASS_IN_STACK need not test padding and mode of types in registers, -+ as there is no longer a "wrong" part of a register; For example, a three -+ byte aggregate may be passed in the high part of a register if so required. -+*/ -+#define BLOCK_REG_PADDING(MODE, TYPE, FIRST) \ -+ avr32_function_arg_padding(MODE, TYPE) -+ -+/* -+If defined, a C expression which determines whether the default -+implementation of va_arg will attempt to pad down before reading the -+next argument, if that argument is smaller than its aligned space as -+controlled by PARM_BOUNDARY. If this macro is not defined, all such -+arguments are padded down if BYTES_BIG_ENDIAN is true. -+*/ -+#define PAD_VARARGS_DOWN \ -+ (FUNCTION_ARG_PADDING (TYPE_MODE (type), type) == downward) -+ -+/* -+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. -+*/ -+/* -+ Use r8 - r12 for function arguments. -+*/ -+#define FUNCTION_ARG_REGNO_P(REGNO) \ -+ (REGNO >= 3 && REGNO <= 7) -+ -+/* Number of registers used for passing function arguments */ -+#define NUM_ARG_REGS 5 -+ -+/* -+If defined, the order in which arguments are loaded into their -+respective argument registers is reversed so that the last -+argument is loaded first. This macro only affects arguments -+passed in registers. -+*/ -+/* #define LOAD_ARGS_REVERSED */ -+ -+/** How Scalar Function Values Are Returned **/ -+ -+/* AVR32 is using r12 as return register. */ -+#define RET_REGISTER (15 - 12) -+ -+/* -+A C expression to create an RTX representing the place where a library -+function returns a value of mode MODE. 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. -+ -+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) avr32_libcall_value(MODE) -+ -+/* -+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) == 0) -+ -+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. -+*/ -+/* -+ When returning a value of mode DImode, r11:r10 is used, else r12 is used. -+*/ -+#define FUNCTION_VALUE_REGNO_P(REGNO) ((REGNO) == RET_REGISTER \ -+ || (REGNO) == INTERNAL_REGNUM(11)) -+ -+ -+/** How Large Values Are Returned **/ -+ -+ -+/* -+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 -+ -+ -+ -+ -+/** Generating Code for Profiling **/ -+ -+/* -+A C statement or compound statement to output to FILE some -+assembler code to call the profiling subroutine mcount. -+ -+The details of how mcount expects to be called are determined by -+your operating system environment, not by GCC. 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. -+ -+Older implementations of mcount expect the address of a counter -+variable to be loaded into some register. The name of this variable is -+'LP' followed by the number LABELNO, so you would generate -+the name using 'LP%d' in a fprintf. -+*/ -+/* ToDo: fixme */ -+#ifndef FUNCTION_PROFILER -+#define FUNCTION_PROFILER(FILE, LABELNO) \ -+ fprintf((FILE), "/* profiler %d */", (LABELNO)) -+#endif -+ -+ -+/***************************************************************************** -+ * Trampolines for Nested Functions * -+ *****************************************************************************/ -+ -+/* -+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 you do not define this macro, it means no template is needed -+for the target. Do not define this macro on systems where the block move -+code to copy the trampoline into place would be larger than the code -+to generate it on the spot. -+*/ -+/* ToDo: correct? */ -+#define TRAMPOLINE_TEMPLATE(FILE) avr32_trampoline_template(FILE); -+ -+ -+/* -+A C expression for the size in bytes of the trampoline, as an integer. -+*/ -+/* ToDo: fixme */ -+#define TRAMPOLINE_SIZE 0x0C -+ -+/* -+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 16 -+ -+/* -+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(ADDR, FNADDR, STATIC_CHAIN) \ -+ avr32_initialize_trampoline(ADDR, FNADDR, STATIC_CHAIN) -+ -+ -+/****************************************************************************** -+ * Implicit Calls to Library Routines -+ *****************************************************************************/ -+ -+/* Tail calling. */ -+ -+/* A C expression that evaluates to true if it is ok to perform a sibling -+ call to DECL. */ -+#define FUNCTION_OK_FOR_SIBCALL(DECL) 0 -+ -+#define OVERRIDE_OPTIONS avr32_override_options () -+ -+#define OPTIMIZATION_OPTIONS(LEVEL, SIZE) avr32_optimization_options (LEVEL, SIZE) -+ -+/****************************************************************************** -+ * Addressing Modes -+ *****************************************************************************/ -+ -+/* -+A C expression that is nonzero if the machine supports pre-increment, -+pre-decrement, post-increment, or post-decrement addressing respectively. -+*/ -+/* -+ AVR32 supports Rp++ and --Rp -+*/ -+#define HAVE_PRE_INCREMENT 0 -+#define HAVE_PRE_DECREMENT 1 -+#define HAVE_POST_INCREMENT 1 -+#define HAVE_POST_DECREMENT 0 -+ -+/* -+A C expression that is nonzero if the machine supports pre- or -+post-address side-effect generation involving constants other than -+the size of the memory operand. -+*/ -+#define HAVE_PRE_MODIFY_DISP 0 -+#define HAVE_POST_MODIFY_DISP 0 -+ -+/* -+A C expression that is nonzero if the machine supports pre- or -+post-address side-effect generation involving a register displacement. -+*/ -+#define HAVE_PRE_MODIFY_REG 0 -+#define HAVE_POST_MODIFY_REG 0 -+ -+/* -+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) CONSTANT_P(X) -+ -+/* -+A number, the maximum number of registers that can appear in a valid -+memory address. Note that it is up to you to specify a value equal to -+the maximum number that GO_IF_LEGITIMATE_ADDRESS would ever -+accept. -+*/ -+#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. -+*/ -+#ifdef REG_OK_STRICT -+# define GO_IF_LEGITIMATE_ADDRESS(MODE, X, LABEL) \ -+ do \ -+ { \ -+ if (avr32_legitimate_address(MODE, X, 1)) \ -+ goto LABEL; \ -+ } \ -+ while (0) -+#else -+# define GO_IF_LEGITIMATE_ADDRESS(MODE, X, LABEL) \ -+ do \ -+ { \ -+ if (avr32_legitimate_address(MODE, X, 0)) \ -+ goto LABEL; \ -+ } \ -+ while (0) -+#endif -+ -+ -+ -+/* -+A C compound statement that attempts to replace X with a valid -+memory address for an operand of mode MODE. win will be a -+C statement label elsewhere in the code; the macro definition may use -+ -+ GO_IF_LEGITIMATE_ADDRESS (MODE, X, WIN); -+ -+to avoid further processing if the address has become legitimate. -+ -+X will always be the result of a call to break_out_memory_refs, -+and OLDX will be the operand that was given to that function to produce -+X. -+ -+The code generated by this macro should not alter the substructure of -+X. If it transforms X into a more legitimate form, it -+should assign X (which will always be a C variable) a new value. -+ -+It is not necessary for this macro to come up with a legitimate -+address. The compiler has standard ways of doing so in all cases. In -+fact, it is safe for this macro to do nothing. But often a -+machine-dependent strategy can generate better code. -+*/ -+#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \ -+ do \ -+ { \ -+ if (GET_CODE(X) == PLUS \ -+ && GET_CODE(XEXP(X, 0)) == REG \ -+ && GET_CODE(XEXP(X, 1)) == CONST_INT \ -+ && !CONST_OK_FOR_CONSTRAINT_P(INTVAL(XEXP(X, 1)), \ -+ 'K', "Ks16")) \ -+ { \ -+ rtx index = force_reg(SImode, XEXP(X, 1)); \ -+ X = gen_rtx_PLUS( SImode, XEXP(X, 0), index); \ -+ } \ -+ GO_IF_LEGITIMATE_ADDRESS(MODE, X, WIN); \ -+ } \ -+ while(0) -+ -+ -+/* -+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) \ -+ do \ -+ { \ -+ if (GET_CODE (ADDR) == POST_INC \ -+ || GET_CODE (ADDR) == PRE_DEC) \ -+ goto LABEL; \ -+ } \ -+ while (0) -+ -+/* -+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) avr32_legitimate_constant_p(X) -+ -+ -+/****************************************************************************** -+ * Condition Code Status -+ *****************************************************************************/ -+ -+/* -+C code for a data type which is used for declaring the mdep -+component of cc_status. It defaults to int. -+ -+This macro is not used on machines that do not use cc0. -+*/ -+ -+typedef struct -+{ -+ int flags; -+ rtx value; -+ int cond_exec_cmp_clobbered; -+} avr32_status_reg; -+ -+ -+#define CC_STATUS_MDEP avr32_status_reg -+ -+/* -+A C expression to initialize the mdep field to "empty". -+The default definition does nothing, since most machines don't use -+the field anyway. If you want to use the field, you should probably -+define this macro to initialize it. -+ -+This macro is not used on machines that do not use cc0. -+*/ -+ -+#define CC_STATUS_MDEP_INIT \ -+ (cc_status.mdep.flags = CC_NONE , cc_status.mdep.cond_exec_cmp_clobbered = 0, cc_status.mdep.value = 0) -+ -+/* -+A C compound statement to set the components of cc_status -+appropriately for an insn INSN whose body is EXP. It is -+this macro's responsibility to recognize insns that set the condition -+code as a byproduct of other activity as well as those that explicitly -+set (cc0). -+ -+This macro is not used on machines that do not use cc0. -+ -+If there are insns that do not set the condition code but do alter -+other machine registers, this macro must check to see whether they -+invalidate the expressions that the condition code is recorded as -+reflecting. For example, on the 68000, insns that store in address -+registers do not set the condition code, which means that usually -+NOTICE_UPDATE_CC can leave cc_status unaltered for such -+insns. But suppose that the previous insn set the condition code -+based on location 'a4@@(102)' and the current insn stores a new -+value in 'a4'. Although the condition code is not changed by -+this, it will no longer be true that it reflects the contents of -+'a4@@(102)'. Therefore, NOTICE_UPDATE_CC must alter -+cc_status in this case to say that nothing is known about the -+condition code value. -+ -+The definition of NOTICE_UPDATE_CC must be prepared to deal -+with the results of peephole optimization: insns whose patterns are -+parallel RTXs containing various reg, mem or -+constants which are just the operands. The RTL structure of these -+insns is not sufficient to indicate what the insns actually do. What -+NOTICE_UPDATE_CC should do when it sees one is just to run -+CC_STATUS_INIT. -+ -+A possible definition of NOTICE_UPDATE_CC is to call a function -+that looks at an attribute (see Insn Attributes) named, for example, -+'cc'. This avoids having detailed information about patterns in -+two places, the 'md' file and in NOTICE_UPDATE_CC. -+*/ -+ -+#define NOTICE_UPDATE_CC(EXP, INSN) avr32_notice_update_cc(EXP, INSN) -+ -+ -+ -+ -+/****************************************************************************** -+ * Describing Relative Costs of Operations -+ *****************************************************************************/ -+ -+ -+ -+/* -+A C expression for the cost of moving data of mode MODE from a -+register in class FROM to one in class TO. The classes are -+expressed using the enumeration values such as GENERAL_REGS. A -+value of 2 is the default; other values are interpreted relative to -+that. -+ -+It is not required that the cost always equal 2 when FROM is the -+same as TO; on some machines it is expensive to move between -+registers if they are not general registers. -+ -+If reload sees an insn consisting of a single set between two -+hard registers, and if REGISTER_MOVE_COST applied to their -+classes returns a value of 2, reload does not check to ensure that the -+constraints of the insn are met. Setting a cost of other than 2 will -+allow reload to verify that the constraints are met. You should do this -+if the movm pattern's constraints do not allow such copying. -+*/ -+#define REGISTER_MOVE_COST(MODE, FROM, TO) \ -+ ((GET_MODE_SIZE(MODE) <= 4) ? 2: \ -+ (GET_MODE_SIZE(MODE) <= 8) ? 3: \ -+ 4) -+ -+/* -+A C expression for the cost of moving data of mode MODE between a -+register of class CLASS and memory; IN is zero if the value -+is to be written to memory, nonzero if it is to be read in. This cost -+is relative to those in REGISTER_MOVE_COST. If moving between -+registers and memory is more expensive than between two registers, you -+should define this macro to express the relative cost. -+ -+If you do not define this macro, GCC uses a default cost of 4 plus -+the cost of copying via a secondary reload register, if one is -+needed. If your machine requires a secondary reload register to copy -+between memory and a register of CLASS but the reload mechanism is -+more complex than copying via an intermediate, define this macro to -+reflect the actual cost of the move. -+ -+GCC defines the function memory_move_secondary_cost if -+secondary reloads are needed. It computes the costs due to copying via -+a secondary register. If your machine copies from memory using a -+secondary register in the conventional way but the default base value of -+4 is not correct for your machine, define this macro to add some other -+value to the result of that function. The arguments to that function -+are the same as to this macro. -+*/ -+/* -+ Memory moves are costly -+*/ -+#define MEMORY_MOVE_COST(MODE, CLASS, IN) \ -+ (((IN) ? ((GET_MODE_SIZE(MODE) < 4) ? 4 : \ -+ (GET_MODE_SIZE(MODE) > 8) ? 6 : \ -+ 3) \ -+ : ((GET_MODE_SIZE(MODE) > 8) ? 6 : 3))) -+ -+/* -+A C expression for the cost of a branch instruction. A value of 1 is -+the default; other values are interpreted relative to that. -+*/ -+ /* Try to use conditionals as much as possible */ -+#define BRANCH_COST (TARGET_BRANCH_PRED ? 3 : 4) -+ -+/*A C expression for the maximum number of instructions to execute via conditional -+ execution instructions instead of a branch. A value of BRANCH_COST+1 is the default -+ if the machine does not use cc0, and 1 if it does use cc0.*/ -+#define MAX_CONDITIONAL_EXECUTE 4 -+ -+/* -+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 1 -+ -+ -+/* -+Define this macro if it is as good or better to call a constant -+function address than to call an address kept in a register. -+*/ -+#define NO_FUNCTION_CSE -+ -+ -+/****************************************************************************** -+ * Adjusting the Instruction Scheduler -+ *****************************************************************************/ -+ -+/***************************************************************************** -+ * Dividing the Output into Sections (Texts, Data, ...) * -+ *****************************************************************************/ -+ -+/* -+A C expression whose value is a string, including spacing, containing the -+assembler operation that should precede instructions and read-only data. -+Normally "\t.text" is right. -+*/ -+#define TEXT_SECTION_ASM_OP "\t.text" -+/* -+A C statement that switches to the default section containing instructions. -+Normally this is not needed, as simply defining TEXT_SECTION_ASM_OP -+is enough. The MIPS port uses this to sort all functions after all data -+declarations. -+*/ -+/* #define TEXT_SECTION */ -+ -+/* -+A C expression whose value is a string, including spacing, containing the -+assembler operation to identify the following data as writable initialized -+data. Normally "\t.data" is right. -+*/ -+#define DATA_SECTION_ASM_OP "\t.data" -+ -+/* -+If defined, a C expression whose value is a string, including spacing, -+containing the assembler operation to identify the following data as -+shared data. If not defined, DATA_SECTION_ASM_OP will be used. -+*/ -+ -+/* -+A C expression whose value is a string, including spacing, containing -+the assembler operation to identify the following data as read-only -+initialized data. -+*/ -+#undef READONLY_DATA_SECTION_ASM_OP -+#define READONLY_DATA_SECTION_ASM_OP \ -+ ((TARGET_USE_RODATA_SECTION) ? \ -+ "\t.section\t.rodata" : \ -+ TEXT_SECTION_ASM_OP ) -+ -+ -+/* -+If defined, a C expression whose value is a string, including spacing, -+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\t.bss" -+ -+/* -+If defined, a C expression whose value is a string, including spacing, -+containing the assembler operation to identify the following data as -+uninitialized global shared data. If not defined, and -+BSS_SECTION_ASM_OP is, the latter will be used. -+*/ -+/*#define SHARED_BSS_SECTION_ASM_OP "\trseg\tshared_bbs_section:data:noroot(0)\n"*/ -+/* -+If defined, a C expression whose value is a string, including spacing, -+containing the assembler operation to identify the following data as -+initialization code. If not defined, GCC will assume such a section does -+not exist. -+*/ -+#undef INIT_SECTION_ASM_OP -+#define INIT_SECTION_ASM_OP "\t.section\t.init" -+ -+/* -+If defined, a C expression whose value is a string, including spacing, -+containing the assembler operation to identify the following data as -+finalization code. If not defined, GCC will assume such a section does -+not exist. -+*/ -+#undef FINI_SECTION_ASM_OP -+#define FINI_SECTION_ASM_OP "\t.section\t.fini" -+ -+/* -+If defined, an ASM statement that switches to a different section -+via SECTION_OP, calls FUNCTION, and switches back to -+the text section. This is used in crtstuff.c if -+INIT_SECTION_ASM_OP or FINI_SECTION_ASM_OP to calls -+to initialization and finalization functions from the init and fini -+sections. By default, this macro uses a simple function call. Some -+ports need hand-crafted assembly code to avoid dependencies on -+registers initialized in the function prologue or to ensure that -+constant pools don't end up too far way in the text section. -+*/ -+#define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC) \ -+ asm ( SECTION_OP "\n" \ -+ "mcall r6[" USER_LABEL_PREFIX #FUNC "@got]\n" \ -+ TEXT_SECTION_ASM_OP); -+ -+ -+/* -+Define this macro to be an expression with a nonzero value if jump -+tables (for tablejump insns) should be output in the text -+section, along with the assembler instructions. Otherwise, the -+readonly data section is used. -+ -+This macro is irrelevant if there is no separate readonly data section. -+*/ -+/* Put jump tables in text section if we have caches. Otherwise assume that -+ loading data from code memory is slow. */ -+#define JUMP_TABLES_IN_TEXT_SECTION \ -+ (TARGET_CACHES ? 1 : 0) -+ -+ -+/****************************************************************************** -+ * Position Independent Code (PIC) -+ *****************************************************************************/ -+ -+#ifndef AVR32_ALWAYS_PIC -+#define AVR32_ALWAYS_PIC 0 -+#endif -+ -+/* GOT is set to r6 */ -+#define PIC_OFFSET_TABLE_REGNUM INTERNAL_REGNUM(6) -+ -+/* -+A C expression that is nonzero if X is a legitimate immediate -+operand on the target machine when generating position independent code. -+You can assume that X satisfies CONSTANT_P, so you need not -+check this. You can also assume flag_pic is true, so you need not -+check it either. You need not define this macro if all constants -+(including SYMBOL_REF) can be immediate operands when generating -+position independent code. -+*/ -+/* We can't directly access anything that contains a symbol, -+ nor can we indirect via the constant pool. */ -+#define LEGITIMATE_PIC_OPERAND_P(X) avr32_legitimate_pic_operand_p(X) -+ -+ -+/* We need to know when we are making a constant pool; this determines -+ whether data needs to be in the GOT or can be referenced via a GOT -+ offset. */ -+extern int making_const_table; -+ -+/****************************************************************************** -+ * Defining the Output Assembler Language -+ *****************************************************************************/ -+ -+ -+/* -+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. -+*/ -+#undef ASM_APP_ON -+#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. -+*/ -+#undef ASM_APP_OFF -+#define ASM_APP_OFF "#NO_APP\n" -+ -+ -+ -+#define FILE_ASM_OP "\t.file\n" -+#define IDENT_ASM_OP "\t.ident\t" -+#define SET_ASM_OP "\t.set\t" -+ -+ -+/* -+ * Output assembly directives to switch to section name. The section -+ * should have attributes as specified by flags, which is a bit mask -+ * of the SECTION_* flags defined in 'output.h'. If align is nonzero, -+ * it contains an alignment in bytes to be used for the section, -+ * otherwise some target default should be used. Only targets that -+ * must specify an alignment within the section directive need pay -+ * attention to align -- we will still use ASM_OUTPUT_ALIGN. -+ * -+ * NOTE: This one must not be moved to avr32.c -+ */ -+#undef TARGET_ASM_NAMED_SECTION -+#define TARGET_ASM_NAMED_SECTION default_elf_asm_named_section -+ -+ -+/* -+You may define this macro as a C expression. You should define the -+expression to have a nonzero value if GCC should output the constant -+pool for a function before the code for the function, or a zero value if -+GCC should output the constant pool after the function. If you do -+not define this macro, the usual case, GCC will output the constant -+pool before the function. -+*/ -+#define CONSTANT_POOL_BEFORE_FUNCTION 0 -+ -+ -+/* -+Define this macro as a C expression which is nonzero if the constant -+EXP, of type tree, should be output after the code for a -+function. The compiler will normally output all constants before the -+function; you need not define this macro if this is OK. -+*/ -+#define CONSTANT_AFTER_FUNCTION_P(EXP) 1 -+ -+ -+/* -+Define this macro as a C expression which is nonzero if C is -+as a logical line separator by the assembler. STR points to the -+position in the string where C was found; this can be used if a -+line separator uses multiple characters. -+ -+If you do not define this macro, the default is that only -+the character ';' is treated as a logical line separator. -+*/ -+#define IS_ASM_LOGICAL_LINE_SEPARATOR(C,STR) (((C) == '\n') || ((C) == ';')) -+ -+ -+/** Output of Uninitialized Variables **/ -+ -+/* -+A C statement (sans semicolon) to output to the stdio stream -+STREAM the assembler definition of a common-label named -+NAME whose size is SIZE bytes. The variable ROUNDED -+is the size rounded up to whatever alignment the caller wants. -+ -+Use the expression assemble_name(STREAM, NAME) to -+output the name itself; before and after that, output the additional -+assembler syntax for defining the name, and a newline. -+ -+This macro controls how the assembler definitions of uninitialized -+common global variables are output. -+*/ -+/* -+#define ASM_OUTPUT_COMMON(STREAM, NAME, SIZE, ROUNDED) \ -+ avr32_asm_output_common(STREAM, NAME, SIZE, ROUNDED) -+*/ -+ -+#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \ -+ do \ -+ { \ -+ fputs ("\t.comm ", (FILE)); \ -+ assemble_name ((FILE), (NAME)); \ -+ fprintf ((FILE), ",%d\n", (SIZE)); \ -+ } \ -+ while (0) -+ -+/* -+ * 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(STREAM, DECL, NAME, SIZE, ALIGNMENT) \ -+ asm_output_aligned_bss (STREAM, DECL, NAME, SIZE, ALIGNMENT) -+ -+/* -+A C statement (sans semicolon) to output to the stdio stream -+STREAM the assembler definition of a local-common-label named -+NAME whose size is SIZE bytes. The variable ROUNDED -+is the size rounded up to whatever alignment the caller wants. -+ -+Use the expression assemble_name(STREAM, NAME) to -+output the name itself; before and after that, output the additional -+assembler syntax for defining the name, and a newline. -+ -+This macro controls how the assembler definitions of uninitialized -+static variables are output. -+*/ -+#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \ -+ do \ -+ { \ -+ fputs ("\t.lcomm ", (FILE)); \ -+ assemble_name ((FILE), (NAME)); \ -+ fprintf ((FILE), ",%d, %d\n", (SIZE), 2); \ -+ } \ -+ while (0) -+ -+ -+/* -+A C statement (sans semicolon) to output to the stdio stream -+STREAM the assembler definition of a label named NAME. -+Use the expression assemble_name(STREAM, NAME) to -+output the name itself; before and after that, output the additional -+assembler syntax for defining the name, and a newline. -+*/ -+#define ASM_OUTPUT_LABEL(STREAM, NAME) avr32_asm_output_label(STREAM, NAME) -+ -+/* A C string containing the appropriate assembler directive to -+ * specify the size of a symbol, without any arguments. On systems -+ * that use ELF, the default (in 'config/elfos.h') is '"\t.size\t"'; -+ * on other systems, the default is not to define this macro. -+ * -+ * Define this macro only if it is correct to use the default -+ * definitions of ASM_ OUTPUT_SIZE_DIRECTIVE and -+ * ASM_OUTPUT_MEASURED_SIZE for your system. If you need your own -+ * custom definitions of those macros, or if you do not need explicit -+ * symbol sizes at all, do not define this macro. -+ */ -+#define SIZE_ASM_OP "\t.size\t" -+ -+ -+/* -+A C statement (sans semicolon) to output to the stdio stream -+STREAM some commands that will make the label NAME global; -+that is, available for reference from other files. Use the expression -+assemble_name(STREAM, NAME) to output the name -+itself; before and after that, output the additional assembler syntax -+for making that name global, and a newline. -+*/ -+#define GLOBAL_ASM_OP "\t.global\t" -+ -+ -+ -+/* -+A C expression which evaluates to true if the target supports weak symbols. -+ -+If you don't define this macro, defaults.h provides a default -+definition. If either ASM_WEAKEN_LABEL or ASM_WEAKEN_DECL -+is defined, the default definition is '1'; otherwise, it is -+'0'. Define this macro if you want to control weak symbol support -+with a compiler flag such as -melf. -+*/ -+#define SUPPORTS_WEAK 1 -+ -+/* -+A C statement (sans semicolon) to output to the stdio stream -+STREAM a reference in assembler syntax to a label named -+NAME. This should add '_' to the front of the name, if that -+is customary on your operating system, as it is in most Berkeley Unix -+systems. This macro is used in assemble_name. -+*/ -+#define ASM_OUTPUT_LABELREF(STREAM, NAME) \ -+ avr32_asm_output_labelref(STREAM, NAME) -+ -+ -+ -+/* -+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(OUTVAR, NAME, NUMBER) \ -+ do \ -+ { \ -+ (OUTVAR) = (char *) alloca (strlen ((NAME)) + 10); \ -+ sprintf ((OUTVAR), "%s.%d", (NAME), (NUMBER)); \ -+ } \ -+ while (0) -+ -+ -+/** Macros Controlling Initialization Routines **/ -+ -+ -+/* -+If defined, main will not call __main as described above. -+This macro should be defined for systems that control start-up code -+on a symbol-by-symbol basis, such as OSF/1, and should not -+be defined explicitly for systems that support INIT_SECTION_ASM_OP. -+*/ -+/* -+ __main is not defined when debugging. -+*/ -+#define HAS_INIT_SECTION -+ -+ -+/** Output of Assembler Instructions **/ -+ -+/* -+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 \ -+{ \ -+ "pc", "lr", \ -+ "sp", "r12", \ -+ "r11", "r10", \ -+ "r9", "r8", \ -+ "r7", "r6", \ -+ "r5", "r4", \ -+ "r3", "r2", \ -+ "r1", "r0", \ -+} -+ -+/* -+A C compound statement to output to stdio stream STREAM the -+assembler syntax for an instruction operand X. X is an -+RTL expression. -+ -+CODE is a value that can be used to specify one of several ways -+of printing the operand. It is used when identical operands must be -+printed differently depending on the context. CODE comes from -+the '%' specification that was used to request printing of the -+operand. If the specification was just '%digit' then -+CODE is 0; if the specification was '%ltr digit' -+then CODE is the ASCII code for ltr. -+ -+If X is a register, this macro should print the register's name. -+The names can be found in an array reg_names whose type is -+char *[]. reg_names is initialized from REGISTER_NAMES. -+ -+When the machine description has a specification '%punct' -+(a '%' followed by a punctuation character), this macro is called -+with a null pointer for X and the punctuation character for -+CODE. -+*/ -+#define PRINT_OPERAND(STREAM, X, CODE) avr32_print_operand(STREAM, X, CODE) -+ -+/* A C statement to be executed just prior to the output of -+ assembler code for INSN, to modify the extracted operands so -+ they will be output differently. -+ -+ Here the argument OPVEC is the vector containing the operands -+ extracted from INSN, and NOPERANDS is the number of elements of -+ the vector which contain meaningful data for this insn. -+ The contents of this vector are what will be used to convert the insn -+ template into assembler code, so you can change the assembler output -+ by changing the contents of the vector. */ -+#define FINAL_PRESCAN_INSN(INSN, OPVEC, NOPERANDS) \ -+ avr32_final_prescan_insn ((INSN), (OPVEC), (NOPERANDS)) -+ -+/* -+A C expression which evaluates to true if CODE is a valid -+punctuation character for use in the PRINT_OPERAND macro. If -+PRINT_OPERAND_PUNCT_VALID_P is not defined, it means that no -+punctuation characters (except for the standard one, '%') are used -+in this way. -+*/ -+#define PRINT_OPERAND_PUNCT_VALID_P(CODE) \ -+ (((CODE) == '?') \ -+ || ((CODE) == '!')) -+ -+/* -+A C compound statement to output to stdio stream STREAM the -+assembler syntax for an instruction operand that is a memory reference -+whose address is X. X is an RTL expression. -+ -+On some machines, the syntax for a symbolic address 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. (see Assembler Format.) -+*/ -+#define PRINT_OPERAND_ADDRESS(STREAM, X) avr32_print_operand_address(STREAM, X) -+ -+ -+/** Output of Dispatch Tables **/ -+ -+/* -+ * 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 -+ * (*targetm.asm_out.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) -+ * -+ * You must provide this macro on machines where the addresses in a -+ * dispatch table are relative to the table's own address. If defined, -+ * GCC will also use this macro on all machines when producing -+ * PIC. body is the body of the ADDR_DIFF_VEC; it is provided so that -+ * the mode and flags can be read. -+ */ -+#define ASM_OUTPUT_ADDR_DIFF_ELT(STREAM, BODY, VALUE, REL) \ -+ fprintf(STREAM, "\tbral\t%sL%d\n", LOCAL_LABEL_PREFIX, VALUE) -+ -+/* -+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.long %sL%d\n", LOCAL_LABEL_PREFIX, VALUE) -+ -+/** Assembler Commands for Exception Regions */ -+ -+/* ToDo: All of this subsection */ -+ -+/** Assembler Commands for Alignment */ -+ -+ -+/* -+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(STREAM, POWER) \ -+ do \ -+ { \ -+ if ((POWER) != 0) \ -+ fprintf(STREAM, "\t.align\t%d\n", POWER); \ -+ } \ -+ while (0) -+ -+/* -+Like ASM_OUTPUT_ALIGN, except that the \nop" instruction is used for padding, if -+necessary. -+*/ -+#define ASM_OUTPUT_ALIGN_WITH_NOP(STREAM, POWER) \ -+ fprintf(STREAM, "\t.balignw\t%d, 0xd703\n", (1 << POWER)) -+ -+ -+ -+/****************************************************************************** -+ * Controlling Debugging Information Format -+ *****************************************************************************/ -+ -+/* How to renumber registers for dbx and gdb. */ -+#define DBX_REGISTER_NUMBER(REGNO) ASM_REGNUM (REGNO) -+ -+/* The DWARF 2 CFA column which tracks the return address. */ -+#define DWARF_FRAME_RETURN_COLUMN DWARF_FRAME_REGNUM(LR_REGNUM) -+ -+/* -+Define this macro if GCC 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 TARGET_ASM_FUNCTION_PROLOGUE if you don't. -+*/ -+#define DWARF2_DEBUGGING_INFO 1 -+ -+ -+#define DWARF2_ASM_LINE_DEBUG_INFO 1 -+#define DWARF2_FRAME_INFO 1 -+ -+ -+/****************************************************************************** -+ * Miscellaneous Parameters -+ *****************************************************************************/ -+ -+/* ToDo: a lot */ -+ -+/* -+An alias for a machine mode name. This is the machine mode that -+elements of a jump-table should have. -+*/ -+#define CASE_VECTOR_MODE SImode -+ -+/* -+Define this macro to be a C expression to indicate when jump-tables -+should contain relative addresses. If jump-tables never contain -+relative addresses, then you need not define this macro. -+*/ -+#define CASE_VECTOR_PC_RELATIVE 0 -+ -+/* Increase the threshold for using table jumps on the UC arch. */ -+#define CASE_VALUES_THRESHOLD (TARGET_BRANCH_PRED ? 4 : 7) -+ -+/* -+The maximum number of bytes that a single instruction can move quickly -+between memory and registers or between two memory locations. -+*/ -+#define MOVE_MAX (2*UNITS_PER_WORD) -+ -+ -+/* 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 nonzero, 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 bit-fields at variable positions, which may include 'bit test' -+ 378 GNU Compiler Collection (GCC) Internals -+ instructions, a nonzero SHIFT_COUNT_TRUNCATED also enables deletion of truncations -+ of the values that serve as arguments to bit-field instructions. -+ If both types of instructions truncate the count (for shifts) and position (for bit-field -+ operations), or if no variable-position bit-field 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) bit-field 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 de ne 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 -+ -+/* -+An alias for the machine mode for pointers. On most machines, define -+this to be the integer mode corresponding to the width of a hardware -+pointer; SImode on 32-bit machine or DImode on 64-bit machines. -+On some machines you must define this to be one of the partial integer -+modes, such as PSImode. -+ -+The width of Pmode must be at least as large as the value of -+POINTER_SIZE. If it is not equal, you must define the macro -+POINTERS_EXTEND_UNSIGNED to specify how pointers are extended -+to Pmode. -+*/ -+#define Pmode SImode -+ -+/* -+An alias for the machine mode used for memory references to functions -+being called, in call RTL expressions. On most machines this -+should be QImode. -+*/ -+#define FUNCTION_MODE SImode -+ -+ -+#define REG_S_P(x) \ -+ (REG_P (x) || (GET_CODE (x) == SUBREG && REG_P (XEXP (x, 0)))) -+ -+ -+/* If defined, modifies the length assigned to instruction INSN as a -+ function of the context in which it is used. LENGTH is an lvalue -+ that contains the initially computed length of the insn and should -+ be updated with the correct length of the insn. */ -+#define ADJUST_INSN_LENGTH(INSN, LENGTH) \ -+ ((LENGTH) = avr32_adjust_insn_length ((INSN), (LENGTH))) -+ -+ -+#define CLZ_DEFINED_VALUE_AT_ZERO(mode, value) \ -+ (value = 32, (mode == SImode)) -+ -+#define CTZ_DEFINED_VALUE_AT_ZERO(mode, value) \ -+ (value = 32, (mode == SImode)) -+ -+#define UNITS_PER_SIMD_WORD UNITS_PER_WORD -+ -+#define STORE_FLAG_VALUE 1 -+ -+ -+/* IF-conversion macros. */ -+#define IFCVT_MODIFY_INSN( CE_INFO, PATTERN, INSN ) \ -+ { \ -+ (PATTERN) = avr32_ifcvt_modify_insn (CE_INFO, PATTERN, INSN, &num_true_changes); \ -+ } -+ -+#define IFCVT_EXTRA_FIELDS \ -+ int num_cond_clobber_insns; \ -+ int num_extra_move_insns; \ -+ rtx extra_move_insns[MAX_CONDITIONAL_EXECUTE]; \ -+ rtx moved_insns[MAX_CONDITIONAL_EXECUTE]; -+ -+#define IFCVT_INIT_EXTRA_FIELDS( CE_INFO ) \ -+ { \ -+ (CE_INFO)->num_cond_clobber_insns = 0; \ -+ (CE_INFO)->num_extra_move_insns = 0; \ -+ } -+ -+ -+#define IFCVT_MODIFY_CANCEL( CE_INFO ) avr32_ifcvt_modify_cancel (CE_INFO, &num_true_changes) -+ -+#define IFCVT_ALLOW_MODIFY_TEST_IN_INSN 1 -+#define IFCVT_COND_EXEC_BEFORE_RELOAD (TARGET_COND_EXEC_BEFORE_RELOAD) -+ -+enum avr32_builtins -+{ -+ AVR32_BUILTIN_MTSR, -+ AVR32_BUILTIN_MFSR, -+ AVR32_BUILTIN_MTDR, -+ AVR32_BUILTIN_MFDR, -+ AVR32_BUILTIN_CACHE, -+ AVR32_BUILTIN_SYNC, -+ AVR32_BUILTIN_SSRF, -+ AVR32_BUILTIN_CSRF, -+ AVR32_BUILTIN_TLBR, -+ AVR32_BUILTIN_TLBS, -+ AVR32_BUILTIN_TLBW, -+ AVR32_BUILTIN_BREAKPOINT, -+ AVR32_BUILTIN_XCHG, -+ AVR32_BUILTIN_LDXI, -+ AVR32_BUILTIN_BSWAP16, -+ AVR32_BUILTIN_BSWAP32, -+ AVR32_BUILTIN_COP, -+ AVR32_BUILTIN_MVCR_W, -+ AVR32_BUILTIN_MVRC_W, -+ AVR32_BUILTIN_MVCR_D, -+ AVR32_BUILTIN_MVRC_D, -+ AVR32_BUILTIN_MULSATHH_H, -+ AVR32_BUILTIN_MULSATHH_W, -+ AVR32_BUILTIN_MULSATRNDHH_H, -+ AVR32_BUILTIN_MULSATRNDWH_W, -+ AVR32_BUILTIN_MULSATWH_W, -+ AVR32_BUILTIN_MACSATHH_W, -+ AVR32_BUILTIN_SATADD_H, -+ AVR32_BUILTIN_SATSUB_H, -+ AVR32_BUILTIN_SATADD_W, -+ AVR32_BUILTIN_SATSUB_W, -+ AVR32_BUILTIN_MULWH_D, -+ AVR32_BUILTIN_MULNWH_D, -+ AVR32_BUILTIN_MACWH_D, -+ AVR32_BUILTIN_MACHH_D, -+ AVR32_BUILTIN_MUSFR, -+ AVR32_BUILTIN_MUSTR, -+ AVR32_BUILTIN_SATS, -+ AVR32_BUILTIN_SATU, -+ AVR32_BUILTIN_SATRNDS, -+ AVR32_BUILTIN_SATRNDU, -+ AVR32_BUILTIN_MEMS, -+ AVR32_BUILTIN_MEMC, -+ AVR32_BUILTIN_MEMT, -+ AVR32_BUILTIN_SLEEP, -+ AVR32_BUILTIN_DELAY_CYCLES -+}; -+ -+ -+#define FLOAT_LIB_COMPARE_RETURNS_BOOL(MODE, COMPARISON) \ -+ ((MODE == SFmode) || (MODE == DFmode)) -+ -+#define RENAME_LIBRARY_SET ".set" -+ -+/* Make ABI_NAME an alias for __GCC_NAME. */ -+#define RENAME_LIBRARY(GCC_NAME, ABI_NAME) \ -+ __asm__ (".globl\t__avr32_" #ABI_NAME "\n" \ -+ ".set\t__avr32_" #ABI_NAME \ -+ ", __" #GCC_NAME "\n"); -+ -+/* Give libgcc functions avr32 ABI name. */ -+#ifdef L_muldi3 -+#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (muldi3, mul64) -+#endif -+#ifdef L_divdi3 -+#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (divdi3, sdiv64) -+#endif -+#ifdef L_udivdi3 -+#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (udivdi3, udiv64) -+#endif -+#ifdef L_moddi3 -+#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (moddi3, smod64) -+#endif -+#ifdef L_umoddi3 -+#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (umoddi3, umod64) -+#endif -+#ifdef L_ashldi3 -+#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (ashldi3, lsl64) -+#endif -+#ifdef L_lshrdi3 -+#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (lshrdi3, lsr64) -+#endif -+#ifdef L_ashrdi3 -+#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (ashrdi3, asr64) -+#endif -+ -+#ifdef L_fixsfdi -+#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (fixsfdi, f32_to_s64) -+#endif -+#ifdef L_fixunssfdi -+#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (fixunssfdi, f32_to_u64) -+#endif -+#ifdef L_floatdidf -+#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (floatdidf, s64_to_f64) -+#endif -+#ifdef L_floatdisf -+#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (floatdisf, s64_to_f32) -+#endif -+ -+#endif ---- /dev/null -+++ b/gcc/config/avr32/avr32.md -@@ -0,0 +1,5025 @@ -+;; AVR32 machine description file. -+;; Copyright 2003,2004,2005,2006,2007,2008,2009 Atmel Corporation. -+;; -+;; This file is part of GCC. -+;; -+;; 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 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 this program; if not, write to the Free Software -+;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ -+;; -*- Mode: Scheme -*- -+ -+(define_attr "type" "alu,alu2,alu_sat,mulhh,mulwh,mulww_w,mulww_d,div,machh_w,macww_w,macww_d,branch,call,load,load_rm,store,load2,load4,store2,store4,fmul,fcmps,fcmpd,fcast,fmv,fmvcpu,fldd,fstd,flds,fsts,fstm" -+ (const_string "alu")) -+ -+ -+(define_attr "cc" "none,set_vncz,set_ncz,set_cz,set_z,set_z_if_not_v2,bld,compare,cmp_cond_insn,clobber,call_set,fpcompare,from_fpcc" -+ (const_string "none")) -+ -+ -+; NB! Keep this in sync with enum architecture_type in avr32.h -+(define_attr "pipeline" "ap,ucr1,ucr2,ucr2nomul,ucr3,ucr3fp" -+ (const (symbol_ref "avr32_arch->arch_type"))) -+ -+; Insn length in bytes -+(define_attr "length" "" -+ (const_int 4)) -+ -+; Signal if an insn is predicable and hence can be conditionally executed. -+(define_attr "predicable" "no,yes" (const_string "no")) -+ -+;; Uses of UNSPEC in this file: -+(define_constants -+ [(UNSPEC_PUSHM 0) -+ (UNSPEC_POPM 1) -+ (UNSPEC_UDIVMODSI4_INTERNAL 2) -+ (UNSPEC_DIVMODSI4_INTERNAL 3) -+ (UNSPEC_STM 4) -+ (UNSPEC_LDM 5) -+ (UNSPEC_MOVSICC 6) -+ (UNSPEC_ADDSICC 7) -+ (UNSPEC_COND_MI 8) -+ (UNSPEC_COND_PL 9) -+ (UNSPEC_PIC_SYM 10) -+ (UNSPEC_PIC_BASE 11) -+ (UNSPEC_STORE_MULTIPLE 12) -+ (UNSPEC_STMFP 13) -+ (UNSPEC_FRCPA 14) -+ (UNSPEC_REG_TO_CC 15) -+ (UNSPEC_FORCE_MINIPOOL 16) -+ (UNSPEC_SATS 17) -+ (UNSPEC_SATU 18) -+ (UNSPEC_SATRNDS 19) -+ (UNSPEC_SATRNDU 20) -+ ]) -+ -+(define_constants -+ [(VUNSPEC_EPILOGUE 0) -+ (VUNSPEC_CACHE 1) -+ (VUNSPEC_MTSR 2) -+ (VUNSPEC_MFSR 3) -+ (VUNSPEC_BLOCKAGE 4) -+ (VUNSPEC_SYNC 5) -+ (VUNSPEC_TLBR 6) -+ (VUNSPEC_TLBW 7) -+ (VUNSPEC_TLBS 8) -+ (VUNSPEC_BREAKPOINT 9) -+ (VUNSPEC_MTDR 10) -+ (VUNSPEC_MFDR 11) -+ (VUNSPEC_MVCR 12) -+ (VUNSPEC_MVRC 13) -+ (VUNSPEC_COP 14) -+ (VUNSPEC_ALIGN 15) -+ (VUNSPEC_POOL_START 16) -+ (VUNSPEC_POOL_END 17) -+ (VUNSPEC_POOL_4 18) -+ (VUNSPEC_POOL_8 19) -+ (VUNSPEC_POOL_16 20) -+ (VUNSPEC_MUSFR 21) -+ (VUNSPEC_MUSTR 22) -+ (VUNSPEC_SYNC_CMPXCHG 23) -+ (VUNSPEC_SYNC_SET_LOCK_AND_LOAD 24) -+ (VUNSPEC_SYNC_STORE_IF_LOCK 25) -+ (VUNSPEC_EH_RETURN 26) -+ (VUNSPEC_FRS 27) -+ (VUNSPEC_CSRF 28) -+ (VUNSPEC_SSRF 29) -+ (VUNSPEC_SLEEP 30) -+ (VUNSPEC_DELAY_CYCLES 31) -+ (VUNSPEC_DELAY_CYCLES_1 32) -+ (VUNSPEC_DELAY_CYCLES_2 33) -+ (VUNSPEC_NOP 34) -+ (VUNSPEC_NOP3 35) -+ ]) -+ -+(define_constants -+ [ -+ ;; R7 = 15-7 = 8 -+ (FP_REGNUM 8) -+ ;; Return Register = R12 = 15 - 12 = 3 -+ (RETVAL_REGNUM 3) -+ ;; SP = R13 = 15 - 13 = 2 -+ (SP_REGNUM 2) -+ ;; LR = R14 = 15 - 14 = 1 -+ (LR_REGNUM 1) -+ ;; PC = R15 = 15 - 15 = 0 -+ (PC_REGNUM 0) -+ ;; FPSR = GENERAL_REGS + 1 = 17 -+ (FPCC_REGNUM 17) -+ ]) -+ -+ -+ -+ -+;;****************************************************************************** -+;; Macros -+;;****************************************************************************** -+ -+;; Integer Modes for basic alu insns -+(define_mode_iterator INTM [SI HI QI]) -+(define_mode_attr alu_cc_attr [(SI "set_vncz") (HI "clobber") (QI "clobber")]) -+ -+;; Move word modes -+(define_mode_iterator MOVM [SI V2HI V4QI]) -+ -+;; For mov/addcc insns -+(define_mode_iterator ADDCC [SI HI QI]) -+(define_mode_iterator MOVCC [SF SI HI QI]) -+(define_mode_iterator CMP [DI SI HI QI]) -+(define_mode_attr store_postfix [(SF ".w") (SI ".w") (HI ".h") (QI ".b")]) -+(define_mode_attr load_postfix [(SF ".w") (SI ".w") (HI ".sh") (QI ".ub")]) -+(define_mode_attr load_postfix_s [(SI ".w") (HI ".sh") (QI ".sb")]) -+(define_mode_attr load_postfix_u [(SI ".w") (HI ".uh") (QI ".ub")]) -+(define_mode_attr pred_mem_constraint [(SF "RKu11") (SI "RKu11") (HI "RKu10") (QI "RKu09")]) -+(define_mode_attr cmp_constraint [(DI "rKu20") (SI "rKs21") (HI "r") (QI "r")]) -+(define_mode_attr cmp_predicate [(DI "register_immediate_operand") -+ (SI "register_const_int_operand") -+ (HI "register_operand") -+ (QI "register_operand")]) -+(define_mode_attr cmp_length [(DI "6") -+ (SI "4") -+ (HI "4") -+ (QI "4")]) -+ -+;; For all conditional insns -+(define_code_iterator any_cond [eq ne gt ge lt le gtu geu ltu leu]) -+(define_code_attr cond [(eq "eq") (ne "ne") (gt "gt") (ge "ge") (lt "lt") (le "le") -+ (gtu "hi") (geu "hs") (ltu "lo") (leu "ls")]) -+(define_code_attr invcond [(eq "ne") (ne "eq") (gt "le") (ge "lt") (lt "ge") (le "gt") -+ (gtu "ls") (geu "lo") (ltu "hs") (leu "hi")]) -+ -+;; For logical operations -+(define_code_iterator logical [and ior xor]) -+(define_code_attr logical_insn [(and "and") (ior "or") (xor "eor")]) -+ -+;; Predicable operations with three register operands -+(define_code_iterator predicable_op3 [and ior xor plus minus]) -+(define_code_attr predicable_insn3 [(and "and") (ior "or") (xor "eor") (plus "add") (minus "sub")]) -+(define_code_attr predicable_commutative3 [(and "%") (ior "%") (xor "%") (plus "%") (minus "")]) -+ -+;; Load the predicates -+(include "predicates.md") -+ -+ -+;;****************************************************************************** -+;; Automaton pipeline description for avr32 -+;;****************************************************************************** -+ -+(define_automaton "avr32_ap") -+ -+ -+(define_cpu_unit "is" "avr32_ap") -+(define_cpu_unit "a1,m1,da" "avr32_ap") -+(define_cpu_unit "a2,m2,d" "avr32_ap") -+ -+;;Alu instructions -+(define_insn_reservation "alu_op" 1 -+ (and (eq_attr "pipeline" "ap") -+ (eq_attr "type" "alu")) -+ "is,a1,a2") -+ -+(define_insn_reservation "alu2_op" 2 -+ (and (eq_attr "pipeline" "ap") -+ (eq_attr "type" "alu2")) -+ "is,is+a1,a1+a2,a2") -+ -+(define_insn_reservation "alu_sat_op" 2 -+ (and (eq_attr "pipeline" "ap") -+ (eq_attr "type" "alu_sat")) -+ "is,a1,a2") -+ -+ -+;;Mul instructions -+(define_insn_reservation "mulhh_op" 2 -+ (and (eq_attr "pipeline" "ap") -+ (eq_attr "type" "mulhh,mulwh")) -+ "is,m1,m2") -+ -+(define_insn_reservation "mulww_w_op" 3 -+ (and (eq_attr "pipeline" "ap") -+ (eq_attr "type" "mulww_w")) -+ "is,m1,m1+m2,m2") -+ -+(define_insn_reservation "mulww_d_op" 5 -+ (and (eq_attr "pipeline" "ap") -+ (eq_attr "type" "mulww_d")) -+ "is,m1,m1+m2,m1+m2,m2,m2") -+ -+(define_insn_reservation "div_op" 33 -+ (and (eq_attr "pipeline" "ap") -+ (eq_attr "type" "div")) -+ "is,m1,m1*31 + m2*31,m2") -+ -+(define_insn_reservation "machh_w_op" 3 -+ (and (eq_attr "pipeline" "ap") -+ (eq_attr "type" "machh_w")) -+ "is*2,m1,m2") -+ -+ -+(define_insn_reservation "macww_w_op" 4 -+ (and (eq_attr "pipeline" "ap") -+ (eq_attr "type" "macww_w")) -+ "is*2,m1,m1,m2") -+ -+ -+(define_insn_reservation "macww_d_op" 6 -+ (and (eq_attr "pipeline" "ap") -+ (eq_attr "type" "macww_d")) -+ "is*2,m1,m1+m2,m1+m2,m2") -+ -+;;Bypasses for Mac instructions, because of accumulator cache. -+;;Set latency as low as possible in order to let the compiler let -+;;mul -> mac and mac -> mac combinations which use the same -+;;accumulator cache be placed close together to avoid any -+;;instructions which can ruin the accumulator cache come inbetween. -+(define_bypass 4 "machh_w_op" "alu_op,alu2_op,alu_sat_op,load_op" "avr32_mul_waw_bypass") -+(define_bypass 5 "macww_w_op" "alu_op,alu2_op,alu_sat_op,load_op" "avr32_mul_waw_bypass") -+(define_bypass 7 "macww_d_op" "alu_op,alu2_op,alu_sat_op,load_op" "avr32_mul_waw_bypass") -+ -+(define_bypass 3 "mulhh_op" "alu_op,alu2_op,alu_sat_op,load_op" "avr32_mul_waw_bypass") -+(define_bypass 4 "mulww_w_op" "alu_op,alu2_op,alu_sat_op,load_op" "avr32_mul_waw_bypass") -+(define_bypass 6 "mulww_d_op" "alu_op,alu2_op,alu_sat_op,load_op" "avr32_mul_waw_bypass") -+ -+ -+;;Bypasses for all mul/mac instructions followed by an instruction -+;;which reads the output AND writes the result to the same register. -+;;This will generate an Write After Write hazard which gives an -+;;extra cycle before the result is ready. -+(define_bypass 0 "machh_w_op" "machh_w_op" "avr32_valid_macmac_bypass") -+(define_bypass 0 "macww_w_op" "macww_w_op" "avr32_valid_macmac_bypass") -+(define_bypass 0 "macww_d_op" "macww_d_op" "avr32_valid_macmac_bypass") -+ -+(define_bypass 0 "mulhh_op" "machh_w_op" "avr32_valid_mulmac_bypass") -+(define_bypass 0 "mulww_w_op" "macww_w_op" "avr32_valid_mulmac_bypass") -+(define_bypass 0 "mulww_d_op" "macww_d_op" "avr32_valid_mulmac_bypass") -+ -+;;Branch and call instructions -+;;We assume that all branches and rcalls are predicted correctly :-) -+;;while calls use a lot of cycles. -+(define_insn_reservation "branch_op" 0 -+ (and (eq_attr "pipeline" "ap") -+ (eq_attr "type" "branch")) -+ "nothing") -+ -+(define_insn_reservation "call_op" 10 -+ (and (eq_attr "pipeline" "ap") -+ (eq_attr "type" "call")) -+ "nothing") -+ -+ -+;;Load store instructions -+(define_insn_reservation "load_op" 2 -+ (and (eq_attr "pipeline" "ap") -+ (eq_attr "type" "load")) -+ "is,da,d") -+ -+(define_insn_reservation "load_rm_op" 3 -+ (and (eq_attr "pipeline" "ap") -+ (eq_attr "type" "load_rm")) -+ "is,da,d") -+ -+ -+(define_insn_reservation "store_op" 0 -+ (and (eq_attr "pipeline" "ap") -+ (eq_attr "type" "store")) -+ "is,da,d") -+ -+ -+(define_insn_reservation "load_double_op" 3 -+ (and (eq_attr "pipeline" "ap") -+ (eq_attr "type" "load2")) -+ "is,da,da+d,d") -+ -+(define_insn_reservation "load_quad_op" 4 -+ (and (eq_attr "pipeline" "ap") -+ (eq_attr "type" "load4")) -+ "is,da,da+d,da+d,d") -+ -+(define_insn_reservation "store_double_op" 0 -+ (and (eq_attr "pipeline" "ap") -+ (eq_attr "type" "store2")) -+ "is,da,da+d,d") -+ -+ -+(define_insn_reservation "store_quad_op" 0 -+ (and (eq_attr "pipeline" "ap") -+ (eq_attr "type" "store4")) -+ "is,da,da+d,da+d,d") -+ -+;;For store the operand to write to memory is read in d and -+;;the real latency between any instruction and a store is therefore -+;;one less than for the instructions which reads the operands in the first -+;;excecution stage -+(define_bypass 2 "load_double_op" "store_double_op" "avr32_store_bypass") -+(define_bypass 3 "load_quad_op" "store_quad_op" "avr32_store_bypass") -+(define_bypass 1 "load_op" "store_op" "avr32_store_bypass") -+(define_bypass 2 "load_rm_op" "store_op" "avr32_store_bypass") -+(define_bypass 1 "alu_sat_op" "store_op" "avr32_store_bypass") -+(define_bypass 1 "alu2_op" "store_op" "avr32_store_bypass") -+(define_bypass 1 "mulhh_op" "store_op" "avr32_store_bypass") -+(define_bypass 2 "mulww_w_op" "store_op" "avr32_store_bypass") -+(define_bypass 4 "mulww_d_op" "store_op" "avr32_store_bypass" ) -+(define_bypass 2 "machh_w_op" "store_op" "avr32_store_bypass") -+(define_bypass 3 "macww_w_op" "store_op" "avr32_store_bypass") -+(define_bypass 5 "macww_d_op" "store_op" "avr32_store_bypass") -+ -+ -+; Bypass for load double operation. If only the first loaded word is needed -+; then the latency is 2 -+(define_bypass 2 "load_double_op" -+ "load_op,load_rm_op,alu_sat_op, alu2_op, alu_op, mulhh_op, mulww_w_op, -+ mulww_d_op, machh_w_op, macww_w_op, macww_d_op" -+ "avr32_valid_load_double_bypass") -+ -+; Bypass for load quad operation. If only the first or second loaded word is needed -+; we set the latency to 2 -+(define_bypass 2 "load_quad_op" -+ "load_op,load_rm_op,alu_sat_op, alu2_op, alu_op, mulhh_op, mulww_w_op, -+ mulww_d_op, machh_w_op, macww_w_op, macww_d_op" -+ "avr32_valid_load_quad_bypass") -+ -+ -+;;****************************************************************************** -+;; End of Automaton pipeline description for avr32 -+;;****************************************************************************** -+ -+(define_cond_exec -+ [(match_operator 0 "avr32_comparison_operator" -+ [(match_operand:CMP 1 "register_operand" "r") -+ (match_operand:CMP 2 "" "")])] -+ "TARGET_V2_INSNS" -+ "%!" -+) -+ -+(define_cond_exec -+ [(match_operator 0 "avr32_comparison_operator" -+ [(and:SI (match_operand:SI 1 "register_operand" "r") -+ (match_operand:SI 2 "one_bit_set_operand" "i")) -+ (const_int 0)])] -+ "TARGET_V2_INSNS" -+ "%!" -+ ) -+ -+;;============================================================================= -+;; move -+;;----------------------------------------------------------------------------- -+ -+ -+;;== char - 8 bits ============================================================ -+(define_expand "movqi" -+ [(set (match_operand:QI 0 "nonimmediate_operand" "") -+ (match_operand:QI 1 "general_operand" ""))] -+ "" -+ { -+ if ( can_create_pseudo_p () ){ -+ if (GET_CODE (operands[1]) == MEM && optimize){ -+ rtx reg = gen_reg_rtx (SImode); -+ -+ emit_insn (gen_zero_extendqisi2 (reg, operands[1])); -+ operands[1] = gen_lowpart (QImode, reg); -+ } -+ -+ /* One of the ops has to be in a register. */ -+ if (GET_CODE (operands[0]) == MEM) -+ operands[1] = force_reg (QImode, operands[1]); -+ } -+ -+ }) -+ -+(define_insn "*movqi_internal" -+ [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,r") -+ (match_operand:QI 1 "general_operand" "rKs08,m,r,i"))] -+ "register_operand (operands[0], QImode) -+ || register_operand (operands[1], QImode)" -+ "@ -+ mov\t%0, %1 -+ ld.ub\t%0, %1 -+ st.b\t%0, %1 -+ mov\t%0, %1" -+ [(set_attr "length" "2,4,4,4") -+ (set_attr "type" "alu,load_rm,store,alu")]) -+ -+ -+ -+;;== short - 16 bits ========================================================== -+(define_expand "movhi" -+ [(set (match_operand:HI 0 "nonimmediate_operand" "") -+ (match_operand:HI 1 "general_operand" ""))] -+ "" -+ { -+ if ( can_create_pseudo_p () ){ -+ if (GET_CODE (operands[1]) == MEM && optimize){ -+ rtx reg = gen_reg_rtx (SImode); -+ -+ emit_insn (gen_extendhisi2 (reg, operands[1])); -+ operands[1] = gen_lowpart (HImode, reg); -+ } -+ -+ /* One of the ops has to be in a register. */ -+ if (GET_CODE (operands[0]) == MEM) -+ operands[1] = force_reg (HImode, operands[1]); -+ } -+ -+ }) -+ -+ -+(define_insn "*movhi_internal" -+ [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r") -+ (match_operand:HI 1 "general_operand" "rKs08,m,r,i"))] -+ "register_operand (operands[0], HImode) -+ || register_operand (operands[1], HImode)" -+ "@ -+ mov\t%0, %1 -+ ld.sh\t%0, %1 -+ st.h\t%0, %1 -+ mov\t%0, %1" -+ [(set_attr "length" "2,4,4,4") -+ (set_attr "type" "alu,load_rm,store,alu")]) -+ -+ -+;;== int - 32 bits ============================================================ -+ -+(define_expand "movmisalignsi" -+ [(set (match_operand:SI 0 "nonimmediate_operand" "") -+ (match_operand:SI 1 "nonimmediate_operand" ""))] -+ "TARGET_UNALIGNED_WORD" -+ { -+ } -+) -+ -+(define_expand "mov" -+ [(set (match_operand:MOVM 0 "avr32_non_rmw_nonimmediate_operand" "") -+ (match_operand:MOVM 1 "avr32_non_rmw_general_operand" ""))] -+ "" -+ { -+ -+ /* One of the ops has to be in a register. */ -+ if (GET_CODE (operands[0]) == MEM) -+ operands[1] = force_reg (mode, operands[1]); -+ -+ /* Check for out of range immediate constants as these may -+ occur during reloading, since it seems like reload does -+ not check if the immediate is legitimate. Don't know if -+ this is a bug? */ -+ if ( reload_in_progress -+ && avr32_imm_in_const_pool -+ && GET_CODE(operands[1]) == CONST_INT -+ && !avr32_const_ok_for_constraint_p(INTVAL(operands[1]), 'K', "Ks21") ){ -+ operands[1] = force_const_mem(SImode, operands[1]); -+ } -+ /* Check for RMW memory operands. They are not allowed for mov operations -+ only the atomic memc/s/t operations */ -+ if ( !reload_in_progress -+ && avr32_rmw_memory_operand (operands[0], mode) ){ -+ operands[0] = copy_rtx (operands[0]); -+ XEXP(operands[0], 0) = force_reg (mode, XEXP(operands[0], 0)); -+ } -+ -+ if ( !reload_in_progress -+ && avr32_rmw_memory_operand (operands[1], mode) ){ -+ operands[1] = copy_rtx (operands[1]); -+ XEXP(operands[1], 0) = force_reg (mode, XEXP(operands[1], 0)); -+ } -+ if ( (flag_pic || TARGET_HAS_ASM_ADDR_PSEUDOS) -+ && !avr32_legitimate_pic_operand_p(operands[1]) ) -+ operands[1] = legitimize_pic_address (operands[1], mode, -+ (can_create_pseudo_p () ? 0: operands[0])); -+ else if ( flag_pic && avr32_address_operand(operands[1], GET_MODE(operands[1])) ) -+ /* If we have an address operand then this function uses the pic register. */ -+ current_function_uses_pic_offset_table = 1; -+ }) -+ -+ -+(define_insn "mov_internal" -+ [(set (match_operand:MOVM 0 "avr32_non_rmw_nonimmediate_operand" "=r, r, r,r,r,Q,r") -+ (match_operand:MOVM 1 "avr32_non_rmw_general_operand" "rKs08,Ks21,J,n,Q,r,W"))] -+ "(register_operand (operands[0], mode) -+ || register_operand (operands[1], mode)) -+ && !avr32_rmw_memory_operand (operands[0], mode) -+ && !avr32_rmw_memory_operand (operands[1], mode)" -+ { -+ switch (which_alternative) { -+ case 0: -+ case 1: return "mov\t%0, %1"; -+ case 2: -+ if ( TARGET_V2_INSNS ) -+ return "movh\t%0, hi(%1)"; -+ /* Fallthrough */ -+ case 3: return "mov\t%0, lo(%1)\;orh\t%0,hi(%1)"; -+ case 4: -+ if ( (REG_P(XEXP(operands[1], 0)) -+ && REGNO(XEXP(operands[1], 0)) == SP_REGNUM) -+ || (GET_CODE(XEXP(operands[1], 0)) == PLUS -+ && REGNO(XEXP(XEXP(operands[1], 0), 0)) == SP_REGNUM -+ && GET_CODE(XEXP(XEXP(operands[1], 0), 1)) == CONST_INT -+ && INTVAL(XEXP(XEXP(operands[1], 0), 1)) % 4 == 0 -+ && INTVAL(XEXP(XEXP(operands[1], 0), 1)) <= 0x1FC) ) -+ return "lddsp\t%0, %1"; -+ else if ( avr32_const_pool_ref_operand(operands[1], GET_MODE(operands[1])) ) -+ return "lddpc\t%0, %1"; -+ else -+ return "ld.w\t%0, %1"; -+ case 5: -+ if ( (REG_P(XEXP(operands[0], 0)) -+ && REGNO(XEXP(operands[0], 0)) == SP_REGNUM) -+ || (GET_CODE(XEXP(operands[0], 0)) == PLUS -+ && REGNO(XEXP(XEXP(operands[0], 0), 0)) == SP_REGNUM -+ && GET_CODE(XEXP(XEXP(operands[0], 0), 1)) == CONST_INT -+ && INTVAL(XEXP(XEXP(operands[0], 0), 1)) % 4 == 0 -+ && INTVAL(XEXP(XEXP(operands[0], 0), 1)) <= 0x1FC) ) -+ return "stdsp\t%0, %1"; -+ else -+ return "st.w\t%0, %1"; -+ case 6: -+ if ( TARGET_HAS_ASM_ADDR_PSEUDOS ) -+ return "lda.w\t%0, %1"; -+ else -+ return "ld.w\t%0, r6[%1@got]"; -+ default: -+ abort(); -+ } -+ } -+ -+ [(set_attr "length" "2,4,4,8,4,4,8") -+ (set_attr "type" "alu,alu,alu,alu2,load,store,load") -+ (set_attr "cc" "none,none,set_z_if_not_v2,set_z,none,none,clobber")]) -+ -+ -+(define_expand "reload_out_rmw_memory_operand" -+ [(set (match_operand:SI 2 "register_operand" "=r") -+ (match_operand:SI 0 "address_operand" "")) -+ (set (mem:SI (match_dup 2)) -+ (match_operand:SI 1 "register_operand" ""))] -+ "" -+ { -+ operands[0] = XEXP(operands[0], 0); -+ } -+) -+ -+(define_expand "reload_in_rmw_memory_operand" -+ [(set (match_operand:SI 2 "register_operand" "=r") -+ (match_operand:SI 1 "address_operand" "")) -+ (set (match_operand:SI 0 "register_operand" "") -+ (mem:SI (match_dup 2)))] -+ "" -+ { -+ operands[1] = XEXP(operands[1], 0); -+ } -+) -+ -+ -+;; These instructions are for loading constants which cannot be loaded -+;; directly from the constant pool because the offset is too large -+;; high and lo_sum are used even tough for our case it should be -+;; low and high sum :-) -+(define_insn "mov_symbol_lo" -+ [(set (match_operand:SI 0 "register_operand" "=r") -+ (high:SI (match_operand:SI 1 "immediate_operand" "i" )))] -+ "" -+ "mov\t%0, lo(%1)" -+ [(set_attr "type" "alu") -+ (set_attr "length" "4")] -+) -+ -+(define_insn "add_symbol_hi" -+ [(set (match_operand:SI 0 "register_operand" "=r") -+ (lo_sum:SI (match_dup 0) -+ (match_operand:SI 1 "immediate_operand" "i" )))] -+ "" -+ "orh\t%0, hi(%1)" -+ [(set_attr "type" "alu") -+ (set_attr "length" "4")] -+) -+ -+ -+ -+;; When generating pic, we need to load the symbol offset into a register. -+;; So that the optimizer does not confuse this with a normal symbol load -+;; we use an unspec. The offset will be loaded from a constant pool entry, -+;; since that is the only type of relocation we can use. -+(define_insn "pic_load_addr" -+ [(set (match_operand:SI 0 "register_operand" "=r") -+ (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC_SYM))] -+ "flag_pic && CONSTANT_POOL_ADDRESS_P(XEXP(operands[1], 0))" -+ "lddpc\t%0, %1" -+ [(set_attr "type" "load") -+ (set_attr "length" "4")] -+) -+ -+(define_insn "pic_compute_got_from_pc" -+ [(set (match_operand:SI 0 "register_operand" "+r") -+ (unspec:SI [(minus:SI (pc) -+ (match_dup 0))] UNSPEC_PIC_BASE)) -+ (use (label_ref (match_operand 1 "" "")))] -+ "flag_pic" -+ { -+ (*targetm.asm_out.internal_label) (asm_out_file, "L", -+ CODE_LABEL_NUMBER (operands[1])); -+ return \"rsub\t%0, pc\"; -+ } -+ [(set_attr "cc" "clobber") -+ (set_attr "length" "2")] -+) -+ -+;;== long long int - 64 bits ================================================== -+ -+(define_expand "movdi" -+ [(set (match_operand:DI 0 "nonimmediate_operand" "") -+ (match_operand:DI 1 "general_operand" ""))] -+ "" -+ { -+ -+ /* One of the ops has to be in a register. */ -+ if (GET_CODE (operands[0]) != REG) -+ operands[1] = force_reg (DImode, operands[1]); -+ -+ }) -+ -+ -+(define_insn_and_split "*movdi_internal" -+ [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r, r, r,r,r,m") -+ (match_operand:DI 1 "general_operand" "r, Ks08,Ks21,G,n,m,r"))] -+ "register_operand (operands[0], DImode) -+ || register_operand (operands[1], DImode)" -+ { -+ switch (which_alternative ){ -+ case 0: -+ case 1: -+ case 2: -+ case 3: -+ case 4: -+ return "#"; -+ case 5: -+ if ( avr32_const_pool_ref_operand(operands[1], GET_MODE(operands[1]))) -+ return "ld.d\t%0, pc[%1 - .]"; -+ else -+ return "ld.d\t%0, %1"; -+ case 6: -+ return "st.d\t%0, %1"; -+ default: -+ abort(); -+ } -+ } -+;; Lets split all reg->reg or imm->reg transfers into two SImode transfers -+ "reload_completed && -+ (REG_P (operands[0]) && -+ (REG_P (operands[1]) -+ || GET_CODE (operands[1]) == CONST_INT -+ || GET_CODE (operands[1]) == CONST_DOUBLE))" -+ [(set (match_dup 0) (match_dup 1)) -+ (set (match_dup 2) (match_dup 3))] -+ { -+ operands[2] = gen_highpart (SImode, operands[0]); -+ operands[0] = gen_lowpart (SImode, operands[0]); -+ if ( REG_P(operands[1]) ){ -+ operands[3] = gen_highpart(SImode, operands[1]); -+ operands[1] = gen_lowpart(SImode, operands[1]); -+ } else if ( GET_CODE(operands[1]) == CONST_DOUBLE -+ || GET_CODE(operands[1]) == CONST_INT ){ -+ rtx split_const[2]; -+ avr32_split_const_expr (DImode, SImode, operands[1], split_const); -+ operands[3] = split_const[1]; -+ operands[1] = split_const[0]; -+ } else { -+ internal_error("Illegal operand[1] for movdi split!"); -+ } -+ } -+ -+ [(set_attr "length" "*,*,*,*,*,4,4") -+ (set_attr "type" "*,*,*,*,*,load2,store2") -+ (set_attr "cc" "*,*,*,*,*,none,none")]) -+ -+ -+;;== 128 bits ================================================== -+(define_expand "movti" -+ [(set (match_operand:TI 0 "nonimmediate_operand" "") -+ (match_operand:TI 1 "nonimmediate_operand" ""))] -+ "TARGET_ARCH_AP" -+ { -+ -+ /* One of the ops has to be in a register. */ -+ if (GET_CODE (operands[0]) != REG) -+ operands[1] = force_reg (TImode, operands[1]); -+ -+ /* We must fix any pre_dec for loads and post_inc stores */ -+ if ( GET_CODE (operands[0]) == MEM -+ && GET_CODE (XEXP(operands[0],0)) == POST_INC ){ -+ emit_move_insn(gen_rtx_MEM(TImode, XEXP(XEXP(operands[0],0),0)), operands[1]); -+ emit_insn(gen_addsi3(XEXP(XEXP(operands[0],0),0), XEXP(XEXP(operands[0],0),0), GEN_INT(GET_MODE_SIZE(TImode)))); -+ DONE; -+ } -+ -+ if ( GET_CODE (operands[1]) == MEM -+ && GET_CODE (XEXP(operands[1],0)) == PRE_DEC ){ -+ emit_insn(gen_addsi3(XEXP(XEXP(operands[1],0),0), XEXP(XEXP(operands[1],0),0), GEN_INT(-GET_MODE_SIZE(TImode)))); -+ emit_move_insn(operands[0], gen_rtx_MEM(TImode, XEXP(XEXP(operands[1],0),0))); -+ DONE; -+ } -+ }) -+ -+ -+(define_insn_and_split "*movti_internal" -+ [(set (match_operand:TI 0 "avr32_movti_dst_operand" "=r,&r, r, ,RKu00,r, n,T"))] -+ "(register_operand (operands[0], TImode) -+ || register_operand (operands[1], TImode))" -+ { -+ switch (which_alternative ){ -+ case 0: -+ case 2: -+ case 4: -+ return "#"; -+ case 1: -+ return "ldm\t%p1, %0"; -+ case 3: -+ return "stm\t%p0, %1"; -+ case 5: -+ return "ld.d\t%U0, pc[%1 - .]\;ld.d\t%B0, pc[%1 - . + 8]"; -+ } -+ } -+ -+ "reload_completed && -+ (REG_P (operands[0]) && -+ (REG_P (operands[1]) -+ /* If this is a load from the constant pool we split it into -+ two double loads. */ -+ || (GET_CODE (operands[1]) == MEM -+ && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF -+ && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))) -+ /* If this is a load where the pointer register is a part -+ of the register list, we must split it into two double -+ loads in order for it to be exception safe. */ -+ || (GET_CODE (operands[1]) == MEM -+ && register_operand (XEXP (operands[1], 0), SImode) -+ && reg_overlap_mentioned_p (operands[0], XEXP (operands[1], 0))) -+ || GET_CODE (operands[1]) == CONST_INT -+ || GET_CODE (operands[1]) == CONST_DOUBLE))" -+ [(set (match_dup 0) (match_dup 1)) -+ (set (match_dup 2) (match_dup 3))] -+ { -+ operands[2] = simplify_gen_subreg ( DImode, operands[0], -+ TImode, 0 ); -+ operands[0] = simplify_gen_subreg ( DImode, operands[0], -+ TImode, 8 ); -+ if ( REG_P(operands[1]) ){ -+ operands[3] = simplify_gen_subreg ( DImode, operands[1], -+ TImode, 0 ); -+ operands[1] = simplify_gen_subreg ( DImode, operands[1], -+ TImode, 8 ); -+ } else if ( GET_CODE(operands[1]) == CONST_DOUBLE -+ || GET_CODE(operands[1]) == CONST_INT ){ -+ rtx split_const[2]; -+ avr32_split_const_expr (TImode, DImode, operands[1], split_const); -+ operands[3] = split_const[1]; -+ operands[1] = split_const[0]; -+ } else if (avr32_const_pool_ref_operand (operands[1], GET_MODE(operands[1]))){ -+ rtx split_const[2]; -+ rtx cop = avoid_constant_pool_reference (operands[1]); -+ if (operands[1] == cop) -+ cop = get_pool_constant (XEXP (operands[1], 0)); -+ avr32_split_const_expr (TImode, DImode, cop, split_const); -+ operands[3] = force_const_mem (DImode, split_const[1]); -+ operands[1] = force_const_mem (DImode, split_const[0]); -+ } else { -+ rtx ptr_reg = XEXP (operands[1], 0); -+ operands[1] = gen_rtx_MEM (DImode, -+ gen_rtx_PLUS ( SImode, -+ ptr_reg, -+ GEN_INT (8) )); -+ operands[3] = gen_rtx_MEM (DImode, -+ ptr_reg); -+ -+ /* Check if the first load will clobber the pointer. -+ If so, we must switch the order of the operations. */ -+ if ( reg_overlap_mentioned_p (operands[0], ptr_reg) ) -+ { -+ /* We need to switch the order of the operations -+ so that the pointer register does not get clobbered -+ after the first double word load. */ -+ rtx tmp; -+ tmp = operands[0]; -+ operands[0] = operands[2]; -+ operands[2] = tmp; -+ tmp = operands[1]; -+ operands[1] = operands[3]; -+ operands[3] = tmp; -+ } -+ -+ -+ } -+ } -+ [(set_attr "length" "*,*,4,4,*,8") -+ (set_attr "type" "*,*,load4,store4,*,load4")]) -+ -+ -+;;== float - 32 bits ========================================================== -+(define_expand "movsf" -+ [(set (match_operand:SF 0 "nonimmediate_operand" "") -+ (match_operand:SF 1 "general_operand" ""))] -+ "" -+ { -+ -+ -+ /* One of the ops has to be in a register. */ -+ if (GET_CODE (operands[0]) != REG) -+ operands[1] = force_reg (SFmode, operands[1]); -+ -+ }) -+ -+(define_insn "*movsf_internal" -+ [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,m") -+ (match_operand:SF 1 "general_operand" "r, G,F,m,r"))] -+ "(register_operand (operands[0], SFmode) -+ || register_operand (operands[1], SFmode))" -+ { -+ switch (which_alternative) { -+ case 0: -+ case 1: return "mov\t%0, %1"; -+ case 2: -+ { -+ HOST_WIDE_INT target_float[2]; -+ real_to_target (target_float, CONST_DOUBLE_REAL_VALUE (operands[1]), SFmode); -+ if ( TARGET_V2_INSNS -+ && avr32_hi16_immediate_operand (GEN_INT (target_float[0]), VOIDmode) ) -+ return "movh\t%0, hi(%1)"; -+ else -+ return "mov\t%0, lo(%1)\;orh\t%0, hi(%1)"; -+ } -+ case 3: -+ if ( (REG_P(XEXP(operands[1], 0)) -+ && REGNO(XEXP(operands[1], 0)) == SP_REGNUM) -+ || (GET_CODE(XEXP(operands[1], 0)) == PLUS -+ && REGNO(XEXP(XEXP(operands[1], 0), 0)) == SP_REGNUM -+ && GET_CODE(XEXP(XEXP(operands[1], 0), 1)) == CONST_INT -+ && INTVAL(XEXP(XEXP(operands[1], 0), 1)) % 4 == 0 -+ && INTVAL(XEXP(XEXP(operands[1], 0), 1)) <= 0x1FC) ) -+ return "lddsp\t%0, %1"; -+ else if ( avr32_const_pool_ref_operand(operands[1], GET_MODE(operands[1])) ) -+ return "lddpc\t%0, %1"; -+ else -+ return "ld.w\t%0, %1"; -+ case 4: -+ if ( (REG_P(XEXP(operands[0], 0)) -+ && REGNO(XEXP(operands[0], 0)) == SP_REGNUM) -+ || (GET_CODE(XEXP(operands[0], 0)) == PLUS -+ && REGNO(XEXP(XEXP(operands[0], 0), 0)) == SP_REGNUM -+ && GET_CODE(XEXP(XEXP(operands[0], 0), 1)) == CONST_INT -+ && INTVAL(XEXP(XEXP(operands[0], 0), 1)) % 4 == 0 -+ && INTVAL(XEXP(XEXP(operands[0], 0), 1)) <= 0x1FC) ) -+ return "stdsp\t%0, %1"; -+ else -+ return "st.w\t%0, %1"; -+ default: -+ abort(); -+ } -+ } -+ -+ [(set_attr "length" "2,4,8,4,4") -+ (set_attr "type" "alu,alu,alu2,load,store") -+ (set_attr "cc" "none,none,clobber,none,none")]) -+ -+ -+ -+;;== double - 64 bits ========================================================= -+(define_expand "movdf" -+ [(set (match_operand:DF 0 "nonimmediate_operand" "") -+ (match_operand:DF 1 "general_operand" ""))] -+ "" -+ { -+ /* One of the ops has to be in a register. */ -+ if (GET_CODE (operands[0]) != REG){ -+ operands[1] = force_reg (DFmode, operands[1]); -+ } -+ }) -+ -+ -+(define_insn_and_split "*movdf_internal" -+ [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,r,r,m") -+ (match_operand:DF 1 "general_operand" " r,G,F,m,r"))] -+ "(register_operand (operands[0], DFmode) -+ || register_operand (operands[1], DFmode))" -+ { -+ switch (which_alternative ){ -+ case 0: -+ case 1: -+ case 2: -+ return "#"; -+ case 3: -+ if ( avr32_const_pool_ref_operand(operands[1], GET_MODE(operands[1]))) -+ return "ld.d\t%0, pc[%1 - .]"; -+ else -+ return "ld.d\t%0, %1"; -+ case 4: -+ return "st.d\t%0, %1"; -+ default: -+ abort(); -+ } -+ } -+ "reload_completed -+ && (REG_P (operands[0]) -+ && (REG_P (operands[1]) -+ || GET_CODE (operands[1]) == CONST_DOUBLE))" -+ [(set (match_dup 0) (match_dup 1)) -+ (set (match_dup 2) (match_dup 3))] -+ " -+ { -+ operands[2] = gen_highpart (SImode, operands[0]); -+ operands[0] = gen_lowpart (SImode, operands[0]); -+ operands[3] = gen_highpart(SImode, operands[1]); -+ operands[1] = gen_lowpart(SImode, operands[1]); -+ } -+ " -+ -+ [(set_attr "length" "*,*,*,4,4") -+ (set_attr "type" "*,*,*,load2,store2") -+ (set_attr "cc" "*,*,*,none,none")]) -+ -+ -+;;============================================================================= -+;; Conditional Moves -+;;============================================================================= -+(define_insn "ld_predicable" -+ [(set (match_operand:MOVCC 0 "register_operand" "=r") -+ (match_operand:MOVCC 1 "avr32_non_rmw_memory_operand" ""))] -+ "TARGET_V2_INSNS" -+ "ld%?\t%0, %1" -+ [(set_attr "length" "4") -+ (set_attr "cc" "cmp_cond_insn") -+ (set_attr "type" "load") -+ (set_attr "predicable" "yes")] -+) -+ -+ -+(define_insn "st_predicable" -+ [(set (match_operand:MOVCC 0 "avr32_non_rmw_memory_operand" "=") -+ (match_operand:MOVCC 1 "register_operand" "r"))] -+ "TARGET_V2_INSNS" -+ "st%?\t%0, %1" -+ [(set_attr "length" "4") -+ (set_attr "cc" "cmp_cond_insn") -+ (set_attr "type" "store") -+ (set_attr "predicable" "yes")] -+) -+ -+(define_insn "mov_predicable" -+ [(set (match_operand:MOVCC 0 "register_operand" "=r") -+ (match_operand:MOVCC 1 "avr32_cond_register_immediate_operand" "rKs08"))] -+ "" -+ "mov%?\t%0, %1" -+ [(set_attr "length" "4") -+ (set_attr "cc" "cmp_cond_insn") -+ (set_attr "type" "alu") -+ (set_attr "predicable" "yes")] -+) -+ -+ -+;;============================================================================= -+;; Move chunks of memory -+;;============================================================================= -+ -+(define_expand "movmemsi" -+ [(match_operand:BLK 0 "general_operand" "") -+ (match_operand:BLK 1 "general_operand" "") -+ (match_operand:SI 2 "const_int_operand" "") -+ (match_operand:SI 3 "const_int_operand" "")] -+ "" -+ " -+ if (avr32_gen_movmemsi (operands)) -+ DONE; -+ FAIL; -+ " -+ ) -+ -+ -+ -+ -+;;============================================================================= -+;; Bit field instructions -+;;----------------------------------------------------------------------------- -+;; Instructions to insert or extract bit-fields -+;;============================================================================= -+ -+(define_insn "insv" -+ [ (set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r") -+ (match_operand:SI 1 "immediate_operand" "Ku05") -+ (match_operand:SI 2 "immediate_operand" "Ku05")) -+ (match_operand 3 "register_operand" "r"))] -+ "" -+ "bfins\t%0, %3, %2, %1" -+ [(set_attr "type" "alu") -+ (set_attr "length" "4") -+ (set_attr "cc" "set_ncz")]) -+ -+ -+ -+(define_expand "extv" -+ [ (set (match_operand:SI 0 "register_operand" "") -+ (sign_extract:SI (match_operand:SI 1 "register_operand" "") -+ (match_operand:SI 2 "immediate_operand" "") -+ (match_operand:SI 3 "immediate_operand" "")))] -+ "" -+ { -+ if ( INTVAL(operands[2]) >= 32 ) -+ FAIL; -+ } -+) -+ -+(define_expand "extzv" -+ [ (set (match_operand:SI 0 "register_operand" "") -+ (zero_extract:SI (match_operand:SI 1 "register_operand" "") -+ (match_operand:SI 2 "immediate_operand" "") -+ (match_operand:SI 3 "immediate_operand" "")))] -+ "" -+ { -+ if ( INTVAL(operands[2]) >= 32 ) -+ FAIL; -+ } -+) -+ -+(define_insn "extv_internal" -+ [ (set (match_operand:SI 0 "register_operand" "=r") -+ (sign_extract:SI (match_operand:SI 1 "register_operand" "r") -+ (match_operand:SI 2 "immediate_operand" "Ku05") -+ (match_operand:SI 3 "immediate_operand" "Ku05")))] -+ "INTVAL(operands[2]) < 32" -+ "bfexts\t%0, %1, %3, %2" -+ [(set_attr "type" "alu") -+ (set_attr "length" "4") -+ (set_attr "cc" "set_ncz")]) -+ -+ -+(define_insn "extzv_internal" -+ [ (set (match_operand:SI 0 "register_operand" "=r") -+ (zero_extract:SI (match_operand:SI 1 "register_operand" "r") -+ (match_operand:SI 2 "immediate_operand" "Ku05") -+ (match_operand:SI 3 "immediate_operand" "Ku05")))] -+ "INTVAL(operands[2]) < 32" -+ "bfextu\t%0, %1, %3, %2" -+ [(set_attr "type" "alu") -+ (set_attr "length" "4") -+ (set_attr "cc" "set_ncz")]) -+ -+ -+ -+;;============================================================================= -+;; Some peepholes for avoiding unnecessary cast instructions -+;; followed by bfins. -+;;----------------------------------------------------------------------------- -+ -+(define_peephole2 -+ [(set (match_operand:SI 0 "register_operand" "") -+ (zero_extend:SI (match_operand:QI 1 "register_operand" ""))) -+ (set (zero_extract:SI (match_operand 2 "register_operand" "") -+ (match_operand:SI 3 "immediate_operand" "") -+ (match_operand:SI 4 "immediate_operand" "")) -+ (match_dup 0))] -+ "((peep2_reg_dead_p(2, operands[0]) && -+ (INTVAL(operands[3]) <= 8)))" -+ [(set (zero_extract:SI (match_dup 2) -+ (match_dup 3) -+ (match_dup 4)) -+ (match_dup 1))] -+ ) -+ -+(define_peephole2 -+ [(set (match_operand:SI 0 "register_operand" "") -+ (zero_extend:SI (match_operand:HI 1 "register_operand" ""))) -+ (set (zero_extract:SI (match_operand 2 "register_operand" "") -+ (match_operand:SI 3 "immediate_operand" "") -+ (match_operand:SI 4 "immediate_operand" "")) -+ (match_dup 0))] -+ "((peep2_reg_dead_p(2, operands[0]) && -+ (INTVAL(operands[3]) <= 16)))" -+ [(set (zero_extract:SI (match_dup 2) -+ (match_dup 3) -+ (match_dup 4)) -+ (match_dup 1))] -+ ) -+ -+;;============================================================================= -+;; push bytes -+;;----------------------------------------------------------------------------- -+;; Implements the push instruction -+;;============================================================================= -+(define_insn "pushm" -+ [(set (mem:BLK (pre_dec:BLK (reg:SI SP_REGNUM))) -+ (unspec:BLK [(match_operand 0 "const_int_operand" "")] -+ UNSPEC_PUSHM))] -+ "" -+ { -+ if (INTVAL(operands[0])) { -+ return "pushm\t%r0"; -+ } else { -+ return ""; -+ } -+ } -+ [(set_attr "type" "store") -+ (set_attr "length" "2") -+ (set_attr "cc" "none")]) -+ -+(define_insn "stm" -+ [(unspec [(match_operand 0 "register_operand" "r") -+ (match_operand 1 "const_int_operand" "") -+ (match_operand 2 "const_int_operand" "")] -+ UNSPEC_STM)] -+ "" -+ { -+ if (INTVAL(operands[1])) { -+ if (INTVAL(operands[2]) != 0) -+ return "stm\t--%0, %s1"; -+ else -+ return "stm\t%0, %s1"; -+ } else { -+ return ""; -+ } -+ } -+ [(set_attr "type" "store") -+ (set_attr "length" "4") -+ (set_attr "cc" "none")]) -+ -+ -+ -+(define_insn "popm" -+ [(unspec [(match_operand 0 "const_int_operand" "")] -+ UNSPEC_POPM)] -+ "" -+ { -+ if (INTVAL(operands[0])) { -+ return "popm %r0"; -+ } else { -+ return ""; -+ } -+ } -+ [(set_attr "type" "load") -+ (set_attr "length" "2")]) -+ -+ -+ -+;;============================================================================= -+;; add -+;;----------------------------------------------------------------------------- -+;; Adds reg1 with reg2 and puts the result in reg0. -+;;============================================================================= -+(define_insn "add3" -+ [(set (match_operand:INTM 0 "register_operand" "=r,r,r,r,r") -+ (plus:INTM (match_operand:INTM 1 "register_operand" "%0,r,0,r,0") -+ (match_operand:INTM 2 "avr32_add_operand" "r,r,Is08,Is16,Is21")))] -+ "" -+ "@ -+ add %0, %2 -+ add %0, %1, %2 -+ sub %0, %n2 -+ sub %0, %1, %n2 -+ sub %0, %n2" -+ -+ [(set_attr "length" "2,4,2,4,4") -+ (set_attr "cc" "")]) -+ -+(define_insn "add3_lsl" -+ [(set (match_operand:INTM 0 "register_operand" "=r") -+ (plus:INTM (ashift:INTM (match_operand:INTM 1 "register_operand" "r") -+ (match_operand:INTM 3 "avr32_add_shift_immediate_operand" "Ku02")) -+ (match_operand:INTM 2 "register_operand" "r")))] -+ "" -+ "add %0, %2, %1 << %3" -+ [(set_attr "length" "4") -+ (set_attr "cc" "")]) -+ -+(define_insn "add3_lsl2" -+ [(set (match_operand:INTM 0 "register_operand" "=r") -+ (plus:INTM (match_operand:INTM 1 "register_operand" "r") -+ (ashift:INTM (match_operand:INTM 2 "register_operand" "r") -+ (match_operand:INTM 3 "avr32_add_shift_immediate_operand" "Ku02"))))] -+ "" -+ "add %0, %1, %2 << %3" -+ [(set_attr "length" "4") -+ (set_attr "cc" "")]) -+ -+ -+(define_insn "add3_mul" -+ [(set (match_operand:INTM 0 "register_operand" "=r") -+ (plus:INTM (mult:INTM (match_operand:INTM 1 "register_operand" "r") -+ (match_operand:INTM 3 "immediate_operand" "Ku04" )) -+ (match_operand:INTM 2 "register_operand" "r")))] -+ "(INTVAL(operands[3]) == 0) || (INTVAL(operands[3]) == 2) || -+ (INTVAL(operands[3]) == 4) || (INTVAL(operands[3]) == 8)" -+ "add %0, %2, %1 << %p3" -+ [(set_attr "length" "4") -+ (set_attr "cc" "")]) -+ -+(define_insn "add3_mul2" -+ [(set (match_operand:INTM 0 "register_operand" "=r") -+ (plus:INTM (match_operand:INTM 1 "register_operand" "r") -+ (mult:INTM (match_operand:INTM 2 "register_operand" "r") -+ (match_operand:INTM 3 "immediate_operand" "Ku04" ))))] -+ "(INTVAL(operands[3]) == 0) || (INTVAL(operands[3]) == 2) || -+ (INTVAL(operands[3]) == 4) || (INTVAL(operands[3]) == 8)" -+ "add %0, %1, %2 << %p3" -+ [(set_attr "length" "4") -+ (set_attr "cc" "")]) -+ -+ -+(define_peephole2 -+ [(set (match_operand:SI 0 "register_operand" "") -+ (ashift:SI (match_operand:SI 1 "register_operand" "") -+ (match_operand:SI 2 "immediate_operand" ""))) -+ (set (match_operand:SI 3 "register_operand" "") -+ (plus:SI (match_dup 0) -+ (match_operand:SI 4 "register_operand" "")))] -+ "(peep2_reg_dead_p(2, operands[0]) && -+ (INTVAL(operands[2]) < 4 && INTVAL(operands[2]) > 0))" -+ [(set (match_dup 3) -+ (plus:SI (ashift:SI (match_dup 1) -+ (match_dup 2)) -+ (match_dup 4)))] -+ ) -+ -+(define_peephole2 -+ [(set (match_operand:SI 0 "register_operand" "") -+ (ashift:SI (match_operand:SI 1 "register_operand" "") -+ (match_operand:SI 2 "immediate_operand" ""))) -+ (set (match_operand:SI 3 "register_operand" "") -+ (plus:SI (match_operand:SI 4 "register_operand" "") -+ (match_dup 0)))] -+ "(peep2_reg_dead_p(2, operands[0]) && -+ (INTVAL(operands[2]) < 4 && INTVAL(operands[2]) > 0))" -+ [(set (match_dup 3) -+ (plus:SI (ashift:SI (match_dup 1) -+ (match_dup 2)) -+ (match_dup 4)))] -+ ) -+ -+(define_insn "adddi3" -+ [(set (match_operand:DI 0 "register_operand" "=r,r") -+ (plus:DI (match_operand:DI 1 "register_operand" "%0,r") -+ (match_operand:DI 2 "register_operand" "r,r")))] -+ "" -+ "@ -+ add %0, %2\;adc %m0, %m0, %m2 -+ add %0, %1, %2\;adc %m0, %m1, %m2" -+ [(set_attr "length" "6,8") -+ (set_attr "type" "alu2") -+ (set_attr "cc" "set_vncz")]) -+ -+ -+(define_insn "add_imm_predicable" -+ [(set (match_operand:INTM 0 "register_operand" "+r") -+ (plus:INTM (match_dup 0) -+ (match_operand:INTM 1 "avr32_cond_immediate_operand" "%Is08")))] -+ "" -+ "sub%?\t%0, -%1" -+ [(set_attr "length" "4") -+ (set_attr "cc" "cmp_cond_insn") -+ (set_attr "predicable" "yes")] -+) -+ -+;;============================================================================= -+;; subtract -+;;----------------------------------------------------------------------------- -+;; Subtract reg2 or immediate value from reg0 and puts the result in reg0. -+;;============================================================================= -+ -+(define_insn "sub3" -+ [(set (match_operand:INTM 0 "general_operand" "=r,r,r,r,r,r,r") -+ (minus:INTM (match_operand:INTM 1 "register_const_int_operand" "0,r,0,r,0,r,Ks08") -+ (match_operand:INTM 2 "register_const_int_operand" "r,r,Ks08,Ks16,Ks21,0,r")))] -+ "" -+ "@ -+ sub %0, %2 -+ sub %0, %1, %2 -+ sub %0, %2 -+ sub %0, %1, %2 -+ sub %0, %2 -+ rsub %0, %1 -+ rsub %0, %2, %1" -+ [(set_attr "length" "2,4,2,4,4,2,4") -+ (set_attr "cc" "")]) -+ -+(define_insn "*sub3_mul" -+ [(set (match_operand:INTM 0 "register_operand" "=r") -+ (minus:INTM (match_operand:INTM 1 "register_operand" "r") -+ (mult:INTM (match_operand:INTM 2 "register_operand" "r") -+ (match_operand:SI 3 "immediate_operand" "Ku04" ))))] -+ "(INTVAL(operands[3]) == 0) || (INTVAL(operands[3]) == 2) || -+ (INTVAL(operands[3]) == 4) || (INTVAL(operands[3]) == 8)" -+ "sub %0, %1, %2 << %p3" -+ [(set_attr "length" "4") -+ (set_attr "cc" "")]) -+ -+(define_insn "*sub3_lsl" -+ [(set (match_operand:INTM 0 "register_operand" "=r") -+ (minus:INTM (match_operand:INTM 1 "register_operand" "r") -+ (ashift:INTM (match_operand:INTM 2 "register_operand" "r") -+ (match_operand:SI 3 "avr32_add_shift_immediate_operand" "Ku02"))))] -+ "" -+ "sub %0, %1, %2 << %3" -+ [(set_attr "length" "4") -+ (set_attr "cc" "")]) -+ -+ -+(define_insn "subdi3" -+ [(set (match_operand:DI 0 "register_operand" "=r,r") -+ (minus:DI (match_operand:DI 1 "register_operand" "%0,r") -+ (match_operand:DI 2 "register_operand" "r,r")))] -+ "" -+ "@ -+ sub %0, %2\;sbc %m0, %m0, %m2 -+ sub %0, %1, %2\;sbc %m0, %m1, %m2" -+ [(set_attr "length" "6,8") -+ (set_attr "type" "alu2") -+ (set_attr "cc" "set_vncz")]) -+ -+ -+(define_insn "sub_imm_predicable" -+ [(set (match_operand:INTM 0 "register_operand" "+r") -+ (minus:INTM (match_dup 0) -+ (match_operand:INTM 1 "avr32_cond_immediate_operand" "Ks08")))] -+ "" -+ "sub%?\t%0, %1" -+ [(set_attr "length" "4") -+ (set_attr "cc" "cmp_cond_insn") -+ (set_attr "predicable" "yes")]) -+ -+(define_insn "rsub_imm_predicable" -+ [(set (match_operand:INTM 0 "register_operand" "+r") -+ (minus:INTM (match_operand:INTM 1 "avr32_cond_immediate_operand" "Ks08") -+ (match_dup 0)))] -+ "" -+ "rsub%?\t%0, %1" -+ [(set_attr "length" "4") -+ (set_attr "cc" "cmp_cond_insn") -+ (set_attr "predicable" "yes")]) -+ -+;;============================================================================= -+;; multiply -+;;----------------------------------------------------------------------------- -+;; Multiply op1 and op2 and put the value in op0. -+;;============================================================================= -+ -+ -+(define_insn "mulqi3" -+ [(set (match_operand:QI 0 "register_operand" "=r,r,r") -+ (mult:QI (match_operand:QI 1 "register_operand" "%0,r,r") -+ (match_operand:QI 2 "avr32_mul_operand" "r,r,Ks08")))] -+ "!TARGET_NO_MUL_INSNS" -+ { -+ switch (which_alternative){ -+ case 0: -+ return "mul %0, %2"; -+ case 1: -+ return "mul %0, %1, %2"; -+ case 2: -+ return "mul %0, %1, %2"; -+ default: -+ gcc_unreachable(); -+ } -+ } -+ [(set_attr "type" "mulww_w,mulww_w,mulwh") -+ (set_attr "length" "2,4,4") -+ (set_attr "cc" "none")]) -+ -+(define_insn "mulsi3" -+ [(set (match_operand:SI 0 "register_operand" "=r,r,r") -+ (mult:SI (match_operand:SI 1 "register_operand" "%0,r,r") -+ (match_operand:SI 2 "avr32_mul_operand" "r,r,Ks08")))] -+ "!TARGET_NO_MUL_INSNS" -+ { -+ switch (which_alternative){ -+ case 0: -+ return "mul %0, %2"; -+ case 1: -+ return "mul %0, %1, %2"; -+ case 2: -+ return "mul %0, %1, %2"; -+ default: -+ gcc_unreachable(); -+ } -+ } -+ [(set_attr "type" "mulww_w,mulww_w,mulwh") -+ (set_attr "length" "2,4,4") -+ (set_attr "cc" "none")]) -+ -+ -+(define_insn "mulhisi3" -+ [(set (match_operand:SI 0 "register_operand" "=r") -+ (mult:SI -+ (sign_extend:SI (match_operand:HI 1 "register_operand" "%r")) -+ (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))] -+ "!TARGET_NO_MUL_INSNS && TARGET_DSP" -+ "mulhh.w %0, %1:b, %2:b" -+ [(set_attr "type" "mulhh") -+ (set_attr "length" "4") -+ (set_attr "cc" "none")]) -+ -+(define_peephole2 -+ [(match_scratch:DI 6 "r") -+ (set (match_operand:SI 0 "register_operand" "") -+ (mult:SI -+ (sign_extend:SI (match_operand:HI 1 "register_operand" "")) -+ (sign_extend:SI (match_operand:HI 2 "register_operand" "")))) -+ (set (match_operand:SI 3 "register_operand" "") -+ (ashiftrt:SI (match_dup 0) -+ (const_int 16)))] -+ "!TARGET_NO_MUL_INSNS && TARGET_DSP -+ && (peep2_reg_dead_p(1, operands[0]) || (REGNO(operands[0]) == REGNO(operands[3])))" -+ [(set (match_dup 4) (sign_extend:SI (match_dup 1))) -+ (set (match_dup 6) -+ (ashift:DI (mult:DI (sign_extend:DI (match_dup 4)) -+ (sign_extend:DI (match_dup 2))) -+ (const_int 16))) -+ (set (match_dup 3) (match_dup 5))] -+ -+ "{ -+ operands[4] = gen_rtx_REG(SImode, REGNO(operands[1])); -+ operands[5] = gen_highpart (SImode, operands[4]); -+ }" -+ ) -+ -+(define_insn "mulnhisi3" -+ [(set (match_operand:SI 0 "register_operand" "=r") -+ (mult:SI -+ (sign_extend:SI (neg:HI (match_operand:HI 1 "register_operand" "r"))) -+ (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))] -+ "!TARGET_NO_MUL_INSNS && TARGET_DSP" -+ "mulnhh.w %0, %1:b, %2:b" -+ [(set_attr "type" "mulhh") -+ (set_attr "length" "4") -+ (set_attr "cc" "none")]) -+ -+(define_insn "machisi3" -+ [(set (match_operand:SI 0 "register_operand" "+r") -+ (plus:SI (mult:SI -+ (sign_extend:SI (match_operand:HI 1 "register_operand" "%r")) -+ (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))) -+ (match_dup 0)))] -+ "!TARGET_NO_MUL_INSNS && TARGET_DSP" -+ "machh.w %0, %1:b, %2:b" -+ [(set_attr "type" "machh_w") -+ (set_attr "length" "4") -+ (set_attr "cc" "none")]) -+ -+ -+ -+(define_insn "mulsidi3" -+ [(set (match_operand:DI 0 "register_operand" "=r") -+ (mult:DI -+ (sign_extend:DI (match_operand:SI 1 "register_operand" "%r")) -+ (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))] -+ "!TARGET_NO_MUL_INSNS" -+ "muls.d %0, %1, %2" -+ [(set_attr "type" "mulww_d") -+ (set_attr "length" "4") -+ (set_attr "cc" "none")]) -+ -+(define_insn "umulsidi3" -+ [(set (match_operand:DI 0 "register_operand" "=r") -+ (mult:DI -+ (zero_extend:DI (match_operand:SI 1 "register_operand" "%r")) -+ (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))] -+ "!TARGET_NO_MUL_INSNS" -+ "mulu.d %0, %1, %2" -+ [(set_attr "type" "mulww_d") -+ (set_attr "length" "4") -+ (set_attr "cc" "none")]) -+ -+(define_insn "*mulaccsi3" -+ [(set (match_operand:SI 0 "register_operand" "+r") -+ (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r") -+ (match_operand:SI 2 "register_operand" "r")) -+ (match_dup 0)))] -+ "!TARGET_NO_MUL_INSNS" -+ "mac %0, %1, %2" -+ [(set_attr "type" "macww_w") -+ (set_attr "length" "4") -+ (set_attr "cc" "none")]) -+ -+(define_insn "*mulaccsidi3" -+ [(set (match_operand:DI 0 "register_operand" "+r") -+ (plus:DI (mult:DI -+ (sign_extend:DI (match_operand:SI 1 "register_operand" "%r")) -+ (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))) -+ (match_dup 0)))] -+ "!TARGET_NO_MUL_INSNS" -+ "macs.d %0, %1, %2" -+ [(set_attr "type" "macww_d") -+ (set_attr "length" "4") -+ (set_attr "cc" "none")]) -+ -+(define_insn "*umulaccsidi3" -+ [(set (match_operand:DI 0 "register_operand" "+r") -+ (plus:DI (mult:DI -+ (zero_extend:DI (match_operand:SI 1 "register_operand" "%r")) -+ (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))) -+ (match_dup 0)))] -+ "!TARGET_NO_MUL_INSNS" -+ "macu.d %0, %1, %2" -+ [(set_attr "type" "macww_d") -+ (set_attr "length" "4") -+ (set_attr "cc" "none")]) -+ -+ -+ -+;; Try to avoid Write-After-Write hazards for mul operations -+;; if it can be done -+(define_peephole2 -+ [(set (match_operand:SI 0 "register_operand" "") -+ (mult:SI -+ (sign_extend:SI (match_operand 1 "general_operand" "")) -+ (sign_extend:SI (match_operand 2 "general_operand" "")))) -+ (set (match_dup 0) -+ (match_operator:SI 3 "alu_operator" [(match_dup 0) -+ (match_operand 4 "general_operand" "")]))] -+ "peep2_reg_dead_p(1, operands[2])" -+ [(set (match_dup 5) -+ (mult:SI -+ (sign_extend:SI (match_dup 1)) -+ (sign_extend:SI (match_dup 2)))) -+ (set (match_dup 0) -+ (match_op_dup 3 [(match_dup 5) -+ (match_dup 4)]))] -+ "{operands[5] = gen_rtx_REG(SImode, REGNO(operands[2]));}" -+ ) -+ -+ -+ -+;;============================================================================= -+;; DSP instructions -+;;============================================================================= -+(define_insn "mulsathh_h" -+ [(set (match_operand:HI 0 "register_operand" "=r") -+ (ss_truncate:HI (ashiftrt:SI (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%r")) -+ (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))) -+ (const_int 15))))] -+ "!TARGET_NO_MUL_INSNS && TARGET_DSP" -+ "mulsathh.h\t%0, %1:b, %2:b" -+ [(set_attr "length" "4") -+ (set_attr "cc" "none") -+ (set_attr "type" "mulhh")]) -+ -+(define_insn "mulsatrndhh_h" -+ [(set (match_operand:HI 0 "register_operand" "=r") -+ (ss_truncate:HI (ashiftrt:SI -+ (plus:SI (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%r")) -+ (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))) -+ (const_int 1073741824)) -+ (const_int 15))))] -+ "!TARGET_NO_MUL_INSNS && TARGET_DSP" -+ "mulsatrndhh.h\t%0, %1:b, %2:b" -+ [(set_attr "length" "4") -+ (set_attr "cc" "none") -+ (set_attr "type" "mulhh")]) -+ -+(define_insn "mulsathh_w" -+ [(set (match_operand:SI 0 "register_operand" "=r") -+ (ss_truncate:SI (ashift:DI (mult:DI (sign_extend:DI (match_operand:HI 1 "register_operand" "%r")) -+ (sign_extend:DI (match_operand:HI 2 "register_operand" "r"))) -+ (const_int 1))))] -+ "!TARGET_NO_MUL_INSNS && TARGET_DSP" -+ "mulsathh.w\t%0, %1:b, %2:b" -+ [(set_attr "length" "4") -+ (set_attr "cc" "none") -+ (set_attr "type" "mulhh")]) -+ -+(define_insn "mulsatwh_w" -+ [(set (match_operand:SI 0 "register_operand" "=r") -+ (ss_truncate:SI (ashiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r")) -+ (sign_extend:DI (match_operand:HI 2 "register_operand" "r"))) -+ (const_int 15))))] -+ "!TARGET_NO_MUL_INSNS && TARGET_DSP" -+ "mulsatwh.w\t%0, %1, %2:b" -+ [(set_attr "length" "4") -+ (set_attr "cc" "none") -+ (set_attr "type" "mulwh")]) -+ -+(define_insn "mulsatrndwh_w" -+ [(set (match_operand:SI 0 "register_operand" "=r") -+ (ss_truncate:SI (ashiftrt:DI (plus:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r")) -+ (sign_extend:DI (match_operand:HI 2 "register_operand" "r"))) -+ (const_int 1073741824)) -+ (const_int 15))))] -+ "!TARGET_NO_MUL_INSNS && TARGET_DSP" -+ "mulsatrndwh.w\t%0, %1, %2:b" -+ [(set_attr "length" "4") -+ (set_attr "cc" "none") -+ (set_attr "type" "mulwh")]) -+ -+(define_insn "macsathh_w" -+ [(set (match_operand:SI 0 "register_operand" "+r") -+ (plus:SI (match_dup 0) -+ (ss_truncate:SI (ashift:DI (mult:DI (sign_extend:DI (match_operand:HI 1 "register_operand" "%r")) -+ (sign_extend:DI (match_operand:HI 2 "register_operand" "r"))) -+ (const_int 1)))))] -+ "!TARGET_NO_MUL_INSNS && TARGET_DSP" -+ "macsathh.w\t%0, %1:b, %2:b" -+ [(set_attr "length" "4") -+ (set_attr "cc" "none") -+ (set_attr "type" "mulhh")]) -+ -+ -+(define_insn "mulwh_d" -+ [(set (match_operand:DI 0 "register_operand" "=r") -+ (ashift:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r")) -+ (sign_extend:DI (match_operand:HI 2 "register_operand" "r"))) -+ (const_int 16)))] -+ "!TARGET_NO_MUL_INSNS && TARGET_DSP" -+ "mulwh.d\t%0, %1, %2:b" -+ [(set_attr "length" "4") -+ (set_attr "cc" "none") -+ (set_attr "type" "mulwh")]) -+ -+ -+(define_insn "mulnwh_d" -+ [(set (match_operand:DI 0 "register_operand" "=r") -+ (ashift:DI (mult:DI (not:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))) -+ (sign_extend:DI (match_operand:HI 2 "register_operand" "r"))) -+ (const_int 16)))] -+ "!TARGET_NO_MUL_INSNS && TARGET_DSP" -+ "mulnwh.d\t%0, %1, %2:b" -+ [(set_attr "length" "4") -+ (set_attr "cc" "none") -+ (set_attr "type" "mulwh")]) -+ -+(define_insn "macwh_d" -+ [(set (match_operand:DI 0 "register_operand" "+r") -+ (plus:DI (match_dup 0) -+ (ashift:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%r")) -+ (sign_extend:DI (match_operand:HI 2 "register_operand" "r"))) -+ (const_int 16))))] -+ "!TARGET_NO_MUL_INSNS && TARGET_DSP" -+ "macwh.d\t%0, %1, %2:b" -+ [(set_attr "length" "4") -+ (set_attr "cc" "none") -+ (set_attr "type" "mulwh")]) -+ -+(define_insn "machh_d" -+ [(set (match_operand:DI 0 "register_operand" "+r") -+ (plus:DI (match_dup 0) -+ (mult:DI (sign_extend:DI (match_operand:HI 1 "register_operand" "%r")) -+ (sign_extend:DI (match_operand:HI 2 "register_operand" "r")))))] -+ "!TARGET_NO_MUL_INSNS && TARGET_DSP" -+ "machh.d\t%0, %1:b, %2:b" -+ [(set_attr "length" "4") -+ (set_attr "cc" "none") -+ (set_attr "type" "mulwh")]) -+ -+(define_insn "satadd_w" -+ [(set (match_operand:SI 0 "register_operand" "=r") -+ (ss_plus:SI (match_operand:SI 1 "register_operand" "r") -+ (match_operand:SI 2 "register_operand" "r")))] -+ "TARGET_DSP" -+ "satadd.w\t%0, %1, %2" -+ [(set_attr "length" "4") -+ (set_attr "cc" "none") -+ (set_attr "type" "alu_sat")]) -+ -+(define_insn "satsub_w" -+ [(set (match_operand:SI 0 "register_operand" "=r") -+ (ss_minus:SI (match_operand:SI 1 "register_operand" "r") -+ (match_operand:SI 2 "register_operand" "r")))] -+ "TARGET_DSP" -+ "satsub.w\t%0, %1, %2" -+ [(set_attr "length" "4") -+ (set_attr "cc" "none") -+ (set_attr "type" "alu_sat")]) -+ -+(define_insn "satadd_h" -+ [(set (match_operand:HI 0 "register_operand" "=r") -+ (ss_plus:HI (match_operand:HI 1 "register_operand" "r") -+ (match_operand:HI 2 "register_operand" "r")))] -+ "TARGET_DSP" -+ "satadd.h\t%0, %1, %2" -+ [(set_attr "length" "4") -+ (set_attr "cc" "none") -+ (set_attr "type" "alu_sat")]) -+ -+(define_insn "satsub_h" -+ [(set (match_operand:HI 0 "register_operand" "=r") -+ (ss_minus:HI (match_operand:HI 1 "register_operand" "r") -+ (match_operand:HI 2 "register_operand" "r")))] -+ "TARGET_DSP" -+ "satsub.h\t%0, %1, %2" -+ [(set_attr "length" "4") -+ (set_attr "cc" "none") -+ (set_attr "type" "alu_sat")]) -+ -+ -+;;============================================================================= -+;; smin -+;;----------------------------------------------------------------------------- -+;; Set reg0 to the smallest value of reg1 and reg2. It is used for signed -+;; values in the registers. -+;;============================================================================= -+(define_insn "sminsi3" -+ [(set (match_operand:SI 0 "register_operand" "=r") -+ (smin:SI (match_operand:SI 1 "register_operand" "r") -+ (match_operand:SI 2 "register_operand" "r")))] -+ "" -+ "min %0, %1, %2" -+ [(set_attr "length" "4") -+ (set_attr "cc" "none")]) -+ -+;;============================================================================= -+;; smax -+;;----------------------------------------------------------------------------- -+;; Set reg0 to the largest value of reg1 and reg2. It is used for signed -+;; values in the registers. -+;;============================================================================= -+(define_insn "smaxsi3" -+ [(set (match_operand:SI 0 "register_operand" "=r") -+ (smax:SI (match_operand:SI 1 "register_operand" "r") -+ (match_operand:SI 2 "register_operand" "r")))] -+ "" -+ "max %0, %1, %2" -+ [(set_attr "length" "4") -+ (set_attr "cc" "none")]) -+ -+ -+ -+;;============================================================================= -+;; Logical operations -+;;----------------------------------------------------------------------------- -+ -+ -+;; Split up simple DImode logical operations. Simply perform the logical -+;; operation on the upper and lower halves of the registers. -+(define_split -+ [(set (match_operand:DI 0 "register_operand" "") -+ (match_operator:DI 6 "logical_binary_operator" -+ [(match_operand:DI 1 "register_operand" "") -+ (match_operand:DI 2 "register_operand" "")]))] -+ "reload_completed" -+ [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)])) -+ (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))] -+ " -+ { -+ operands[3] = gen_highpart (SImode, operands[0]); -+ operands[0] = gen_lowpart (SImode, operands[0]); -+ operands[4] = gen_highpart (SImode, operands[1]); -+ operands[1] = gen_lowpart (SImode, operands[1]); -+ operands[5] = gen_highpart (SImode, operands[2]); -+ operands[2] = gen_lowpart (SImode, operands[2]); -+ }" -+) -+ -+;;============================================================================= -+;; Logical operations with shifted operand -+;;============================================================================= -+(define_insn "si_lshift" -+ [(set (match_operand:SI 0 "register_operand" "=r") -+ (logical:SI (match_operator:SI 4 "logical_shift_operator" -+ [(match_operand:SI 2 "register_operand" "r") -+ (match_operand:SI 3 "immediate_operand" "Ku05")]) -+ (match_operand:SI 1 "register_operand" "r")))] -+ "" -+ { -+ if ( GET_CODE(operands[4]) == ASHIFT ) -+ return "\t%0, %1, %2 << %3"; -+ else -+ return "\t%0, %1, %2 >> %3"; -+ } -+ -+ [(set_attr "cc" "set_z")] -+) -+ -+ -+;;************************************************ -+;; Peepholes for detecting logical operantions -+;; with shifted operands -+;;************************************************ -+ -+(define_peephole -+ [(set (match_operand:SI 3 "register_operand" "") -+ (match_operator:SI 5 "logical_shift_operator" -+ [(match_operand:SI 1 "register_operand" "") -+ (match_operand:SI 2 "immediate_operand" "")])) -+ (set (match_operand:SI 0 "register_operand" "") -+ (logical:SI (match_operand:SI 4 "register_operand" "") -+ (match_dup 3)))] -+ "(dead_or_set_p(insn, operands[3])) || (REGNO(operands[3]) == REGNO(operands[0]))" -+ { -+ if ( GET_CODE(operands[5]) == ASHIFT ) -+ return "\t%0, %4, %1 << %2"; -+ else -+ return "\t%0, %4, %1 >> %2"; -+ } -+ [(set_attr "cc" "set_z")] -+ ) -+ -+(define_peephole -+ [(set (match_operand:SI 3 "register_operand" "") -+ (match_operator:SI 5 "logical_shift_operator" -+ [(match_operand:SI 1 "register_operand" "") -+ (match_operand:SI 2 "immediate_operand" "")])) -+ (set (match_operand:SI 0 "register_operand" "") -+ (logical:SI (match_dup 3) -+ (match_operand:SI 4 "register_operand" "")))] -+ "(dead_or_set_p(insn, operands[3])) || (REGNO(operands[3]) == REGNO(operands[0]))" -+ { -+ if ( GET_CODE(operands[5]) == ASHIFT ) -+ return "\t%0, %4, %1 << %2"; -+ else -+ return "\t%0, %4, %1 >> %2"; -+ } -+ [(set_attr "cc" "set_z")] -+ ) -+ -+ -+(define_peephole2 -+ [(set (match_operand:SI 0 "register_operand" "") -+ (match_operator:SI 5 "logical_shift_operator" -+ [(match_operand:SI 1 "register_operand" "") -+ (match_operand:SI 2 "immediate_operand" "")])) -+ (set (match_operand:SI 3 "register_operand" "") -+ (logical:SI (match_operand:SI 4 "register_operand" "") -+ (match_dup 0)))] -+ "(peep2_reg_dead_p(2, operands[0])) || (REGNO(operands[3]) == REGNO(operands[0]))" -+ -+ [(set (match_dup 3) -+ (logical:SI (match_op_dup:SI 5 [(match_dup 1) (match_dup 2)]) -+ (match_dup 4)))] -+ -+ "" -+) -+ -+(define_peephole2 -+ [(set (match_operand:SI 0 "register_operand" "") -+ (match_operator:SI 5 "logical_shift_operator" -+ [(match_operand:SI 1 "register_operand" "") -+ (match_operand:SI 2 "immediate_operand" "")])) -+ (set (match_operand:SI 3 "register_operand" "") -+ (logical:SI (match_dup 0) -+ (match_operand:SI 4 "register_operand" "")))] -+ "(peep2_reg_dead_p(2, operands[0])) || (REGNO(operands[3]) == REGNO(operands[0]))" -+ -+ [(set (match_dup 3) -+ (logical:SI (match_op_dup:SI 5 [(match_dup 1) (match_dup 2)]) -+ (match_dup 4)))] -+ -+ "" -+) -+ -+ -+;;============================================================================= -+;; and -+;;----------------------------------------------------------------------------- -+;; Store the result after a bitwise logical-and between reg0 and reg2 in reg0. -+;;============================================================================= -+ -+(define_insn "andnsi" -+ [(set (match_operand:SI 0 "register_operand" "+r") -+ (and:SI (match_dup 0) -+ (not:SI (match_operand:SI 1 "register_operand" "r"))))] -+ "" -+ "andn %0, %1" -+ [(set_attr "cc" "set_z") -+ (set_attr "length" "2")] -+) -+ -+ -+(define_insn "andsi3" -+ [(set (match_operand:SI 0 "avr32_rmw_memory_or_register_operand" "=Y,r,r,r, r, r,r,r,r,r") -+ (and:SI (match_operand:SI 1 "avr32_rmw_memory_or_register_operand" "%0,r,0,0, 0, 0,0,0,0,r" ) -+ (match_operand:SI 2 "nonmemory_operand" " N,M,N,Ku16,Ks17,J,L,r,i,r")))] -+ "" -+ "@ -+ memc\t%0, %z2 -+ bfextu\t%0, %1, 0, %z2 -+ cbr\t%0, %z2 -+ andl\t%0, %2, COH -+ andl\t%0, lo(%2) -+ andh\t%0, hi(%2), COH -+ andh\t%0, hi(%2) -+ and\t%0, %2 -+ andh\t%0, hi(%2)\;andl\t%0, lo(%2) -+ and\t%0, %1, %2" -+ -+ [(set_attr "length" "4,4,2,4,4,4,4,2,8,4") -+ (set_attr "cc" "none,set_z,set_z,set_z,set_z,set_z,set_z,set_z,set_z,set_z")]) -+ -+ -+ -+(define_insn "anddi3" -+ [(set (match_operand:DI 0 "register_operand" "=&r,&r") -+ (and:DI (match_operand:DI 1 "register_operand" "%0,r") -+ (match_operand:DI 2 "register_operand" "r,r")))] -+ "" -+ "#" -+ [(set_attr "length" "8") -+ (set_attr "cc" "clobber")] -+) -+ -+;;============================================================================= -+;; or -+;;----------------------------------------------------------------------------- -+;; Store the result after a bitwise inclusive-or between reg0 and reg2 in reg0. -+;;============================================================================= -+ -+(define_insn "iorsi3" -+ [(set (match_operand:SI 0 "avr32_rmw_memory_or_register_operand" "=Y,r,r, r,r,r,r") -+ (ior:SI (match_operand:SI 1 "avr32_rmw_memory_or_register_operand" "%0,0,0, 0,0,0,r" ) -+ (match_operand:SI 2 "nonmemory_operand" " O,O,Ku16,J,r,i,r")))] -+ "" -+ "@ -+ mems\t%0, %p2 -+ sbr\t%0, %p2 -+ orl\t%0, %2 -+ orh\t%0, hi(%2) -+ or\t%0, %2 -+ orh\t%0, hi(%2)\;orl\t%0, lo(%2) -+ or\t%0, %1, %2" -+ -+ [(set_attr "length" "4,2,4,4,2,8,4") -+ (set_attr "cc" "none,set_z,set_z,set_z,set_z,set_z,set_z")]) -+ -+ -+(define_insn "iordi3" -+ [(set (match_operand:DI 0 "register_operand" "=&r,&r") -+ (ior:DI (match_operand:DI 1 "register_operand" "%0,r") -+ (match_operand:DI 2 "register_operand" "r,r")))] -+ "" -+ "#" -+ [(set_attr "length" "8") -+ (set_attr "cc" "clobber")] -+) -+ -+;;============================================================================= -+;; xor bytes -+;;----------------------------------------------------------------------------- -+;; Store the result after a bitwise exclusive-or between reg0 and reg2 in reg0. -+;;============================================================================= -+ -+(define_insn "xorsi3" -+ [(set (match_operand:SI 0 "avr32_rmw_memory_or_register_operand" "=Y,r, r,r,r,r") -+ (xor:SI (match_operand:SI 1 "avr32_rmw_memory_or_register_operand" "%0,0, 0,0,0,r" ) -+ (match_operand:SI 2 "nonmemory_operand" " O,Ku16,J,r,i,r")))] -+ "" -+ "@ -+ memt\t%0, %p2 -+ eorl\t%0, %2 -+ eorh\t%0, hi(%2) -+ eor\t%0, %2 -+ eorh\t%0, hi(%2)\;eorl\t%0, lo(%2) -+ eor\t%0, %1, %2" -+ -+ [(set_attr "length" "4,4,4,2,8,4") -+ (set_attr "cc" "none,set_z,set_z,set_z,set_z,set_z")]) -+ -+(define_insn "xordi3" -+ [(set (match_operand:DI 0 "register_operand" "=&r,&r") -+ (xor:DI (match_operand:DI 1 "register_operand" "%0,r") -+ (match_operand:DI 2 "register_operand" "r,r")))] -+ "" -+ "#" -+ [(set_attr "length" "8") -+ (set_attr "cc" "clobber")] -+) -+ -+;;============================================================================= -+;; Three operand predicable insns -+;;============================================================================= -+ -+(define_insn "_predicable" -+ [(set (match_operand:INTM 0 "register_operand" "=r") -+ (predicable_op3:INTM (match_operand:INTM 1 "register_operand" "r") -+ (match_operand:INTM 2 "register_operand" "r")))] -+ "TARGET_V2_INSNS" -+ "%?\t%0, %1, %2" -+ [(set_attr "length" "4") -+ (set_attr "cc" "cmp_cond_insn") -+ (set_attr "predicable" "yes")] -+) -+ -+(define_insn_and_split "_imm_clobber_predicable" -+ [(parallel -+ [(set (match_operand:INTM 0 "register_operand" "=r") -+ (predicable_op3:INTM (match_operand:INTM 1 "register_operand" "r") -+ (match_operand:INTM 2 "avr32_mov_immediate_operand" "JKs21"))) -+ (clobber (match_operand:INTM 3 "register_operand" "=&r"))])] -+ "TARGET_V2_INSNS" -+ { -+ if ( current_insn_predicate != NULL_RTX ) -+ { -+ if ( avr32_const_ok_for_constraint_p (INTVAL (operands[2]), 'K', "Ks08") ) -+ return "%! mov%?\t%3, %2\;%?\t%0, %1, %3"; -+ else if ( avr32_const_ok_for_constraint_p (INTVAL (operands[2]), 'K', "Ks21") ) -+ return "%! mov\t%3, %2\;%?\t%0, %1, %3"; -+ else -+ return "%! movh\t%3, hi(%2)\;%?\t%0, %1, %3"; -+ } -+ else -+ { -+ if ( !avr32_cond_imm_clobber_splittable (insn, operands) ) -+ { -+ if ( avr32_const_ok_for_constraint_p (INTVAL (operands[2]), 'K', "Ks08") ) -+ return "mov%?\t%3, %2\;%?\t%0, %1, %3"; -+ else if ( avr32_const_ok_for_constraint_p (INTVAL (operands[2]), 'K', "Ks21") ) -+ return "mov\t%3, %2\;%?\t%0, %1, %3"; -+ else -+ return "movh\t%3, hi(%2)\;%?\t%0, %1, %3"; -+ } -+ return "#"; -+ } -+ -+ } -+ ;; If we find out that we could not actually do if-conversion on the block -+ ;; containing this insn we convert it back to normal immediate format -+ ;; to avoid outputing a redundant move insn -+ ;; Do not split until after we have checked if we can make the insn -+ ;; conditional. -+ "(GET_CODE (PATTERN (insn)) != COND_EXEC -+ && cfun->machine->ifcvt_after_reload -+ && avr32_cond_imm_clobber_splittable (insn, operands))" -+ [(set (match_dup 0) -+ (predicable_op3:INTM (match_dup 1) -+ (match_dup 2)))] -+ "" -+ [(set_attr "length" "8") -+ (set_attr "cc" "cmp_cond_insn") -+ (set_attr "predicable" "yes")] -+ ) -+ -+ -+;;============================================================================= -+;; Zero extend predicable insns -+;;============================================================================= -+(define_insn_and_split "zero_extendhisi_clobber_predicable" -+ [(parallel -+ [(set (match_operand:SI 0 "register_operand" "=r") -+ (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))) -+ (clobber (match_operand:SI 2 "register_operand" "=&r"))])] -+ "TARGET_V2_INSNS" -+ { -+ if ( current_insn_predicate != NULL_RTX ) -+ { -+ return "%! mov\t%2, 0xffff\;and%?\t%0, %1, %2"; -+ } -+ else -+ { -+ return "#"; -+ } -+ -+ } -+ ;; If we find out that we could not actually do if-conversion on the block -+ ;; containing this insn we convert it back to normal immediate format -+ ;; to avoid outputing a redundant move insn -+ ;; Do not split until after we have checked if we can make the insn -+ ;; conditional. -+ "(GET_CODE (PATTERN (insn)) != COND_EXEC -+ && cfun->machine->ifcvt_after_reload)" -+ [(set (match_dup 0) -+ (zero_extend:SI (match_dup 1)))] -+ "" -+ [(set_attr "length" "8") -+ (set_attr "cc" "cmp_cond_insn") -+ (set_attr "predicable" "yes")] -+ ) -+ -+(define_insn_and_split "zero_extendqisi_clobber_predicable" -+ [(parallel -+ [(set (match_operand:SI 0 "register_operand" "=r") -+ (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))) -+ (clobber (match_operand:SI 2 "register_operand" "=&r"))])] -+ "TARGET_V2_INSNS" -+ { -+ if ( current_insn_predicate != NULL_RTX ) -+ { -+ return "%! mov\t%2, 0xff\;and%?\t%0, %1, %2"; -+ } -+ else -+ { -+ return "#"; -+ } -+ -+ } -+ ;; If we find out that we could not actually do if-conversion on the block -+ ;; containing this insn we convert it back to normal immediate format -+ ;; to avoid outputing a redundant move insn -+ ;; Do not split until after we have checked if we can make the insn -+ ;; conditional. -+ "(GET_CODE (PATTERN (insn)) != COND_EXEC -+ && cfun->machine->ifcvt_after_reload)" -+ [(set (match_dup 0) -+ (zero_extend:SI (match_dup 1)))] -+ "" -+ [(set_attr "length" "8") -+ (set_attr "cc" "cmp_cond_insn") -+ (set_attr "predicable" "yes")] -+ ) -+ -+(define_insn_and_split "zero_extendqihi_clobber_predicable" -+ [(parallel -+ [(set (match_operand:HI 0 "register_operand" "=r") -+ (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))) -+ (clobber (match_operand:SI 2 "register_operand" "=&r"))])] -+ "TARGET_V2_INSNS" -+ { -+ if ( current_insn_predicate != NULL_RTX ) -+ { -+ return "%! mov\t%2, 0xff\;and%?\t%0, %1, %2"; -+ } -+ else -+ { -+ return "#"; -+ } -+ -+ } -+ ;; If we find out that we could not actually do if-conversion on the block -+ ;; containing this insn we convert it back to normal immediate format -+ ;; to avoid outputing a redundant move insn -+ ;; Do not split until after we have checked if we can make the insn -+ ;; conditional. -+ "(GET_CODE (PATTERN (insn)) != COND_EXEC -+ && cfun->machine->ifcvt_after_reload)" -+ [(set (match_dup 0) -+ (zero_extend:HI (match_dup 1)))] -+ "" -+ [(set_attr "length" "8") -+ (set_attr "cc" "cmp_cond_insn") -+ (set_attr "predicable" "yes")] -+ ) -+;;============================================================================= -+;; divmod -+;;----------------------------------------------------------------------------- -+;; Signed division that produces both a quotient and a remainder. -+;;============================================================================= -+ -+(define_expand "divmodsi4" -+ [(parallel [ -+ (parallel [ -+ (set (match_operand:SI 0 "register_operand" "=r") -+ (div:SI (match_operand:SI 1 "register_operand" "r") -+ (match_operand:SI 2 "register_operand" "r"))) -+ (set (match_operand:SI 3 "register_operand" "=r") -+ (mod:SI (match_dup 1) -+ (match_dup 2)))]) -+ (use (match_dup 4))])] -+ "" -+ { -+ if (can_create_pseudo_p ()) { -+ operands[4] = gen_reg_rtx (DImode); -+ emit_insn(gen_divmodsi4_internal(operands[4],operands[1],operands[2])); -+ emit_move_insn(operands[0], gen_rtx_SUBREG( SImode, operands[4], 4)); -+ emit_move_insn(operands[3], gen_rtx_SUBREG( SImode, operands[4], 0)); -+ DONE; -+ } else { -+ FAIL; -+ } -+ }) -+ -+ -+(define_insn "divmodsi4_internal" -+ [(set (match_operand:DI 0 "register_operand" "=r") -+ (unspec:DI [(match_operand:SI 1 "register_operand" "r") -+ (match_operand:SI 2 "register_operand" "r")] -+ UNSPEC_DIVMODSI4_INTERNAL))] -+ "" -+ "divs %0, %1, %2" -+ [(set_attr "type" "div") -+ (set_attr "cc" "none")]) -+ -+ -+;;============================================================================= -+;; udivmod -+;;----------------------------------------------------------------------------- -+;; Unsigned division that produces both a quotient and a remainder. -+;;============================================================================= -+(define_expand "udivmodsi4" -+ [(parallel [ -+ (parallel [ -+ (set (match_operand:SI 0 "register_operand" "=r") -+ (udiv:SI (match_operand:SI 1 "register_operand" "r") -+ (match_operand:SI 2 "register_operand" "r"))) -+ (set (match_operand:SI 3 "register_operand" "=r") -+ (umod:SI (match_dup 1) -+ (match_dup 2)))]) -+ (use (match_dup 4))])] -+ "" -+ { -+ if (can_create_pseudo_p ()) { -+ operands[4] = gen_reg_rtx (DImode); -+ -+ emit_insn(gen_udivmodsi4_internal(operands[4],operands[1],operands[2])); -+ emit_move_insn(operands[0], gen_rtx_SUBREG( SImode, operands[4], 4)); -+ emit_move_insn(operands[3], gen_rtx_SUBREG( SImode, operands[4], 0)); -+ -+ DONE; -+ } else { -+ FAIL; -+ } -+ }) -+ -+(define_insn "udivmodsi4_internal" -+ [(set (match_operand:DI 0 "register_operand" "=r") -+ (unspec:DI [(match_operand:SI 1 "register_operand" "r") -+ (match_operand:SI 2 "register_operand" "r")] -+ UNSPEC_UDIVMODSI4_INTERNAL))] -+ "" -+ "divu %0, %1, %2" -+ [(set_attr "type" "div") -+ (set_attr "cc" "none")]) -+ -+ -+;;============================================================================= -+;; Arithmetic-shift left -+;;----------------------------------------------------------------------------- -+;; Arithmetic-shift reg0 left by reg2 or immediate value. -+;;============================================================================= -+ -+(define_insn "ashlsi3" -+ [(set (match_operand:SI 0 "register_operand" "=r,r,r") -+ (ashift:SI (match_operand:SI 1 "register_operand" "r,0,r") -+ (match_operand:SI 2 "register_const_int_operand" "r,Ku05,Ku05")))] -+ "" -+ "@ -+ lsl %0, %1, %2 -+ lsl %0, %2 -+ lsl %0, %1, %2" -+ [(set_attr "length" "4,2,4") -+ (set_attr "cc" "set_ncz")]) -+ -+;;============================================================================= -+;; Arithmetic-shift right -+;;----------------------------------------------------------------------------- -+;; Arithmetic-shift reg0 right by an immediate value. -+;;============================================================================= -+ -+(define_insn "ashrsi3" -+ [(set (match_operand:SI 0 "register_operand" "=r,r,r") -+ (ashiftrt:SI (match_operand:SI 1 "register_operand" "r,0,r") -+ (match_operand:SI 2 "register_const_int_operand" "r,Ku05,Ku05")))] -+ "" -+ "@ -+ asr %0, %1, %2 -+ asr %0, %2 -+ asr %0, %1, %2" -+ [(set_attr "length" "4,2,4") -+ (set_attr "cc" "set_ncz")]) -+ -+;;============================================================================= -+;; Logical shift right -+;;----------------------------------------------------------------------------- -+;; Logical shift reg0 right by an immediate value. -+;;============================================================================= -+ -+(define_insn "lshrsi3" -+ [(set (match_operand:SI 0 "register_operand" "=r,r,r") -+ (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0,r") -+ (match_operand:SI 2 "register_const_int_operand" "r,Ku05,Ku05")))] -+ "" -+ "@ -+ lsr %0, %1, %2 -+ lsr %0, %2 -+ lsr %0, %1, %2" -+ [(set_attr "length" "4,2,4") -+ (set_attr "cc" "set_ncz")]) -+ -+ -+;;============================================================================= -+;; neg -+;;----------------------------------------------------------------------------- -+;; Negate operand 1 and store the result in operand 0. -+;;============================================================================= -+(define_insn "negsi2" -+ [(set (match_operand:SI 0 "register_operand" "=r,r") -+ (neg:SI (match_operand:SI 1 "register_operand" "0,r")))] -+ "" -+ "@ -+ neg\t%0 -+ rsub\t%0, %1, 0" -+ [(set_attr "length" "2,4") -+ (set_attr "cc" "set_vncz")]) -+ -+(define_insn "negsi2_predicable" -+ [(set (match_operand:SI 0 "register_operand" "+r") -+ (neg:SI (match_dup 0)))] -+ "TARGET_V2_INSNS" -+ "rsub%?\t%0, 0" -+ [(set_attr "length" "4") -+ (set_attr "cc" "cmp_cond_insn") -+ (set_attr "predicable" "yes")]) -+ -+;;============================================================================= -+;; abs -+;;----------------------------------------------------------------------------- -+;; Store the absolute value of operand 1 into operand 0. -+;;============================================================================= -+(define_insn "abssi2" -+ [(set (match_operand:SI 0 "register_operand" "=r") -+ (abs:SI (match_operand:SI 1 "register_operand" "0")))] -+ "" -+ "abs\t%0" -+ [(set_attr "length" "2") -+ (set_attr "cc" "set_z")]) -+ -+ -+;;============================================================================= -+;; one_cmpl -+;;----------------------------------------------------------------------------- -+;; Store the bitwise-complement of operand 1 into operand 0. -+;;============================================================================= -+ -+(define_insn "one_cmplsi2" -+ [(set (match_operand:SI 0 "register_operand" "=r,r") -+ (not:SI (match_operand:SI 1 "register_operand" "0,r")))] -+ "" -+ "@ -+ com\t%0 -+ rsub\t%0, %1, -1" -+ [(set_attr "length" "2,4") -+ (set_attr "cc" "set_z")]) -+ -+ -+(define_insn "one_cmplsi2_predicable" -+ [(set (match_operand:SI 0 "register_operand" "+r") -+ (not:SI (match_dup 0)))] -+ "TARGET_V2_INSNS" -+ "rsub%?\t%0, -1" -+ [(set_attr "length" "4") -+ (set_attr "cc" "cmp_cond_insn") -+ (set_attr "predicable" "yes")]) -+ -+ -+;;============================================================================= -+;; Bit load -+;;----------------------------------------------------------------------------- -+;; Load a bit into Z and C flags -+;;============================================================================= -+(define_insn "bldsi" -+ [(set (cc0) -+ (and:SI (match_operand:SI 0 "register_operand" "r") -+ (match_operand:SI 1 "one_bit_set_operand" "i")))] -+ "" -+ "bld\t%0, %p1" -+ [(set_attr "length" "4") -+ (set_attr "cc" "bld")] -+ ) -+ -+ -+;;============================================================================= -+;; Compare -+;;----------------------------------------------------------------------------- -+;; Compare reg0 with reg1 or an immediate value. -+;;============================================================================= -+ -+(define_expand "cmp" -+ [(set (cc0) -+ (compare:CMP -+ (match_operand:CMP 0 "register_operand" "") -+ (match_operand:CMP 1 "" "")))] -+ "" -+ "{ -+ avr32_compare_op0 = operands[0]; -+ avr32_compare_op1 = operands[1]; -+ }" -+) -+ -+(define_insn "cmp_internal" -+ [(set (cc0) -+ (compare:CMP -+ (match_operand:CMP 0 "register_operand" "r") -+ (match_operand:CMP 1 "" "")))] -+ "" -+ { -+ /* Check if the next insn already will output a compare. */ -+ if (!next_insn_emits_cmp (insn)) -+ set_next_insn_cond(insn, -+ avr32_output_cmp(get_next_insn_cond(insn), GET_MODE (operands[0]), operands[0], operands[1])); -+ return ""; -+ } -+ [(set_attr "length" "4") -+ (set_attr "cc" "compare")]) -+ -+(define_expand "cmpsf" -+ [(set (cc0) -+ (compare:SF -+ (match_operand:SF 0 "general_operand" "") -+ (match_operand:SF 1 "general_operand" "")))] -+ "TARGET_ARCH_FPU && TARGET_HARD_FLOAT" -+ "{ -+ rtx tmpreg; -+ if ( !REG_P(operands[0]) ) -+ operands[0] = force_reg(SFmode, operands[0]); -+ -+ if ( !REG_P(operands[1]) ) -+ operands[1] = force_reg(SFmode, operands[1]); -+ -+ avr32_compare_op0 = operands[0]; -+ avr32_compare_op1 = operands[1]; -+ emit_insn(gen_cmpsf_internal_uc3fp(operands[0], operands[1])); -+ DONE; -+ }" -+) -+ -+;;;============================================================================= -+;; Test if zero -+;;----------------------------------------------------------------------------- -+;; Compare reg against zero and set the condition codes. -+;;============================================================================= -+ -+ -+(define_expand "tstsi" -+ [(set (cc0) -+ (match_operand:SI 0 "register_operand" ""))] -+ "" -+ { -+ avr32_compare_op0 = operands[0]; -+ avr32_compare_op1 = const0_rtx; -+ } -+) -+ -+(define_insn "tstsi_internal" -+ [(set (cc0) -+ (match_operand:SI 0 "register_operand" "r"))] -+ "" -+ { -+ /* Check if the next insn already will output a compare. */ -+ if (!next_insn_emits_cmp (insn)) -+ set_next_insn_cond(insn, -+ avr32_output_cmp(get_next_insn_cond(insn), SImode, operands[0], const0_rtx)); -+ -+ return ""; -+ } -+ [(set_attr "length" "2") -+ (set_attr "cc" "compare")]) -+ -+ -+(define_expand "tstdi" -+ [(set (cc0) -+ (match_operand:DI 0 "register_operand" ""))] -+ "" -+ { -+ avr32_compare_op0 = operands[0]; -+ avr32_compare_op1 = const0_rtx; -+ } -+) -+ -+(define_insn "tstdi_internal" -+ [(set (cc0) -+ (match_operand:DI 0 "register_operand" "r"))] -+ "" -+ { -+ /* Check if the next insn already will output a compare. */ -+ if (!next_insn_emits_cmp (insn)) -+ set_next_insn_cond(insn, -+ avr32_output_cmp(get_next_insn_cond(insn), DImode, operands[0], const0_rtx)); -+ return ""; -+ } -+ [(set_attr "length" "4") -+ (set_attr "type" "alu2") -+ (set_attr "cc" "compare")]) -+ -+ -+ -+;;============================================================================= -+;; Convert operands -+;;----------------------------------------------------------------------------- -+;; -+;;============================================================================= -+(define_insn "truncdisi2" -+ [(set (match_operand:SI 0 "general_operand" "") -+ (truncate:SI (match_operand:DI 1 "general_operand" "")))] -+ "" -+ "truncdisi2") -+ -+;;============================================================================= -+;; Extend -+;;----------------------------------------------------------------------------- -+;; -+;;============================================================================= -+ -+ -+(define_insn "extendhisi2" -+ [(set (match_operand:SI 0 "register_operand" "=r,r,r,r") -+ (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,r,,m")))] -+ "" -+ { -+ switch ( which_alternative ){ -+ case 0: -+ return "casts.h\t%0"; -+ case 1: -+ return "bfexts\t%0, %1, 0, 16"; -+ case 2: -+ case 3: -+ return "ld.sh\t%0, %1"; -+ default: -+ abort(); -+ } -+ } -+ [(set_attr "length" "2,4,2,4") -+ (set_attr "cc" "set_ncz,set_ncz,none,none") -+ (set_attr "type" "alu,alu,load_rm,load_rm")]) -+ -+(define_insn "extendqisi2" -+ [(set (match_operand:SI 0 "register_operand" "=r,r,r,r") -+ (sign_extend:SI (match_operand:QI 1 "extendqi_operand" "0,r,RKu00,m")))] -+ "" -+ { -+ switch ( which_alternative ){ -+ case 0: -+ return "casts.b\t%0"; -+ case 1: -+ return "bfexts\t%0, %1, 0, 8"; -+ case 2: -+ case 3: -+ return "ld.sb\t%0, %1"; -+ default: -+ abort(); -+ } -+ } -+ [(set_attr "length" "2,4,2,4") -+ (set_attr "cc" "set_ncz,set_ncz,none,none") -+ (set_attr "type" "alu,alu,load_rm,load_rm")]) -+ -+(define_insn "extendqihi2" -+ [(set (match_operand:HI 0 "register_operand" "=r,r,r,r") -+ (sign_extend:HI (match_operand:QI 1 "extendqi_operand" "0,r,RKu00,m")))] -+ "" -+ { -+ switch ( which_alternative ){ -+ case 0: -+ return "casts.b\t%0"; -+ case 1: -+ return "bfexts\t%0, %1, 0, 8"; -+ case 2: -+ case 3: -+ return "ld.sb\t%0, %1"; -+ default: -+ abort(); -+ } -+ } -+ [(set_attr "length" "2,4,2,4") -+ (set_attr "cc" "set_ncz,set_ncz,none,none") -+ (set_attr "type" "alu,alu,load_rm,load_rm")]) -+ -+ -+;;============================================================================= -+;; Zero-extend -+;;----------------------------------------------------------------------------- -+;; -+;;============================================================================= -+ -+(define_insn "zero_extendhisi2" -+ [(set (match_operand:SI 0 "register_operand" "=r,r,r,r") -+ (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,r,,m")))] -+ "" -+ { -+ switch ( which_alternative ){ -+ case 0: -+ return "castu.h\t%0"; -+ case 1: -+ return "bfextu\t%0, %1, 0, 16"; -+ case 2: -+ case 3: -+ return "ld.uh\t%0, %1"; -+ default: -+ abort(); -+ } -+ } -+ -+ [(set_attr "length" "2,4,2,4") -+ (set_attr "cc" "set_ncz,set_ncz,none,none") -+ (set_attr "type" "alu,alu,load_rm,load_rm")]) -+ -+(define_insn "zero_extendqisi2" -+ [(set (match_operand:SI 0 "register_operand" "=r,r,r,r") -+ (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,r,,m")))] -+ "" -+ { -+ switch ( which_alternative ){ -+ case 0: -+ return "castu.b\t%0"; -+ case 1: -+ return "bfextu\t%0, %1, 0, 8"; -+ case 2: -+ case 3: -+ return "ld.ub\t%0, %1"; -+ default: -+ abort(); -+ } -+ } -+ [(set_attr "length" "2,4,2,4") -+ (set_attr "cc" "set_ncz, set_ncz, none, none") -+ (set_attr "type" "alu, alu, load_rm, load_rm")]) -+ -+(define_insn "zero_extendqihi2" -+ [(set (match_operand:HI 0 "register_operand" "=r,r,r,r") -+ (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,r,,m")))] -+ "" -+ { -+ switch ( which_alternative ){ -+ case 0: -+ return "castu.b\t%0"; -+ case 1: -+ return "bfextu\t%0, %1, 0, 8"; -+ case 2: -+ case 3: -+ return "ld.ub\t%0, %1"; -+ default: -+ abort(); -+ } -+ } -+ [(set_attr "length" "2,4,2,4") -+ (set_attr "cc" "set_ncz, set_ncz, none, none") -+ (set_attr "type" "alu, alu, load_rm, load_rm")]) -+ -+ -+;;============================================================================= -+;; Conditional load and extend insns -+;;============================================================================= -+(define_insn "ldsi_predicable_se" -+ [(set (match_operand:SI 0 "register_operand" "=r") -+ (sign_extend:SI -+ (match_operand:INTM 1 "memory_operand" "")))] -+ "TARGET_V2_INSNS" -+ "ld%?\t%0, %1" -+ [(set_attr "length" "4") -+ (set_attr "cc" "cmp_cond_insn") -+ (set_attr "type" "load") -+ (set_attr "predicable" "yes")] -+) -+ -+(define_insn "ldsi_predicable_ze" -+ [(set (match_operand:SI 0 "register_operand" "=r") -+ (zero_extend:SI -+ (match_operand:INTM 1 "memory_operand" "")))] -+ "TARGET_V2_INSNS" -+ "ld%?\t%0, %1" -+ [(set_attr "length" "4") -+ (set_attr "cc" "cmp_cond_insn") -+ (set_attr "type" "load") -+ (set_attr "predicable" "yes")] -+) -+ -+(define_insn "ldhi_predicable_ze" -+ [(set (match_operand:HI 0 "register_operand" "=r") -+ (zero_extend:HI -+ (match_operand:QI 1 "memory_operand" "RKs10")))] -+ "TARGET_V2_INSNS" -+ "ld.ub%?\t%0, %1" -+ [(set_attr "length" "4") -+ (set_attr "cc" "cmp_cond_insn") -+ (set_attr "type" "load") -+ (set_attr "predicable" "yes")] -+) -+ -+(define_insn "ldhi_predicable_se" -+ [(set (match_operand:HI 0 "register_operand" "=r") -+ (sign_extend:HI -+ (match_operand:QI 1 "memory_operand" "RKs10")))] -+ "TARGET_V2_INSNS" -+ "ld.sb%?\t%0, %1" -+ [(set_attr "length" "4") -+ (set_attr "cc" "cmp_cond_insn") -+ (set_attr "type" "load") -+ (set_attr "predicable" "yes")] -+) -+ -+;;============================================================================= -+;; Conditional set register -+;; sr{cond4} rd -+;;----------------------------------------------------------------------------- -+ -+;;Because of the same issue as with conditional moves and adds we must -+;;not separate the compare instrcution from the scc instruction as -+;;they might be sheduled "badly". -+ -+(define_insn "s" -+ [(set (match_operand:SI 0 "register_operand" "=r") -+ (any_cond:SI (cc0) -+ (const_int 0)))] -+ "" -+ "sr\t%0" -+ [(set_attr "length" "2") -+ (set_attr "cc" "none")]) -+ -+(define_insn "smi" -+ [(set (match_operand:SI 0 "register_operand" "=r") -+ (unspec:SI [(cc0) -+ (const_int 0)] UNSPEC_COND_MI))] -+ "" -+ "srmi\t%0" -+ [(set_attr "length" "2") -+ (set_attr "cc" "none")]) -+ -+(define_insn "spl" -+ [(set (match_operand:SI 0 "register_operand" "=r") -+ (unspec:SI [(cc0) -+ (const_int 0)] UNSPEC_COND_PL))] -+ "" -+ "srpl\t%0" -+ [(set_attr "length" "2") -+ (set_attr "cc" "none")]) -+ -+ -+;;============================================================================= -+;; Conditional branch -+;;----------------------------------------------------------------------------- -+;; Branch to label if the specified condition codes are set. -+;;============================================================================= -+; branch if negative -+(define_insn "bmi" -+ [(set (pc) -+ (if_then_else (unspec:CC [(cc0) (const_int 0)] UNSPEC_COND_MI) -+ (label_ref (match_operand 0 "" "")) -+ (pc)))] -+ "" -+ "brmi %0" -+ [(set_attr "type" "branch") -+ (set (attr "length") -+ (cond [(and (le (minus (match_dup 0) (pc)) (const_int 254)) -+ (le (minus (pc) (match_dup 0)) (const_int 256))) -+ (const_int 2)] ; use compact branch -+ (const_int 4))) ; use extended branch -+ (set_attr "cc" "none")]) -+ -+(define_insn "*bmi-reverse" -+ [(set (pc) -+ (if_then_else (unspec:CC [(cc0) (const_int 0)] UNSPEC_COND_MI) -+ (pc) -+ (label_ref (match_operand 0 "" ""))))] -+ "" -+ "brpl %0" -+ [(set_attr "type" "branch") -+ (set (attr "length") -+ (cond [(and (le (minus (match_dup 0) (pc)) (const_int 254)) -+ (le (minus (pc) (match_dup 0)) (const_int 256))) -+ (const_int 2)] ; use compact branch -+ (const_int 4))) ; use extended branch -+ (set_attr "cc" "none")]) -+ -+; branch if positive -+(define_insn "bpl" -+ [(set (pc) -+ (if_then_else (unspec:CC [(cc0) (const_int 0)] UNSPEC_COND_PL) -+ (label_ref (match_operand 0 "" "")) -+ (pc)))] -+ "" -+ "brpl %0" -+ [(set_attr "type" "branch") -+ (set (attr "length") -+ (cond [(and (le (minus (match_dup 0) (pc)) (const_int 254)) -+ (le (minus (pc) (match_dup 0)) (const_int 256))) -+ (const_int 2)] ; use compact branch -+ (const_int 4))) ; use extended branch -+ (set_attr "cc" "none")]) -+ -+(define_insn "*bpl-reverse" -+ [(set (pc) -+ (if_then_else (unspec:CC [(cc0) (const_int 0)] UNSPEC_COND_PL) -+ (pc) -+ (label_ref (match_operand 0 "" ""))))] -+ "" -+ "brmi %0" -+ [(set_attr "type" "branch") -+ (set (attr "length") -+ (cond [(and (le (minus (match_dup 0) (pc)) (const_int 254)) -+ (le (minus (pc) (match_dup 0)) (const_int 256))) -+ (const_int 2)] ; use compact branch -+ (const_int 4))) ; use extended branch -+ (set_attr "cc" "none")]) -+ -+; branch if equal -+(define_insn "b" -+ [(set (pc) -+ (if_then_else (any_cond:CC (cc0) -+ (const_int 0)) -+ (label_ref (match_operand 0 "" "")) -+ (pc)))] -+ "" -+ "br %0 " -+ [(set_attr "type" "branch") -+ (set (attr "length") -+ (cond [(and (le (minus (match_dup 0) (pc)) (const_int 254)) -+ (le (minus (pc) (match_dup 0)) (const_int 256))) -+ (const_int 2)] ; use compact branch -+ (const_int 4))) ; use extended branch -+ (set_attr "cc" "none")]) -+ -+ -+(define_insn "*b-reverse" -+ [(set (pc) -+ (if_then_else (any_cond:CC (cc0) -+ (const_int 0)) -+ (pc) -+ (label_ref (match_operand 0 "" ""))))] -+ "" -+ "br %0 " -+ [(set_attr "type" "branch") -+ (set (attr "length") -+ (cond [(and (le (minus (match_dup 0) (pc)) (const_int 254)) -+ (le (minus (pc) (match_dup 0)) (const_int 256))) -+ (const_int 2)] ; use compact branch -+ (const_int 4))) ; use extended branch -+ (set_attr "cc" "none")]) -+ -+ -+ -+;============================================================================= -+; Conditional Add/Subtract -+;----------------------------------------------------------------------------- -+; sub{cond4} Rd, imm -+;============================================================================= -+ -+ -+(define_expand "addcc" -+ [(set (match_operand:ADDCC 0 "register_operand" "") -+ (if_then_else:ADDCC (match_operator 1 "avr32_comparison_operator" -+ [(match_dup 4) -+ (match_dup 5)]) -+ (match_operand:ADDCC 2 "register_operand" "") -+ (plus:ADDCC -+ (match_dup 2) -+ (match_operand:ADDCC 3 "" ""))))] -+ "" -+ { -+ if ( !(GET_CODE (operands[3]) == CONST_INT -+ || (TARGET_V2_INSNS && REG_P(operands[3]))) ){ -+ FAIL; -+ } -+ -+ /* Delete compare instruction as it is merged into this instruction */ -+ remove_insn (get_last_insn_anywhere ()); -+ -+ operands[4] = avr32_compare_op0; -+ operands[5] = avr32_compare_op1; -+ -+ if ( TARGET_V2_INSNS -+ && REG_P(operands[3]) -+ && REGNO(operands[0]) != REGNO(operands[2]) ){ -+ emit_move_insn (operands[0], operands[2]); -+ operands[2] = operands[0]; -+ } -+ } -+ ) -+ -+(define_insn "addcc_cmp_reg" -+ [(set (match_operand:ADDCC 0 "register_operand" "=r") -+ (if_then_else:ADDCC (match_operator 1 "avr32_comparison_operator" -+ [(match_operand:CMP 4 "register_operand" "r") -+ (match_operand:CMP 5 "" "")]) -+ (match_dup 0) -+ (plus:ADDCC -+ (match_operand:ADDCC 2 "register_operand" "r") -+ (match_operand:ADDCC 3 "register_operand" "r"))))] -+ "TARGET_V2_INSNS" -+ { -+ operands[1] = avr32_output_cmp(operands[1], GET_MODE(operands[4]), operands[4], operands[5]); -+ return "add%i1\t%0, %2, %3"; -+ } -+ [(set_attr "length" "8") -+ (set_attr "cc" "cmp_cond_insn")]) -+ -+(define_insn "addcc_cmp" -+ [(set (match_operand:ADDCC 0 "register_operand" "=r") -+ (if_then_else:ADDCC (match_operator 1 "avr32_comparison_operator" -+ [(match_operand:CMP 4 "register_operand" "r") -+ (match_operand:CMP 5 "" "")]) -+ (match_operand:ADDCC 2 "register_operand" "0") -+ (plus:ADDCC -+ (match_dup 2) -+ (match_operand:ADDCC 3 "avr32_cond_immediate_operand" "Is08"))))] -+ "" -+ { -+ operands[1] = avr32_output_cmp(operands[1], GET_MODE(operands[4]), operands[4], operands[5]); -+ return "sub%i1\t%0, -%3"; -+ } -+ [(set_attr "length" "8") -+ (set_attr "cc" "cmp_cond_insn")]) -+ -+;============================================================================= -+; Conditional Move -+;----------------------------------------------------------------------------- -+; mov{cond4} Rd, (Rs/imm) -+;============================================================================= -+(define_expand "movcc" -+ [(set (match_operand:MOVCC 0 "register_operand" "") -+ (if_then_else:MOVCC (match_operator 1 "avr32_comparison_operator" -+ [(match_dup 4) -+ (match_dup 5)]) -+ (match_operand:MOVCC 2 "avr32_cond_register_immediate_operand" "") -+ (match_operand:MOVCC 3 "avr32_cond_register_immediate_operand" "")))] -+ "" -+ { -+ /* Delete compare instruction as it is merged into this instruction */ -+ remove_insn (get_last_insn_anywhere ()); -+ -+ operands[4] = avr32_compare_op0; -+ operands[5] = avr32_compare_op1; -+ } -+ ) -+ -+ -+(define_insn "movcc_cmp" -+ [(set (match_operand:MOVCC 0 "register_operand" "=r,r,r") -+ (if_then_else:MOVCC (match_operator 1 "avr32_comparison_operator" -+ [(match_operand:CMP 4 "register_operand" "r,r,r") -+ (match_operand:CMP 5 "" ",,")]) -+ (match_operand:MOVCC 2 "avr32_cond_register_immediate_operand" "0, rKs08,rKs08") -+ (match_operand:MOVCC 3 "avr32_cond_register_immediate_operand" "rKs08,0,rKs08")))] -+ "" -+ { -+ operands[1] = avr32_output_cmp(operands[1], GET_MODE(operands[4]), operands[4], operands[5]); -+ -+ switch( which_alternative ){ -+ case 0: -+ return "mov%i1 %0, %3"; -+ case 1: -+ return "mov%1 %0, %2"; -+ case 2: -+ return "mov%1 %0, %2\;mov%i1 %0, %3"; -+ default: -+ abort(); -+ } -+ -+ } -+ [(set_attr "length" "8,8,12") -+ (set_attr "cc" "cmp_cond_insn")]) -+ -+ -+ -+ -+;;============================================================================= -+;; jump -+;;----------------------------------------------------------------------------- -+;; Jump inside a function; an unconditional branch to a label. -+;;============================================================================= -+(define_insn "jump" -+ [(set (pc) -+ (label_ref (match_operand 0 "" "")))] -+ "" -+ { -+ if (get_attr_length(insn) > 4) -+ return "Can't jump this far"; -+ return (get_attr_length(insn) == 2 ? -+ "rjmp %0" : "bral %0"); -+ } -+ [(set_attr "type" "branch") -+ (set (attr "length") -+ (cond [(and (le (minus (match_dup 0) (pc)) (const_int 1022)) -+ (le (minus (pc) (match_dup 0)) (const_int 1024))) -+ (const_int 2) ; use rjmp -+ (le (match_dup 0) (const_int 1048575)) -+ (const_int 4)] ; use bral -+ (const_int 8))) ; do something else -+ (set_attr "cc" "none")]) -+ -+;;============================================================================= -+;; call -+;;----------------------------------------------------------------------------- -+;; Subroutine call instruction returning no value. -+;;============================================================================= -+(define_insn "call_internal" -+ [(parallel [(call (mem:SI (match_operand:SI 0 "avr32_call_operand" "r,U,T,W")) -+ (match_operand 1 "" "")) -+ (clobber (reg:SI LR_REGNUM))])] -+ "" -+ { -+ -+ /* Check for a flashvault call. */ -+ if (avr32_flashvault_call (SYMBOL_REF_DECL (operands[0]))) -+ { -+ /* Assembly is already emitted. */ -+ return ""; -+ } -+ -+ switch (which_alternative) { -+ case 0: -+ return "icall\t%0"; -+ case 1: -+ return "rcall\t%0"; -+ case 2: -+ return "mcall\t%0"; -+ case 3: -+ if (TARGET_HAS_ASM_ADDR_PSEUDOS) -+ return "call\t%0"; -+ else -+ return "mcall\tr6[%0@got]"; -+ default: -+ abort(); -+ } -+ } -+ [(set_attr "type" "call") -+ (set_attr "length" "2,4,4,10") -+ (set_attr "cc" "clobber")]) -+ -+ -+(define_expand "call" -+ [(parallel [(call (match_operand:SI 0 "" "") -+ (match_operand 1 "" "")) -+ (clobber (reg:SI LR_REGNUM))])] -+ "" -+ { -+ rtx call_address; -+ if ( GET_CODE(operands[0]) != MEM ) -+ FAIL; -+ -+ call_address = XEXP(operands[0], 0); -+ -+ /* If assembler supports call pseudo insn and the call address is a symbol then nothing special needs to be done. */ -+ if (TARGET_HAS_ASM_ADDR_PSEUDOS && (GET_CODE(call_address) == SYMBOL_REF) ) -+ { -+ /* We must however mark the function as using the GOT if flag_pic is set, since the call insn might turn into a mcall using the GOT ptr register. */ -+ if (flag_pic) -+ { -+ current_function_uses_pic_offset_table = 1; -+ emit_call_insn(gen_call_internal(call_address, operands[1])); -+ DONE; -+ } -+ } -+ else -+ { -+ if (flag_pic && GET_CODE(call_address) == SYMBOL_REF ) -+ { -+ current_function_uses_pic_offset_table = 1; -+ emit_call_insn(gen_call_internal(call_address, operands[1])); -+ DONE; -+ } -+ -+ if (!SYMBOL_REF_RCALL_FUNCTION_P(operands[0]) ) -+ { -+ if (optimize_size && GET_CODE(call_address) == SYMBOL_REF ) -+ { -+ call_address = force_const_mem(SImode, call_address); -+ } -+ else -+ { -+ call_address = force_reg(SImode, call_address); -+ } -+ } -+ } -+ emit_call_insn(gen_call_internal(call_address, operands[1])); -+ DONE; -+ -+ } -+) -+ -+;;============================================================================= -+;; call_value -+;;----------------------------------------------------------------------------- -+;; Subroutine call instruction returning a value. -+;;============================================================================= -+(define_expand "call_value" -+ [(parallel [(set (match_operand:SI 0 "" "") -+ (call (match_operand:SI 1 "" "") -+ (match_operand 2 "" ""))) -+ (clobber (reg:SI LR_REGNUM))])] -+ "" -+ { -+ rtx call_address; -+ if ( GET_CODE(operands[1]) != MEM ) -+ FAIL; -+ -+ call_address = XEXP(operands[1], 0); -+ -+ /* Check for a flashvault call. -+ if (GET_CODE (call_address) == SYMBOL_REF -+ && avr32_flashvault_call (SYMBOL_REF_DECL (call_address))) -+ DONE; -+ -+ */ -+ -+ /* If assembler supports call pseudo insn and the call -+ address is a symbol then nothing special needs to be done. */ -+ if ( TARGET_HAS_ASM_ADDR_PSEUDOS -+ && (GET_CODE(call_address) == SYMBOL_REF) ){ -+ /* We must however mark the function as using the GOT if -+ flag_pic is set, since the call insn might turn into -+ a mcall using the GOT ptr register. */ -+ if ( flag_pic ) { -+ current_function_uses_pic_offset_table = 1; -+ emit_call_insn(gen_call_value_internal(operands[0], call_address, operands[2])); -+ DONE; -+ } -+ } else { -+ if ( flag_pic && -+ GET_CODE(call_address) == SYMBOL_REF ){ -+ current_function_uses_pic_offset_table = 1; -+ emit_call_insn(gen_call_value_internal(operands[0], call_address, operands[2])); -+ DONE; -+ } -+ -+ if ( !SYMBOL_REF_RCALL_FUNCTION_P(operands[1]) ){ -+ if ( optimize_size && -+ GET_CODE(call_address) == SYMBOL_REF){ -+ call_address = force_const_mem(SImode, call_address); -+ } else { -+ call_address = force_reg(SImode, call_address); -+ } -+ } -+ } -+ emit_call_insn(gen_call_value_internal(operands[0], call_address, -+ operands[2])); -+ DONE; -+ -+ }) -+ -+(define_insn "call_value_internal" -+ [(parallel [(set (match_operand 0 "register_operand" "=r,r,r,r") -+ (call (mem:SI (match_operand:SI 1 "avr32_call_operand" "r,U,T,W")) -+ (match_operand 2 "" ""))) -+ (clobber (reg:SI LR_REGNUM))])] -+ ;; Operand 2 not used on the AVR32. -+ "" -+ { -+ /* Check for a flashvault call. */ -+ if (avr32_flashvault_call (SYMBOL_REF_DECL (operands[1]))) -+ { -+ /* Assembly is already emitted. */ -+ return ""; -+ } -+ -+ -+ switch (which_alternative) { -+ case 0: -+ return "icall\t%1"; -+ case 1: -+ return "rcall\t%1"; -+ case 2: -+ return "mcall\t%1"; -+ case 3: -+ if ( TARGET_HAS_ASM_ADDR_PSEUDOS ) -+ return "call\t%1"; -+ else -+ return "mcall\tr6[%1@got]"; -+ default: -+ abort(); -+ } -+ } -+ [(set_attr "type" "call") -+ (set_attr "length" "2,4,4,10") -+ (set_attr "cc" "call_set")]) -+ -+ -+;;============================================================================= -+;; untyped_call -+;;----------------------------------------------------------------------------- -+;; Subrutine call instruction returning a value of any type. -+;; The code is copied from m68k.md (except gen_blockage is removed) -+;; Fixme! -+;;============================================================================= -+(define_expand "untyped_call" -+ [(parallel [(call (match_operand 0 "avr32_call_operand" "") -+ (const_int 0)) -+ (match_operand 1 "" "") -+ (match_operand 2 "" "")])] -+ "" -+ { -+ int i; -+ -+ emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, 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)); -+ } -+ -+ /* The optimizer does not know that the call sets the function value -+ registers we stored in the result block. We avoid problems by -+ claiming that all hard registers are used and clobbered at this -+ point. */ -+ emit_insn (gen_blockage ()); -+ -+ DONE; -+ }) -+ -+ -+;;============================================================================= -+;; return -+;;============================================================================= -+ -+(define_insn "return" -+ [(return)] -+ "USE_RETURN_INSN (FALSE)" -+ { -+ avr32_output_return_instruction(TRUE, FALSE, NULL, NULL); -+ return ""; -+ } -+ [(set_attr "length" "4") -+ (set_attr "type" "call")] -+ ) -+ -+ -+(define_insn "return_cond" -+ [(set (pc) -+ (if_then_else (match_operand 0 "avr32_comparison_operand" "") -+ (return) -+ (pc)))] -+ "USE_RETURN_INSN (TRUE)" -+ "ret%0\tr12"; -+ [(set_attr "type" "call")]) -+ -+(define_insn "return_cond_predicable" -+ [(return)] -+ "USE_RETURN_INSN (TRUE)" -+ "ret%?\tr12"; -+ [(set_attr "type" "call") -+ (set_attr "predicable" "yes")]) -+ -+ -+(define_insn "return_imm" -+ [(parallel [(set (reg RETVAL_REGNUM) (match_operand 0 "immediate_operand" "i")) -+ (use (reg RETVAL_REGNUM)) -+ (return)])] -+ "USE_RETURN_INSN (FALSE) && -+ ((INTVAL(operands[0]) == -1) || (INTVAL(operands[0]) == 0) || (INTVAL(operands[0]) == 1))" -+ { -+ avr32_output_return_instruction(TRUE, FALSE, NULL, operands[0]); -+ return ""; -+ } -+ [(set_attr "length" "4") -+ (set_attr "type" "call")] -+ ) -+ -+(define_insn "return_imm_cond" -+ [(parallel [(set (reg RETVAL_REGNUM) (match_operand 0 "immediate_operand" "i")) -+ (use (reg RETVAL_REGNUM)) -+ (set (pc) -+ (if_then_else (match_operand 1 "avr32_comparison_operand" "") -+ (return) -+ (pc)))])] -+ "USE_RETURN_INSN (TRUE) && -+ ((INTVAL(operands[0]) == -1) || (INTVAL(operands[0]) == 0) || (INTVAL(operands[0]) == 1))" -+ "ret%1\t%0"; -+ [(set_attr "type" "call")] -+ ) -+ -+(define_insn "return_imm_predicable" -+ [(parallel [(set (reg RETVAL_REGNUM) (match_operand 0 "immediate_operand" "i")) -+ (use (reg RETVAL_REGNUM)) -+ (return)])] -+ "USE_RETURN_INSN (TRUE) && -+ ((INTVAL(operands[0]) == -1) || (INTVAL(operands[0]) == 0) || (INTVAL(operands[0]) == 1))" -+ "ret%?\t%0"; -+ [(set_attr "type" "call") -+ (set_attr "predicable" "yes")]) -+ -+(define_insn "return_reg" -+ [(set (reg RETVAL_REGNUM) (match_operand:MOVM 0 "register_operand" "r")) -+ (use (reg RETVAL_REGNUM)) -+ (return)] -+ "USE_RETURN_INSN (TRUE)" -+ "ret%?\t%0"; -+ [(set_attr "type" "call") -+ (set_attr "predicable" "yes")]) -+ -+(define_insn "return_reg_cond" -+ [(set (reg RETVAL_REGNUM) (match_operand:MOVM 0 "register_operand" "r")) -+ (use (reg RETVAL_REGNUM)) -+ (set (pc) -+ (if_then_else (match_operator 1 "avr32_comparison_operator" -+ [(cc0) (const_int 0)]) -+ (return) -+ (pc)))] -+ "USE_RETURN_INSN (TRUE)" -+ "ret%1\t%0"; -+ [(set_attr "type" "call")]) -+ -+;;============================================================================= -+;; nonlocal_goto_receiver -+;;----------------------------------------------------------------------------- -+;; For targets with a return stack we must make sure to flush the return stack -+;; since it will be corrupt after a nonlocal goto. -+;;============================================================================= -+(define_expand "nonlocal_goto_receiver" -+ [(const_int 0)] -+ "TARGET_RETURN_STACK" -+ " -+ { -+ emit_insn ( gen_frs() ); -+ DONE; -+ } -+ " -+ ) -+ -+ -+;;============================================================================= -+;; builtin_setjmp_receiver -+;;----------------------------------------------------------------------------- -+;; For pic code we need to reload the pic register. -+;; For targets with a return stack we must make sure to flush the return stack -+;; since it will probably be corrupted. -+;;============================================================================= -+(define_expand "builtin_setjmp_receiver" -+ [(label_ref (match_operand 0 "" ""))] -+ "flag_pic" -+ " -+ { -+ if ( TARGET_RETURN_STACK ) -+ emit_insn ( gen_frs() ); -+ -+ avr32_load_pic_register (); -+ DONE; -+ } -+ " -+) -+ -+ -+;;============================================================================= -+;; indirect_jump -+;;----------------------------------------------------------------------------- -+;; Jump to an address in reg or memory. -+;;============================================================================= -+(define_expand "indirect_jump" -+ [(set (pc) -+ (match_operand:SI 0 "general_operand" ""))] -+ "" -+ { -+ /* One of the ops has to be in a register. */ -+ if ( (flag_pic || TARGET_HAS_ASM_ADDR_PSEUDOS ) -+ && !avr32_legitimate_pic_operand_p(operands[0]) ) -+ operands[0] = legitimize_pic_address (operands[0], SImode, 0); -+ else if ( flag_pic && avr32_address_operand(operands[0], GET_MODE(operands[0])) ) -+ /* If we have an address operand then this function uses the pic register. */ -+ current_function_uses_pic_offset_table = 1; -+ }) -+ -+ -+(define_insn "indirect_jump_internal" -+ [(set (pc) -+ (match_operand:SI 0 "avr32_non_rmw_general_operand" "r,m,W"))] -+ "" -+ { -+ switch( which_alternative ){ -+ case 0: -+ return "mov\tpc, %0"; -+ case 1: -+ if ( avr32_const_pool_ref_operand(operands[0], GET_MODE(operands[0])) ) -+ return "lddpc\tpc, %0"; -+ else -+ return "ld.w\tpc, %0"; -+ case 2: -+ if ( flag_pic ) -+ return "ld.w\tpc, r6[%0@got]"; -+ else -+ return "lda.w\tpc, %0"; -+ default: -+ abort(); -+ } -+ } -+ [(set_attr "length" "2,4,8") -+ (set_attr "type" "call,call,call") -+ (set_attr "cc" "none,none,clobber")]) -+ -+ -+ -+;;============================================================================= -+;; casesi and tablejump -+;;============================================================================= -+(define_insn "tablejump_add" -+ [(set (pc) -+ (plus:SI (match_operand:SI 0 "register_operand" "r") -+ (mult:SI (match_operand:SI 1 "register_operand" "r") -+ (match_operand:SI 2 "immediate_operand" "Ku04" )))) -+ (use (label_ref (match_operand 3 "" "")))] -+ "flag_pic && -+ ((INTVAL(operands[2]) == 0) || (INTVAL(operands[2]) == 2) || -+ (INTVAL(operands[2]) == 4) || (INTVAL(operands[2]) == 8))" -+ "add\tpc, %0, %1 << %p2" -+ [(set_attr "length" "4") -+ (set_attr "cc" "clobber")]) -+ -+(define_insn "tablejump_insn" -+ [(set (pc) (match_operand:SI 0 "memory_operand" "m")) -+ (use (label_ref (match_operand 1 "" "")))] -+ "!flag_pic" -+ "ld.w\tpc, %0" -+ [(set_attr "length" "4") -+ (set_attr "type" "call") -+ (set_attr "cc" "none")]) -+ -+(define_expand "casesi" -+ [(match_operand:SI 0 "register_operand" "") ; index to jump on -+ (match_operand:SI 1 "const_int_operand" "") ; lower bound -+ (match_operand:SI 2 "const_int_operand" "") ; total range -+ (match_operand:SI 3 "" "") ; table label -+ (match_operand:SI 4 "" "")] ; Out of range label -+ "" -+ " -+ { -+ rtx reg; -+ rtx index = operands[0]; -+ rtx low_bound = operands[1]; -+ rtx range = operands[2]; -+ rtx table_label = operands[3]; -+ rtx oor_label = operands[4]; -+ -+ index = force_reg ( SImode, index ); -+ if (low_bound != const0_rtx) -+ { -+ if (!avr32_const_ok_for_constraint_p(INTVAL (low_bound), 'I', \"Is21\")){ -+ reg = force_reg(SImode, GEN_INT (INTVAL (low_bound))); -+ emit_insn (gen_subsi3 (reg, index, -+ reg)); -+ } else { -+ reg = gen_reg_rtx (SImode); -+ emit_insn (gen_addsi3 (reg, index, -+ GEN_INT (-INTVAL (low_bound)))); -+ } -+ index = reg; -+ } -+ -+ if (!avr32_const_ok_for_constraint_p (INTVAL (range), 'K', \"Ks21\")) -+ range = force_reg (SImode, range); -+ -+ emit_cmp_and_jump_insns ( index, range, GTU, NULL_RTX, SImode, 1, oor_label ); -+ reg = gen_reg_rtx (SImode); -+ emit_move_insn ( reg, gen_rtx_LABEL_REF (VOIDmode, table_label)); -+ -+ if ( flag_pic ) -+ emit_jump_insn ( gen_tablejump_add ( reg, index, GEN_INT(4), table_label)); -+ else -+ emit_jump_insn ( -+ gen_tablejump_insn ( gen_rtx_MEM ( SImode, -+ gen_rtx_PLUS ( SImode, -+ reg, -+ gen_rtx_MULT ( SImode, -+ index, -+ GEN_INT(4)))), -+ table_label)); -+ DONE; -+ }" -+) -+ -+ -+ -+(define_insn "prefetch" -+ [(prefetch (match_operand:SI 0 "avr32_ks16_address_operand" "p") -+ (match_operand 1 "const_int_operand" "") -+ (match_operand 2 "const_int_operand" ""))] -+ "" -+ { -+ return "pref\t%0"; -+ } -+ -+ [(set_attr "length" "4") -+ (set_attr "type" "load") -+ (set_attr "cc" "none")]) -+ -+ -+ -+;;============================================================================= -+;; prologue -+;;----------------------------------------------------------------------------- -+;; This pattern, if defined, emits RTL for entry to a function. The function -+;; entry i responsible for setting up the stack frame, initializing the frame -+;; pointer register, saving callee saved registers, etc. -+;;============================================================================= -+(define_expand "prologue" -+ [(clobber (const_int 0))] -+ "" -+ " -+ avr32_expand_prologue(); -+ DONE; -+ " -+ ) -+ -+;;============================================================================= -+;; eh_return -+;;----------------------------------------------------------------------------- -+;; This pattern, if defined, affects the way __builtin_eh_return, and -+;; thence the call frame exception handling library routines, are -+;; built. It is intended to handle non-trivial actions needed along -+;; the abnormal return path. -+;; -+;; The address of the exception handler to which the function should -+;; return is passed as operand to this pattern. It will normally need -+;; to copied by the pattern to some special register or memory -+;; location. If the pattern needs to determine the location of the -+;; target call frame in order to do so, it may use -+;; EH_RETURN_STACKADJ_RTX, if defined; it will have already been -+;; assigned. -+;; -+;; If this pattern is not defined, the default action will be to -+;; simply copy the return address to EH_RETURN_HANDLER_RTX. Either -+;; that macro or this pattern needs to be defined if call frame -+;; exception handling is to be used. -+ -+;; We can't expand this before we know where the link register is stored. -+(define_insn_and_split "eh_return" -+ [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] -+ VUNSPEC_EH_RETURN) -+ (clobber (match_scratch:SI 1 "=&r"))] -+ "" -+ "#" -+ "reload_completed" -+ [(const_int 0)] -+ " -+ { -+ avr32_set_return_address (operands[0], operands[1]); -+ DONE; -+ }" -+ ) -+ -+ -+;;============================================================================= -+;; ffssi2 -+;;----------------------------------------------------------------------------- -+(define_insn "ffssi2" -+ [ (set (match_operand:SI 0 "register_operand" "=r") -+ (ffs:SI (match_operand:SI 1 "register_operand" "r"))) ] -+ "" -+ "mov %0, %1 -+ brev %0 -+ clz %0, %0 -+ sub %0, -1 -+ cp %0, 33 -+ moveq %0, 0" -+ [(set_attr "length" "18") -+ (set_attr "cc" "clobber")] -+ ) -+ -+ -+ -+;;============================================================================= -+;; swap_h -+;;----------------------------------------------------------------------------- -+(define_insn "*swap_h" -+ [ (set (match_operand:SI 0 "register_operand" "=r") -+ (ior:SI (ashift:SI (match_dup 0) (const_int 16)) -+ (lshiftrt:SI (match_dup 0) (const_int 16))))] -+ "" -+ "swap.h %0" -+ [(set_attr "length" "2")] -+ ) -+ -+(define_insn_and_split "bswap_16" -+ [ (set (match_operand:HI 0 "avr32_bswap_operand" "=r,RKs13,r") -+ (ior:HI (and:HI (lshiftrt:HI (match_operand:HI 1 "avr32_bswap_operand" "r,r,RKs13") -+ (const_int 8)) -+ (const_int 255)) -+ (ashift:HI (and:HI (match_dup 1) -+ (const_int 255)) -+ (const_int 8))))] -+ "" -+ { -+ switch ( which_alternative ){ -+ case 0: -+ if ( REGNO(operands[0]) == REGNO(operands[1])) -+ return "swap.bh\t%0"; -+ else -+ return "mov\t%0, %1\;swap.bh\t%0"; -+ case 1: -+ return "stswp.h\t%0, %1"; -+ case 2: -+ return "ldswp.sh\t%0, %1"; -+ default: -+ abort(); -+ } -+ } -+ -+ "(reload_completed && -+ REG_P(operands[0]) && REG_P(operands[1]) -+ && (REGNO(operands[0]) != REGNO(operands[1])))" -+ [(set (match_dup 0) (match_dup 1)) -+ (set (match_dup 0) -+ (ior:HI (and:HI (lshiftrt:HI (match_dup 0) -+ (const_int 8)) -+ (const_int 255)) -+ (ashift:HI (and:HI (match_dup 0) -+ (const_int 255)) -+ (const_int 8))))] -+ "" -+ -+ [(set_attr "length" "4,4,4") -+ (set_attr "type" "alu,store,load_rm")] -+ ) -+ -+(define_insn_and_split "bswap_32" -+ [ (set (match_operand:SI 0 "avr32_bswap_operand" "=r,RKs14,r") -+ (ior:SI (ior:SI (lshiftrt:SI (and:SI (match_operand:SI 1 "avr32_bswap_operand" "r,r,RKs14") -+ (const_int -16777216)) -+ (const_int 24)) -+ (lshiftrt:SI (and:SI (match_dup 1) -+ (const_int 16711680)) -+ (const_int 8))) -+ (ior:SI (ashift:SI (and:SI (match_dup 1) -+ (const_int 65280)) -+ (const_int 8)) -+ (ashift:SI (and:SI (match_dup 1) -+ (const_int 255)) -+ (const_int 24)))))] -+ "" -+ { -+ switch ( which_alternative ){ -+ case 0: -+ if ( REGNO(operands[0]) == REGNO(operands[1])) -+ return "swap.b\t%0"; -+ else -+ return "#"; -+ case 1: -+ return "stswp.w\t%0, %1"; -+ case 2: -+ return "ldswp.w\t%0, %1"; -+ default: -+ abort(); -+ } -+ } -+ "(reload_completed && -+ REG_P(operands[0]) && REG_P(operands[1]) -+ && (REGNO(operands[0]) != REGNO(operands[1])))" -+ [(set (match_dup 0) (match_dup 1)) -+ (set (match_dup 0) -+ (ior:SI (ior:SI (lshiftrt:SI (and:SI (match_dup 0) -+ (const_int -16777216)) -+ (const_int 24)) -+ (lshiftrt:SI (and:SI (match_dup 0) -+ (const_int 16711680)) -+ (const_int 8))) -+ (ior:SI (ashift:SI (and:SI (match_dup 0) -+ (const_int 65280)) -+ (const_int 8)) -+ (ashift:SI (and:SI (match_dup 0) -+ (const_int 255)) -+ (const_int 24)))))] -+ "" -+ -+ [(set_attr "length" "4,4,4") -+ (set_attr "type" "alu,store,load_rm")] -+ ) -+ -+ -+;;============================================================================= -+;; blockage -+;;----------------------------------------------------------------------------- -+;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and -+;; all of memory. This blocks insns from being moved across this point. -+ -+(define_insn "blockage" -+ [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)] -+ "" -+ "" -+ [(set_attr "length" "0")] -+) -+ -+;;============================================================================= -+;; clzsi2 -+;;----------------------------------------------------------------------------- -+(define_insn "clzsi2" -+ [ (set (match_operand:SI 0 "register_operand" "=r") -+ (clz:SI (match_operand:SI 1 "register_operand" "r"))) ] -+ "" -+ "clz %0, %1" -+ [(set_attr "length" "4") -+ (set_attr "cc" "set_z")] -+ ) -+ -+;;============================================================================= -+;; ctzsi2 -+;;----------------------------------------------------------------------------- -+(define_insn "ctzsi2" -+ [ (set (match_operand:SI 0 "register_operand" "=r,r") -+ (ctz:SI (match_operand:SI 1 "register_operand" "0,r"))) ] -+ "" -+ "@ -+ brev\t%0\;clz\t%0, %0 -+ mov\t%0, %1\;brev\t%0\;clz\t%0, %0" -+ [(set_attr "length" "8") -+ (set_attr "cc" "set_z")] -+ ) -+ -+;;============================================================================= -+;; cache instructions -+;;----------------------------------------------------------------------------- -+(define_insn "cache" -+ [ (unspec_volatile [(match_operand:SI 0 "avr32_ks11_address_operand" "p") -+ (match_operand:SI 1 "immediate_operand" "Ku05")] VUNSPEC_CACHE)] -+ "" -+ "cache %0, %1" -+ [(set_attr "length" "4")] -+ ) -+ -+(define_insn "sync" -+ [ (unspec_volatile [(match_operand:SI 0 "immediate_operand" "Ku08")] VUNSPEC_SYNC)] -+ "" -+ "sync %0" -+ [(set_attr "length" "4")] -+ ) -+ -+;;============================================================================= -+;; TLB instructions -+;;----------------------------------------------------------------------------- -+(define_insn "tlbr" -+ [ (unspec_volatile [(const_int 0)] VUNSPEC_TLBR)] -+ "" -+ "tlbr" -+ [(set_attr "length" "2")] -+ ) -+ -+(define_insn "tlbw" -+ [ (unspec_volatile [(const_int 0)] VUNSPEC_TLBW)] -+ "" -+ "tlbw" -+ [(set_attr "length" "2")] -+ ) -+ -+(define_insn "tlbs" -+ [ (unspec_volatile [(const_int 0)] VUNSPEC_TLBS)] -+ "" -+ "tlbs" -+ [(set_attr "length" "2")] -+ ) -+ -+;;============================================================================= -+;; Breakpoint instruction -+;;----------------------------------------------------------------------------- -+(define_insn "breakpoint" -+ [ (unspec_volatile [(const_int 0)] VUNSPEC_BREAKPOINT)] -+ "" -+ "breakpoint" -+ [(set_attr "length" "2")] -+ ) -+ -+ -+;;============================================================================= -+;; mtsr/mfsr instruction -+;;----------------------------------------------------------------------------- -+(define_insn "mtsr" -+ [ (unspec_volatile [(match_operand 0 "immediate_operand" "i") -+ (match_operand:SI 1 "register_operand" "r")] VUNSPEC_MTSR)] -+ "" -+ "mtsr\t%0, %1" -+ [(set_attr "length" "4")] -+ ) -+ -+(define_insn "mfsr" -+ [ (set (match_operand:SI 0 "register_operand" "=r") -+ (unspec_volatile:SI [(match_operand 1 "immediate_operand" "i")] VUNSPEC_MFSR)) ] -+ "" -+ "mfsr\t%0, %1" -+ [(set_attr "length" "4")] -+ ) -+ -+;;============================================================================= -+;; mtdr/mfdr instruction -+;;----------------------------------------------------------------------------- -+(define_insn "mtdr" -+ [ (unspec_volatile [(match_operand 0 "immediate_operand" "i") -+ (match_operand:SI 1 "register_operand" "r")] VUNSPEC_MTDR)] -+ "" -+ "mtdr\t%0, %1" -+ [(set_attr "length" "4")] -+ ) -+ -+(define_insn "mfdr" -+ [ (set (match_operand:SI 0 "register_operand" "=r") -+ (unspec_volatile:SI [(match_operand 1 "immediate_operand" "i")] VUNSPEC_MFDR)) ] -+ "" -+ "mfdr\t%0, %1" -+ [(set_attr "length" "4")] -+ ) -+ -+;;============================================================================= -+;; musfr -+;;----------------------------------------------------------------------------- -+(define_insn "musfr" -+ [ (unspec_volatile [(match_operand:SI 0 "register_operand" "r")] VUNSPEC_MUSFR)] -+ "" -+ "musfr\t%0" -+ [(set_attr "length" "2") -+ (set_attr "cc" "clobber")] -+ ) -+ -+(define_insn "mustr" -+ [ (set (match_operand:SI 0 "register_operand" "=r") -+ (unspec_volatile:SI [(const_int 0)] VUNSPEC_MUSTR)) ] -+ "" -+ "mustr\t%0" -+ [(set_attr "length" "2")] -+ ) -+ -+(define_insn "ssrf" -+ [ (unspec_volatile [(match_operand:SI 0 "immediate_operand" "Ku05")] VUNSPEC_SSRF)] -+ "" -+ "ssrf %0" -+ [(set_attr "length" "2") -+ (set_attr "cc" "clobber")] -+ ) -+ -+(define_insn "csrf" -+ [ (unspec_volatile [(match_operand:SI 0 "immediate_operand" "Ku05")] VUNSPEC_CSRF)] -+ "" -+ "csrf %0" -+ [(set_attr "length" "2") -+ (set_attr "cc" "clobber")] -+ ) -+ -+;;============================================================================= -+;; Flush Return Stack instruction -+;;----------------------------------------------------------------------------- -+(define_insn "frs" -+ [ (unspec_volatile [(const_int 0)] VUNSPEC_FRS)] -+ "" -+ "frs" -+ [(set_attr "length" "2") -+ (set_attr "cc" "none")] -+ ) -+ -+ -+;;============================================================================= -+;; Saturation Round Scale instruction -+;;----------------------------------------------------------------------------- -+(define_insn "sats" -+ [ (set (match_operand:SI 0 "register_operand" "+r") -+ (unspec:SI [(match_dup 0) -+ (match_operand 1 "immediate_operand" "Ku05") -+ (match_operand 2 "immediate_operand" "Ku05")] -+ UNSPEC_SATS)) ] -+ "TARGET_DSP" -+ "sats\t%0 >> %1, %2" -+ [(set_attr "type" "alu_sat") -+ (set_attr "length" "4")] -+ ) -+ -+(define_insn "satu" -+ [ (set (match_operand:SI 0 "register_operand" "+r") -+ (unspec:SI [(match_dup 0) -+ (match_operand 1 "immediate_operand" "Ku05") -+ (match_operand 2 "immediate_operand" "Ku05")] -+ UNSPEC_SATU)) ] -+ "TARGET_DSP" -+ "satu\t%0 >> %1, %2" -+ [(set_attr "type" "alu_sat") -+ (set_attr "length" "4")] -+ ) -+ -+(define_insn "satrnds" -+ [ (set (match_operand:SI 0 "register_operand" "+r") -+ (unspec:SI [(match_dup 0) -+ (match_operand 1 "immediate_operand" "Ku05") -+ (match_operand 2 "immediate_operand" "Ku05")] -+ UNSPEC_SATRNDS)) ] -+ "TARGET_DSP" -+ "satrnds\t%0 >> %1, %2" -+ [(set_attr "type" "alu_sat") -+ (set_attr "length" "4")] -+ ) -+ -+(define_insn "satrndu" -+ [ (set (match_operand:SI 0 "register_operand" "+r") -+ (unspec:SI [(match_dup 0) -+ (match_operand 1 "immediate_operand" "Ku05") -+ (match_operand 2 "immediate_operand" "Ku05")] -+ UNSPEC_SATRNDU)) ] -+ "TARGET_DSP" -+ "sats\t%0 >> %1, %2" -+ [(set_attr "type" "alu_sat") -+ (set_attr "length" "4")] -+ ) -+ -+(define_insn "sleep" -+ [(unspec_volatile [(const_int 0)] VUNSPEC_SLEEP) -+ (match_operand:SI 0 "const_int_operand" "")] -+ "" -+ "sleep %0" -+ [(set_attr "length" "1") -+ (set_attr "cc" "none") -+ ]) -+ -+(define_expand "delay_cycles" -+ [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")] -+ VUNSPEC_DELAY_CYCLES)] -+ "" -+ " -+ unsigned int cycles = UINTVAL (operands[0]); -+ if (IN_RANGE(cycles,0x10000 ,0xFFFFFFFF)) -+ { -+ unsigned int msb = (cycles & 0xFFFF0000); -+ unsigned int shift = 16; -+ msb = (msb >> shift); -+ unsigned int cycles_used = (msb*0x10000); -+ emit_insn (gen_delay_cycles_2 (gen_int_mode (msb, SImode))); -+ cycles -= cycles_used; -+ } -+ if (IN_RANGE(cycles, 4, 0xFFFF)) -+ { -+ unsigned int loop_count = (cycles/ 4); -+ unsigned int cycles_used = (loop_count*4); -+ emit_insn (gen_delay_cycles_1 (gen_int_mode (loop_count, SImode))); -+ cycles -= cycles_used; -+ } -+ while (cycles >= 3) -+ { -+ emit_insn (gen_nop3 ()); -+ cycles -= 3; -+ } -+ if (cycles == 1 || cycles == 2) -+ { -+ while (cycles--) -+ emit_insn (gen_nop ()); -+ } -+ DONE; -+ ") -+ -+(define_insn "delay_cycles_1" -+[(unspec_volatile [(const_int 0)] VUNSPEC_DELAY_CYCLES_1) -+ (match_operand:SI 0 "immediate_operand" "") -+ (clobber (match_scratch:SI 1 "=&r"))] -+ "" -+ "mov\t%1, %0 -+ 1: sub\t%1, 1 -+ brne\t1b -+ nop" -+) -+ -+(define_insn "delay_cycles_2" -+[(unspec_volatile [(const_int 0)] VUNSPEC_DELAY_CYCLES_2) -+ (match_operand:SI 0 "immediate_operand" "") -+ (clobber (match_scratch:SI 1 "=&r")) -+ (clobber (match_scratch:SI 2 "=&r"))] -+ "" -+ "mov\t%1, %0 -+ 1: mov\t%2, 16383 -+ 2: sub\t%2, 1 -+ brne\t2b -+ nop -+ sub\t%1, 1 -+ brne\t1b -+ nop" -+) -+ -+;; CPU instructions -+ -+;;============================================================================= -+;; nop -+;;----------------------------------------------------------------------------- -+;; No-op instruction. -+;;============================================================================= -+(define_insn "nop" -+ [(unspec_volatile [(const_int 0)] VUNSPEC_NOP)] -+ "" -+ "nop" -+ [(set_attr "length" "1") -+ (set_attr "type" "alu") -+ (set_attr "cc" "none")]) -+ -+;; NOP3 -+(define_insn "nop3" -+ [(unspec_volatile [(const_int 0)] VUNSPEC_NOP3)] -+ "" -+ "rjmp\t2" -+ [(set_attr "length" "3") -+ (set_attr "type" "alu") -+ (set_attr "cc" "none")]) -+ -+;; Special patterns for dealing with the constant pool -+ -+(define_insn "align_4" -+ [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)] -+ "" -+ { -+ assemble_align (32); -+ return ""; -+ } -+ [(set_attr "length" "2")] -+) -+ -+ -+(define_insn "consttable_start" -+ [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_START)] -+ "" -+ { -+ return ".cpool"; -+ } -+ [(set_attr "length" "0")] -+ ) -+ -+(define_insn "consttable_end" -+ [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)] -+ "" -+ { -+ making_const_table = FALSE; -+ return ""; -+ } -+ [(set_attr "length" "0")] -+) -+ -+ -+(define_insn "consttable_4" -+ [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)] -+ "" -+ { -+ making_const_table = TRUE; -+ switch (GET_MODE_CLASS (GET_MODE (operands[0]))) -+ { -+ case MODE_FLOAT: -+ { -+ REAL_VALUE_TYPE r; -+ char real_string[1024]; -+ REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]); -+ real_to_decimal(real_string, &r, 1024, 0, 1); -+ asm_fprintf (asm_out_file, "\t.float\t%s\n", real_string); -+ break; -+ } -+ default: -+ assemble_integer (operands[0], 4, 0, 1); -+ break; -+ } -+ return ""; -+ } -+ [(set_attr "length" "4")] -+) -+ -+(define_insn "consttable_8" -+ [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)] -+ "" -+ { -+ making_const_table = TRUE; -+ switch (GET_MODE_CLASS (GET_MODE (operands[0]))) -+ { -+ case MODE_FLOAT: -+ { -+ REAL_VALUE_TYPE r; -+ char real_string[1024]; -+ REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]); -+ real_to_decimal(real_string, &r, 1024, 0, 1); -+ asm_fprintf (asm_out_file, "\t.double\t%s\n", real_string); -+ break; -+ } -+ default: -+ assemble_integer(operands[0], 8, 0, 1); -+ break; -+ } -+ return ""; -+ } -+ [(set_attr "length" "8")] -+) -+ -+(define_insn "consttable_16" -+ [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)] -+ "" -+ { -+ making_const_table = TRUE; -+ assemble_integer(operands[0], 16, 0, 1); -+ return ""; -+ } -+ [(set_attr "length" "16")] -+) -+ -+;;============================================================================= -+;; coprocessor instructions -+;;----------------------------------------------------------------------------- -+(define_insn "cop" -+ [ (unspec_volatile [(match_operand 0 "immediate_operand" "Ku03") -+ (match_operand 1 "immediate_operand" "Ku04") -+ (match_operand 2 "immediate_operand" "Ku04") -+ (match_operand 3 "immediate_operand" "Ku04") -+ (match_operand 4 "immediate_operand" "Ku07")] VUNSPEC_COP)] -+ "" -+ "cop\tcp%0, cr%1, cr%2, cr%3, %4" -+ [(set_attr "length" "4")] -+ ) -+ -+(define_insn "mvcrsi" -+ [ (set (match_operand:SI 0 "avr32_cop_move_operand" "=r,<,Z") -+ (unspec_volatile:SI [(match_operand 1 "immediate_operand" "Ku03,Ku03,Ku03") -+ (match_operand 2 "immediate_operand" "Ku04,Ku04,Ku04")] -+ VUNSPEC_MVCR)) ] -+ "" -+ "@ -+ mvcr.w\tcp%1, %0, cr%2 -+ stcm.w\tcp%1, %0, cr%2 -+ stc.w\tcp%1, %0, cr%2" -+ [(set_attr "length" "4")] -+ ) -+ -+(define_insn "mvcrdi" -+ [ (set (match_operand:DI 0 "avr32_cop_move_operand" "=r,<,Z") -+ (unspec_volatile:DI [(match_operand 1 "immediate_operand" "Ku03,Ku03,Ku03") -+ (match_operand 2 "immediate_operand" "Ku04,Ku04,Ku04")] -+ VUNSPEC_MVCR)) ] -+ "" -+ "@ -+ mvcr.d\tcp%1, %0, cr%2 -+ stcm.d\tcp%1, %0, cr%2-cr%i2 -+ stc.d\tcp%1, %0, cr%2" -+ [(set_attr "length" "4")] -+ ) -+ -+(define_insn "mvrcsi" -+ [ (unspec_volatile:SI [(match_operand 0 "immediate_operand" "Ku03,Ku03,Ku03") -+ (match_operand 1 "immediate_operand" "Ku04,Ku04,Ku04") -+ (match_operand:SI 2 "avr32_cop_move_operand" "r,>,Z")] -+ VUNSPEC_MVRC)] -+ "" -+ { -+ switch (which_alternative){ -+ case 0: -+ return "mvrc.w\tcp%0, cr%1, %2"; -+ case 1: -+ return "ldcm.w\tcp%0, %2, cr%1"; -+ case 2: -+ return "ldc.w\tcp%0, cr%1, %2"; -+ default: -+ abort(); -+ } -+ } -+ [(set_attr "length" "4")] -+ ) -+ -+(define_insn "mvrcdi" -+ [ (unspec_volatile:DI [(match_operand 0 "immediate_operand" "Ku03,Ku03,Ku03") -+ (match_operand 1 "immediate_operand" "Ku04,Ku04,Ku04") -+ (match_operand:DI 2 "avr32_cop_move_operand" "r,>,Z")] -+ VUNSPEC_MVRC)] -+ "" -+ { -+ switch (which_alternative){ -+ case 0: -+ return "mvrc.d\tcp%0, cr%1, %2"; -+ case 1: -+ return "ldcm.d\tcp%0, %2, cr%1-cr%i1"; -+ case 2: -+ return "ldc.d\tcp%0, cr%1, %2"; -+ default: -+ abort(); -+ } -+ } -+ [(set_attr "length" "4")] -+ ) -+ -+;;============================================================================= -+;; epilogue -+;;----------------------------------------------------------------------------- -+;; This pattern emits RTL for exit from a function. The function exit is -+;; responsible for deallocating the stack frame, restoring callee saved -+;; registers and emitting the return instruction. -+;; ToDo: using TARGET_ASM_FUNCTION_PROLOGUE instead. -+;;============================================================================= -+(define_expand "epilogue" -+ [(unspec_volatile [(return)] VUNSPEC_EPILOGUE)] -+ "" -+ " -+ if (USE_RETURN_INSN (FALSE)){ -+ emit_jump_insn (gen_return ()); -+ DONE; -+ } -+ emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode, -+ gen_rtvec (1, -+ gen_rtx_RETURN (VOIDmode)), -+ VUNSPEC_EPILOGUE)); -+ DONE; -+ " -+ ) -+ -+(define_insn "*epilogue_insns" -+ [(unspec_volatile [(return)] VUNSPEC_EPILOGUE)] -+ "" -+ { -+ avr32_output_return_instruction (FALSE, FALSE, NULL, NULL); -+ return ""; -+ } -+ ; Length is absolute worst case -+ [(set_attr "type" "branch") -+ (set_attr "length" "12")] -+ ) -+ -+(define_insn "*epilogue_insns_ret_imm" -+ [(parallel [(set (reg RETVAL_REGNUM) (match_operand 0 "immediate_operand" "i")) -+ (use (reg RETVAL_REGNUM)) -+ (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])] -+ "((INTVAL(operands[0]) == -1) || (INTVAL(operands[0]) == 0) || (INTVAL(operands[0]) == 1))" -+ { -+ avr32_output_return_instruction (FALSE, FALSE, NULL, operands[0]); -+ return ""; -+ } -+ ; Length is absolute worst case -+ [(set_attr "type" "branch") -+ (set_attr "length" "12")] -+ ) -+ -+(define_insn "sibcall_epilogue" -+ [(unspec_volatile [(const_int 0)] VUNSPEC_EPILOGUE)] -+ "" -+ { -+ avr32_output_return_instruction (FALSE, FALSE, NULL, NULL); -+ return ""; -+ } -+;; Length is absolute worst case -+ [(set_attr "type" "branch") -+ (set_attr "length" "12")] -+ ) -+ -+(define_insn "*sibcall_epilogue_insns_ret_imm" -+ [(parallel [(set (reg RETVAL_REGNUM) (match_operand 0 "immediate_operand" "i")) -+ (use (reg RETVAL_REGNUM)) -+ (unspec_volatile [(const_int 0)] VUNSPEC_EPILOGUE)])] -+ "((INTVAL(operands[0]) == -1) || (INTVAL(operands[0]) == 0) || (INTVAL(operands[0]) == 1))" -+ { -+ avr32_output_return_instruction (FALSE, FALSE, NULL, operands[0]); -+ return ""; -+ } -+ ; Length is absolute worst case -+ [(set_attr "type" "branch") -+ (set_attr "length" "12")] -+ ) -+ -+(define_insn "ldxi" -+ [(set (match_operand:SI 0 "register_operand" "=r") -+ (mem:SI (plus:SI -+ (match_operand:SI 1 "register_operand" "r") -+ (mult:SI (zero_extract:SI (match_operand:SI 2 "register_operand" "r") -+ (const_int 8) -+ (match_operand:SI 3 "immediate_operand" "Ku05")) -+ (const_int 4)))))] -+ "(INTVAL(operands[3]) == 24 || INTVAL(operands[3]) == 16 || INTVAL(operands[3]) == 8 -+ || INTVAL(operands[3]) == 0)" -+ { -+ switch ( INTVAL(operands[3]) ){ -+ case 0: -+ return "ld.w %0, %1[%2:b << 2]"; -+ case 8: -+ return "ld.w %0, %1[%2:l << 2]"; -+ case 16: -+ return "ld.w %0, %1[%2:u << 2]"; -+ case 24: -+ return "ld.w %0, %1[%2:t << 2]"; -+ default: -+ internal_error("illegal operand for ldxi"); -+ } -+ } -+ [(set_attr "type" "load") -+ (set_attr "length" "4") -+ (set_attr "cc" "none")]) -+ -+ -+ -+ -+ -+ -+;;============================================================================= -+;; Peephole optimizing -+;;----------------------------------------------------------------------------- -+;; Changing -+;; sub r8, r7, 8 -+;; st.w r8[0x0], r12 -+;; to -+;; sub r8, r7, 8 -+;; st.w r7[-0x8], r12 -+;;============================================================================= -+; (set (reg:SI 9 r8) -+; (plus:SI (reg/f:SI 6 r7) -+; (const_int ...))) -+; (set (mem:SI (reg:SI 9 r8)) -+; (reg:SI 12 r12)) -+(define_peephole2 -+ [(set (match_operand:SI 0 "register_operand" "") -+ (plus:SI (match_operand:SI 1 "register_operand" "") -+ (match_operand:SI 2 "immediate_operand" ""))) -+ (set (mem:SI (match_dup 0)) -+ (match_operand:SI 3 "register_operand" ""))] -+ "REGNO(operands[0]) != REGNO(operands[1]) && avr32_const_ok_for_constraint_p(INTVAL(operands[2]), 'K', \"Ks16\")" -+ [(set (match_dup 0) -+ (plus:SI (match_dup 1) -+ (match_dup 2))) -+ (set (mem:SI (plus:SI (match_dup 1) -+ (match_dup 2))) -+ (match_dup 3))] -+ "") -+ -+;;============================================================================= -+;; Peephole optimizing -+;;----------------------------------------------------------------------------- -+;; Changing -+;; sub r6, r7, 4 -+;; ld.w r6, r6[0x0] -+;; to -+;; sub r6, r7, 4 -+;; ld.w r6, r7[-0x4] -+;;============================================================================= -+; (set (reg:SI 7 r6) -+; (plus:SI (reg/f:SI 6 r7) -+; (const_int -4 [0xfffffffc]))) -+; (set (reg:SI 7 r6) -+; (mem:SI (reg:SI 7 r6))) -+(define_peephole2 -+ [(set (match_operand:SI 0 "register_operand" "") -+ (plus:SI (match_operand:SI 1 "register_operand" "") -+ (match_operand:SI 2 "immediate_operand" ""))) -+ (set (match_operand:SI 3 "register_operand" "") -+ (mem:SI (match_dup 0)))] -+ "REGNO(operands[0]) != REGNO(operands[1]) && avr32_const_ok_for_constraint_p(INTVAL(operands[2]), 'K', \"Ks16\")" -+ [(set (match_dup 0) -+ (plus:SI (match_dup 1) -+ (match_dup 2))) -+ (set (match_dup 3) -+ (mem:SI (plus:SI (match_dup 1) -+ (match_dup 2))))] -+ "") -+ -+;;============================================================================= -+;; Peephole optimizing -+;;----------------------------------------------------------------------------- -+;; Changing -+;; ld.sb r0, r7[-0x6] -+;; cashs.b r0 -+;; to -+;; ld.sb r0, r7[-0x6] -+;;============================================================================= -+(define_peephole2 -+ [(set (match_operand:QI 0 "register_operand" "") -+ (match_operand:QI 1 "load_sb_memory_operand" "")) -+ (set (match_operand:SI 2 "register_operand" "") -+ (sign_extend:SI (match_dup 0)))] -+ "(REGNO(operands[0]) == REGNO(operands[2]) || peep2_reg_dead_p(2, operands[0]))" -+ [(set (match_dup 2) -+ (sign_extend:SI (match_dup 1)))] -+ "") -+ -+;;============================================================================= -+;; Peephole optimizing -+;;----------------------------------------------------------------------------- -+;; Changing -+;; ld.ub r0, r7[-0x6] -+;; cashu.b r0 -+;; to -+;; ld.ub r0, r7[-0x6] -+;;============================================================================= -+(define_peephole2 -+ [(set (match_operand:QI 0 "register_operand" "") -+ (match_operand:QI 1 "memory_operand" "")) -+ (set (match_operand:SI 2 "register_operand" "") -+ (zero_extend:SI (match_dup 0)))] -+ "(REGNO(operands[0]) == REGNO(operands[2])) || peep2_reg_dead_p(2, operands[0])" -+ [(set (match_dup 2) -+ (zero_extend:SI (match_dup 1)))] -+ "") -+ -+;;============================================================================= -+;; Peephole optimizing -+;;----------------------------------------------------------------------------- -+;; Changing -+;; ld.sh r0, r7[-0x6] -+;; casts.h r0 -+;; to -+;; ld.sh r0, r7[-0x6] -+;;============================================================================= -+(define_peephole2 -+ [(set (match_operand:HI 0 "register_operand" "") -+ (match_operand:HI 1 "memory_operand" "")) -+ (set (match_operand:SI 2 "register_operand" "") -+ (sign_extend:SI (match_dup 0)))] -+ "(REGNO(operands[0]) == REGNO(operands[2])) || peep2_reg_dead_p(2, operands[0])" -+ [(set (match_dup 2) -+ (sign_extend:SI (match_dup 1)))] -+ "") -+ -+;;============================================================================= -+;; Peephole optimizing -+;;----------------------------------------------------------------------------- -+;; Changing -+;; ld.uh r0, r7[-0x6] -+;; castu.h r0 -+;; to -+;; ld.uh r0, r7[-0x6] -+;;============================================================================= -+(define_peephole2 -+ [(set (match_operand:HI 0 "register_operand" "") -+ (match_operand:HI 1 "memory_operand" "")) -+ (set (match_operand:SI 2 "register_operand" "") -+ (zero_extend:SI (match_dup 0)))] -+ "(REGNO(operands[0]) == REGNO(operands[2])) || peep2_reg_dead_p(2, operands[0])" -+ [(set (match_dup 2) -+ (zero_extend:SI (match_dup 1)))] -+ "") -+ -+;;============================================================================= -+;; Peephole optimizing -+;;----------------------------------------------------------------------------- -+;; Changing -+;; mul rd, rx, ry -+;; add rd2, rd -+;; or -+;; add rd2, rd, rd2 -+;; to -+;; mac rd2, rx, ry -+;;============================================================================= -+(define_peephole2 -+ [(set (match_operand:SI 0 "register_operand" "") -+ (mult:SI (match_operand:SI 1 "register_operand" "") -+ (match_operand:SI 2 "register_operand" ""))) -+ (set (match_operand:SI 3 "register_operand" "") -+ (plus:SI (match_dup 3) -+ (match_dup 0)))] -+ "peep2_reg_dead_p(2, operands[0])" -+ [(set (match_dup 3) -+ (plus:SI (mult:SI (match_dup 1) -+ (match_dup 2)) -+ (match_dup 3)))] -+ "") -+ -+(define_peephole2 -+ [(set (match_operand:SI 0 "register_operand" "") -+ (mult:SI (match_operand:SI 1 "register_operand" "") -+ (match_operand:SI 2 "register_operand" ""))) -+ (set (match_operand:SI 3 "register_operand" "") -+ (plus:SI (match_dup 0) -+ (match_dup 3)))] -+ "peep2_reg_dead_p(2, operands[0])" -+ [(set (match_dup 3) -+ (plus:SI (mult:SI (match_dup 1) -+ (match_dup 2)) -+ (match_dup 3)))] -+ "") -+ -+ -+;;============================================================================= -+;; Peephole optimizing -+;;----------------------------------------------------------------------------- -+;; Changing -+;; bfextu rd, rs, k5, 1 or and(h/l) rd, one_bit_set_mask -+;; to -+;; bld rs, k5 -+;; -+;; If rd is dead after the operation. -+;;============================================================================= -+(define_peephole2 -+ [ (set (match_operand:SI 0 "register_operand" "") -+ (zero_extract:SI (match_operand:SI 1 "register_operand" "") -+ (const_int 1) -+ (match_operand:SI 2 "immediate_operand" ""))) -+ (set (cc0) -+ (match_dup 0))] -+ "peep2_reg_dead_p(2, operands[0])" -+ [(set (cc0) -+ (and:SI (match_dup 1) -+ (match_dup 2)))] -+ "operands[2] = GEN_INT(1 << INTVAL(operands[2]));") -+ -+(define_peephole2 -+ [ (set (match_operand:SI 0 "register_operand" "") -+ (and:SI (match_operand:SI 1 "register_operand" "") -+ (match_operand:SI 2 "one_bit_set_operand" ""))) -+ (set (cc0) -+ (match_dup 0))] -+ "peep2_reg_dead_p(2, operands[0])" -+ [(set (cc0) -+ (and:SI (match_dup 1) -+ (match_dup 2)))] -+ "") -+ -+;;============================================================================= -+;; Peephole optimizing -+;;----------------------------------------------------------------------------- -+;; Load with extracted index: ld.w Rd, Rb[Ri:{t/u/b/l} << 2] -+;; -+;;============================================================================= -+ -+ -+(define_peephole -+ [(set (match_operand:SI 0 "register_operand" "") -+ (zero_extract:SI (match_operand:SI 1 "register_operand" "") -+ (const_int 8) -+ (match_operand:SI 2 "avr32_extract_shift_operand" ""))) -+ (set (match_operand:SI 3 "register_operand" "") -+ (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4)) -+ (match_operand:SI 4 "register_operand" ""))))] -+ -+ "(dead_or_set_p(insn, operands[0]))" -+ { -+ switch ( INTVAL(operands[2]) ){ -+ case 0: -+ return "ld.w %3, %4[%1:b << 2]"; -+ case 8: -+ return "ld.w %3, %4[%1:l << 2]"; -+ case 16: -+ return "ld.w %3, %4[%1:u << 2]"; -+ case 24: -+ return "ld.w %3, %4[%1:t << 2]"; -+ default: -+ internal_error("illegal operand for ldxi"); -+ } -+ } -+ [(set_attr "type" "load") -+ (set_attr "length" "4") -+ (set_attr "cc" "clobber")] -+ ) -+ -+ -+ -+(define_peephole -+ [(set (match_operand:SI 0 "register_operand" "") -+ (and:SI (match_operand:SI 1 "register_operand" "") (const_int 255))) -+ (set (match_operand:SI 2 "register_operand" "") -+ (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4)) -+ (match_operand:SI 3 "register_operand" ""))))] -+ -+ "(dead_or_set_p(insn, operands[0]))" -+ -+ "ld.w %2, %3[%1:b << 2]" -+ [(set_attr "type" "load") -+ (set_attr "length" "4") -+ (set_attr "cc" "clobber")] -+ ) -+ -+ -+(define_peephole2 -+ [(set (match_operand:SI 0 "register_operand" "") -+ (zero_extract:SI (match_operand:SI 1 "register_operand" "") -+ (const_int 8) -+ (match_operand:SI 2 "avr32_extract_shift_operand" ""))) -+ (set (match_operand:SI 3 "register_operand" "") -+ (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4)) -+ (match_operand:SI 4 "register_operand" ""))))] -+ -+ "(peep2_reg_dead_p(2, operands[0])) -+ || (REGNO(operands[0]) == REGNO(operands[3]))" -+ [(set (match_dup 3) -+ (mem:SI (plus:SI -+ (match_dup 4) -+ (mult:SI (zero_extract:SI (match_dup 1) -+ (const_int 8) -+ (match_dup 2)) -+ (const_int 4)))))] -+ ) -+ -+(define_peephole2 -+ [(set (match_operand:SI 0 "register_operand" "") -+ (zero_extend:SI (match_operand:QI 1 "register_operand" ""))) -+ (set (match_operand:SI 2 "register_operand" "") -+ (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4)) -+ (match_operand:SI 3 "register_operand" ""))))] -+ -+ "(peep2_reg_dead_p(2, operands[0])) -+ || (REGNO(operands[0]) == REGNO(operands[2]))" -+ [(set (match_dup 2) -+ (mem:SI (plus:SI -+ (match_dup 3) -+ (mult:SI (zero_extract:SI (match_dup 1) -+ (const_int 8) -+ (const_int 0)) -+ (const_int 4)))))] -+ "operands[1] = gen_rtx_REG(SImode, REGNO(operands[1]));" -+ ) -+ -+ -+(define_peephole2 -+ [(set (match_operand:SI 0 "register_operand" "") -+ (and:SI (match_operand:SI 1 "register_operand" "") -+ (const_int 255))) -+ (set (match_operand:SI 2 "register_operand" "") -+ (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4)) -+ (match_operand:SI 3 "register_operand" ""))))] -+ -+ "(peep2_reg_dead_p(2, operands[0])) -+ || (REGNO(operands[0]) == REGNO(operands[2]))" -+ [(set (match_dup 2) -+ (mem:SI (plus:SI -+ (match_dup 3) -+ (mult:SI (zero_extract:SI (match_dup 1) -+ (const_int 8) -+ (const_int 0)) -+ (const_int 4)))))] -+ "" -+ ) -+ -+ -+ -+(define_peephole2 -+ [(set (match_operand:SI 0 "register_operand" "") -+ (lshiftrt:SI (match_operand:SI 1 "register_operand" "") -+ (const_int 24))) -+ (set (match_operand:SI 2 "register_operand" "") -+ (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4)) -+ (match_operand:SI 3 "register_operand" ""))))] -+ -+ "(peep2_reg_dead_p(2, operands[0])) -+ || (REGNO(operands[0]) == REGNO(operands[2]))" -+ [(set (match_dup 2) -+ (mem:SI (plus:SI -+ (match_dup 3) -+ (mult:SI (zero_extract:SI (match_dup 1) -+ (const_int 8) -+ (const_int 24)) -+ (const_int 4)))))] -+ "" -+ ) -+ -+ -+;;************************************************ -+;; ANDN -+;; -+;;************************************************ -+ -+ -+(define_peephole2 -+ [(set (match_operand:SI 0 "register_operand" "") -+ (not:SI (match_operand:SI 1 "register_operand" ""))) -+ (set (match_operand:SI 2 "register_operand" "") -+ (and:SI (match_dup 2) -+ (match_dup 0)))] -+ "peep2_reg_dead_p(2, operands[0])" -+ -+ [(set (match_dup 2) -+ (and:SI (match_dup 2) -+ (not:SI (match_dup 1)) -+ ))] -+ "" -+) -+ -+(define_peephole2 -+ [(set (match_operand:SI 0 "register_operand" "") -+ (not:SI (match_operand:SI 1 "register_operand" ""))) -+ (set (match_operand:SI 2 "register_operand" "") -+ (and:SI (match_dup 0) -+ (match_dup 2) -+ ))] -+ "peep2_reg_dead_p(2, operands[0])" -+ -+ [(set (match_dup 2) -+ (and:SI (match_dup 2) -+ (not:SI (match_dup 1)) -+ ))] -+ -+ "" -+) -+ -+ -+;;================================================================= -+;; Addabs peephole -+;;================================================================= -+ -+(define_peephole -+ [(set (match_operand:SI 2 "register_operand" "=r") -+ (abs:SI (match_operand:SI 1 "register_operand" "r"))) -+ (set (match_operand:SI 0 "register_operand" "=r") -+ (plus:SI (match_operand:SI 3 "register_operand" "r") -+ (match_dup 2)))] -+ "dead_or_set_p(insn, operands[2])" -+ "addabs %0, %3, %1" -+ [(set_attr "length" "4") -+ (set_attr "cc" "set_z")]) -+ -+(define_peephole -+ [(set (match_operand:SI 2 "register_operand" "=r") -+ (abs:SI (match_operand:SI 1 "register_operand" "r"))) -+ (set (match_operand:SI 0 "register_operand" "=r") -+ (plus:SI (match_dup 2) -+ (match_operand:SI 3 "register_operand" "r")))] -+ "dead_or_set_p(insn, operands[2])" -+ "addabs %0, %3, %1" -+ [(set_attr "length" "4") -+ (set_attr "cc" "set_z")]) -+ -+ -+;;================================================================= -+;; Detect roundings -+;;================================================================= -+ -+(define_insn "*round" -+ [(set (match_operand:SI 0 "register_operand" "+r") -+ (ashiftrt:SI (plus:SI (match_dup 0) -+ (match_operand:SI 1 "immediate_operand" "i")) -+ (match_operand:SI 2 "immediate_operand" "i")))] -+ "avr32_rnd_operands(operands[1], operands[2])" -+ -+ "satrnds %0 >> %2, 31" -+ -+ [(set_attr "type" "alu_sat") -+ (set_attr "length" "4")] -+ -+ ) -+ -+ -+(define_peephole2 -+ [(set (match_operand:SI 0 "register_operand" "") -+ (plus:SI (match_dup 0) -+ (match_operand:SI 1 "immediate_operand" ""))) -+ (set (match_dup 0) -+ (ashiftrt:SI (match_dup 0) -+ (match_operand:SI 2 "immediate_operand" "")))] -+ "avr32_rnd_operands(operands[1], operands[2])" -+ -+ [(set (match_dup 0) -+ (ashiftrt:SI (plus:SI (match_dup 0) -+ (match_dup 1)) -+ (match_dup 2)))] -+ ) -+ -+(define_peephole -+ [(set (match_operand:SI 0 "register_operand" "r") -+ (plus:SI (match_dup 0) -+ (match_operand:SI 1 "immediate_operand" "i"))) -+ (set (match_dup 0) -+ (ashiftrt:SI (match_dup 0) -+ (match_operand:SI 2 "immediate_operand" "i")))] -+ "avr32_rnd_operands(operands[1], operands[2])" -+ -+ "satrnds %0 >> %2, 31" -+ -+ [(set_attr "type" "alu_sat") -+ (set_attr "length" "4") -+ (set_attr "cc" "clobber")] -+ -+ ) -+ -+ -+;;================================================================= -+;; mcall -+;;================================================================= -+(define_peephole -+ [(set (match_operand:SI 0 "register_operand" "") -+ (match_operand 1 "avr32_const_pool_ref_operand" "")) -+ (parallel [(call (mem:SI (match_dup 0)) -+ (match_operand 2 "" "")) -+ (clobber (reg:SI LR_REGNUM))])] -+ "dead_or_set_p(insn, operands[0])" -+ "mcall %1" -+ [(set_attr "type" "call") -+ (set_attr "length" "4") -+ (set_attr "cc" "clobber")] -+) -+ -+(define_peephole -+ [(set (match_operand:SI 2 "register_operand" "") -+ (match_operand 1 "avr32_const_pool_ref_operand" "")) -+ (parallel [(set (match_operand 0 "register_operand" "") -+ (call (mem:SI (match_dup 2)) -+ (match_operand 3 "" ""))) -+ (clobber (reg:SI LR_REGNUM))])] -+ "dead_or_set_p(insn, operands[2])" -+ "mcall %1" -+ [(set_attr "type" "call") -+ (set_attr "length" "4") -+ (set_attr "cc" "call_set")] -+) -+ -+ -+(define_peephole2 -+ [(set (match_operand:SI 0 "register_operand" "") -+ (match_operand 1 "avr32_const_pool_ref_operand" "")) -+ (parallel [(call (mem:SI (match_dup 0)) -+ (match_operand 2 "" "")) -+ (clobber (reg:SI LR_REGNUM))])] -+ "peep2_reg_dead_p(2, operands[0])" -+ [(parallel [(call (mem:SI (match_dup 1)) -+ (match_dup 2)) -+ (clobber (reg:SI LR_REGNUM))])] -+ "" -+) -+ -+(define_peephole2 -+ [(set (match_operand:SI 0 "register_operand" "") -+ (match_operand 1 "avr32_const_pool_ref_operand" "")) -+ (parallel [(set (match_operand 2 "register_operand" "") -+ (call (mem:SI (match_dup 0)) -+ (match_operand 3 "" ""))) -+ (clobber (reg:SI LR_REGNUM))])] -+ "(peep2_reg_dead_p(2, operands[0]) || (REGNO(operands[2]) == REGNO(operands[0])))" -+ [(parallel [(set (match_dup 2) -+ (call (mem:SI (match_dup 1)) -+ (match_dup 3))) -+ (clobber (reg:SI LR_REGNUM))])] -+ "" -+) -+ -+;;================================================================= -+;; Returning a value -+;;================================================================= -+ -+ -+(define_peephole -+ [(set (match_operand 0 "register_operand" "") -+ (match_operand 1 "register_operand" "")) -+ (return)] -+ "USE_RETURN_INSN (TRUE) && (REGNO(operands[0]) == RETVAL_REGNUM) -+ && (REGNO(operands[1]) != LR_REGNUM) -+ && (REGNO_REG_CLASS(REGNO(operands[1])) == GENERAL_REGS)" -+ "retal %1" -+ [(set_attr "type" "call") -+ (set_attr "length" "2")] -+ ) -+ -+ -+(define_peephole -+ [(set (match_operand 0 "register_operand" "r") -+ (match_operand 1 "immediate_operand" "i")) -+ (return)] -+ "(USE_RETURN_INSN (FALSE) && (REGNO(operands[0]) == RETVAL_REGNUM) && -+ ((INTVAL(operands[1]) == -1) || (INTVAL(operands[1]) == 0) || (INTVAL(operands[1]) == 1)))" -+ { -+ avr32_output_return_instruction (TRUE, FALSE, NULL, operands[1]); -+ return ""; -+ } -+ [(set_attr "type" "call") -+ (set_attr "length" "4")] -+ ) -+ -+(define_peephole -+ [(set (match_operand 0 "register_operand" "r") -+ (match_operand 1 "immediate_operand" "i")) -+ (unspec_volatile [(return)] VUNSPEC_EPILOGUE)] -+ "(REGNO(operands[0]) == RETVAL_REGNUM) && -+ ((INTVAL(operands[1]) == -1) || (INTVAL(operands[1]) == 0) || (INTVAL(operands[1]) == 1))" -+ { -+ avr32_output_return_instruction (FALSE, FALSE, NULL, operands[1]); -+ return ""; -+ } -+ ; Length is absolute worst case -+ [(set_attr "type" "branch") -+ (set_attr "length" "12")] -+ ) -+ -+(define_peephole -+ [(set (match_operand 0 "register_operand" "=r") -+ (if_then_else (match_operator 1 "avr32_comparison_operator" -+ [(match_operand 4 "register_operand" "r") -+ (match_operand 5 "register_immediate_operand" "rKs21")]) -+ (match_operand 2 "avr32_cond_register_immediate_operand" "rKs08") -+ (match_operand 3 "avr32_cond_register_immediate_operand" "rKs08"))) -+ (return)] -+ "USE_RETURN_INSN (TRUE) && (REGNO(operands[0]) == RETVAL_REGNUM)" -+ { -+ operands[1] = avr32_output_cmp(operands[1], GET_MODE(operands[4]), operands[4], operands[5]); -+ -+ if ( GET_CODE(operands[2]) == REG -+ && GET_CODE(operands[3]) == REG -+ && REGNO(operands[2]) != LR_REGNUM -+ && REGNO(operands[3]) != LR_REGNUM ){ -+ return "ret%1 %2\;ret%i1 %3"; -+ } else if ( GET_CODE(operands[2]) == REG -+ && GET_CODE(operands[3]) == CONST_INT ){ -+ if ( INTVAL(operands[3]) == -1 -+ || INTVAL(operands[3]) == 0 -+ || INTVAL(operands[3]) == 1 ){ -+ return "ret%1 %2\;ret%i1 %d3"; -+ } else { -+ return "mov%1 r12, %2\;mov%i1 r12, %3\;retal r12"; -+ } -+ } else if ( GET_CODE(operands[2]) == CONST_INT -+ && GET_CODE(operands[3]) == REG ){ -+ if ( INTVAL(operands[2]) == -1 -+ || INTVAL(operands[2]) == 0 -+ || INTVAL(operands[2]) == 1 ){ -+ return "ret%1 %d2\;ret%i1 %3"; -+ } else { -+ return "mov%1 r12, %2\;mov%i1 r12, %3\;retal r12"; -+ } -+ } else { -+ if ( (INTVAL(operands[2]) == -1 -+ || INTVAL(operands[2]) == 0 -+ || INTVAL(operands[2]) == 1 ) -+ && (INTVAL(operands[3]) == -1 -+ || INTVAL(operands[3]) == 0 -+ || INTVAL(operands[3]) == 1 )){ -+ return "ret%1 %d2\;ret%i1 %d3"; -+ } else { -+ return "mov%1 r12, %2\;mov%i1 r12, %3\;retal r12"; -+ } -+ } -+ } -+ -+ [(set_attr "length" "10") -+ (set_attr "cc" "none") -+ (set_attr "type" "call")]) -+ -+ -+ -+;;================================================================= -+;; mulnhh.w -+;;================================================================= -+ -+(define_peephole2 -+ [(set (match_operand:HI 0 "register_operand" "") -+ (neg:HI (match_operand:HI 1 "register_operand" ""))) -+ (set (match_operand:SI 2 "register_operand" "") -+ (mult:SI -+ (sign_extend:SI (match_dup 0)) -+ (sign_extend:SI (match_operand:HI 3 "register_operand" ""))))] -+ "(peep2_reg_dead_p(2, operands[0])) || (REGNO(operands[2]) == REGNO(operands[0]))" -+ [ (set (match_dup 2) -+ (mult:SI -+ (sign_extend:SI (neg:HI (match_dup 1))) -+ (sign_extend:SI (match_dup 3))))] -+ "" -+ ) -+ -+(define_peephole2 -+ [(set (match_operand:HI 0 "register_operand" "") -+ (neg:HI (match_operand:HI 1 "register_operand" ""))) -+ (set (match_operand:SI 2 "register_operand" "") -+ (mult:SI -+ (sign_extend:SI (match_operand:HI 3 "register_operand" "")) -+ (sign_extend:SI (match_dup 0))))] -+ "(peep2_reg_dead_p(2, operands[0])) || (REGNO(operands[2]) == REGNO(operands[0]))" -+ [ (set (match_dup 2) -+ (mult:SI -+ (sign_extend:SI (neg:HI (match_dup 1))) -+ (sign_extend:SI (match_dup 3))))] -+ "" -+ ) -+ -+ -+ -+;;================================================================= -+;; Vector set and extract operations -+;;================================================================= -+(define_insn "vec_setv2hi_hi" -+ [(set (match_operand:V2HI 0 "register_operand" "=r") -+ (vec_merge:V2HI -+ (match_dup 0) -+ (vec_duplicate:V2HI -+ (match_operand:HI 1 "register_operand" "r")) -+ (const_int 1)))] -+ "" -+ "bfins\t%0, %1, 16, 16" -+ [(set_attr "type" "alu") -+ (set_attr "length" "4") -+ (set_attr "cc" "clobber")]) -+ -+(define_insn "vec_setv2hi_lo" -+ [(set (match_operand:V2HI 0 "register_operand" "+r") -+ (vec_merge:V2HI -+ (match_dup 0) -+ (vec_duplicate:V2HI -+ (match_operand:HI 1 "register_operand" "r")) -+ (const_int 2)))] -+ "" -+ "bfins\t%0, %1, 0, 16" -+ [(set_attr "type" "alu") -+ (set_attr "length" "4") -+ (set_attr "cc" "clobber")]) -+ -+(define_expand "vec_setv2hi" -+ [(set (match_operand:V2HI 0 "register_operand" "") -+ (vec_merge:V2HI -+ (match_dup 0) -+ (vec_duplicate:V2HI -+ (match_operand:HI 1 "register_operand" "")) -+ (match_operand 2 "immediate_operand" "")))] -+ "" -+ { operands[2] = GEN_INT(INTVAL(operands[2]) + 1); } -+ ) -+ -+(define_insn "vec_extractv2hi" -+ [(set (match_operand:HI 0 "register_operand" "=r") -+ (vec_select:HI -+ (match_operand:V2HI 1 "register_operand" "r") -+ (parallel [(match_operand:SI 2 "immediate_operand" "i")])))] -+ "" -+ { -+ if ( INTVAL(operands[2]) == 0 ) -+ return "bfextu\t%0, %1, 16, 16"; -+ else -+ return "bfextu\t%0, %1, 0, 16"; -+ } -+ [(set_attr "type" "alu") -+ (set_attr "length" "4") -+ (set_attr "cc" "clobber")]) -+ -+(define_insn "vec_extractv4qi" -+ [(set (match_operand:QI 0 "register_operand" "=r") -+ (vec_select:QI -+ (match_operand:V4QI 1 "register_operand" "r") -+ (parallel [(match_operand:SI 2 "immediate_operand" "i")])))] -+ "" -+ { -+ switch ( INTVAL(operands[2]) ){ -+ case 0: -+ return "bfextu\t%0, %1, 24, 8"; -+ case 1: -+ return "bfextu\t%0, %1, 16, 8"; -+ case 2: -+ return "bfextu\t%0, %1, 8, 8"; -+ case 3: -+ return "bfextu\t%0, %1, 0, 8"; -+ default: -+ abort(); -+ } -+ } -+ [(set_attr "type" "alu") -+ (set_attr "length" "4") -+ (set_attr "cc" "clobber")]) -+ -+ -+(define_insn "concatv2hi" -+ [(set (match_operand:V2HI 0 "register_operand" "=r, r, r") -+ (vec_concat:V2HI -+ (match_operand:HI 1 "register_operand" "r, r, 0") -+ (match_operand:HI 2 "register_operand" "r, 0, r")))] -+ "" -+ "@ -+ mov\t%0, %1\;bfins\t%0, %2, 0, 16 -+ bfins\t%0, %2, 0, 16 -+ bfins\t%0, %1, 16, 16" -+ [(set_attr "length" "6, 4, 4") -+ (set_attr "type" "alu")]) -+ -+ -+;; Load the atomic operation description -+(include "sync.md") -+ -+;; Load the SIMD description -+(include "simd.md") -+ -+;; Include the FPU for uc3 -+(include "uc3fpu.md") ---- /dev/null -+++ b/gcc/config/avr32/avr32-modes.def -@@ -0,0 +1 @@ -+VECTOR_MODES (INT, 4); /* V4QI V2HI */ ---- /dev/null -+++ b/gcc/config/avr32/avr32.opt -@@ -0,0 +1,89 @@ -+; Options for the ATMEL AVR32 port of the compiler. -+ -+; Copyright 2007 Atmel Corporation. -+; -+; 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. -+ -+muse-rodata-section -+Target Report Mask(USE_RODATA_SECTION) -+Use section .rodata for read-only data instead of .text. -+ -+mhard-float -+Target Report Mask(HARD_FLOAT) -+Use FPU instructions instead of floating point emulation. -+ -+msoft-float -+Target Report InverseMask(HARD_FLOAT, SOFT_FLOAT) -+Use floating point emulation for floating point operations. -+ -+mforce-double-align -+Target Report RejectNegative Mask(FORCE_DOUBLE_ALIGN) -+Force double-word alignment for double-word memory accesses. -+ -+mno-init-got -+Target Report RejectNegative Mask(NO_INIT_GOT) -+Do not initialize GOT register before using it when compiling PIC code. -+ -+mrelax -+Target Report Mask(RELAX) -+Let invoked assembler and linker do relaxing (Enabled by default when optimization level is >1). -+ -+mmd-reorg-opt -+Target Report Undocumented Mask(MD_REORG_OPTIMIZATION) -+Perform machine dependent optimizations in reorg stage. -+ -+masm-addr-pseudos -+Target Report Mask(HAS_ASM_ADDR_PSEUDOS) -+Use assembler pseudo-instructions lda.w and call for handling direct addresses. (Enabled by default) -+ -+mpart= -+Target Report RejectNegative Joined Var(avr32_part_name) -+Specify the AVR32 part name -+ -+mcpu= -+Target Report RejectNegative Joined Undocumented Var(avr32_part_name) -+Specify the AVR32 part name (deprecated) -+ -+march= -+Target Report RejectNegative Joined Var(avr32_arch_name) -+Specify the AVR32 architecture name -+ -+mfast-float -+Target Report Mask(FAST_FLOAT) -+Enable fast floating-point library. Enabled by default if the -funsafe-math-optimizations switch is specified. -+ -+mimm-in-const-pool -+Target Report Var(avr32_imm_in_const_pool) Init(-1) -+Put large immediates in constant pool. This is enabled by default for archs with insn-cache. -+ -+mno-pic -+Target Report RejectNegative Mask(NO_PIC) -+Do not generate position-independent code. (deprecated, use -fno-pic instead) -+ -+mcond-exec-before-reload -+Target Report Undocumented Mask(COND_EXEC_BEFORE_RELOAD) -+Enable experimental conditional execution preparation before the reload stage. -+ -+mrmw-addressable-data -+Target Report Mask(RMW_ADDRESSABLE_DATA) -+Signal that all data is in range for the Atomic Read-Modify-Write memory instructions, and that -+gcc can safely generate these whenever possible. -+ -+mflashvault -+Target Var(TARGET_FLASHVAULT) -+Generate code for flashvault ---- /dev/null -+++ b/gcc/config/avr32/avr32-protos.h -@@ -0,0 +1,196 @@ -+/* -+ Prototypes for exported functions defined in avr32.c -+ Copyright 2003,2004,2005,2006,2007,2008,2009 Atmel Corporation. -+ -+ This file is part of GCC. -+ -+ 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 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 this program; if not, write to the Free Software -+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -+ -+ -+#ifndef AVR32_PROTOS_H -+#define AVR32_PROTOS_H -+ -+extern const int swap_reg[]; -+ -+extern int avr32_valid_macmac_bypass (rtx, rtx); -+extern int avr32_valid_mulmac_bypass (rtx, rtx); -+ -+extern int avr32_decode_lcomm_symbol_offset (rtx, int *); -+extern void avr32_encode_lcomm_symbol_offset (tree, char *, int); -+ -+extern const char *avr32_strip_name_encoding (const char *); -+ -+extern rtx avr32_get_note_reg_equiv (rtx insn); -+ -+extern int avr32_use_return_insn (int iscond); -+ -+extern void avr32_make_reglist16 (int reglist16_vect, char *reglist16_string); -+ -+extern void avr32_make_reglist8 (int reglist8_vect, char *reglist8_string); -+extern void avr32_make_fp_reglist_w (int reglist_mask, char *reglist_string); -+extern void avr32_make_fp_reglist_d (int reglist_mask, char *reglist_string); -+ -+extern void avr32_output_return_instruction (int single_ret_inst, -+ int iscond, rtx cond, -+ rtx r12_imm); -+extern void avr32_expand_prologue (void); -+extern void avr32_set_return_address (rtx source, rtx scratch); -+ -+extern int avr32_hard_regno_mode_ok (int regno, enum machine_mode mode); -+extern int avr32_extra_constraint_s (rtx value, const int strict); -+extern int avr32_eh_return_data_regno (const int n); -+extern int avr32_initial_elimination_offset (const int from, const int to); -+extern rtx avr32_function_arg (CUMULATIVE_ARGS * cum, enum machine_mode mode, -+ tree type, int named); -+extern void avr32_init_cumulative_args (CUMULATIVE_ARGS * cum, tree fntype, -+ rtx libname, tree fndecl); -+extern void avr32_function_arg_advance (CUMULATIVE_ARGS * cum, -+ enum machine_mode mode, -+ tree type, int named); -+#ifdef ARGS_SIZE_RTX -+/* expr.h defines ARGS_SIZE_RTX and `enum direction'. */ -+extern enum direction avr32_function_arg_padding (enum machine_mode mode, -+ tree type); -+#endif /* ARGS_SIZE_RTX */ -+extern rtx avr32_function_value (tree valtype, tree func, bool outgoing); -+extern rtx avr32_libcall_value (enum machine_mode mode); -+extern int avr32_sched_use_dfa_pipeline_interface (void); -+extern bool avr32_return_in_memory (tree type, tree fntype); -+extern void avr32_regs_to_save (char *operand); -+extern void avr32_target_asm_function_prologue (FILE * file, -+ HOST_WIDE_INT size); -+extern void avr32_target_asm_function_epilogue (FILE * file, -+ HOST_WIDE_INT size); -+extern void avr32_trampoline_template (FILE * file); -+extern void avr32_initialize_trampoline (rtx addr, rtx fnaddr, -+ rtx static_chain); -+extern int avr32_legitimate_address (enum machine_mode mode, rtx x, -+ int strict); -+extern int avr32_legitimate_constant_p (rtx x); -+ -+extern int avr32_legitimate_pic_operand_p (rtx x); -+ -+extern rtx avr32_find_symbol (rtx x); -+extern void avr32_select_section (rtx exp, int reloc, int align); -+extern void avr32_encode_section_info (tree decl, rtx rtl, int first); -+extern void avr32_asm_file_end (FILE * stream); -+extern void avr32_asm_output_ascii (FILE * stream, char *ptr, int len); -+extern void avr32_asm_output_common (FILE * stream, const char *name, -+ int size, int rounded); -+extern void avr32_asm_output_label (FILE * stream, const char *name); -+extern void avr32_asm_declare_object_name (FILE * stream, char *name, -+ tree decl); -+extern void avr32_asm_globalize_label (FILE * stream, const char *name); -+extern void avr32_asm_weaken_label (FILE * stream, const char *name); -+extern void avr32_asm_output_external (FILE * stream, tree decl, -+ const char *name); -+extern void avr32_asm_output_external_libcall (FILE * stream, rtx symref); -+extern void avr32_asm_output_labelref (FILE * stream, const char *name); -+extern void avr32_notice_update_cc (rtx exp, rtx insn); -+extern void avr32_print_operand (FILE * stream, rtx x, int code); -+extern void avr32_print_operand_address (FILE * stream, rtx x); -+ -+extern int avr32_symbol (rtx x); -+ -+extern void avr32_select_rtx_section (enum machine_mode mode, rtx x, -+ unsigned HOST_WIDE_INT align); -+ -+extern int avr32_load_multiple_operation (rtx op, enum machine_mode mode); -+extern int avr32_store_multiple_operation (rtx op, enum machine_mode mode); -+ -+extern int avr32_const_ok_for_constraint_p (HOST_WIDE_INT value, char c, -+ const char *str); -+ -+extern bool avr32_cannot_force_const_mem (rtx x); -+ -+extern void avr32_init_builtins (void); -+ -+extern rtx avr32_expand_builtin (tree exp, rtx target, rtx subtarget, -+ enum machine_mode mode, int ignore); -+ -+extern bool avr32_must_pass_in_stack (enum machine_mode mode, tree type); -+ -+extern bool avr32_strict_argument_naming (CUMULATIVE_ARGS * ca); -+ -+extern bool avr32_pass_by_reference (CUMULATIVE_ARGS * cum, -+ enum machine_mode mode, -+ tree type, bool named); -+ -+extern rtx avr32_gen_load_multiple (rtx * regs, int count, rtx from, -+ int write_back, int in_struct_p, -+ int scalar_p); -+extern rtx avr32_gen_store_multiple (rtx * regs, int count, rtx to, -+ int in_struct_p, int scalar_p); -+extern int avr32_gen_movmemsi (rtx * operands); -+ -+extern int avr32_rnd_operands (rtx add, rtx shift); -+extern int avr32_adjust_insn_length (rtx insn, int length); -+ -+extern int symbol_mentioned_p (rtx x); -+extern int label_mentioned_p (rtx x); -+extern rtx legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg); -+extern int avr32_address_register_rtx_p (rtx x, int strict_p); -+extern int avr32_legitimate_index_p (enum machine_mode mode, rtx index, -+ int strict_p); -+ -+extern int avr32_const_double_immediate (rtx value); -+extern void avr32_init_expanders (void); -+extern rtx avr32_return_addr (int count, rtx frame); -+extern bool avr32_got_mentioned_p (rtx addr); -+ -+extern void avr32_final_prescan_insn (rtx insn, rtx * opvec, int noperands); -+ -+extern int avr32_expand_movcc (enum machine_mode mode, rtx operands[]); -+extern int avr32_expand_addcc (enum machine_mode mode, rtx operands[]); -+#ifdef RTX_CODE -+extern int avr32_expand_scc (RTX_CODE cond, rtx * operands); -+#endif -+ -+extern int avr32_store_bypass (rtx insn_out, rtx insn_in); -+extern int avr32_mul_waw_bypass (rtx insn_out, rtx insn_in); -+extern int avr32_valid_load_double_bypass (rtx insn_out, rtx insn_in); -+extern int avr32_valid_load_quad_bypass (rtx insn_out, rtx insn_in); -+extern rtx avr32_output_cmp (rtx cond, enum machine_mode mode, -+ rtx op0, rtx op1); -+ -+rtx get_next_insn_cond (rtx cur_insn); -+int set_next_insn_cond (rtx cur_insn, rtx cond); -+rtx next_insn_emits_cmp (rtx cur_insn); -+void avr32_override_options (void); -+void avr32_load_pic_register (void); -+#ifdef GCC_BASIC_BLOCK_H -+rtx avr32_ifcvt_modify_insn (ce_if_block_t *ce_info, rtx pattern, rtx insn, -+ int *num_true_changes); -+rtx avr32_ifcvt_modify_test (ce_if_block_t *ce_info, rtx test ); -+void avr32_ifcvt_modify_cancel ( ce_if_block_t *ce_info, int *num_true_changes); -+#endif -+void avr32_optimization_options (int level, int size); -+int avr32_const_ok_for_move (HOST_WIDE_INT c); -+ -+void avr32_split_const_expr (enum machine_mode mode, -+ enum machine_mode new_mode, -+ rtx expr, -+ rtx *split_expr); -+void avr32_get_intval (enum machine_mode mode, -+ rtx const_expr, -+ HOST_WIDE_INT *val); -+ -+int avr32_cond_imm_clobber_splittable (rtx insn, -+ rtx operands[]); -+ -+bool avr32_flashvault_call(tree decl); -+extern void avr32_emit_swdivsf (rtx, rtx, rtx); -+ -+#endif /* AVR32_PROTOS_H */ ---- /dev/null -+++ b/gcc/config/avr32/crti.asm -@@ -0,0 +1,64 @@ -+/* -+ Init/fini stuff for AVR32. -+ Copyright 2003-2006 Atmel Corporation. -+ -+ Written by Ronny Pedersen, Atmel Norway, -+ -+ This file is part of GCC. -+ -+ 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 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 this program; if not, write to the Free Software -+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -+ -+ -+/* The code in sections .init and .fini is supposed to be a single -+ regular function. The function in .init is called directly from -+ start in crt1.asm. The function in .fini is atexit()ed in crt1.asm -+ too. -+ -+ crti.asm contributes the prologue of a function to these sections, -+ and crtn.asm comes up the epilogue. STARTFILE_SPEC should list -+ crti.o before any other object files that might add code to .init -+ or .fini sections, and ENDFILE_SPEC should list crtn.o after any -+ such object files. */ -+ -+ .file "crti.asm" -+ -+ .section ".init" -+/* Just load the GOT */ -+ .align 2 -+ .global _init -+_init: -+ stm --sp, r6, lr -+ lddpc r6, 1f -+0: -+ rsub r6, pc -+ rjmp 2f -+ .align 2 -+1: .long 0b - _GLOBAL_OFFSET_TABLE_ -+2: -+ -+ .section ".fini" -+/* Just load the GOT */ -+ .align 2 -+ .global _fini -+_fini: -+ stm --sp, r6, lr -+ lddpc r6, 1f -+0: -+ rsub r6, pc -+ rjmp 2f -+ .align 2 -+1: .long 0b - _GLOBAL_OFFSET_TABLE_ -+2: -+ ---- /dev/null -+++ b/gcc/config/avr32/crtn.asm -@@ -0,0 +1,44 @@ -+/* Copyright (C) 2001 Free Software Foundation, Inc. -+ Written By Nick Clifton -+ -+ 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 2, or (at your option) any -+ later version. -+ -+ In addition to the permissions in the GNU General Public License, the -+ Free Software Foundation gives you unlimited permission to link the -+ compiled version of this file with other programs, and to distribute -+ those programs without any restriction coming from the use of this -+ file. (The General Public License restrictions do apply in other -+ respects; for example, they cover modification of the file, and -+ distribution when not linked into another program.) -+ -+ 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. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; 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. -+*/ -+ -+ -+ -+ -+ .file "crtn.asm" -+ -+ .section ".init" -+ ldm sp++, r6, pc -+ -+ .section ".fini" -+ ldm sp++, r6, pc -+ ---- /dev/null -+++ b/gcc/config/avr32/lib1funcs.S -@@ -0,0 +1,2903 @@ -+/* Macro for moving immediate value to register. */ -+.macro mov_imm reg, imm -+.if (((\imm & 0xfffff) == \imm) || ((\imm | 0xfff00000) == \imm)) -+ mov \reg, \imm -+#if __AVR32_UC__ >= 2 -+.elseif ((\imm & 0xffff) == 0) -+ movh \reg, hi(\imm) -+ -+#endif -+.else -+ mov \reg, lo(\imm) -+ orh \reg, hi(\imm) -+.endif -+.endm -+ -+ -+ -+/* Adjust the unpacked double number if it is a subnormal number. -+ The exponent and mantissa pair are stored -+ in [mant_hi,mant_lo] and [exp]. A register with the correct sign bit in -+ the MSB is passed in [sign]. Needs two scratch -+ registers [scratch1] and [scratch2]. An adjusted and packed double float -+ is present in [mant_hi,mant_lo] after macro has executed */ -+.macro adjust_subnormal_df exp, mant_lo, mant_hi, sign, scratch1, scratch2 -+ /* We have an exponent which is <=0 indicating a subnormal number -+ As it should be stored as if the exponent was 1 (although the -+ exponent field is all zeros to indicate a subnormal number) -+ we have to shift down the mantissa to its correct position. */ -+ neg \exp -+ sub \exp,-1 /* amount to shift down */ -+ cp.w \exp,54 -+ brlo 50f /* if more than 53 shift steps, the -+ entire mantissa will disappear -+ without any rounding to occur */ -+ mov \mant_hi, 0 -+ mov \mant_lo, 0 -+ rjmp 52f -+50: -+ sub \exp,-10 /* do the shift to position the -+ mantissa at the same time -+ note! this does not include the -+ final 1 step shift to add the sign */ -+ -+ /* when shifting, save all shifted out bits in [scratch2]. we may need to -+ look at them to make correct rounding. */ -+ -+ rsub \scratch1,\exp,32 /* get inverted shift count */ -+ cp.w \exp,32 /* handle shifts >= 32 separately */ -+ brhs 51f -+ -+ /* small (<32) shift amount, both words are part of the shift */ -+ lsl \scratch2,\mant_lo,\scratch1 /* save bits to shift out from lsw*/ -+ lsl \scratch1,\mant_hi,\scratch1 /* get bits from msw destined for lsw*/ -+ lsr \mant_lo,\mant_lo,\exp /* shift down lsw */ -+ lsr \mant_hi,\mant_hi,\exp /* shift down msw */ -+ or \mant_hi,\scratch1 /* add bits from msw with prepared lsw */ -+ rjmp 50f -+ -+ /* large (>=32) shift amount, only lsw will have bits left after shift. -+ note that shift operations will use ((shift count) mod 32) so -+ we do not need to subtract 32 from shift count. */ -+51: -+ lsl \scratch2,\mant_hi,\scratch1 /* save bits to shift out from msw */ -+ or \scratch2,\mant_lo /* also save all bits from lsw */ -+ mov \mant_lo,\mant_hi /* msw -> lsw (i.e. "shift 32 first") */ -+ mov \mant_hi,0 /* clear msw */ -+ lsr \mant_lo,\mant_lo,\exp /* make rest of shift inside lsw */ -+ -+50: -+ /* result is almost ready to return, except that least significant bit -+ and the part we already shifted out may cause the result to be -+ rounded */ -+ bld \mant_lo,0 /* get bit to be shifted out */ -+ brcc 51f /* if bit was 0, no rounding */ -+ -+ /* msb of part to remove is 1, so rounding depends on rest of bits */ -+ tst \scratch2,\scratch2 /* get shifted out tail */ -+ brne 50f /* if rest > 0, do round */ -+ bld \mant_lo,1 /* we have to look at lsb in result */ -+ brcc 51f /* if lsb is 0, don't round */ -+ -+50: -+ /* subnormal result requires rounding -+ rounding may cause subnormal to become smallest normal number -+ luckily, smallest normal number has exactly the representation -+ we got by rippling a one bit up from mantissa into exponent field. */ -+ sub \mant_lo,-1 -+ subcc \mant_hi,-1 -+ -+51: -+ /* shift and return packed double with correct sign */ -+ rol \sign -+ ror \mant_hi -+ ror \mant_lo -+52: -+.endm -+ -+ -+/* Adjust subnormal single float number with exponent [exp] -+ and mantissa [mant] and round. */ -+.macro adjust_subnormal_sf sf, exp, mant, sign, scratch -+ /* subnormal number */ -+ rsub \exp,\exp, 1 /* shift amount */ -+ cp.w \exp, 25 -+ movhs \mant, 0 -+ brhs 90f /* Return zero */ -+ rsub \scratch, \exp, 32 -+ lsl \scratch, \mant,\scratch/* Check if there are any bits set -+ in the bits discarded in the mantissa */ -+ srne \scratch /* If so set the lsb of the shifted mantissa */ -+ lsr \mant,\mant,\exp /* Shift the mantissa */ -+ or \mant, \scratch /* Round lsb if any bits were shifted out */ -+ /* Rounding : For explaination, see round_sf. */ -+ mov \scratch, 0x7f /* Set rounding constant */ -+ bld \mant, 8 -+ subeq \scratch, -1 /* For odd numbers use rounding constant 0x80 */ -+ add \mant, \scratch /* Add rounding constant to mantissa */ -+ /* We can't overflow because mantissa is at least shifted one position -+ to the right so the implicit bit is zero. We can however get the implicit -+ bit set after rounding which means that we have the lowest normal number -+ but this is ok since this bit has the same position as the LSB of the -+ exponent */ -+ lsr \sf, \mant, 7 -+ /* Rotate in sign */ -+ lsl \sign, 1 -+ ror \sf -+90: -+.endm -+ -+ -+/* Round the unpacked df number with exponent [exp] and -+ mantissa [mant_hi, mant_lo]. Uses scratch register -+ [scratch] */ -+.macro round_df exp, mant_lo, mant_hi, scratch -+ mov \scratch, 0x3ff /* Rounding constant */ -+ bld \mant_lo,11 /* Check if lsb in the final result is -+ set */ -+ subeq \scratch, -1 /* Adjust rounding constant to 0x400 -+ if rounding 0.5 upwards */ -+ add \mant_lo, \scratch /* Round */ -+ acr \mant_hi /* If overflowing we know that -+ we have all zeros in the bits not -+ scaled out so we can leave them -+ but we must increase the exponent with -+ two since we had an implicit bit -+ which is lost + the extra overflow bit */ -+ subcs \exp, -2 /* Update exponent */ -+.endm -+ -+/* Round single float number stored in [mant] and [exp] */ -+.macro round_sf exp, mant, scratch -+ /* Round: -+ For 0.5 we round to nearest even integer -+ for all other cases we round to nearest integer. -+ This means that if the digit left of the "point" (.) -+ is 1 we can add 0x80 to the mantissa since the -+ corner case 0x180 will round up to 0x200. If the -+ digit left of the "point" is 0 we will have to -+ add 0x7f since this will give 0xff and hence a -+ truncation/rounding downwards for the corner -+ case when the 9 lowest bits are 0x080 */ -+ mov \scratch, 0x7f /* Set rounding constant */ -+ /* Check if the mantissa is even or odd */ -+ bld \mant, 8 -+ subeq \scratch, -1 /* Rounding constant should be 0x80 */ -+ add \mant, \scratch -+ subcs \exp, -2 /* Adjust exponent if we overflowed */ -+.endm -+ -+ -+ -+/* Pack a single float number stored in [mant] and [exp] -+ into a single float number in [sf] */ -+.macro pack_sf sf, exp, mant -+ bld \mant,31 /* implicit bit to z */ -+ subne \exp,1 /* if subnormal (implicit bit 0) -+ adjust exponent to storage format */ -+ -+ lsr \sf, \mant, 7 -+ bfins \sf, \exp, 24, 8 -+.endm -+ -+/* Pack exponent [exp] and mantissa [mant_hi, mant_lo] -+ into [df_hi, df_lo]. [df_hi] is shifted -+ one bit up so the sign bit can be shifted into it */ -+ -+.macro pack_df exp, mant_lo, mant_hi, df_lo, df_hi -+ bld \mant_hi,31 /* implicit bit to z */ -+ subne \exp,1 /* if subnormal (implicit bit 0) -+ adjust exponent to storage format */ -+ -+ lsr \mant_lo,11 /* shift back lsw */ -+ or \df_lo,\mant_lo,\mant_hi<<21 /* combine with low bits from msw */ -+ lsl \mant_hi,1 /* get rid of implicit bit */ -+ lsr \mant_hi,11 /* shift back msw except for one step*/ -+ or \df_hi,\mant_hi,\exp<<21 /* combine msw with exponent */ -+.endm -+ -+/* Normalize single float number stored in [mant] and [exp] -+ using scratch register [scratch] */ -+.macro normalize_sf exp, mant, scratch -+ /* Adjust exponent and mantissa */ -+ clz \scratch, \mant -+ sub \exp, \scratch -+ lsl \mant, \mant, \scratch -+.endm -+ -+/* Normalize the exponent and mantissa pair stored -+ in [mant_hi,mant_lo] and [exp]. Needs two scratch -+ registers [scratch1] and [scratch2]. */ -+.macro normalize_df exp, mant_lo, mant_hi, scratch1, scratch2 -+ clz \scratch1,\mant_hi /* Check if we have zeros in high bits */ -+ breq 80f /* No need for scaling if no zeros in high bits */ -+ brcs 81f /* Check for all zeros */ -+ -+ /* shift amount is smaller than 32, and involves both msw and lsw*/ -+ rsub \scratch2,\scratch1,32 /* shift mantissa */ -+ lsl \mant_hi,\mant_hi,\scratch1 -+ lsr \scratch2,\mant_lo,\scratch2 -+ or \mant_hi,\scratch2 -+ lsl \mant_lo,\mant_lo,\scratch1 -+ sub \exp,\scratch1 /* adjust exponent */ -+ rjmp 80f /* Finished */ -+81: -+ /* shift amount is greater than 32 */ -+ clz \scratch1,\mant_lo /* shift mantissa */ -+ movcs \scratch1, 0 -+ subcc \scratch1,-32 -+ lsl \mant_hi,\mant_lo,\scratch1 -+ mov \mant_lo,0 -+ sub \exp,\scratch1 /* adjust exponent */ -+80: -+.endm -+ -+ -+/* Fast but approximate multiply of two 64-bit numbers to give a 64 bit result. -+ The multiplication of [al]x[bl] is discarded. -+ Operands in [ah], [al], [bh], [bl]. -+ Scratch registers in [sh], [sl]. -+ Returns results in registers [rh], [rl].*/ -+.macro mul_approx_df ah, al, bh, bl, rh, rl, sh, sl -+ mulu.d \sl, \ah, \bl -+ macu.d \sl, \al, \bh -+ mulu.d \rl, \ah, \bh -+ add \rl, \sh -+ acr \rh -+.endm -+ -+ -+ -+#if defined(L_avr32_f64_mul) || defined(L_avr32_f64_mul_fast) -+ .align 2 -+#if defined(L_avr32_f64_mul) -+ .global __avr32_f64_mul -+ .type __avr32_f64_mul,@function -+__avr32_f64_mul: -+#else -+ .global __avr32_f64_mul_fast -+ .type __avr32_f64_mul_fast,@function -+__avr32_f64_mul_fast: -+#endif -+ or r12, r10, r11 << 1 -+ breq __avr32_f64_mul_op1_zero -+ -+#if defined(L_avr32_f64_mul) -+ pushm r4-r7, lr -+#else -+ stm --sp, r5,r6,r7,lr -+#endif -+ -+#define AVR32_F64_MUL_OP1_INT_BITS 1 -+#define AVR32_F64_MUL_OP2_INT_BITS 10 -+#define AVR32_F64_MUL_RES_INT_BITS 11 -+ -+ /* op1 in {r11,r10}*/ -+ /* op2 in {r9,r8}*/ -+ eor lr, r11, r9 /* MSB(lr) = Sign(op1) ^ Sign(op2) */ -+ -+ /* Unpack op1 to 1.63 format*/ -+ /* exp: r7 */ -+ /* sf: r11, r10 */ -+ bfextu r7, r11, 20, 11 /* Extract exponent */ -+ -+ mov r5, 1 -+ -+ /* Check if normalization is needed */ -+ breq __avr32_f64_mul_op1_subnormal /*If number is subnormal, normalize it */ -+ -+ lsl r11, (12-AVR32_F64_MUL_OP1_INT_BITS-1) /* Extract mantissa, leave room for implicit bit */ -+ or r11, r11, r10>>(32-(12-AVR32_F64_MUL_OP1_INT_BITS-1)) -+ lsl r10, (12-AVR32_F64_MUL_OP1_INT_BITS-1) -+ bfins r11, r5, 32 - (1 + AVR32_F64_MUL_OP1_INT_BITS), 1 + AVR32_F64_MUL_OP1_INT_BITS /* Insert implicit bit */ -+ -+ -+22: -+ /* Unpack op2 to 10.54 format */ -+ /* exp: r6 */ -+ /* sf: r9, r8 */ -+ bfextu r6, r9, 20, 11 /* Extract exponent */ -+ -+ /* Check if normalization is needed */ -+ breq __avr32_f64_mul_op2_subnormal /*If number is subnormal, normalize it */ -+ -+ lsl r8, 1 /* Extract mantissa, leave room for implicit bit */ -+ rol r9 -+ bfins r9, r5, 32 - (1 + AVR32_F64_MUL_OP2_INT_BITS), 1 + AVR32_F64_MUL_OP2_INT_BITS /* Insert implicit bit */ -+ -+23: -+ -+ /* Check if any operands are NaN or INF */ -+ cp r7, 0x7ff -+ breq __avr32_f64_mul_op_nan_or_inf /* Check op1 for NaN or Inf */ -+ cp r6, 0x7ff -+ breq __avr32_f64_mul_op_nan_or_inf /* Check op2 for NaN or Inf */ -+ -+ -+ /* Calculate new exponent in r12*/ -+ add r12, r7, r6 -+ sub r12, (1023-1) -+ -+#if defined(L_avr32_f64_mul) -+ /* Do the multiplication. -+ Place result in [r11, r10, r7, r6]. The result is in 11.117 format. */ -+ mulu.d r4, r11, r8 -+ macu.d r4, r10, r9 -+ mulu.d r6, r10, r8 -+ mulu.d r10, r11, r9 -+ add r7, r4 -+ adc r10, r10, r5 -+ acr r11 -+#else -+ /* Do the multiplication using approximate calculation. discard the al x bl -+ calculation. -+ Place result in [r11, r10, r7]. The result is in 11.85 format. */ -+ -+ /* Do the multiplication using approximate calculation. -+ Place result in r11, r10. Use r7, r6 as scratch registers */ -+ mulu.d r6, r11, r8 -+ macu.d r6, r10, r9 -+ mulu.d r10, r11, r9 -+ add r10, r7 -+ acr r11 -+#endif -+ /* Adjust exponent and mantissa */ -+ /* [r12]:exp, [r11, r10]:mant [r7, r6]:sticky bits */ -+ /* Mantissa may be of the format 00000000000.0xxx or 00000000000.1xxx. */ -+ /* In the first case, shift one pos to left.*/ -+ bld r11, 32-AVR32_F64_MUL_RES_INT_BITS-1 -+ breq 0f -+ lsl r7, 1 -+ rol r10 -+ rol r11 -+ sub r12, 1 -+0: -+ cp r12, 0 -+ brle __avr32_f64_mul_res_subnormal /*Result was subnormal.*/ -+ -+ /* Check for Inf. */ -+ cp.w r12, 0x7ff -+ brge __avr32_f64_mul_res_inf -+ -+ /* Insert exponent. */ -+ bfins r11, r12, 20, 11 -+ -+ /* Result was not subnormal. Perform rounding. */ -+ /* For the fast version we discard the sticky bits and always round -+ the halfwaycase up. */ -+24: -+#if defined(L_avr32_f64_mul) -+ or r6, r6, r10 << 31 /* Or in parity bit into stickybits */ -+ or r7, r7, r6 >> 1 /* Or together sticky and still make the msb -+ of r7 represent the halfway bit. */ -+ eorh r7, 0x8000 /* Toggle halfway bit. */ -+ /* We should now round up by adding one for the following cases: -+ -+ halfway sticky|parity round-up -+ 0 x no -+ 1 0 no -+ 1 1 yes -+ -+ Since we have inverted the halfway bit we can use the satu instruction -+ by saturating to 1 bit to implement this. -+ */ -+ satu r7 >> 0, 1 -+#else -+ lsr r7, 31 -+#endif -+ add r10, r7 -+ acr r11 -+ -+ /* Insert sign bit*/ -+ bld lr, 31 -+ bst r11, 31 -+ -+ /* Return result in [r11,r10] */ -+#if defined(L_avr32_f64_mul) -+ popm r4-r7, pc -+#else -+ ldm sp++, r5, r6, r7,pc -+#endif -+ -+ -+__avr32_f64_mul_op1_subnormal: -+ andh r11, 0x000f /* Remove sign bit and exponent */ -+ clz r12, r10 /* Count leading zeros in lsw */ -+ clz r6, r11 /* Count leading zeros in msw */ -+ subcs r12, -32 + AVR32_F64_MUL_OP1_INT_BITS -+ movcs r6, r12 -+ subcc r6, AVR32_F64_MUL_OP1_INT_BITS -+ cp.w r6, 32 -+ brge 0f -+ -+ /* shifting involves both msw and lsw*/ -+ rsub r12, r6, 32 /* shift mantissa */ -+ lsl r11, r11, r6 -+ lsr r12, r10, r12 -+ or r11, r12 -+ lsl r10, r10, r6 -+ sub r6, 12-AVR32_F64_MUL_OP1_INT_BITS -+ sub r7, r6 /* adjust exponent */ -+ rjmp 22b /* Finished */ -+0: -+ /* msw is zero so only need to consider lsw */ -+ lsl r11, r10, r6 -+ breq __avr32_f64_mul_res_zero -+ mov r10, 0 -+ sub r6, 12-AVR32_F64_MUL_OP1_INT_BITS -+ sub r7, r6 /* adjust exponent */ -+ rjmp 22b -+ -+ -+__avr32_f64_mul_op2_subnormal: -+ andh r9, 0x000f /* Remove sign bit and exponent */ -+ clz r12, r8 /* Count leading zeros in lsw */ -+ clz r5, r9 /* Count leading zeros in msw */ -+ subcs r12, -32 + AVR32_F64_MUL_OP2_INT_BITS -+ movcs r5, r12 -+ subcc r5, AVR32_F64_MUL_OP2_INT_BITS -+ cp.w r5, 32 -+ brge 0f -+ -+ /* shifting involves both msw and lsw*/ -+ rsub r12, r5, 32 /* shift mantissa */ -+ lsl r9, r9, r5 -+ lsr r12, r8, r12 -+ or r9, r12 -+ lsl r8, r8, r5 -+ sub r5, 12 - AVR32_F64_MUL_OP2_INT_BITS -+ sub r6, r5 /* adjust exponent */ -+ rjmp 23b /* Finished */ -+0: -+ /* msw is zero so only need to consider lsw */ -+ lsl r9, r8, r5 -+ breq __avr32_f64_mul_res_zero -+ mov r8, 0 -+ sub r5, 12 - AVR32_F64_MUL_OP2_INT_BITS -+ sub r6, r5 /* adjust exponent */ -+ rjmp 23b -+ -+ -+__avr32_f64_mul_op_nan_or_inf: -+ /* Same code for OP1 and OP2*/ -+ /* Since we are here, at least one of the OPs were NaN or INF*/ -+ andh r9, 0x000f /* Remove sign bit and exponent */ -+ andh r11, 0x000f /* Remove sign bit and exponent */ -+ /* Merge the regs in each operand to check for zero*/ -+ or r11, r10 /* op1 */ -+ or r9, r8 /* op2 */ -+ /* Check if op1 is NaN or INF */ -+ cp r7, 0x7ff -+ brne __avr32_f64_mul_op1_not_naninf -+ /* op1 was NaN or INF.*/ -+ cp r11, 0 -+ brne __avr32_f64_mul_res_nan /* op1 was NaN. Result will be NaN*/ -+ /*op1 was INF. check if op2 is NaN or INF*/ -+ cp r6, 0x7ff -+ brne __avr32_f64_mul_res_inf /*op1 was INF, op2 was neither NaN nor INF*/ -+ /* op1 is INF, op2 is either NaN or INF*/ -+ cp r9, 0 -+ breq __avr32_f64_mul_res_inf /*op2 was also INF*/ -+ rjmp __avr32_f64_mul_res_nan /*op2 was NaN*/ -+ -+__avr32_f64_mul_op1_not_naninf: -+ /* op1 was not NaN nor INF. Then op2 must be NaN or INF*/ -+ cp r9, 0 -+ breq __avr32_f64_mul_res_inf /*op2 was INF, return INF*/ -+ rjmp __avr32_f64_mul_res_nan /*else return NaN*/ -+ -+__avr32_f64_mul_res_subnormal:/* Multiply result was subnormal. */ -+#if defined(L_avr32_f64_mul) -+ /* Check how much we must scale down the mantissa. */ -+ neg r12 -+ sub r12, -1 /* We do no longer have an implicit bit. */ -+ satu r12 >> 0, 6 /* Saturate shift amount to max 63. */ -+ cp.w r12, 32 -+ brge 0f -+ /* Shift amount <32 */ -+ rsub r8, r12, 32 -+ or r6, r7 -+ lsr r7, r7, r12 -+ lsl r9, r10, r8 -+ or r7, r9 -+ lsr r10, r10, r12 -+ lsl r9, r11, r8 -+ or r10, r9 -+ lsr r11, r11, r12 -+ rjmp 24b -+0: -+ /* Shift amount >=32 */ -+ rsub r8, r12, 32 -+ moveq r9, 0 -+ breq 0f -+ lsl r9, r11, r8 -+0: -+ or r6, r7 -+ or r6, r6, r10 << 1 -+ lsr r10, r10, r12 -+ or r7, r9, r10 -+ lsr r10, r11, r12 -+ mov r11, 0 -+ rjmp 24b -+#else -+ /* Flush to zero for the fast version. */ -+ mov r11, lr /*Get correct sign*/ -+ andh r11, 0x8000, COH -+ mov r10, 0 -+ ldm sp++, r5, r6, r7,pc -+#endif -+ -+__avr32_f64_mul_res_zero:/* Multiply result is zero. */ -+ mov r11, lr /*Get correct sign*/ -+ andh r11, 0x8000, COH -+ mov r10, 0 -+#if defined(L_avr32_f64_mul) -+ popm r4-r7, pc -+#else -+ ldm sp++, r5, r6, r7,pc -+#endif -+ -+__avr32_f64_mul_res_nan: /* Return NaN. */ -+ mov r11, -1 -+ mov r10, -1 -+#if defined(L_avr32_f64_mul) -+ popm r4-r7, pc -+#else -+ ldm sp++, r5, r6, r7,pc -+#endif -+ -+__avr32_f64_mul_res_inf: /* Return INF. */ -+ mov r11, 0xfff00000 -+ bld lr, 31 -+ bst r11, 31 -+ mov r10, 0 -+#if defined(L_avr32_f64_mul) -+ popm r4-r7, pc -+#else -+ ldm sp++, r5, r6, r7,pc -+#endif -+ -+__avr32_f64_mul_op1_zero: -+ /* Get sign */ -+ eor r11, r11, r9 -+ andh r11, 0x8000, COH -+ /* Check if op2 is Inf or NaN. */ -+ bfextu r12, r9, 20, 11 -+ cp.w r12, 0x7ff -+ retne r12 /* Return 0.0 */ -+ /* Return NaN */ -+ mov r10, -1 -+ mov r11, -1 -+ ret r12 -+ -+ -+ -+#endif -+ -+ -+#if defined(L_avr32_f64_addsub) || defined(L_avr32_f64_addsub_fast) -+ .align 2 -+ -+__avr32_f64_sub_from_add: -+ /* Switch sign on op2 */ -+ eorh r9, 0x8000 -+ -+#if defined(L_avr32_f64_addsub_fast) -+ .global __avr32_f64_sub_fast -+ .type __avr32_f64_sub_fast,@function -+__avr32_f64_sub_fast: -+#else -+ .global __avr32_f64_sub -+ .type __avr32_f64_sub,@function -+__avr32_f64_sub: -+#endif -+ -+ /* op1 in {r11,r10}*/ -+ /* op2 in {r9,r8}*/ -+ -+#if defined(L_avr32_f64_addsub_fast) -+ /* If op2 is zero just return op1 */ -+ or r12, r8, r9 << 1 -+ reteq r12 -+#endif -+ -+ /* Check signs */ -+ eor r12, r11, r9 -+ /* Different signs, use addition. */ -+ brmi __avr32_f64_add_from_sub -+ -+ stm --sp, r5, r6, r7, lr -+ -+ /* Get sign of op1 into r12 */ -+ mov r12, r11 -+ andh r12, 0x8000, COH -+ -+ /* Remove sign from operands */ -+ cbr r11, 31 -+ cbr r9, 31 -+ -+ /* Put the largest number in [r11, r10] -+ and the smallest number in [r9, r8] */ -+ cp r10, r8 -+ cpc r11, r9 -+ brhs 1f /* Skip swap if operands already correctly ordered*/ -+ /* Operands were not correctly ordered, swap them*/ -+ mov r7, r11 -+ mov r11, r9 -+ mov r9, r7 -+ mov r7, r10 -+ mov r10, r8 -+ mov r8, r7 -+ eorh r12, 0x8000 /* Invert sign in r12*/ -+1: -+ /* Unpack largest operand - opH */ -+ /* exp: r7 */ -+ /* sf: r11, r10 */ -+ lsr r7, r11, 20 /* Extract exponent */ -+ lsl r11, 11 /* Extract mantissa, leave room for implicit bit */ -+ or r11, r11, r10>>21 -+ lsl r10, 11 -+ sbr r11, 31 /* Insert implicit bit */ -+ -+ -+ /* Unpack smallest operand - opL */ -+ /* exp: r6 */ -+ /* sf: r9, r8 */ -+ lsr r6, r9, 20 /* Extract exponent */ -+ breq __avr32_f64_sub_opL_subnormal /* If either zero or subnormal */ -+ lsl r9, 11 /* Extract mantissa, leave room for implicit bit */ -+ or r9, r9, r8>>21 -+ lsl r8, 11 -+ sbr r9, 31 /* Insert implicit bit */ -+ -+ -+__avr32_f64_sub_opL_subnormal_done: -+ /* opH is NaN or Inf. */ -+ cp.w r7, 0x7ff -+ breq __avr32_f64_sub_opH_nan_or_inf -+ -+ /* Get shift amount to scale mantissa of op2. */ -+ rsub r6, r7 -+ breq __avr32_f64_sub_shift_done /* No need to shift, exponents are equal*/ -+ -+ /* Scale mantissa [r9, r8] with amount [r6]. -+ Uses scratch registers [r5] and [lr]. -+ In IEEE mode:Must not forget the sticky bits we intend to shift out. */ -+ -+ rsub r5,r6,32 /* get (32 - shift count) -+ (if shift count > 32 we get a -+ negative value, but that will -+ work as well in the code below.) */ -+ -+ cp.w r6,32 /* handle shifts >= 32 separately */ -+ brhs __avr32_f64_sub_longshift -+ -+ /* small (<32) shift amount, both words are part of the shift -+ first remember whether part that is lost contains any 1 bits ... */ -+ lsl lr,r8,r5 /* shift away bits that are part of -+ final mantissa. only part that goes -+ to lr are bits that will be lost */ -+ -+ /* ... and now to the actual shift */ -+ lsl r5,r9,r5 /* get bits from msw destined for lsw*/ -+ lsr r8,r8,r6 /* shift down lsw of mantissa */ -+ lsr r9,r9,r6 /* shift down msw of mantissa */ -+ or r8,r5 /* combine these bits with prepared lsw*/ -+#if defined(L_avr32_f64_addsub) -+ cp.w lr,0 /* if any '1' bit in part we lost ...*/ -+ srne lr -+ or r8, lr /* ... we need to set sticky bit*/ -+#endif -+ -+__avr32_f64_sub_shift_done: -+ /* Now subtract the mantissas. */ -+ sub r10, r8 -+ sbc r11, r11, r9 -+ -+ /* Normalize the exponent and mantissa pair stored in -+ [r11,r10] and exponent in [r7]. Needs two scratch registers [r6] and [lr]. */ -+ clz r6,r11 /* Check if we have zeros in high bits */ -+ breq __avr32_f64_sub_longnormalize_done /* No need for scaling if no zeros in high bits */ -+ brcs __avr32_f64_sub_longnormalize -+ -+ -+ /* shift amount is smaller than 32, and involves both msw and lsw*/ -+ rsub lr,r6,32 /* shift mantissa */ -+ lsl r11,r11,r6 -+ lsr lr,r10,lr -+ or r11,lr -+ lsl r10,r10,r6 -+ -+ sub r7,r6 /* adjust exponent */ -+ brle __avr32_f64_sub_subnormal_result -+__avr32_f64_sub_longnormalize_done: -+ -+#if defined(L_avr32_f64_addsub) -+ /* Insert the bits we will remove from the mantissa r9[31:21] */ -+ lsl r9, r10, (32 - 11) -+#else -+ /* Keep the last bit shifted out. */ -+ bfextu r9, r10, 10, 1 -+#endif -+ -+ /* Pack final result*/ -+ /* Input: [r7]:exp, [r11, r10]:mant, [r12]:sign in MSB */ -+ /* Result in [r11,r10] */ -+ /* Insert mantissa */ -+ lsr r10, 11 -+ or r10, r10, r11<<21 -+ lsr r11, 11 -+ /* Insert exponent and sign bit*/ -+ bfins r11, r7, 20, 11 -+ or r11, r12 -+ -+ /* Round */ -+__avr32_f64_sub_round: -+#if defined(L_avr32_f64_addsub) -+ mov_imm r7, 0x80000000 -+ bld r10, 0 -+ subne r7, -1 -+ -+ cp.w r9, r7 -+ srhs r9 -+#endif -+ add r10, r9 -+ acr r11 -+ -+ /* Return result in [r11,r10] */ -+ ldm sp++, r5, r6, r7,pc -+ -+ -+ -+__avr32_f64_sub_opL_subnormal: -+ /* Extract the of mantissa */ -+ lsl r9, 11 /* Extract mantissa, leave room for implicit bit */ -+ or r9, r9, r8>>21 -+ lsl r8, 11 -+ -+ /* Set exponent to 1 if we do not have a zero. */ -+ or lr, r9, r8 -+ movne r6,1 -+ -+ /* Check if opH is also subnormal. If so, clear implicit bit in r11*/ -+ rsub lr, r7, 0 -+ moveq r7,1 -+ bst r11, 31 -+ -+ /* Check if op1 is zero, if so set exponent to 0. */ -+ or lr, r11, r10 -+ moveq r7,0 -+ -+ rjmp __avr32_f64_sub_opL_subnormal_done -+ -+__avr32_f64_sub_opH_nan_or_inf: -+ /* Check if opH is NaN, if so return NaN */ -+ cbr r11, 31 -+ or lr, r11, r10 -+ brne __avr32_f64_sub_return_nan -+ -+ /* opH is Inf. */ -+ /* Check if opL is Inf. or NaN */ -+ cp.w r6, 0x7ff -+ breq __avr32_f64_sub_return_nan -+ /* Return infinity with correct sign. */ -+ or r11, r12, r7 << 20 -+ ldm sp++, r5, r6, r7, pc/* opL not Inf or NaN, return opH */ -+__avr32_f64_sub_return_nan: -+ mov r10, -1 /* Generate NaN in r11, r10 */ -+ mov r11, -1 -+ ldm sp++, r5, r6, r7, pc/* opL Inf or NaN, return NaN */ -+ -+ -+__avr32_f64_sub_subnormal_result: -+#if defined(L_avr32_f64_addsub) -+ /* Check how much we must scale down the mantissa. */ -+ neg r7 -+ sub r7, -1 /* We do no longer have an implicit bit. */ -+ satu r7 >> 0, 6 /* Saturate shift amount to max 63. */ -+ cp.w r7, 32 -+ brge 0f -+ /* Shift amount <32 */ -+ rsub r8, r7, 32 -+ lsl r9, r10, r8 -+ srne r6 -+ lsr r10, r10, r7 -+ or r10, r6 /* Sticky bit from the -+ part that was shifted out. */ -+ lsl r9, r11, r8 -+ or r10, r10, r9 -+ lsr r11, r10, r7 -+ /* Set exponent */ -+ mov r7, 0 -+ rjmp __avr32_f64_sub_longnormalize_done -+0: -+ /* Shift amount >=32 */ -+ rsub r8, r7, 64 -+ lsl r9, r11, r8 -+ or r9, r10 -+ srne r6 -+ lsr r10, r11, r7 -+ or r10, r6 /* Sticky bit from the -+ part that was shifted out. */ -+ mov r11, 0 -+ /* Set exponent */ -+ mov r7, 0 -+ rjmp __avr32_f64_sub_longnormalize_done -+#else -+ /* Just flush subnormals to zero. */ -+ mov r10, 0 -+ mov r11, 0 -+#endif -+ ldm sp++, r5, r6, r7, pc -+ -+__avr32_f64_sub_longshift: -+ /* large (>=32) shift amount, only lsw will have bits left after shift. -+ note that shift operations will use ((shift count=r6) mod 32) so -+ we do not need to subtract 32 from shift count. */ -+ /* Saturate the shift amount to 63. If the amount -+ is any larger op2 is insignificant. */ -+ satu r6 >> 0, 6 -+ -+#if defined(L_avr32_f64_addsub) -+ /* first remember whether part that is lost contains any 1 bits ... */ -+ moveq lr, r8 /* If shift amount is 32, no bits from msw are lost. */ -+ breq 0f -+ lsl lr,r9,r5 /* save all lost bits from msw */ -+ or lr,r8 /* also save lost bits (all) from lsw -+ now lr != 0 if we lose any bits */ -+#endif -+0: -+ /* ... and now to the actual shift */ -+ lsr r8,r9,r6 /* Move msw to lsw and shift. */ -+ mov r9,0 /* clear msw */ -+#if defined(L_avr32_f64_addsub) -+ cp.w lr,0 /* if any '1' bit in part we lost ...*/ -+ srne lr -+ or r8, lr /* ... we need to set sticky bit*/ -+#endif -+ rjmp __avr32_f64_sub_shift_done -+ -+__avr32_f64_sub_longnormalize: -+ /* shift amount is greater than 32 */ -+ clz r6,r10 /* shift mantissa */ -+ /* If the resulting mantissa is zero the result is -+ zero so force exponent to zero. */ -+ movcs r7, 0 -+ movcs r6, 0 -+ movcs r12, 0 /* Also clear sign bit. A zero result from subtraction -+ always is +0.0 */ -+ subcc r6,-32 -+ lsl r11,r10,r6 -+ mov r10,0 -+ sub r7,r6 /* adjust exponent */ -+ brle __avr32_f64_sub_subnormal_result -+ rjmp __avr32_f64_sub_longnormalize_done -+ -+ -+ -+ .align 2 -+__avr32_f64_add_from_sub: -+ /* Switch sign on op2 */ -+ eorh r9, 0x8000 -+ -+#if defined(L_avr32_f64_addsub_fast) -+ .global __avr32_f64_add_fast -+ .type __avr32_f64_add_fast,@function -+__avr32_f64_add_fast: -+#else -+ .global __avr32_f64_add -+ .type __avr32_f64_add,@function -+__avr32_f64_add: -+#endif -+ -+ /* op1 in {r11,r10}*/ -+ /* op2 in {r9,r8}*/ -+ -+#if defined(L_avr32_f64_addsub_fast) -+ /* If op2 is zero just return op1 */ -+ or r12, r8, r9 << 1 -+ reteq r12 -+#endif -+ -+ /* Check signs */ -+ eor r12, r11, r9 -+ /* Different signs, use subtraction. */ -+ brmi __avr32_f64_sub_from_add -+ -+ stm --sp, r5, r6, r7, lr -+ -+ /* Get sign of op1 into r12 */ -+ mov r12, r11 -+ andh r12, 0x8000, COH -+ -+ /* Remove sign from operands */ -+ cbr r11, 31 -+ cbr r9, 31 -+ -+ /* Put the number with the largest exponent in [r11, r10] -+ and the number with the smallest exponent in [r9, r8] */ -+ cp r11, r9 -+ brhs 1f /* Skip swap if operands already correctly ordered */ -+ /* Operands were not correctly ordered, swap them */ -+ mov r7, r11 -+ mov r11, r9 -+ mov r9, r7 -+ mov r7, r10 -+ mov r10, r8 -+ mov r8, r7 -+1: -+ mov lr, 0 /* Set sticky bits to zero */ -+ /* Unpack largest operand - opH */ -+ /* exp: r7 */ -+ /* sf: r11, r10 */ -+ bfextu R7, R11, 20, 11 /* Extract exponent */ -+ bfextu r11, r11, 0, 20 /* Extract mantissa */ -+ sbr r11, 20 /* Insert implicit bit */ -+ -+ /* Unpack smallest operand - opL */ -+ /* exp: r6 */ -+ /* sf: r9, r8 */ -+ bfextu R6, R9, 20, 11 /* Extract exponent */ -+ breq __avr32_f64_add_op2_subnormal -+ bfextu r9, r9, 0, 20 /* Extract mantissa */ -+ sbr r9, 20 /* Insert implicit bit */ -+ -+2: -+ /* opH is NaN or Inf. */ -+ cp.w r7, 0x7ff -+ breq __avr32_f64_add_opH_nan_or_inf -+ -+ /* Get shift amount to scale mantissa of op2. */ -+ rsub r6, r7 -+ breq __avr32_f64_add_shift_done /* No need to shift, exponents are equal*/ -+ -+ /* Scale mantissa [r9, r8] with amount [r6]. -+ Uses scratch registers [r5] and [lr]. -+ In IEEE mode:Must not forget the sticky bits we intend to shift out. */ -+ rsub r5,r6,32 /* get (32 - shift count) -+ (if shift count > 32 we get a -+ negative value, but that will -+ work as well in the code below.) */ -+ -+ cp.w r6,32 /* handle shifts >= 32 separately */ -+ brhs __avr32_f64_add_longshift -+ -+ /* small (<32) shift amount, both words are part of the shift -+ first remember whether part that is lost contains any 1 bits ... */ -+ lsl lr,r8,r5 /* shift away bits that are part of -+ final mantissa. only part that goes -+ to lr are bits that will be lost */ -+ -+ /* ... and now to the actual shift */ -+ lsl r5,r9,r5 /* get bits from msw destined for lsw*/ -+ lsr r8,r8,r6 /* shift down lsw of mantissa */ -+ lsr r9,r9,r6 /* shift down msw of mantissa */ -+ or r8,r5 /* combine these bits with prepared lsw*/ -+ -+__avr32_f64_add_shift_done: -+ /* Now add the mantissas. */ -+ add r10, r8 -+ adc r11, r11, r9 -+ -+ /* Check if we overflowed. */ -+ bld r11, 21 -+ breq __avr32_f64_add_res_of: -+ -+__avr32_f64_add_res_of_done: -+ -+ /* Pack final result*/ -+ /* Input: [r7]:exp, [r11, r10]:mant, [r12]:sign in MSB */ -+ /* Result in [r11,r10] */ -+ /* Insert exponent and sign bit*/ -+ bfins r11, r7, 20, 11 -+ or r11, r12 -+ -+ /* Round */ -+__avr32_f64_add_round: -+#if defined(L_avr32_f64_addsub) -+ bfextu r12, r10, 0, 1 /* Extract parity bit.*/ -+ or lr, r12 /* or it together with the sticky bits. */ -+ eorh lr, 0x8000 /* Toggle round bit. */ -+ /* We should now round up by adding one for the following cases: -+ -+ halfway sticky|parity round-up -+ 0 x no -+ 1 0 no -+ 1 1 yes -+ -+ Since we have inverted the halfway bit we can use the satu instruction -+ by saturating to 1 bit to implement this. -+ */ -+ satu lr >> 0, 1 -+#else -+ lsr lr, 31 -+#endif -+ add r10, lr -+ acr r11 -+ -+ /* Return result in [r11,r10] */ -+ ldm sp++, r5, r6, r7,pc -+ -+ -+__avr32_f64_add_opH_nan_or_inf: -+ /* Check if opH is NaN, if so return NaN */ -+ cbr r11, 20 -+ or lr, r11, r10 -+ brne __avr32_f64_add_return_nan -+ -+ /* opH is Inf. */ -+ /* Check if opL is Inf. or NaN */ -+ cp.w r6, 0x7ff -+ breq __avr32_f64_add_opL_nan_or_inf -+ ldm sp++, r5, r6, r7, pc/* opL not Inf or NaN, return opH */ -+__avr32_f64_add_opL_nan_or_inf: -+ cbr r9, 20 -+ or lr, r9, r8 -+ brne __avr32_f64_add_return_nan -+ mov r10, 0 /* Generate Inf in r11, r10 */ -+ mov_imm r11, 0x7ff00000 -+ or r11, r12 /* Put sign bit back */ -+ ldm sp++, r5, r6, r7, pc/* opL Inf, return Inf */ -+__avr32_f64_add_return_nan: -+ mov r10, -1 /* Generate NaN in r11, r10 */ -+ mov r11, -1 -+ ldm sp++, r5, r6, r7, pc/* opL Inf or NaN, return NaN */ -+ -+ -+__avr32_f64_add_longshift: -+ /* large (>=32) shift amount, only lsw will have bits left after shift. -+ note that shift operations will use ((shift count=r6) mod 32) so -+ we do not need to subtract 32 from shift count. */ -+ /* Saturate the shift amount to 63. If the amount -+ is any larger op2 is insignificant. */ -+ satu r6 >> 0, 6 -+ /* If shift amount is 32 there are no bits from the msw that are lost. */ -+ moveq lr, r8 -+ breq 0f -+ /* first remember whether part that is lost contains any 1 bits ... */ -+ lsl lr,r9,r5 /* save all lost bits from msw */ -+#if defined(L_avr32_f64_addsub) -+ cp.w r8, 0 -+ srne r8 -+ or lr,r8 /* also save lost bits (all) from lsw -+ now lr != 0 if we lose any bits */ -+#endif -+0: -+ /* ... and now to the actual shift */ -+ lsr r8,r9,r6 /* msw -> lsw and make rest of shift inside lsw*/ -+ mov r9,0 /* clear msw */ -+ rjmp __avr32_f64_add_shift_done -+ -+__avr32_f64_add_res_of: -+ /* We overflowed. Scale down mantissa by shifting right one position. */ -+ or lr, lr, lr << 1 /* Remember stickybits*/ -+ lsr r11, 1 -+ ror r10 -+ ror lr -+ sub r7, -1 /* Increment exponent */ -+ -+ /* Clear mantissa to set result to Inf if the exponent is 255. */ -+ cp.w r7, 0x7ff -+ moveq r10, 0 -+ moveq r11, 0 -+ moveq lr, 0 -+ rjmp __avr32_f64_add_res_of_done -+ -+__avr32_f64_add_op2_subnormal: -+ /* Set epxponent to 1 */ -+ mov r6, 1 -+ -+ /* Check if op2 is also subnormal. */ -+ cp.w r7, 0 -+ brne 2b -+ -+ cbr r11, 20 -+ /* Both operands are subnormal. Just addd the mantissas -+ and the exponent will automatically be set to 1 if -+ we overflow into a normal number. */ -+ add r10, r8 -+ adc r11, r11, r9 -+ -+ /* Add sign bit */ -+ or r11, r12 -+ -+ /* Return result in [r11,r10] */ -+ ldm sp++, r5, r6, r7,pc -+ -+ -+ -+#endif -+ -+#ifdef L_avr32_f64_to_u32 -+ /* This goes into L_fixdfsi */ -+#endif -+ -+ -+#ifdef L_avr32_f64_to_s32 -+ .global __avr32_f64_to_u32 -+ .type __avr32_f64_to_u32,@function -+__avr32_f64_to_u32: -+ cp.w r11, 0 -+ retmi 0 /* Negative returns 0 */ -+ -+ /* Fallthrough to df to signed si conversion */ -+ .global __avr32_f64_to_s32 -+ .type __avr32_f64_to_s32,@function -+__avr32_f64_to_s32: -+ lsl r12,r11,1 -+ lsr r12,21 /* extract exponent*/ -+ sub r12,1023 /* convert to unbiased exponent.*/ -+ retlo 0 /* too small exponent implies zero. */ -+ -+1: -+ rsub r12,r12,31 /* shift count = 31 - exponent */ -+ mov r9,r11 /* save sign for later...*/ -+ lsl r11,11 /* remove exponent and sign*/ -+ sbr r11,31 /* add implicit bit*/ -+ or r11,r11,r10>>21 /* get rest of bits from lsw of double */ -+ lsr r11,r11,r12 /* shift down mantissa to final place */ -+ lsl r9,1 /* sign -> carry */ -+ retcc r11 /* if positive, we are done */ -+ neg r11 /* if negative float, negate result */ -+ ret r11 -+ -+#endif /* L_fixdfsi*/ -+ -+#ifdef L_avr32_f64_to_u64 -+ /* Actual function is in L_fixdfdi */ -+#endif -+ -+#ifdef L_avr32_f64_to_s64 -+ .global __avr32_f64_to_u64 -+ .type __avr32_f64_to_u64,@function -+__avr32_f64_to_u64: -+ cp.w r11,0 -+ /* Negative numbers return zero */ -+ movmi r10, 0 -+ movmi r11, 0 -+ retmi r11 -+ -+ -+ -+ /* Fallthrough */ -+ .global __avr32_f64_to_s64 -+ .type __avr32_f64_to_s64,@function -+__avr32_f64_to_s64: -+ lsl r9,r11,1 -+ lsr r9,21 /* get exponent*/ -+ sub r9,1023 /* convert to correct range*/ -+ /* Return zero if exponent to small */ -+ movlo r10, 0 -+ movlo r11, 0 -+ retlo r11 -+ -+ mov r8,r11 /* save sign for later...*/ -+1: -+ lsl r11,11 /* remove exponent */ -+ sbr r11,31 /* add implicit bit*/ -+ or r11,r11,r10>>21 /* get rest of bits from lsw of double*/ -+ lsl r10,11 /* align lsw correctly as well */ -+ rsub r9,r9,63 /* shift count = 63 - exponent */ -+ breq 1f -+ -+ cp.w r9,32 /* is shift count more than one reg? */ -+ brhs 0f -+ -+ mov r12,r11 /* save msw */ -+ lsr r10,r10,r9 /* small shift count, shift down lsw */ -+ lsr r11,r11,r9 /* small shift count, shift down msw */ -+ rsub r9,r9,32 /* get 32-size of shifted out tail */ -+ lsl r12,r12,r9 /* align part to move from msw to lsw */ -+ or r10,r12 /* combine to get new lsw */ -+ rjmp 1f -+ -+0: -+ lsr r10,r11,r9 /* large shift count,only lsw get bits -+ note that shift count is modulo 32*/ -+ mov r11,0 /* msw will be 0 */ -+ -+1: -+ lsl r8,1 /* sign -> carry */ -+ retcc r11 /* if positive, we are done */ -+ -+ neg r11 /* if negative float, negate result */ -+ neg r10 -+ scr r11 -+ ret r11 -+ -+#endif -+ -+#ifdef L_avr32_u32_to_f64 -+ /* Code located in L_floatsidf */ -+#endif -+ -+#ifdef L_avr32_s32_to_f64 -+ .global __avr32_u32_to_f64 -+ .type __avr32_u32_to_f64,@function -+__avr32_u32_to_f64: -+ sub r11, r12, 0 /* Move to r11 and force Z flag to be updated */ -+ mov r12, 0 /* always positive */ -+ rjmp 0f /* Jump to common code for floatsidf */ -+ -+ .global __avr32_s32_to_f64 -+ .type __avr32_s32_to_f64,@function -+__avr32_s32_to_f64: -+ mov r11, r12 /* Keep original value in r12 for sign */ -+ abs r11 /* Absolute value if r12 */ -+0: -+ mov r10,0 /* let remaining bits be zero */ -+ reteq r11 /* zero long will return zero float */ -+ -+ pushm lr -+ mov r9,31+1023 /* set exponent */ -+ -+ normalize_df r9 /*exp*/, r10, r11 /* mantissa */, r8, lr /* scratch */ -+ -+ /* Check if a subnormal result was created */ -+ cp.w r9, 0 -+ brgt 0f -+ -+ adjust_subnormal_df r9 /* exp */, r10, r11 /* Mantissa */, r12 /*sign*/, r8, lr /* scratch */ -+ popm pc -+0: -+ -+ /* Round result */ -+ round_df r9 /*exp*/, r10, r11 /* Mantissa */, r8 /*scratch*/ -+ cp.w r9,0x7ff -+ brlt 0f -+ /*Return infinity */ -+ mov r10, 0 -+ mov_imm r11, 0xffe00000 -+ rjmp __floatsidf_return_op1 -+ -+0: -+ -+ /* Pack */ -+ pack_df r9 /*exp*/, r10, r11 /* mantissa */, r10, r11 /* Output df number*/ -+__floatsidf_return_op1: -+ lsl r12,1 /* shift in sign bit */ -+ ror r11 -+ -+ popm pc -+#endif -+ -+ -+#ifdef L_avr32_f32_cmp_eq -+ .global __avr32_f32_cmp_eq -+ .type __avr32_f32_cmp_eq,@function -+__avr32_f32_cmp_eq: -+ cp.w r12, r11 -+ breq 0f -+ /* If not equal check for +/-0 */ -+ /* Or together the two values and shift out the sign bit. -+ If the result is zero, then the two values are both zero. */ -+ or r12, r11 -+ lsl r12, 1 -+ reteq 1 -+ ret 0 -+0: -+ /* Numbers were equal. Check for NaN or Inf */ -+ mov_imm r11, 0xff000000 -+ lsl r12, 1 -+ cp.w r12, r11 -+ retls 1 /* 0 if NaN, 1 otherwise */ -+ ret 0 -+#endif -+ -+#if defined(L_avr32_f32_cmp_ge) || defined(L_avr32_f32_cmp_lt) -+#ifdef L_avr32_f32_cmp_ge -+ .global __avr32_f32_cmp_ge -+ .type __avr32_f32_cmp_ge,@function -+__avr32_f32_cmp_ge: -+#endif -+#ifdef L_avr32_f32_cmp_lt -+ .global __avr32_f32_cmp_lt -+ .type __avr32_f32_cmp_lt,@function -+__avr32_f32_cmp_lt: -+#endif -+ lsl r10, r12, 1 /* Remove sign bits */ -+ lsl r9, r11, 1 -+ subfeq r10, 0 -+#ifdef L_avr32_f32_cmp_ge -+ reteq 1 /* Both number are zero. Return true. */ -+#endif -+#ifdef L_avr32_f32_cmp_lt -+ reteq 0 /* Both number are zero. Return false. */ -+#endif -+ mov_imm r8, 0xff000000 -+ cp.w r10, r8 -+ rethi 0 /* Op0 is NaN */ -+ cp.w r9, r8 -+ rethi 0 /* Op1 is Nan */ -+ -+ eor r8, r11, r12 -+ bld r12, 31 -+#ifdef L_avr32_f32_cmp_ge -+ srcc r8 /* Set result to true if op0 is positive*/ -+#endif -+#ifdef L_avr32_f32_cmp_lt -+ srcs r8 /* Set result to true if op0 is negative*/ -+#endif -+ retmi r8 /* Return if signs are different */ -+ brcs 0f /* Both signs negative? */ -+ -+ /* Both signs positive */ -+ cp.w r12, r11 -+#ifdef L_avr32_f32_cmp_ge -+ reths 1 -+ retlo 0 -+#endif -+#ifdef L_avr32_f32_cmp_lt -+ reths 0 -+ retlo 1 -+#endif -+0: -+ /* Both signs negative */ -+ cp.w r11, r12 -+#ifdef L_avr32_f32_cmp_ge -+ reths 1 -+ retlo 0 -+#endif -+#ifdef L_avr32_f32_cmp_lt -+ reths 0 -+ retlo 1 -+#endif -+#endif -+ -+ -+#ifdef L_avr32_f64_cmp_eq -+ .global __avr32_f64_cmp_eq -+ .type __avr32_f64_cmp_eq,@function -+__avr32_f64_cmp_eq: -+ cp.w r10,r8 -+ cpc r11,r9 -+ breq 0f -+ -+ /* Args were not equal*/ -+ /* Both args could be zero with different sign bits */ -+ lsl r11,1 /* get rid of sign bits */ -+ lsl r9,1 -+ or r11,r10 /* Check if all bits are zero */ -+ or r11,r9 -+ or r11,r8 -+ reteq 1 /* If all zeros the arguments are equal -+ so return 1 else return 0 */ -+ ret 0 -+0: -+ /* check for NaN */ -+ lsl r11,1 -+ mov_imm r12, 0xffe00000 -+ cp.w r10,0 -+ cpc r11,r12 /* check if nan or inf */ -+ retls 1 /* If Arg is NaN return 0 else 1*/ -+ ret 0 /* Return */ -+ -+#endif -+ -+ -+#if defined(L_avr32_f64_cmp_ge) || defined(L_avr32_f64_cmp_lt) -+ -+#ifdef L_avr32_f64_cmp_ge -+ .global __avr32_f64_cmp_ge -+ .type __avr32_f64_cmp_ge,@function -+__avr32_f64_cmp_ge: -+#endif -+#ifdef L_avr32_f64_cmp_lt -+ .global __avr32_f64_cmp_lt -+ .type __avr32_f64_cmp_lt,@function -+__avr32_f64_cmp_lt: -+#endif -+ -+ /* compare magnitude of op1 and op2 */ -+ st.w --sp, lr -+ st.w --sp, r7 -+ lsl r11,1 /* Remove sign bit of op1 */ -+ srcs r12 /* Sign op1 to lsb of r12*/ -+ lsl r9,1 /* Remove sign bit of op2 */ -+ srcs r7 -+ rol r12 /* Sign op2 to lsb of lr, sign bit op1 bit 1 of r12*/ -+ -+ -+ /* Check for Nan */ -+ mov_imm lr, 0xffe00000 -+ cp.w r10,0 -+ cpc r11,lr -+ brhi 0f /* We have NaN */ -+ cp.w r8,0 -+ cpc r9,lr -+ brhi 0f /* We have NaN */ -+ -+ cp.w r11, 0 -+ subfeq r10, 0 -+ breq 3f /* op1 zero */ -+ ld.w r7, sp++ -+ ld.w lr, sp++ -+ -+ cp.w r12,3 /* both operands negative ?*/ -+ breq 1f -+ -+ cp.w r12,1 /* both operands positive? */ -+ brlo 2f -+ -+ /* Different signs. If sign of op1 is negative the difference -+ between op1 and op2 will always be negative, and if op1 is -+ positive the difference will always be positive */ -+#ifdef L_avr32_f64_cmp_ge -+ reteq 1 -+ retne 0 -+#endif -+#ifdef L_avr32_f64_cmp_lt -+ reteq 0 -+ retne 1 -+#endif -+ -+2: -+ /* Both operands positive. Just compute the difference */ -+ cp.w r10,r8 -+ cpc r11,r9 -+#ifdef L_avr32_f64_cmp_ge -+ reths 1 -+ retlo 0 -+#endif -+#ifdef L_avr32_f64_cmp_lt -+ reths 0 -+ retlo 1 -+#endif -+ -+1: -+ /* Both operands negative. Compute the difference with operands switched */ -+ cp r8,r10 -+ cpc r9,r11 -+#ifdef L_avr32_f64_cmp_ge -+ reths 1 -+ retlo 0 -+#endif -+#ifdef L_avr32_f64_cmp_lt -+ reths 0 -+ retlo 1 -+#endif -+ -+0: -+ ld.w r7, sp++ -+ popm pc, r12=0 -+#endif -+ -+3: -+ cp.w r7, 1 /* Check sign bit from r9 */ -+#ifdef L_avr32_f64_cmp_ge -+ sreq r12 /* If op2 is negative then op1 >= op2. */ -+#endif -+#ifdef L_avr32_f64_cmp_lt -+ srne r12 /* If op2 is positve then op1 <= op2. */ -+#endif -+ cp.w r9, 0 -+ subfeq r8, 0 -+ ld.w r7, sp++ -+ ld.w lr, sp++ -+#ifdef L_avr32_f64_cmp_ge -+ reteq 1 /* Both operands are zero. Return true. */ -+#endif -+#ifdef L_avr32_f64_cmp_lt -+ reteq 0 /* Both operands are zero. Return false. */ -+#endif -+ ret r12 -+ -+ -+#if defined(L_avr32_f64_div) || defined(L_avr32_f64_div_fast) -+ .align 2 -+ -+#if defined(L_avr32_f64_div_fast) -+ .global __avr32_f64_div_fast -+ .type __avr32_f64_div_fast,@function -+__avr32_f64_div_fast: -+#else -+ .global __avr32_f64_div -+ .type __avr32_f64_div,@function -+__avr32_f64_div: -+#endif -+ stm --sp, r0, r1, r2, r3, r4, r5, r6, r7,lr -+ /* op1 in {r11,r10}*/ -+ /* op2 in {r9,r8}*/ -+ eor lr, r11, r9 /* MSB(lr) = Sign(op1) ^ Sign(op2) */ -+ -+ -+ /* Unpack op1 to 2.62 format*/ -+ /* exp: r7 */ -+ /* sf: r11, r10 */ -+ lsr r7, r11, 20 /* Extract exponent */ -+ -+ lsl r11, 9 /* Extract mantissa, leave room for implicit bit */ -+ or r11, r11, r10>>23 -+ lsl r10, 9 -+ sbr r11, 29 /* Insert implicit bit */ -+ andh r11, 0x3fff /*Mask last part of exponent since we use 2.62 format*/ -+ -+ cbr r7, 11 /* Clear sign bit */ -+ /* Check if normalization is needed */ -+ breq 11f /*If number is subnormal, normalize it */ -+22: -+ cp r7, 0x7ff -+ brge 2f /* Check op1 for NaN or Inf */ -+ -+ /* Unpack op2 to 2.62 format*/ -+ /* exp: r6 */ -+ /* sf: r9, r8 */ -+ lsr r6, r9, 20 /* Extract exponent */ -+ -+ lsl r9, 9 /* Extract mantissa, leave room for implicit bit */ -+ or r9, r9, r8>>23 -+ lsl r8, 9 -+ sbr r9, 29 /* Insert implicit bit */ -+ andh r9, 0x3fff /*Mask last part of exponent since we use 2.62 format*/ -+ -+ cbr r6, 11 /* Clear sign bit */ -+ /* Check if normalization is needed */ -+ breq 13f /*If number is subnormal, normalize it */ -+23: -+ cp r6, 0x7ff -+ brge 3f /* Check op2 for NaN or Inf */ -+ -+ /* Calculate new exponent */ -+ sub r7, r6 -+ sub r7,-1023 -+ -+ /* Divide */ -+ /* Approximating 1/d with the following recurrence: */ -+ /* R[j+1] = R[j]*(2-R[j]*d) */ -+ /* Using 2.62 format */ -+ /* TWO: r12 */ -+ /* d = op2 = divisor (2.62 format): r9,r8 */ -+ /* Multiply result : r5, r4 */ -+ /* Initial guess : r3, r2 */ -+ /* New approximations : r3, r2 */ -+ /* op1 = Dividend (2.62 format) : r11, r10 */ -+ -+ mov_imm r12, 0x80000000 -+ -+ /* Load initial guess, using look-up table */ -+ /* Initial guess is of format 01.XY, where XY is constructed as follows: */ -+ /* Let d be of following format: 00.1xy....., then XY=~xy */ -+ /* For d=00.100 = 0,5 -> initial guess=01.11 = 1,75 */ -+ /* For d=00.101 = 0,625 -> initial guess=01.11 = 1,5 */ -+ /* For d=00.110 = 0,75 -> initial guess=01.11 = 1,25 */ -+ /* For d=00.111 = 0,875 -> initial guess=01.11 = 1,0 */ -+ /* r2 is also part of the reg pair forming initial guess, but it*/ -+ /* is kept uninitialized to save one cycle since it has so low significance*/ -+ -+ lsr r3, r12, 1 -+ bfextu r4, r9, 27, 2 -+ com r4 -+ bfins r3, r4, 28, 2 -+ -+ /* First approximation */ -+ /* Approximating to 32 bits */ -+ /* r5 = R[j]*d */ -+ mulu.d r4, r3, r9 -+ /* r5 = 2-R[j]*d */ -+ sub r5, r12, r5<<2 -+ /* r3 = R[j]*(2-R[j]*d) */ -+ mulu.d r4, r3, r5 -+ lsl r3, r5, 2 -+ -+ /* Second approximation */ -+ /* Approximating to 32 bits */ -+ /* r5 = R[j]*d */ -+ mulu.d r4, r3, r9 -+ /* r5 = 2-R[j]*d */ -+ sub r5, r12, r5<<2 -+ /* r3 = R[j]*(2-R[j]*d) */ -+ mulu.d r4, r3, r5 -+ lsl r3, r5, 2 -+ -+ /* Third approximation */ -+ /* Approximating to 32 bits */ -+ /* r5 = R[j]*d */ -+ mulu.d r4, r3, r9 -+ /* r5 = 2-R[j]*d */ -+ sub r5, r12, r5<<2 -+ /* r3 = R[j]*(2-R[j]*d) */ -+ mulu.d r4, r3, r5 -+ lsl r3, r5, 2 -+ -+ /* Fourth approximation */ -+ /* Approximating to 64 bits */ -+ /* r5,r4 = R[j]*d */ -+ mul_approx_df r3 /*ah*/, r2 /*al*/, r9 /*bh*/, r8 /*bl*/, r5 /*rh*/, r4 /*rl*/, r1 /*sh*/, r0 /*sl*/ -+ lsl r5, 2 -+ or r5, r5, r4>>30 -+ lsl r4, 2 -+ /* r5,r4 = 2-R[j]*d */ -+ neg r4 -+ sbc r5, r12, r5 -+ /* r3,r2 = R[j]*(2-R[j]*d) */ -+ mul_approx_df r3 /*ah*/, r2 /*al*/, r5 /*bh*/, r4 /*bl*/, r5 /*rh*/, r4 /*rl*/, r1 /*sh*/, r0 /*sl*/ -+ lsl r3, r5, 2 -+ or r3, r3, r4>>30 -+ lsl r2, r4, 2 -+ -+ -+ /* Fifth approximation */ -+ /* Approximating to 64 bits */ -+ /* r5,r4 = R[j]*d */ -+ mul_approx_df r3 /*ah*/, r2 /*al*/, r9 /*bh*/, r8 /*bl*/, r5 /*rh*/, r4 /*rl*/, r1 /*sh*/, r0 /*sl*/ -+ lsl r5, 2 -+ or r5, r5, r4>>30 -+ lsl r4, 2 -+ /* r5,r4 = 2-R[j]*d */ -+ neg r4 -+ sbc r5, r12, r5 -+ /* r3,r2 = R[j]*(2-R[j]*d) */ -+ mul_approx_df r3 /*ah*/, r2 /*al*/, r5 /*bh*/, r4 /*bl*/, r5 /*rh*/, r4 /*rl*/, r1 /*sh*/, r0 /*sl*/ -+ lsl r3, r5, 2 -+ or r3, r3, r4>>30 -+ lsl r2, r4, 2 -+ -+ -+ /* Multiply with dividend to get quotient */ -+ mul_approx_df r3 /*ah*/, r2 /*al*/, r11 /*bh*/, r10 /*bl*/, r3 /*rh*/, r2 /*rl*/, r1 /*sh*/, r0 /*sl*/ -+ -+ -+ /* To increase speed, this result is not corrected before final rounding.*/ -+ /* This may give a difference to IEEE compliant code of 1 ULP.*/ -+ -+ -+ /* Adjust exponent and mantissa */ -+ /* r7:exp, [r3, r2]:mant, [r5, r4]:scratch*/ -+ /* Mantissa may be of the format 0.xxxx or 1.xxxx. */ -+ /* In the first case, shift one pos to left.*/ -+ bld r3, 31-3 -+ breq 0f -+ lsl r2, 1 -+ rol r3 -+ sub r7, 1 -+#if defined(L_avr32_f64_div) -+ /* We must scale down the dividend to 5.59 format. */ -+ lsr r10, 3 -+ or r10, r10, r11 << 29 -+ lsr r11, 3 -+ rjmp 1f -+#endif -+0: -+#if defined(L_avr32_f64_div) -+ /* We must scale down the dividend to 6.58 format. */ -+ lsr r10, 4 -+ or r10, r10, r11 << 28 -+ lsr r11, 4 -+1: -+#endif -+ cp r7, 0 -+ brle __avr32_f64_div_res_subnormal /* Result was subnormal. */ -+ -+ -+#if defined(L_avr32_f64_div) -+ /* In order to round correctly we calculate the remainder: -+ Remainder = dividend[11:r10] - divisor[r9:r8]*quotient[r3:r2] -+ for the case when the quotient is halfway between the round-up -+ value and the round down value. If the remainder then is negative -+ it means that the quotient was to big and that it should not be -+ rounded up, if the remainder is positive the quotient was to small -+ and we need to round up. If the remainder is zero it means that the -+ quotient is exact but since we need to remove the guard bit we should -+ round to even. */ -+ -+ /* Truncate and add guard bit. */ -+ andl r2, 0xff00 -+ orl r2, 0x0080 -+ -+ -+ /* Now do the multiplication. The quotient has the format 4.60 -+ while the divisor has the format 2.62 which gives a result -+ of 6.58 */ -+ mulu.d r0, r3, r8 -+ macu.d r0, r2, r9 -+ mulu.d r4, r2, r8 -+ mulu.d r8, r3, r9 -+ add r5, r0 -+ adc r8, r8, r1 -+ acr r9 -+ -+ -+ /* Check if remainder is positive, negative or equal. */ -+ bfextu r12, r2, 8, 1 /* Get parity bit into bit 0 of r0 */ -+ cp r4, 0 -+ cpc r5 -+__avr32_f64_div_round_subnormal: -+ cpc r8, r10 -+ cpc r9, r11 -+ srlo r6 /* Remainder positive: we need to round up.*/ -+ moveq r6, r12 /* Remainder zero: round up if mantissa odd. */ -+#else -+ bfextu r6, r2, 7, 1 /* Get guard bit */ -+#endif -+ /* Final packing, scale down mantissa. */ -+ lsr r10, r2, 8 -+ or r10, r10, r3<<24 -+ lsr r11, r3, 8 -+ /* Insert exponent and sign bit*/ -+ bfins r11, r7, 20, 11 -+ bld lr, 31 -+ bst r11, 31 -+ -+ /* Final rounding */ -+ add r10, r6 -+ acr r11 -+ -+ /* Return result in [r11,r10] */ -+ ldm sp++, r0, r1, r2, r3, r4, r5, r6, r7,pc -+ -+ -+2: -+ /* Op1 is NaN or inf */ -+ andh r11, 0x000f /* Extract mantissa */ -+ or r11, r10 -+ brne 16f /* Return NaN if op1 is NaN */ -+ /* Op1 is inf check op2 */ -+ lsr r6, r9, 20 /* Extract exponent */ -+ cbr r6, 11 /* Clear sign bit */ -+ cp r6, 0x7ff -+ brne 17f /* Inf/number gives inf, return inf */ -+ rjmp 16f /* The rest gives NaN*/ -+ -+3: -+ /* Op1 is a valid number. Op 2 is NaN or inf */ -+ andh r9, 0x000f /* Extract mantissa */ -+ or r9, r8 -+ brne 16f /* Return NaN if op2 is NaN */ -+ rjmp 15f /* Op2 was inf, return zero*/ -+ -+11: /* Op1 was denormal. Fix it. */ -+ lsl r11, 3 -+ or r11, r11, r10 >> 29 -+ lsl r10, 3 -+ /* Check if op1 is zero. */ -+ or r4, r10, r11 -+ breq __avr32_f64_div_op1_zero -+ normalize_df r7 /*exp*/, r10, r11 /*Mantissa*/, r4, r5 /*scratch*/ -+ lsr r10, 2 -+ or r10, r10, r11 << 30 -+ lsr r11, 2 -+ rjmp 22b -+ -+ -+13: /* Op2 was denormal. Fix it */ -+ lsl r9, 3 -+ or r9, r9, r8 >> 29 -+ lsl r8, 3 -+ /* Check if op2 is zero. */ -+ or r4, r9, r8 -+ breq 17f /* Divisor is zero -> return Inf */ -+ normalize_df r6 /*exp*/, r8, r9 /*Mantissa*/, r4, r5 /*scratch*/ -+ lsr r8, 2 -+ or r8, r8, r9 << 30 -+ lsr r9, 2 -+ rjmp 23b -+ -+ -+__avr32_f64_div_res_subnormal:/* Divide result was subnormal. */ -+#if defined(L_avr32_f64_div) -+ /* Check how much we must scale down the mantissa. */ -+ neg r7 -+ sub r7, -1 /* We do no longer have an implicit bit. */ -+ satu r7 >> 0, 6 /* Saturate shift amount to max 63. */ -+ cp.w r7, 32 -+ brge 0f -+ /* Shift amount <32 */ -+ /* Scale down quotient */ -+ rsub r6, r7, 32 -+ lsr r2, r2, r7 -+ lsl r12, r3, r6 -+ or r2, r12 -+ lsr r3, r3, r7 -+ /* Scale down the dividend to match the scaling of the quotient. */ -+ lsl r1, r10, r6 -+ lsr r10, r10, r7 -+ lsl r12, r11, r6 -+ or r10, r12 -+ lsr r11, r11, r7 -+ mov r0, 0 -+ rjmp 1f -+0: -+ /* Shift amount >=32 */ -+ rsub r6, r7, 32 -+ moveq r0, 0 -+ moveq r12, 0 -+ breq 0f -+ lsl r0, r10, r6 -+ lsl r12, r11, r6 -+0: -+ lsr r2, r3, r7 -+ mov r3, 0 -+ /* Scale down the dividend to match the scaling of the quotient. */ -+ lsr r1, r10, r7 -+ or r1, r12 -+ lsr r10, r11, r7 -+ mov r11, 0 -+1: -+ /* Start performing the same rounding as done for normal numbers -+ but this time we have scaled the quotient and dividend and hence -+ need a little different comparison. */ -+ /* Truncate and add guard bit. */ -+ andl r2, 0xff00 -+ orl r2, 0x0080 -+ -+ /* Now do the multiplication. */ -+ mulu.d r6, r3, r8 -+ macu.d r6, r2, r9 -+ mulu.d r4, r2, r8 -+ mulu.d r8, r3, r9 -+ add r5, r6 -+ adc r8, r8, r7 -+ acr r9 -+ -+ /* Set exponent to 0 */ -+ mov r7, 0 -+ -+ /* Check if remainder is positive, negative or equal. */ -+ bfextu r12, r2, 8, 1 /* Get parity bit into bit 0 of r0 */ -+ cp r4, r0 -+ cpc r5, r1 -+ /* Now the rest of the rounding is the same as for normals. */ -+ rjmp __avr32_f64_div_round_subnormal -+ -+#endif -+15: -+ /* Flush to zero for the fast version. */ -+ mov r11, lr /*Get correct sign*/ -+ andh r11, 0x8000, COH -+ mov r10, 0 -+ ldm sp++, r0, r1, r2, r3, r4, r5, r6, r7,pc -+ -+16: /* Return NaN. */ -+ mov r11, -1 -+ mov r10, 0 -+ ldm sp++, r0, r1, r2, r3, r4, r5, r6, r7,pc -+ -+17: -+ /* Check if op1 is zero. */ -+ or r4, r10, r11 -+ breq __avr32_f64_div_op1_zero -+ /* Return INF. */ -+ mov r11, lr /*Get correct sign*/ -+ andh r11, 0x8000, COH -+ orh r11, 0x7ff0 -+ mov r10, 0 -+ ldm sp++, r0, r1, r2, r3, r4, r5, r6, r7,pc -+ -+__avr32_f64_div_op1_zero: -+ or r5, r8, r9 << 1 -+ breq 16b /* 0.0/0.0 -> NaN */ -+ bfextu r4, r9, 20, 11 -+ cp r4, 0x7ff -+ brne 15b /* Return zero */ -+ /* Check if divisor is Inf or NaN */ -+ or r5, r8, r9 << 12 -+ breq 15b /* Divisor is inf -> return zero */ -+ rjmp 16b /* Return NaN */ -+ -+ -+ -+ -+#endif -+ -+#if defined(L_avr32_f32_addsub) || defined(L_avr32_f32_addsub_fast) -+ -+ .align 2 -+__avr32_f32_sub_from_add: -+ /* Switch sign on op2 */ -+ eorh r11, 0x8000 -+ -+#if defined(L_avr32_f32_addsub_fast) -+ .global __avr32_f32_sub_fast -+ .type __avr32_f32_sub_fast,@function -+__avr32_f32_sub_fast: -+#else -+ .global __avr32_f32_sub -+ .type __avr32_f32_sub,@function -+__avr32_f32_sub: -+#endif -+ -+ /* Check signs */ -+ eor r8, r11, r12 -+ /* Different signs, use subtraction. */ -+ brmi __avr32_f32_add_from_sub -+ -+ /* Get sign of op1 */ -+ mov r8, r12 -+ andh r12, 0x8000, COH -+ -+ /* Remove sign from operands */ -+ cbr r11, 31 -+#if defined(L_avr32_f32_addsub_fast) -+ reteq r8 /* If op2 is zero return op1 */ -+#endif -+ cbr r8, 31 -+ -+ /* Put the number with the largest exponent in r10 -+ and the number with the smallest exponent in r9 */ -+ max r10, r8, r11 -+ min r9, r8, r11 -+ cp r10, r8 /*If largest operand (in R10) is not equal to op1*/ -+ subne r12, 1 /* Subtract 1 from sign, which will invert MSB of r12*/ -+ andh r12, 0x8000, COH /*Mask all but MSB*/ -+ -+ /* Unpack exponent and mantissa of op1 */ -+ lsl r8, r10, 8 -+ sbr r8, 31 /* Set implicit bit. */ -+ lsr r10, 23 -+ -+ /* op1 is NaN or Inf. */ -+ cp.w r10, 0xff -+ breq __avr32_f32_sub_op1_nan_or_inf -+ -+ /* Unpack exponent and mantissa of op2 */ -+ lsl r11, r9, 8 -+ sbr r11, 31 /* Set implicit bit. */ -+ lsr r9, 23 -+ -+#if defined(L_avr32_f32_addsub) -+ /* Keep sticky bit for correct IEEE rounding */ -+ st.w --sp, r12 -+ -+ /* op2 is either zero or subnormal. */ -+ breq __avr32_f32_sub_op2_subnormal -+0: -+ /* Get shift amount to scale mantissa of op2. */ -+ sub r12, r10, r9 -+ -+ breq __avr32_f32_sub_shift_done -+ -+ /* Saturate the shift amount to 31. If the amount -+ is any larger op2 is insignificant. */ -+ satu r12 >> 0, 5 -+ -+ /* Put the remaining bits into r9.*/ -+ rsub r9, r12, 32 -+ lsl r9, r11, r9 -+ -+ /* If the remaining bits are non-zero then we must subtract one -+ more from opL. */ -+ subne r8, 1 -+ srne r9 /* LSB of r9 represents sticky bits. */ -+ -+ /* Shift mantissa of op2 to same decimal point as the mantissa -+ of op1. */ -+ lsr r11, r11, r12 -+ -+ -+__avr32_f32_sub_shift_done: -+ /* Now subtract the mantissas. */ -+ sub r8, r11 -+ -+ ld.w r12, sp++ -+ -+ /* Normalize resulting mantissa. */ -+ clz r11, r8 -+ -+ retcs 0 -+ lsl r8, r8, r11 -+ sub r10, r11 -+ brle __avr32_f32_sub_subnormal_result -+ -+ /* Insert the bits we will remove from the mantissa into r9[31:24] */ -+ or r9, r9, r8 << 24 -+#else -+ /* Ignore sticky bit to simplify and speed up rounding */ -+ /* op2 is either zero or subnormal. */ -+ breq __avr32_f32_sub_op2_subnormal -+0: -+ /* Get shift amount to scale mantissa of op2. */ -+ rsub r9, r10 -+ -+ /* Saturate the shift amount to 31. If the amount -+ is any larger op2 is insignificant. */ -+ satu r9 >> 0, 5 -+ -+ /* Shift mantissa of op2 to same decimal point as the mantissa -+ of op1. */ -+ lsr r11, r11, r9 -+ -+ /* Now subtract the mantissas. */ -+ sub r8, r11 -+ -+ /* Normalize resulting mantissa. */ -+ clz r9, r8 -+ retcs 0 -+ lsl r8, r8, r9 -+ sub r10, r9 -+ brle __avr32_f32_sub_subnormal_result -+#endif -+ -+ /* Pack result. */ -+ or r12, r12, r8 >> 8 -+ bfins r12, r10, 23, 8 -+ -+ /* Round */ -+__avr32_f32_sub_round: -+#if defined(L_avr32_f32_addsub) -+ mov_imm r10, 0x80000000 -+ bld r12, 0 -+ subne r10, -1 -+ cp.w r9, r10 -+ subhs r12, -1 -+#else -+ bld r8, 7 -+ acr r12 -+#endif -+ -+ ret r12 -+ -+ -+__avr32_f32_sub_op2_subnormal: -+ /* Fix implicit bit and adjust exponent of subnormals. */ -+ cbr r11, 31 -+ /* Set exponent to 1 if we do not have a zero. */ -+ movne r9,1 -+ -+ /* Check if op1 is also subnormal. */ -+ cp.w r10, 0 -+ brne 0b -+ -+ cbr r8, 31 -+ /* If op1 is not zero set exponent to 1. */ -+ movne r10,1 -+ -+ rjmp 0b -+ -+__avr32_f32_sub_op1_nan_or_inf: -+ /* Check if op1 is NaN, if so return NaN */ -+ lsl r11, r8, 1 -+ retne -1 -+ -+ /* op1 is Inf. */ -+ bfins r12, r10, 23, 8 /* Generate Inf in r12 */ -+ -+ /* Check if op2 is Inf. or NaN */ -+ lsr r11, r9, 23 -+ cp.w r11, 0xff -+ retne r12 /* op2 not Inf or NaN, return op1 */ -+ -+ ret -1 /* op2 Inf or NaN, return NaN */ -+ -+__avr32_f32_sub_subnormal_result: -+ /* Check if the number is so small that -+ it will be represented with zero. */ -+ rsub r10, r10, 9 -+ rsub r11, r10, 32 -+ retcs 0 -+ -+ /* Shift the mantissa into the correct position.*/ -+ lsr r10, r8, r10 -+ /* Add sign bit. */ -+ or r12, r10 -+ -+ /* Put the shifted out bits in the most significant part -+ of r8. */ -+ lsl r8, r8, r11 -+ -+#if defined(L_avr32_f32_addsub) -+ /* Add all the remainder bits used for rounding into r9 */ -+ or r9, r8 -+#else -+ lsr r8, 24 -+#endif -+ rjmp __avr32_f32_sub_round -+ -+ -+ .align 2 -+ -+__avr32_f32_add_from_sub: -+ /* Switch sign on op2 */ -+ eorh r11, 0x8000 -+ -+#if defined(L_avr32_f32_addsub_fast) -+ .global __avr32_f32_add_fast -+ .type __avr32_f32_add_fast,@function -+__avr32_f32_add_fast: -+#else -+ .global __avr32_f32_add -+ .type __avr32_f32_add,@function -+__avr32_f32_add: -+#endif -+ -+ /* Check signs */ -+ eor r8, r11, r12 -+ /* Different signs, use subtraction. */ -+ brmi __avr32_f32_sub_from_add -+ -+ /* Get sign of op1 */ -+ mov r8, r12 -+ andh r12, 0x8000, COH -+ -+ /* Remove sign from operands */ -+ cbr r11, 31 -+#if defined(L_avr32_f32_addsub_fast) -+ reteq r8 /* If op2 is zero return op1 */ -+#endif -+ cbr r8, 31 -+ -+ /* Put the number with the largest exponent in r10 -+ and the number with the smallest exponent in r9 */ -+ max r10, r8, r11 -+ min r9, r8, r11 -+ -+ /* Unpack exponent and mantissa of op1 */ -+ lsl r8, r10, 8 -+ sbr r8, 31 /* Set implicit bit. */ -+ lsr r10, 23 -+ -+ /* op1 is NaN or Inf. */ -+ cp.w r10, 0xff -+ breq __avr32_f32_add_op1_nan_or_inf -+ -+ /* Unpack exponent and mantissa of op2 */ -+ lsl r11, r9, 8 -+ sbr r11, 31 /* Set implicit bit. */ -+ lsr r9, 23 -+ -+#if defined(L_avr32_f32_addsub) -+ /* op2 is either zero or subnormal. */ -+ breq __avr32_f32_add_op2_subnormal -+0: -+ /* Keep sticky bit for correct IEEE rounding */ -+ st.w --sp, r12 -+ -+ /* Get shift amount to scale mantissa of op2. */ -+ rsub r9, r10 -+ -+ /* Saturate the shift amount to 31. If the amount -+ is any larger op2 is insignificant. */ -+ satu r9 >> 0, 5 -+ -+ /* Shift mantissa of op2 to same decimal point as the mantissa -+ of op1. */ -+ lsr r12, r11, r9 -+ -+ /* Put the remainding bits into r11[23:..].*/ -+ rsub r9, r9, (32-8) -+ lsl r11, r11, r9 -+ /* Insert the bits we will remove from the mantissa into r11[31:24] */ -+ bfins r11, r12, 24, 8 -+ -+ /* Now add the mantissas. */ -+ add r8, r12 -+ -+ ld.w r12, sp++ -+#else -+ /* Ignore sticky bit to simplify and speed up rounding */ -+ /* op2 is either zero or subnormal. */ -+ breq __avr32_f32_add_op2_subnormal -+0: -+ /* Get shift amount to scale mantissa of op2. */ -+ rsub r9, r10 -+ -+ /* Saturate the shift amount to 31. If the amount -+ is any larger op2 is insignificant. */ -+ satu r9 >> 0, 5 -+ -+ /* Shift mantissa of op2 to same decimal point as the mantissa -+ of op1. */ -+ lsr r11, r11, r9 -+ -+ /* Now add the mantissas. */ -+ add r8, r11 -+ -+#endif -+ /* Check if we overflowed. */ -+ brcs __avr32_f32_add_res_of -+1: -+ /* Pack result. */ -+ or r12, r12, r8 >> 8 -+ bfins r12, r10, 23, 8 -+ -+ /* Round */ -+#if defined(L_avr32_f32_addsub) -+ mov_imm r10, 0x80000000 -+ bld r12, 0 -+ subne r10, -1 -+ cp.w r11, r10 -+ subhs r12, -1 -+#else -+ bld r8, 7 -+ acr r12 -+#endif -+ -+ ret r12 -+ -+__avr32_f32_add_op2_subnormal: -+ /* Fix implicit bit and adjust exponent of subnormals. */ -+ cbr r11, 31 -+ /* Set exponent to 1 if we do not have a zero. */ -+ movne r9,1 -+ -+ /* Check if op1 is also subnormal. */ -+ cp.w r10, 0 -+ brne 0b -+ /* Both operands subnormal, just add the mantissas and -+ pack. If the addition of the subnormal numbers results -+ in a normal number then the exponent will automatically -+ be set to 1 by the addition. */ -+ cbr r8, 31 -+ add r11, r8 -+ or r12, r12, r11 >> 8 -+ ret r12 -+ -+__avr32_f32_add_op1_nan_or_inf: -+ /* Check if op1 is NaN, if so return NaN */ -+ lsl r11, r8, 1 -+ retne -1 -+ -+ /* op1 is Inf. */ -+ bfins r12, r10, 23, 8 /* Generate Inf in r12 */ -+ -+ /* Check if op2 is Inf. or NaN */ -+ lsr r11, r9, 23 -+ cp.w r11, 0xff -+ retne r12 /* op2 not Inf or NaN, return op1 */ -+ -+ lsl r9, 9 -+ reteq r12 /* op2 Inf return op1 */ -+ ret -1 /* op2 is NaN, return NaN */ -+ -+__avr32_f32_add_res_of: -+ /* We overflowed. Increase exponent and shift mantissa.*/ -+ lsr r8, 1 -+ sub r10, -1 -+ -+ /* Clear mantissa to set result to Inf if the exponent is 255. */ -+ cp.w r10, 255 -+ moveq r8, 0 -+ moveq r11, 0 -+ rjmp 1b -+ -+ -+#endif -+ -+ -+#if defined(L_avr32_f32_div) || defined(L_avr32_f32_div_fast) -+ .align 2 -+ -+#if defined(L_avr32_f32_div_fast) -+ .global __avr32_f32_div_fast -+ .type __avr32_f32_div_fast,@function -+__avr32_f32_div_fast: -+#else -+ .global __avr32_f32_div -+ .type __avr32_f32_div,@function -+__avr32_f32_div: -+#endif -+ -+ eor r8, r11, r12 /* MSB(r8) = Sign(op1) ^ Sign(op2) */ -+ -+ /* Unpack */ -+ lsl r12,1 -+ lsl r11,1 -+ breq 4f /* Check op2 for zero */ -+ -+ tst r12, r12 -+ moveq r9, 0 -+ breq 12f -+ -+ /* Unpack op1*/ -+ /* exp: r9 */ -+ /* sf: r12 */ -+ lsr r9, r12, 24 -+ breq 11f /*If number is subnormal*/ -+ cp r9, 0xff -+ brhs 2f /* Check op1 for NaN or Inf */ -+ lsl r12, 7 -+ sbr r12, 31 /*Implicit bit*/ -+12: -+ -+ /* Unpack op2*/ -+ /* exp: r10 */ -+ /* sf: r11 */ -+ lsr r10, r11, 24 -+ breq 13f /*If number is subnormal*/ -+ cp r10, 0xff -+ brhs 3f /* Check op2 for NaN or Inf */ -+ lsl r11,7 -+ sbr r11, 31 /*Implicit bit*/ -+ -+ cp.w r9, 0 -+ subfeq r12, 0 -+ reteq 0 /* op1 is zero and op2 is not zero */ -+ /* or NaN so return zero */ -+ -+14: -+ -+ /* For UC3, store with predecrement is faster than stm */ -+ st.w --sp, r5 -+ st.d --sp, r6 -+ -+ /* Calculate new exponent */ -+ sub r9, r10 -+ sub r9,-127 -+ -+ /* Divide */ -+ /* Approximating 1/d with the following recurrence: */ -+ /* R[j+1] = R[j]*(2-R[j]*d) */ -+ /* Using 2.30 format */ -+ /* TWO: r10 */ -+ /* d: r5 */ -+ /* Multiply result : r6, r7 */ -+ /* Initial guess : r11 */ -+ /* New approximations : r11 */ -+ /* Dividend : r12 */ -+ -+ /* Load TWO */ -+ mov_imm r10, 0x80000000 -+ -+ lsr r12, 2 /* Get significand of Op1 in 2.30 format */ -+ lsr r5, r11, 2 /* Get significand of Op2 (=d) in 2.30 format */ -+ -+ /* Load initial guess, using look-up table */ -+ /* Initial guess is of format 01.XY, where XY is constructed as follows: */ -+ /* Let d be of following format: 00.1xy....., then XY=~xy */ -+ /* For d=00.100 = 0,5 -> initial guess=01.11 = 1,75 */ -+ /* For d=00.101 = 0,625 -> initial guess=01.11 = 1,5 */ -+ /* For d=00.110 = 0,75 -> initial guess=01.11 = 1,25 */ -+ /* For d=00.111 = 0,875 -> initial guess=01.11 = 1,0 */ -+ -+ lsr r11, r10, 1 -+ bfextu r6, r5, 27, 2 -+ com r6 -+ bfins r11, r6, 28, 2 -+ -+ /* First approximation */ -+ /* r7 = R[j]*d */ -+ mulu.d r6, r11, r5 -+ /* r7 = 2-R[j]*d */ -+ sub r7, r10, r7<<2 -+ /* r11 = R[j]*(2-R[j]*d) */ -+ mulu.d r6, r11, r7 -+ lsl r11, r7, 2 -+ -+ /* Second approximation */ -+ /* r7 = R[j]*d */ -+ mulu.d r6, r11, r5 -+ /* r7 = 2-R[j]*d */ -+ sub r7, r10, r7<<2 -+ /* r11 = R[j]*(2-R[j]*d) */ -+ mulu.d r6, r11, r7 -+ lsl r11, r7, 2 -+ -+ /* Third approximation */ -+ /* r7 = R[j]*d */ -+ mulu.d r6, r11, r5 -+ /* r7 = 2-R[j]*d */ -+ sub r7, r10, r7<<2 -+ /* r11 = R[j]*(2-R[j]*d) */ -+ mulu.d r6, r11, r7 -+ lsl r11, r7, 2 -+ -+ /* Fourth approximation */ -+ /* r7 = R[j]*d */ -+ mulu.d r6, r11, r5 -+ /* r7 = 2-R[j]*d */ -+ sub r7, r10, r7<<2 -+ /* r11 = R[j]*(2-R[j]*d) */ -+ mulu.d r6, r11, r7 -+ lsl r11, r7, 2 -+ -+ -+ /* Multiply with dividend to get quotient, r7 = sf(op1)/sf(op2) */ -+ mulu.d r6, r11, r12 -+ -+ /* Shift by 3 to get result in 1.31 format, as required by the exponent. */ -+ /* Note that 1.31 format is already used by the exponent in r9, since */ -+ /* a bias of 127 was added to the result exponent, even though the implicit */ -+ /* bit was inserted. This gives the exponent an additional bias of 1, which */ -+ /* supports 1.31 format. */ -+ //lsl r10, r7, 3 -+ -+ /* Adjust exponent and mantissa in case the result is of format -+ 0000.1xxx to 0001.xxx*/ -+#if defined(L_avr32_f32_div) -+ lsr r12, 4 /* Scale dividend to 6.26 format to match the -+ result of the multiplication of the divisor and -+ quotient to get the remainder. */ -+#endif -+ bld r7, 31-3 -+ breq 0f -+ lsl r7, 1 -+ sub r9, 1 -+#if defined(L_avr32_f32_div) -+ lsl r12, 1 /* Scale dividend to 5.27 format to match the -+ result of the multiplication of the divisor and -+ quotient to get the remainder. */ -+#endif -+0: -+ cp r9, 0 -+ brle __avr32_f32_div_res_subnormal /* Result was subnormal. */ -+ -+ -+#if defined(L_avr32_f32_div) -+ /* In order to round correctly we calculate the remainder: -+ Remainder = dividend[r12] - divisor[r5]*quotient[r7] -+ for the case when the quotient is halfway between the round-up -+ value and the round down value. If the remainder then is negative -+ it means that the quotient was to big and that it should not be -+ rounded up, if the remainder is positive the quotient was to small -+ and we need to round up. If the remainder is zero it means that the -+ quotient is exact but since we need to remove the guard bit we should -+ round to even. */ -+ andl r7, 0xffe0 -+ orl r7, 0x0010 -+ -+ /* Now do the multiplication. The quotient has the format 4.28 -+ while the divisor has the format 2.30 which gives a result -+ of 6.26 */ -+ mulu.d r10, r5, r7 -+ -+ /* Check if remainder is positive, negative or equal. */ -+ bfextu r5, r7, 5, 1 /* Get parity bit into bit 0 of r5 */ -+ cp r10, 0 -+__avr32_f32_div_round_subnormal: -+ cpc r11, r12 -+ srlo r11 /* Remainder positive: we need to round up.*/ -+ moveq r11, r5 /* Remainder zero: round up if mantissa odd. */ -+#else -+ bfextu r11, r7, 4, 1 /* Get guard bit */ -+#endif -+ -+ /* Pack final result*/ -+ lsr r12, r7, 5 -+ bfins r12, r9, 23, 8 -+ /* For UC3, load with postincrement is faster than ldm */ -+ ld.d r6, sp++ -+ ld.w r5, sp++ -+ bld r8, 31 -+ bst r12, 31 -+ /* Rounding add. */ -+ add r12, r11 -+ ret r12 -+ -+__divsf_return_op1: -+ lsl r8, 1 -+ ror r12 -+ ret r12 -+ -+ -+2: -+ /* Op1 is NaN or inf */ -+ retne -1 /* Return NaN if op1 is NaN */ -+ /* Op1 is inf check op2 */ -+ mov_imm r9, 0xff000000 -+ cp r11, r9 -+ brlo __divsf_return_op1 /* inf/number gives inf */ -+ ret -1 /* The rest gives NaN*/ -+3: -+ /* Op2 is NaN or inf */ -+ reteq 0 /* Return zero if number/inf*/ -+ ret -1 /* Return NaN*/ -+4: -+ /* Op1 is zero ? */ -+ tst r12,r12 -+ reteq -1 /* 0.0/0.0 is NaN */ -+ /* Op1 is Nan? */ -+ lsr r9, r12, 24 -+ breq 11f /*If number is subnormal*/ -+ cp r9, 0xff -+ brhs 2b /* Check op1 for NaN or Inf */ -+ /* Nonzero/0.0 is Inf. Sign bit will be shifted in before returning*/ -+ mov_imm r12, 0xff000000 -+ rjmp __divsf_return_op1 -+ -+11: /* Op1 was denormal. Fix it. */ -+ lsl r12,7 -+ clz r9,r12 -+ lsl r12,r12,r9 -+ rsub r9,r9,1 -+ rjmp 12b -+ -+13: /* Op2 was denormal. Fix it. */ -+ lsl r11,7 -+ clz r10,r11 -+ lsl r11,r11,r10 -+ rsub r10,r10,1 -+ rjmp 14b -+ -+ -+__avr32_f32_div_res_subnormal: /* Divide result was subnormal */ -+#if defined(L_avr32_f32_div) -+ /* Check how much we must scale down the mantissa. */ -+ neg r9 -+ sub r9, -1 /* We do no longer have an implicit bit. */ -+ satu r9 >> 0, 5 /* Saturate shift amount to max 32. */ -+ /* Scale down quotient */ -+ rsub r10, r9, 32 -+ lsr r7, r7, r9 -+ /* Scale down the dividend to match the scaling of the quotient. */ -+ lsl r6, r12, r10 /* Make the divident 64-bit and put the lsw in r6 */ -+ lsr r12, r12, r9 -+ -+ /* Start performing the same rounding as done for normal numbers -+ but this time we have scaled the quotient and dividend and hence -+ need a little different comparison. */ -+ andl r7, 0xffe0 -+ orl r7, 0x0010 -+ -+ /* Now do the multiplication. The quotient has the format 4.28 -+ while the divisor has the format 2.30 which gives a result -+ of 6.26 */ -+ mulu.d r10, r5, r7 -+ -+ /* Set exponent to 0 */ -+ mov r9, 0 -+ -+ /* Check if remainder is positive, negative or equal. */ -+ bfextu r5, r7, 5, 1 /* Get parity bit into bit 0 of r5 */ -+ cp r10, r6 -+ rjmp __avr32_f32_div_round_subnormal -+ -+#else -+ ld.d r6, sp++ -+ ld.w r5, sp++ -+ /*Flush to zero*/ -+ ret 0 -+#endif -+#endif -+ -+#ifdef L_avr32_f32_mul -+ .global __avr32_f32_mul -+ .type __avr32_f32_mul,@function -+ -+ -+__avr32_f32_mul: -+ mov r8, r12 -+ eor r12, r11 /* MSB(r8) = Sign(op1) ^ Sign(op2) */ -+ andh r12, 0x8000, COH -+ -+ /* arrange operands so that that op1 >= op2 */ -+ cbr r8, 31 -+ breq __avr32_f32_mul_op1_zero -+ cbr r11, 31 -+ -+ /* Put the number with the largest exponent in r10 -+ and the number with the smallest exponent in r9 */ -+ max r10, r8, r11 -+ min r9, r8, r11 -+ -+ /* Unpack exponent and mantissa of op1 */ -+ lsl r8, r10, 8 -+ sbr r8, 31 /* Set implicit bit. */ -+ lsr r10, 23 -+ -+ /* op1 is NaN or Inf. */ -+ cp.w r10, 0xff -+ breq __avr32_f32_mul_op1_nan_or_inf -+ -+ /* Unpack exponent and mantissa of op2 */ -+ lsl r11, r9, 8 -+ sbr r11, 31 /* Set implicit bit. */ -+ lsr r9, 23 -+ -+ /* op2 is either zero or subnormal. */ -+ breq __avr32_f32_mul_op2_subnormal -+0: -+ /* Calculate new exponent */ -+ add r9,r10 -+ -+ /* Do the multiplication */ -+ mulu.d r10,r8,r11 -+ -+ /* We might need to scale up by two if the MSB of the result is -+ zero. */ -+ lsl r8, r11, 1 -+ movcc r11, r8 -+ subcc r9, 1 -+ -+ /* Put the shifted out bits of the mantissa into r10 */ -+ lsr r10, 8 -+ bfins r10, r11, 24, 8 -+ -+ sub r9,(127-1) /* remove extra exponent bias */ -+ brle __avr32_f32_mul_res_subnormal -+ -+ /* Check for Inf. */ -+ cp.w r9, 0xff -+ brge 1f -+ -+ /* Pack result. */ -+ or r12, r12, r11 >> 8 -+ bfins r12, r9, 23, 8 -+ -+ /* Round */ -+__avr32_f32_mul_round: -+ mov_imm r8, 0x80000000 -+ bld r12, 0 -+ subne r8, -1 -+ -+ cp.w r10, r8 -+ subhs r12, -1 -+ -+ ret r12 -+ -+1: -+ /* Return Inf */ -+ orh r12, 0x7f80 -+ ret r12 -+ -+__avr32_f32_mul_op2_subnormal: -+ cbr r11, 31 -+ clz r9, r11 -+ retcs 0 /* op2 is zero. Return 0 */ -+ sub r9, 8 -+ lsl r11, r11, r9 -+ rsub r9, r9, 1 -+ -+ /* Check if op2 is subnormal. */ -+ tst r10, r10 -+ brne 0b -+ -+ /* op2 is subnormal */ -+ cbr r8, 31 -+ clz r10, r11 -+ retcs 0 /* op1 is zero. Return 0 */ -+ lsl r8, r8, r10 -+ rsub r10, r10, 1 -+ -+ rjmp 0b -+ -+ -+__avr32_f32_mul_op1_nan_or_inf: -+ /* Check if op1 is NaN, if so return NaN */ -+ lsl r11, r8, 1 -+ retne -1 -+ -+ /* op1 is Inf. */ -+ tst r9, r9 -+ reteq -1 /* Inf * 0 -> NaN */ -+ -+ bfins r12, r10, 23, 8 /* Generate Inf in r12 */ -+ -+ /* Check if op2 is Inf. or NaN */ -+ lsr r11, r9, 23 -+ cp.w r11, 0xff -+ retne r12 /* op2 not Inf or NaN, return Info */ -+ -+ lsl r9, 9 -+ reteq r12 /* op2 Inf return Inf */ -+ ret -1 /* op2 is NaN, return NaN */ -+ -+__avr32_f32_mul_res_subnormal: -+ /* Check if the number is so small that -+ it will be represented with zero. */ -+ rsub r9, r9, 9 -+ rsub r8, r9, 32 -+ retcs 0 -+ -+ /* Shift the mantissa into the correct position.*/ -+ lsr r9, r11, r9 -+ /* Add sign bit. */ -+ or r12, r9 -+ /* Put the shifted out bits in the most significant part -+ of r8. */ -+ lsl r11, r11, r8 -+ -+ /* Add all the remainder bits used for rounding into r11 */ -+ andh r10, 0x00FF -+ or r10, r11 -+ rjmp __avr32_f32_mul_round -+ -+__avr32_f32_mul_op1_zero: -+ bfextu r10, r11, 23, 8 -+ cp.w r10, 0xff -+ retne r12 -+ reteq -1 -+ -+#endif -+ -+ -+#ifdef L_avr32_s32_to_f32 -+ .global __avr32_s32_to_f32 -+ .type __avr32_s32_to_f32,@function -+__avr32_s32_to_f32: -+ cp r12, 0 -+ reteq r12 /* If zero then return zero float */ -+ mov r11, r12 /* Keep the sign */ -+ abs r12 /* Compute the absolute value */ -+ mov r10, 31 + 127 /* Set the correct exponent */ -+ -+ /* Normalize */ -+ normalize_sf r10 /*exp*/, r12 /*mant*/, r9 /*scratch*/ -+ -+ /* Check for subnormal result */ -+ cp.w r10, 0 -+ brle __avr32_s32_to_f32_subnormal -+ -+ round_sf r10 /*exp*/, r12 /*mant*/, r9 /*scratch*/ -+ pack_sf r12 /*sf*/, r10 /*exp*/, r12 /*mant*/ -+ lsl r11, 1 -+ ror r12 -+ ret r12 -+ -+__avr32_s32_to_f32_subnormal: -+ /* Adjust a subnormal result */ -+ adjust_subnormal_sf r12/*sf*/, r10 /*exp*/, r12 /*mant*/, r11/*sign*/, r9 /*scratch*/ -+ ret r12 -+ -+#endif -+ -+#ifdef L_avr32_u32_to_f32 -+ .global __avr32_u32_to_f32 -+ .type __avr32_u32_to_f32,@function -+__avr32_u32_to_f32: -+ cp r12, 0 -+ reteq r12 /* If zero then return zero float */ -+ mov r10, 31 + 127 /* Set the correct exponent */ -+ -+ /* Normalize */ -+ normalize_sf r10 /*exp*/, r12 /*mant*/, r9 /*scratch*/ -+ -+ /* Check for subnormal result */ -+ cp.w r10, 0 -+ brle __avr32_u32_to_f32_subnormal -+ -+ round_sf r10 /*exp*/, r12 /*mant*/, r9 /*scratch*/ -+ pack_sf r12 /*sf*/, r10 /*exp*/, r12 /*mant*/ -+ lsr r12,1 /* Sign bit is 0 for unsigned int */ -+ ret r12 -+ -+__avr32_u32_to_f32_subnormal: -+ /* Adjust a subnormal result */ -+ mov r8, 0 -+ adjust_subnormal_sf r12/*sf*/,r10 /*exp*/, r12 /*mant*/,r8/*sign*/, r9 /*scratch*/ -+ ret r12 -+ -+ -+#endif -+ -+ -+#ifdef L_avr32_f32_to_s32 -+ .global __avr32_f32_to_s32 -+ .type __avr32_f32_to_s32,@function -+__avr32_f32_to_s32: -+ bfextu r11, r12, 23, 8 -+ sub r11,127 /* Fix bias */ -+ retlo 0 /* Negative exponent yields zero integer */ -+ -+ /* Shift mantissa into correct position */ -+ rsub r11,r11,31 /* Shift amount */ -+ lsl r10,r12,8 /* Get mantissa */ -+ sbr r10,31 /* Add implicit bit */ -+ lsr r10,r10,r11 /* Perform shift */ -+ lsl r12,1 /* Check sign */ -+ retcc r10 /* if positive, we are done */ -+ neg r10 /* if negative float, negate result */ -+ ret r10 -+ -+#endif -+ -+#ifdef L_avr32_f32_to_u32 -+ .global __avr32_f32_to_u32 -+ .type __avr32_f32_to_u32,@function -+__avr32_f32_to_u32: -+ cp r12,0 -+ retmi 0 /* Negative numbers gives 0 */ -+ bfextu r11, r12, 23, 8 /* Extract exponent */ -+ sub r11,127 /* Fix bias */ -+ retlo 0 /* Negative exponent yields zero integer */ -+ -+ /* Shift mantissa into correct position */ -+ rsub r11,r11,31 /* Shift amount */ -+ lsl r12,8 /* Get mantissa */ -+ sbr r12,31 /* Add implicit bit */ -+ lsr r12,r12,r11 /* Perform shift */ -+ ret r12 -+ -+#endif -+ -+#ifdef L_avr32_f32_to_f64 -+ .global __avr32_f32_to_f64 -+ .type __avr32_f32_to_f64,@function -+ -+__avr32_f32_to_f64: -+ lsl r11,r12,1 /* Remove sign bit, keep original value in r12*/ -+ moveq r10, 0 -+ reteq r11 /* Return zero if input is zero */ -+ -+ bfextu r9,r11,24,8 /* Get exponent */ -+ cp.w r9,0xff /* check for NaN or inf */ -+ breq 0f -+ -+ lsl r11,7 /* Convert sf mantissa to df format */ -+ mov r10,0 -+ -+ /* Check if implicit bit should be set */ -+ cp.w r9, 0 -+ subeq r9,-1 /* Adjust exponent if it was 0 */ -+ srne r8 -+ or r11, r11, r8 << 31 /* Set implicit bit if needed */ -+ sub r9,(127-0x3ff) /* Convert exponent to df format exponent */ -+ -+ /*We know that low register of mantissa is 0, and will be unaffected by normalization.*/ -+ /*We can therefore use the faster normalize_sf function instead of normalize_df.*/ -+ normalize_sf r9 /*exp*/, r11 /*mantissa*/, r8 /*scratch*/ -+ pack_df r9 /*exp*/, r10, r11 /*mantissa*/, r10, r11 /*df*/ -+ -+__extendsfdf_return_op1: -+ /* Rotate in sign bit */ -+ lsl r12, 1 -+ ror r11 -+ ret r11 -+ -+0: -+ /* Inf or NaN*/ -+ mov_imm r10, 0xffe00000 -+ lsl r11,8 /* check mantissa */ -+ movne r11, -1 /* Return NaN */ -+ moveq r11, r10 /* Return inf */ -+ mov r10, 0 -+ rjmp __extendsfdf_return_op1 -+#endif -+ -+ -+#ifdef L_avr32_f64_to_f32 -+ .global __avr32_f64_to_f32 -+ .type __avr32_f64_to_f32,@function -+ -+__avr32_f64_to_f32: -+ /* Unpack */ -+ lsl r9,r11,1 /* Unpack exponent */ -+ lsr r9,21 -+ -+ reteq 0 /* If exponent is 0 the number is so small -+ that the conversion to single float gives -+ zero */ -+ -+ lsl r8,r11,10 /* Adjust mantissa */ -+ or r12,r8,r10>>22 -+ -+ lsl r10,10 /* Check if there are any remaining bits -+ in the low part of the mantissa.*/ -+ neg r10 -+ rol r12 /* If there were remaining bits then set lsb -+ of mantissa to 1 */ -+ -+ cp r9,0x7ff -+ breq 2f /* Check for NaN or inf */ -+ -+ sub r9,(0x3ff-127) /* Adjust bias of exponent */ -+ sbr r12,31 /* set the implicit bit.*/ -+ -+ cp.w r9, 0 /* Check for subnormal number */ -+ brle 3f -+ -+ round_sf r9 /*exp*/, r12 /*mant*/, r10 /*scratch*/ -+ pack_sf r12 /*sf*/, r9 /*exp*/, r12 /*mant*/ -+__truncdfsf_return_op1: -+ /* Rotate in sign bit */ -+ lsl r11, 1 -+ ror r12 -+ ret r12 -+ -+2: -+ /* NaN or inf */ -+ cbr r12,31 /* clear implicit bit */ -+ retne -1 /* Return NaN if mantissa not zero */ -+ mov_imm r12, 0x7f800000 -+ ret r12 /* Return inf */ -+ -+3: /* Result is subnormal. Adjust it.*/ -+ adjust_subnormal_sf r12/*sf*/,r9 /*exp*/, r12 /*mant*/, r11/*sign*/, r10 /*scratch*/ -+ ret r12 -+ -+ -+#endif -+ -+#if defined(L_mulsi3) && defined(__AVR32_NO_MUL__) -+ .global __mulsi3 -+ .type __mulsi3,@function -+ -+__mulsi3: -+ mov r9, 0 -+0: -+ lsr r11, 1 -+ addcs r9, r9, r12 -+ breq 1f -+ lsl r12, 1 -+ rjmp 0b -+1: -+ ret r9 -+#endif ---- /dev/null -+++ b/gcc/config/avr32/lib2funcs.S -@@ -0,0 +1,21 @@ -+ .align 4 -+ .global __nonlocal_goto -+ .type __nonlocal_goto,@function -+ -+/* __nonlocal_goto: This function handles nonlocal_goto's in gcc. -+ -+ parameter 0 (r12) = New Frame Pointer -+ parameter 1 (r11) = Address to goto -+ parameter 2 (r10) = New Stack Pointer -+ -+ This function invalidates the return stack, since it returns from a -+ function without using a return instruction. -+*/ -+__nonlocal_goto: -+ mov r7, r12 -+ mov sp, r10 -+ frs # Flush return stack -+ mov pc, r11 -+ -+ -+ ---- /dev/null -+++ b/gcc/config/avr32/linux-elf.h -@@ -0,0 +1,151 @@ -+/* -+ Linux/Elf specific definitions. -+ Copyright 2003-2006 Atmel Corporation. -+ -+ Written by Ronny Pedersen, Atmel Norway, -+ and H�vard Skinnemoen, Atmel Norway, -+ -+ This file is part of GCC. -+ -+ 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 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 this program; if not, write to the Free Software -+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -+ -+ -+ -+/* elfos.h should have already been included. Now just override -+ any conflicting definitions and add any extras. */ -+ -+/* Run-time Target Specification. */ -+#undef TARGET_VERSION -+#define TARGET_VERSION fputs (" (AVR32 GNU/Linux with ELF)", stderr); -+ -+/* Do not assume anything about header files. */ -+#define NO_IMPLICIT_EXTERN_C -+ -+/* The GNU C++ standard library requires that these macros be defined. */ -+#undef CPLUSPLUS_CPP_SPEC -+#define CPLUSPLUS_CPP_SPEC "-D_GNU_SOURCE %(cpp)" -+ -+/* Now we define the strings used to build the spec file. */ -+#undef LIB_SPEC -+#define LIB_SPEC \ -+ "%{pthread:-lpthread} \ -+ %{shared:-lc} \ -+ %{!shared:%{profile:-lc_p}%{!profile:-lc}}" -+ -+/* Provide a STARTFILE_SPEC appropriate for GNU/Linux. Here we add -+ the GNU/Linux magical crtbegin.o file (see crtstuff.c) which -+ provides part of the support for getting C++ file-scope static -+ object constructed before entering `main'. */ -+ -+#undef STARTFILE_SPEC -+#define STARTFILE_SPEC \ -+ "%{!shared: \ -+ %{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} \ -+ %{!p:%{profile:gcrt1.o%s} \ -+ %{!profile:crt1.o%s}}}} \ -+ crti.o%s %{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}" -+ -+/* Provide a ENDFILE_SPEC appropriate for GNU/Linux. Here we tack on -+ the GNU/Linux magical crtend.o file (see crtstuff.c) which -+ provides part of the support for getting C++ file-scope static -+ object constructed before entering `main', followed by a normal -+ GNU/Linux "finalizer" file, `crtn.o'. */ -+ -+#undef ENDFILE_SPEC -+#define ENDFILE_SPEC \ -+ "%{!shared:crtend.o%s} %{shared:crtendS.o%s} crtn.o%s" -+ -+#undef ASM_SPEC -+#define ASM_SPEC "%{!mno-pic:%{!fno-pic:--pic}} %{mrelax|O*:%{mno-relax|O0|O1: ;:--linkrelax}} %{mcpu=*:-mcpu=%*}" -+ -+#undef LINK_SPEC -+#define LINK_SPEC "%{version:-v} \ -+ %{static:-Bstatic} \ -+ %{shared:-shared} \ -+ %{symbolic:-Bsymbolic} \ -+ %{rdynamic:-export-dynamic} \ -+ %{!dynamic-linker:-dynamic-linker /lib/ld-uClibc.so.0} \ -+ %{mrelax|O*:%{mno-relax|O0|O1: ;:--relax}}" -+ -+#define TARGET_OS_CPP_BUILTINS() LINUX_TARGET_OS_CPP_BUILTINS() -+ -+/* This is how we tell the assembler that two symbols have the same value. */ -+#define ASM_OUTPUT_DEF(FILE, NAME1, NAME2) \ -+ do \ -+ { \ -+ assemble_name (FILE, NAME1); \ -+ fputs (" = ", FILE); \ -+ assemble_name (FILE, NAME2); \ -+ fputc ('\n', FILE); \ -+ } \ -+ while (0) -+ -+ -+ -+#undef CC1_SPEC -+#define CC1_SPEC "%{profile:-p}" -+ -+/* Target CPU builtins. */ -+#define TARGET_CPU_CPP_BUILTINS() \ -+ do \ -+ { \ -+ builtin_define ("__avr32__"); \ -+ builtin_define ("__AVR32__"); \ -+ builtin_define ("__AVR32_LINUX__"); \ -+ builtin_define (avr32_part->macro); \ -+ builtin_define (avr32_arch->macro); \ -+ if (avr32_arch->uarch_type == UARCH_TYPE_AVR32A) \ -+ builtin_define ("__AVR32_AVR32A__"); \ -+ else \ -+ builtin_define ("__AVR32_AVR32B__"); \ -+ if (TARGET_UNALIGNED_WORD) \ -+ builtin_define ("__AVR32_HAS_UNALIGNED_WORD__"); \ -+ if (TARGET_SIMD) \ -+ builtin_define ("__AVR32_HAS_SIMD__"); \ -+ if (TARGET_DSP) \ -+ builtin_define ("__AVR32_HAS_DSP__"); \ -+ if (TARGET_RMW) \ -+ builtin_define ("__AVR32_HAS_RMW__"); \ -+ if (TARGET_BRANCH_PRED) \ -+ builtin_define ("__AVR32_HAS_BRANCH_PRED__"); \ -+ if (TARGET_FAST_FLOAT) \ -+ builtin_define ("__AVR32_FAST_FLOAT__"); \ -+ } \ -+ while (0) -+ -+ -+ -+/* Call the function profiler with a given profile label. */ -+#undef FUNCTION_PROFILER -+#define FUNCTION_PROFILER(STREAM, LABELNO) \ -+ do \ -+ { \ -+ fprintf (STREAM, "\tmov\tlr, lo(mcount)\n\torh\tlr, hi(mcount)\n"); \ -+ fprintf (STREAM, "\ticall lr\n"); \ -+ } \ -+ while (0) -+ -+#define NO_PROFILE_COUNTERS 1 -+ -+/* For dynamic libraries to work */ -+/* #define PLT_REG_CALL_CLOBBERED 1 */ -+#define AVR32_ALWAYS_PIC 1 -+ -+/* uclibc does not implement sinf, cosf etc. */ -+#undef TARGET_C99_FUNCTIONS -+#define TARGET_C99_FUNCTIONS 0 -+ -+#define LINK_GCC_C_SEQUENCE_SPEC \ -+ "%{static:--start-group} %G %L %{static:--end-group}%{!static:%G}" ---- /dev/null -+++ b/gcc/config/avr32/predicates.md -@@ -0,0 +1,422 @@ -+;; AVR32 predicates file. -+;; Copyright 2003-2006 Atmel Corporation. -+;; -+;; Written by Ronny Pedersen, Atmel Norway, -+;; -+;; This file is part of GCC. -+;; -+;; 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 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 this program; if not, write to the Free Software -+;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ -+ -+;; True if the operand is a memory reference which contains an -+;; Address consisting of a single pointer register -+(define_predicate "avr32_indirect_register_operand" -+ (and (match_code "mem") -+ (match_test "register_operand(XEXP(op, 0), SImode)"))) -+ -+ -+ -+;; Address expression with a base pointer offset with -+;; a register displacement -+(define_predicate "avr32_indexed_memory_operand" -+ (and (match_code "mem") -+ (match_test "GET_CODE(XEXP(op, 0)) == PLUS")) -+ { -+ -+ rtx op0 = XEXP(XEXP(op, 0), 0); -+ rtx op1 = XEXP(XEXP(op, 0), 1); -+ -+ return ((avr32_address_register_rtx_p (op0, 0) -+ && avr32_legitimate_index_p (GET_MODE(op), op1, 0)) -+ || (avr32_address_register_rtx_p (op1, 0) -+ && avr32_legitimate_index_p (GET_MODE(op), op0, 0))); -+ -+ }) -+ -+;; Operand suitable for the ld.sb instruction -+(define_predicate "load_sb_memory_operand" -+ (ior (match_operand 0 "avr32_indirect_register_operand") -+ (match_operand 0 "avr32_indexed_memory_operand"))) -+ -+ -+;; Operand suitable as operand to insns sign extending QI values -+(define_predicate "extendqi_operand" -+ (ior (match_operand 0 "load_sb_memory_operand") -+ (match_operand 0 "register_operand"))) -+ -+(define_predicate "post_inc_memory_operand" -+ (and (match_code "mem") -+ (match_test "(GET_CODE(XEXP(op, 0)) == POST_INC) -+ && REG_P(XEXP(XEXP(op, 0), 0))"))) -+ -+(define_predicate "pre_dec_memory_operand" -+ (and (match_code "mem") -+ (match_test "(GET_CODE(XEXP(op, 0)) == PRE_DEC) -+ && REG_P(XEXP(XEXP(op, 0), 0))"))) -+ -+;; Operand suitable for add instructions -+(define_predicate "avr32_add_operand" -+ (ior (match_operand 0 "register_operand") -+ (and (match_operand 0 "immediate_operand") -+ (match_test "CONST_OK_FOR_CONSTRAINT_P(INTVAL(op), 'I', \"Is21\")")))) -+ -+;; Operand is a power of two immediate -+(define_predicate "power_of_two_operand" -+ (match_code "const_int") -+{ -+ HOST_WIDE_INT value = INTVAL (op); -+ -+ return value != 0 && (value & (value - 1)) == 0; -+}) -+ -+;; Operand is a multiple of 8 immediate -+(define_predicate "multiple_of_8_operand" -+ (match_code "const_int") -+{ -+ HOST_WIDE_INT value = INTVAL (op); -+ -+ return (value & 0x7) == 0 ; -+}) -+ -+;; Operand is a multiple of 16 immediate -+(define_predicate "multiple_of_16_operand" -+ (match_code "const_int") -+{ -+ HOST_WIDE_INT value = INTVAL (op); -+ -+ return (value & 0xf) == 0 ; -+}) -+ -+;; Operand is a mask used for masking away upper bits of a reg -+(define_predicate "avr32_mask_upper_bits_operand" -+ (match_code "const_int") -+{ -+ HOST_WIDE_INT value = INTVAL (op) + 1; -+ -+ return value != 1 && value != 0 && (value & (value - 1)) == 0; -+}) -+ -+ -+;; Operand suitable for mul instructions -+(define_predicate "avr32_mul_operand" -+ (ior (match_operand 0 "register_operand") -+ (and (match_operand 0 "immediate_operand") -+ (match_test "CONST_OK_FOR_CONSTRAINT_P(INTVAL(op), 'K', \"Ks08\")")))) -+ -+;; True for logical binary operators. -+(define_predicate "logical_binary_operator" -+ (match_code "ior,xor,and")) -+ -+;; True for logical shift operators -+(define_predicate "logical_shift_operator" -+ (match_code "ashift,lshiftrt")) -+ -+;; True for shift operand for logical and, or and eor insns -+(define_predicate "avr32_logical_shift_operand" -+ (and (match_code "ashift,lshiftrt") -+ (ior (and (match_test "GET_CODE(XEXP(op, 1)) == CONST_INT") -+ (match_test "register_operand(XEXP(op, 0), GET_MODE(XEXP(op, 0)))")) -+ (and (match_test "GET_CODE(XEXP(op, 0)) == CONST_INT") -+ (match_test "register_operand(XEXP(op, 1), GET_MODE(XEXP(op, 1)))")))) -+ ) -+ -+ -+;; Predicate for second operand to and, ior and xor insn patterns -+(define_predicate "avr32_logical_insn_operand" -+ (ior (match_operand 0 "register_operand") -+ (match_operand 0 "avr32_logical_shift_operand")) -+) -+ -+ -+;; True for avr32 comparison operators -+(define_predicate "avr32_comparison_operator" -+ (ior (match_code "eq, ne, gt, ge, lt, le, gtu, geu, ltu, leu") -+ (and (match_code "unspec") -+ (match_test "(XINT(op, 1) == UNSPEC_COND_MI) -+ || (XINT(op, 1) == UNSPEC_COND_PL)")))) -+ -+(define_predicate "avr32_cond3_comparison_operator" -+ (ior (match_code "eq, ne, ge, lt, geu, ltu") -+ (and (match_code "unspec") -+ (match_test "(XINT(op, 1) == UNSPEC_COND_MI) -+ || (XINT(op, 1) == UNSPEC_COND_PL)")))) -+ -+;; True for avr32 comparison operand -+(define_predicate "avr32_comparison_operand" -+ (ior (and (match_code "eq, ne, gt, ge, lt, le, gtu, geu, ltu, leu") -+ (match_test "(CC0_P (XEXP(op,0)) && rtx_equal_p (XEXP(op,1), const0_rtx))")) -+ (and (match_code "unspec") -+ (match_test "(XINT(op, 1) == UNSPEC_COND_MI) -+ || (XINT(op, 1) == UNSPEC_COND_PL)")))) -+ -+;; True if this is a const_int with one bit set -+(define_predicate "one_bit_set_operand" -+ (match_code "const_int") -+ { -+ int i; -+ int value; -+ int ones = 0; -+ -+ value = INTVAL(op); -+ for ( i = 0 ; i < 32; i++ ){ -+ if ( value & ( 1 << i ) ){ -+ ones++; -+ } -+ } -+ -+ return ( ones == 1 ); -+ }) -+ -+ -+;; True if this is a const_int with one bit cleared -+(define_predicate "one_bit_cleared_operand" -+ (match_code "const_int") -+ { -+ int i; -+ int value; -+ int zeroes = 0; -+ -+ value = INTVAL(op); -+ for ( i = 0 ; i < 32; i++ ){ -+ if ( !(value & ( 1 << i )) ){ -+ zeroes++; -+ } -+ } -+ -+ return ( zeroes == 1 ); -+ }) -+ -+ -+;; Immediate all the low 16-bits cleared -+(define_predicate "avr32_hi16_immediate_operand" -+ (match_code "const_int") -+ { -+ /* If the low 16-bits are zero then this -+ is a hi16 immediate. */ -+ return ((INTVAL(op) & 0xffff) == 0); -+ } -+) -+ -+;; True if this is a register or immediate operand -+(define_predicate "register_immediate_operand" -+ (ior (match_operand 0 "register_operand") -+ (match_operand 0 "immediate_operand"))) -+ -+;; True if this is a register or const_int operand -+(define_predicate "register_const_int_operand" -+ (ior (match_operand 0 "register_operand") -+ (and (match_operand 0 "const_int_operand") -+ (match_operand 0 "immediate_operand")))) -+ -+;; True if this is a register or const_double operand -+(define_predicate "register_const_double_operand" -+ (ior (match_operand 0 "register_operand") -+ (match_operand 0 "const_double_operand"))) -+ -+;; True if this is an operand containing a label_ref. -+(define_predicate "avr32_label_ref_operand" -+ (and (match_code "mem") -+ (match_test "avr32_find_symbol(op) -+ && (GET_CODE(avr32_find_symbol(op)) == LABEL_REF)"))) -+ -+;; True if this is a valid symbol pointing to the constant pool. -+(define_predicate "avr32_const_pool_operand" -+ (and (match_code "symbol_ref") -+ (match_test "CONSTANT_POOL_ADDRESS_P(op)")) -+ { -+ return (flag_pic ? (!(symbol_mentioned_p (get_pool_constant (op)) -+ || label_mentioned_p (get_pool_constant (op))) -+ || avr32_got_mentioned_p(get_pool_constant (op))) -+ : true); -+ } -+) -+ -+;; True if this is a memory reference to the constant or mini pool. -+(define_predicate "avr32_const_pool_ref_operand" -+ (ior (match_operand 0 "avr32_label_ref_operand") -+ (and (match_code "mem") -+ (match_test "avr32_const_pool_operand(XEXP(op,0), GET_MODE(XEXP(op,0)))")))) -+ -+ -+;; Legal source operand for movti insns -+(define_predicate "avr32_movti_src_operand" -+ (ior (match_operand 0 "avr32_const_pool_ref_operand") -+ (ior (ior (match_operand 0 "register_immediate_operand") -+ (match_operand 0 "avr32_indirect_register_operand")) -+ (match_operand 0 "post_inc_memory_operand")))) -+ -+;; Legal destination operand for movti insns -+(define_predicate "avr32_movti_dst_operand" -+ (ior (ior (match_operand 0 "register_operand") -+ (match_operand 0 "avr32_indirect_register_operand")) -+ (match_operand 0 "pre_dec_memory_operand"))) -+ -+ -+;; True if this is a k12 offseted memory operand. -+(define_predicate "avr32_k12_memory_operand" -+ (and (match_code "mem") -+ (ior (match_test "REG_P(XEXP(op, 0))") -+ (match_test "GET_CODE(XEXP(op, 0)) == PLUS -+ && REG_P(XEXP(XEXP(op, 0), 0)) -+ && (GET_CODE(XEXP(XEXP(op, 0), 1)) == CONST_INT) -+ && (CONST_OK_FOR_CONSTRAINT_P(INTVAL(XEXP(XEXP(op, 0), 0)), -+ 'K', (mode == SImode) ? \"Ks14\" : ((mode == HImode) ? \"Ks13\" : \"Ks12\")))")))) -+ -+;; True if this is a memory operand with an immediate displacement. -+(define_predicate "avr32_imm_disp_memory_operand" -+ (and (match_code "mem") -+ (match_test "GET_CODE(XEXP(op, 0)) == PLUS -+ && REG_P(XEXP(XEXP(op, 0), 0)) -+ && (GET_CODE(XEXP(XEXP(op, 0), 1)) == CONST_INT)"))) -+ -+;; True if this is a bswap operand. -+(define_predicate "avr32_bswap_operand" -+ (ior (match_operand 0 "avr32_k12_memory_operand") -+ (match_operand 0 "register_operand"))) -+ -+;; True if this is a valid coprocessor insn memory operand. -+(define_predicate "avr32_cop_memory_operand" -+ (and (match_operand 0 "memory_operand") -+ (not (match_test "GET_CODE(XEXP(op, 0)) == PLUS -+ && REG_P(XEXP(XEXP(op, 0), 0)) -+ && (GET_CODE(XEXP(XEXP(op, 0), 1)) == CONST_INT) -+ && !(CONST_OK_FOR_CONSTRAINT_P(INTVAL(XEXP(XEXP(op, 0), 0)), 'K', \"Ku10\"))")))) -+ -+;; True if this is a valid source/destination operand. -+;; for moving values to/from a coprocessor -+(define_predicate "avr32_cop_move_operand" -+ (ior (match_operand 0 "register_operand") -+ (match_operand 0 "avr32_cop_memory_operand"))) -+ -+ -+;; True if this is a valid extract byte offset for use in -+;; load extracted index insns. -+(define_predicate "avr32_extract_shift_operand" -+ (and (match_operand 0 "const_int_operand") -+ (match_test "(INTVAL(op) == 0) || (INTVAL(op) == 8) -+ || (INTVAL(op) == 16) || (INTVAL(op) == 24)"))) -+ -+;; True if this is a valid avr32 symbol operand. -+(define_predicate "avr32_symbol_operand" -+ (and (match_code "label_ref, symbol_ref, const") -+ (match_test "avr32_find_symbol(op)"))) -+ -+;; True if this is a valid operand for the lda.w and call pseudo insns. -+(define_predicate "avr32_address_operand" -+ (and (and (match_code "label_ref, symbol_ref") -+ (match_test "avr32_find_symbol(op)")) -+ (ior (match_test "TARGET_HAS_ASM_ADDR_PSEUDOS") -+ (match_test "flag_pic")) )) -+ -+;; An immediate k16 address operand -+(define_predicate "avr32_ks16_address_operand" -+ (and (match_operand 0 "address_operand") -+ (ior (match_test "REG_P(op)") -+ (match_test "GET_CODE(op) == PLUS -+ && ((GET_CODE(XEXP(op,0)) == CONST_INT) -+ || (GET_CODE(XEXP(op,1)) == CONST_INT))")) )) -+ -+;; An offset k16 memory operand -+(define_predicate "avr32_ks16_memory_operand" -+ (and (match_code "mem") -+ (match_test "avr32_ks16_address_operand (XEXP (op, 0), GET_MODE (XEXP (op, 0)))"))) -+ -+;; An immediate k11 address operand -+(define_predicate "avr32_ks11_address_operand" -+ (and (match_operand 0 "address_operand") -+ (ior (match_test "REG_P(op)") -+ (match_test "GET_CODE(op) == PLUS -+ && (((GET_CODE(XEXP(op,0)) == CONST_INT) -+ && avr32_const_ok_for_constraint_p(INTVAL(XEXP(op,0)), 'K', \"Ks11\")) -+ || ((GET_CODE(XEXP(op,1)) == CONST_INT) -+ && avr32_const_ok_for_constraint_p(INTVAL(XEXP(op,1)), 'K', \"Ks11\")))")) )) -+ -+;; True if this is a avr32 call operand -+(define_predicate "avr32_call_operand" -+ (ior (ior (match_operand 0 "register_operand") -+ (ior (match_operand 0 "avr32_const_pool_ref_operand") -+ (match_operand 0 "avr32_address_operand"))) -+ (match_test "SYMBOL_REF_RCALL_FUNCTION_P(op)"))) -+ -+;; Return true for operators performing ALU operations -+ -+(define_predicate "alu_operator" -+ (match_code "ior, xor, and, plus, minus, ashift, lshiftrt, ashiftrt")) -+ -+(define_predicate "avr32_add_shift_immediate_operand" -+ (and (match_operand 0 "immediate_operand") -+ (match_test "CONST_OK_FOR_CONSTRAINT_P(INTVAL(op), 'K', \"Ku02\")"))) -+ -+(define_predicate "avr32_cond_register_immediate_operand" -+ (ior (match_operand 0 "register_operand") -+ (and (match_operand 0 "immediate_operand") -+ (match_test "CONST_OK_FOR_CONSTRAINT_P(INTVAL(op), 'K', \"Ks08\")")))) -+ -+(define_predicate "avr32_cond_immediate_operand" -+ (and (match_operand 0 "immediate_operand") -+ (match_test "CONST_OK_FOR_CONSTRAINT_P(INTVAL(op), 'I', \"Is08\")"))) -+ -+ -+(define_predicate "avr32_cond_move_operand" -+ (ior (ior (match_operand 0 "register_operand") -+ (and (match_operand 0 "immediate_operand") -+ (match_test "CONST_OK_FOR_CONSTRAINT_P(INTVAL(op), 'K', \"Ks08\")"))) -+ (and (match_test "TARGET_V2_INSNS") -+ (match_operand 0 "memory_operand")))) -+ -+(define_predicate "avr32_mov_immediate_operand" -+ (and (match_operand 0 "immediate_operand") -+ (match_test "avr32_const_ok_for_move(INTVAL(op))"))) -+ -+ -+(define_predicate "avr32_rmw_address_operand" -+ (ior (and (match_code "symbol_ref") -+ (match_test "({rtx symbol = avr32_find_symbol(op); \ -+ symbol && (GET_CODE (symbol) == SYMBOL_REF) && SYMBOL_REF_RMW_ADDR(symbol);})")) -+ (and (match_operand 0 "immediate_operand") -+ (match_test "CONST_OK_FOR_CONSTRAINT_P(INTVAL(op), 'K', \"Ks17\")"))) -+ { -+ return TARGET_RMW && !flag_pic; -+ } -+) -+ -+(define_predicate "avr32_rmw_memory_operand" -+ (and (match_code "mem") -+ (match_test "!volatile_refs_p(op) && (GET_MODE(op) == SImode) && -+ avr32_rmw_address_operand(XEXP(op, 0), GET_MODE(XEXP(op, 0)))"))) -+ -+(define_predicate "avr32_rmw_memory_or_register_operand" -+ (ior (match_operand 0 "avr32_rmw_memory_operand") -+ (match_operand 0 "register_operand"))) -+ -+(define_predicate "avr32_non_rmw_memory_operand" -+ (and (not (match_operand 0 "avr32_rmw_memory_operand")) -+ (match_operand 0 "memory_operand"))) -+ -+(define_predicate "avr32_non_rmw_general_operand" -+ (and (not (match_operand 0 "avr32_rmw_memory_operand")) -+ (match_operand 0 "general_operand"))) -+ -+(define_predicate "avr32_non_rmw_nonimmediate_operand" -+ (and (not (match_operand 0 "avr32_rmw_memory_operand")) -+ (match_operand 0 "nonimmediate_operand"))) -+ -+;; Return true if the operand is the 1.0f constant. -+ -+(define_predicate "const_1f_operand" -+ (match_code "const_int,const_double") -+{ -+ return (op == CONST1_RTX (SFmode)); -+}) ---- /dev/null -+++ b/gcc/config/avr32/simd.md -@@ -0,0 +1,145 @@ -+;; AVR32 machine description file for SIMD instructions. -+;; Copyright 2003-2006 Atmel Corporation. -+;; -+;; Written by Ronny Pedersen, Atmel Norway, -+;; -+;; This file is part of GCC. -+;; -+;; 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 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 this program; if not, write to the Free Software -+;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ -+;; -*- Mode: Scheme -*- -+ -+ -+;; Vector modes -+(define_mode_iterator VECM [V2HI V4QI]) -+(define_mode_attr size [(V2HI "h") (V4QI "b")]) -+ -+(define_insn "add3" -+ [(set (match_operand:VECM 0 "register_operand" "=r") -+ (plus:VECM (match_operand:VECM 1 "register_operand" "r") -+ (match_operand:VECM 2 "register_operand" "r")))] -+ "TARGET_SIMD" -+ "padd.\t%0, %1, %2" -+ [(set_attr "length" "4") -+ (set_attr "type" "alu")]) -+ -+ -+(define_insn "sub3" -+ [(set (match_operand:VECM 0 "register_operand" "=r") -+ (minus:VECM (match_operand:VECM 1 "register_operand" "r") -+ (match_operand:VECM 2 "register_operand" "r")))] -+ "TARGET_SIMD" -+ "psub.\t%0, %1, %2" -+ [(set_attr "length" "4") -+ (set_attr "type" "alu")]) -+ -+ -+(define_insn "abs2" -+ [(set (match_operand:VECM 0 "register_operand" "=r") -+ (abs:VECM (match_operand:VECM 1 "register_operand" "r")))] -+ "TARGET_SIMD" -+ "pabs.s\t%0, %1" -+ [(set_attr "length" "4") -+ (set_attr "type" "alu")]) -+ -+(define_insn "ashl3" -+ [(set (match_operand:VECM 0 "register_operand" "=r") -+ (ashift:VECM (match_operand:VECM 1 "register_operand" "r") -+ (match_operand:SI 2 "immediate_operand" "Ku04")))] -+ "TARGET_SIMD" -+ "plsl.\t%0, %1, %2" -+ [(set_attr "length" "4") -+ (set_attr "type" "alu")]) -+ -+(define_insn "ashr3" -+ [(set (match_operand:VECM 0 "register_operand" "=r") -+ (ashiftrt:VECM (match_operand:VECM 1 "register_operand" "r") -+ (match_operand:SI 2 "immediate_operand" "Ku04")))] -+ "TARGET_SIMD" -+ "pasr.\t%0, %1, %2" -+ [(set_attr "length" "4") -+ (set_attr "type" "alu")]) -+ -+(define_insn "lshr3" -+ [(set (match_operand:VECM 0 "register_operand" "=r") -+ (lshiftrt:VECM (match_operand:VECM 1 "register_operand" "r") -+ (match_operand:SI 2 "immediate_operand" "Ku04")))] -+ "TARGET_SIMD" -+ "plsr.\t%0, %1, %2" -+ [(set_attr "length" "4") -+ (set_attr "type" "alu")]) -+ -+(define_insn "smaxv2hi3" -+ [(set (match_operand:V2HI 0 "register_operand" "=r") -+ (smax:V2HI (match_operand:V2HI 1 "register_operand" "r") -+ (match_operand:V2HI 2 "register_operand" "r")))] -+ -+ "TARGET_SIMD" -+ "pmax.sh\t%0, %1, %2" -+ [(set_attr "length" "4") -+ (set_attr "type" "alu")]) -+ -+(define_insn "sminv2hi3" -+ [(set (match_operand:V2HI 0 "register_operand" "=r") -+ (smin:V2HI (match_operand:V2HI 1 "register_operand" "r") -+ (match_operand:V2HI 2 "register_operand" "r")))] -+ -+ "TARGET_SIMD" -+ "pmin.sh\t%0, %1, %2" -+ [(set_attr "length" "4") -+ (set_attr "type" "alu")]) -+ -+(define_insn "umaxv4qi3" -+ [(set (match_operand:V4QI 0 "register_operand" "=r") -+ (umax:V4QI (match_operand:V4QI 1 "register_operand" "r") -+ (match_operand:V4QI 2 "register_operand" "r")))] -+ -+ "TARGET_SIMD" -+ "pmax.ub\t%0, %1, %2" -+ [(set_attr "length" "4") -+ (set_attr "type" "alu")]) -+ -+(define_insn "uminv4qi3" -+ [(set (match_operand:V4QI 0 "register_operand" "=r") -+ (umin:V4QI (match_operand:V4QI 1 "register_operand" "r") -+ (match_operand:V4QI 2 "register_operand" "r")))] -+ -+ "TARGET_SIMD" -+ "pmin.ub\t%0, %1, %2" -+ [(set_attr "length" "4") -+ (set_attr "type" "alu")]) -+ -+ -+(define_insn "addsubv2hi" -+ [(set (match_operand:V2HI 0 "register_operand" "=r") -+ (vec_concat:V2HI -+ (plus:HI (match_operand:HI 1 "register_operand" "r") -+ (match_operand:HI 2 "register_operand" "r")) -+ (minus:HI (match_dup 1) (match_dup 2))))] -+ "TARGET_SIMD" -+ "paddsub.h\t%0, %1:b, %2:b" -+ [(set_attr "length" "4") -+ (set_attr "type" "alu")]) -+ -+(define_insn "subaddv2hi" -+ [(set (match_operand:V2HI 0 "register_operand" "=r") -+ (vec_concat:V2HI -+ (minus:HI (match_operand:HI 1 "register_operand" "r") -+ (match_operand:HI 2 "register_operand" "r")) -+ (plus:HI (match_dup 1) (match_dup 2))))] -+ "TARGET_SIMD" -+ "psubadd.h\t%0, %1:b, %2:b" -+ [(set_attr "length" "4") -+ (set_attr "type" "alu")]) ---- /dev/null -+++ b/gcc/config/avr32/sync.md -@@ -0,0 +1,244 @@ -+;;================================================================= -+;; Atomic operations -+;;================================================================= -+ -+ -+(define_insn "sync_compare_and_swapsi" -+ [(set (match_operand:SI 0 "register_operand" "=&r,&r") -+ (match_operand:SI 1 "memory_operand" "+RKs16,+RKs16")) -+ (set (match_dup 1) -+ (unspec_volatile:SI -+ [(match_dup 1) -+ (match_operand:SI 2 "register_immediate_operand" "r,Ks21") -+ (match_operand:SI 3 "register_operand" "r,r")] -+ VUNSPEC_SYNC_CMPXCHG)) ] -+ "" -+ "0: -+ ssrf\t5 -+ ld.w\t%0,%1 -+ cp.w\t%0,%2 -+ brne\t0f -+ stcond\t%1, %3 -+ brne\t0b -+ 0: -+ " -+ [(set_attr "length" "16,18") -+ (set_attr "cc" "clobber")] -+ ) -+ -+ -+(define_code_iterator atomic_op [plus minus and ior xor]) -+(define_code_attr atomic_asm_insn [(plus "add") (minus "sub") (and "and") (ior "or") (xor "eor")]) -+(define_code_attr atomic_insn [(plus "add") (minus "sub") (and "and") (ior "ior") (xor "xor")]) -+ -+(define_insn "sync_loadsi" -+ ; NB! Put an early clobber on the destination operand to -+ ; avoid gcc using the same register in the source and -+ ; destination. This is done in order to avoid gcc to -+ ; clobber the source operand since these instructions -+ ; are actually inside a "loop". -+ [(set (match_operand:SI 0 "register_operand" "=&r") -+ (unspec_volatile:SI -+ [(match_operand:SI 1 "avr32_ks16_memory_operand" "RKs16") -+ (label_ref (match_operand 2 "" ""))] -+ VUNSPEC_SYNC_SET_LOCK_AND_LOAD) )] -+ "" -+ "%2: -+ ssrf\t5 -+ ld.w\t%0,%1" -+ [(set_attr "length" "6") -+ (set_attr "cc" "clobber")] -+ ) -+ -+(define_insn "sync_store_if_lock" -+ [(set (match_operand:SI 0 "avr32_ks16_memory_operand" "=RKs16") -+ (unspec_volatile:SI -+ [(match_operand:SI 1 "register_operand" "r") -+ (label_ref (match_operand 2 "" ""))] -+ VUNSPEC_SYNC_STORE_IF_LOCK) )] -+ "" -+ "stcond\t%0, %1 -+ brne\t%2" -+ [(set_attr "length" "6") -+ (set_attr "cc" "clobber")] -+ ) -+ -+ -+(define_expand "sync_si" -+ [(set (match_dup 2) -+ (unspec_volatile:SI -+ [(match_operand:SI 0 "avr32_ks16_memory_operand" "") -+ (match_dup 3)] -+ VUNSPEC_SYNC_SET_LOCK_AND_LOAD)) -+ (set (match_dup 2) -+ (atomic_op:SI (match_dup 2) -+ (match_operand:SI 1 "register_immediate_operand" ""))) -+ (set (match_dup 0) -+ (unspec_volatile:SI -+ [(match_dup 2) -+ (match_dup 3)] -+ VUNSPEC_SYNC_STORE_IF_LOCK) ) -+ (use (match_dup 1)) -+ (use (match_dup 4))] -+ "" -+ { -+ rtx *mem_expr = &operands[0]; -+ rtx ptr_reg; -+ if ( !avr32_ks16_memory_operand (*mem_expr, GET_MODE (*mem_expr)) ) -+ { -+ ptr_reg = force_reg (Pmode, XEXP (*mem_expr, 0)); -+ XEXP (*mem_expr, 0) = ptr_reg; -+ } -+ else -+ { -+ rtx address = XEXP (*mem_expr, 0); -+ if ( REG_P (address) ) -+ ptr_reg = address; -+ else if ( REG_P (XEXP (address, 0)) ) -+ ptr_reg = XEXP (address, 0); -+ else -+ ptr_reg = XEXP (address, 1); -+ } -+ -+ operands[2] = gen_reg_rtx (SImode); -+ operands[3] = gen_rtx_LABEL_REF(Pmode, gen_label_rtx ()); -+ operands[4] = ptr_reg; -+ -+ } -+ ) -+ -+ -+ -+(define_expand "sync_old_si" -+ [(set (match_operand:SI 0 "register_operand" "") -+ (unspec_volatile:SI -+ [(match_operand:SI 1 "avr32_ks16_memory_operand" "") -+ (match_dup 4)] -+ VUNSPEC_SYNC_SET_LOCK_AND_LOAD)) -+ (set (match_dup 3) -+ (atomic_op:SI (match_dup 0) -+ (match_operand:SI 2 "register_immediate_operand" ""))) -+ (set (match_dup 1) -+ (unspec_volatile:SI -+ [(match_dup 3) -+ (match_dup 4)] -+ VUNSPEC_SYNC_STORE_IF_LOCK) ) -+ (use (match_dup 2)) -+ (use (match_dup 5))] -+ "" -+ { -+ rtx *mem_expr = &operands[1]; -+ rtx ptr_reg; -+ if ( !avr32_ks16_memory_operand (*mem_expr, GET_MODE (*mem_expr)) ) -+ { -+ ptr_reg = force_reg (Pmode, XEXP (*mem_expr, 0)); -+ XEXP (*mem_expr, 0) = ptr_reg; -+ } -+ else -+ { -+ rtx address = XEXP (*mem_expr, 0); -+ if ( REG_P (address) ) -+ ptr_reg = address; -+ else if ( REG_P (XEXP (address, 0)) ) -+ ptr_reg = XEXP (address, 0); -+ else -+ ptr_reg = XEXP (address, 1); -+ } -+ -+ operands[3] = gen_reg_rtx (SImode); -+ operands[4] = gen_rtx_LABEL_REF(Pmode, gen_label_rtx ()); -+ operands[5] = ptr_reg; -+ } -+ ) -+ -+(define_expand "sync_new_si" -+ [(set (match_operand:SI 0 "register_operand" "") -+ (unspec_volatile:SI -+ [(match_operand:SI 1 "avr32_ks16_memory_operand" "") -+ (match_dup 3)] -+ VUNSPEC_SYNC_SET_LOCK_AND_LOAD)) -+ (set (match_dup 0) -+ (atomic_op:SI (match_dup 0) -+ (match_operand:SI 2 "register_immediate_operand" ""))) -+ (set (match_dup 1) -+ (unspec_volatile:SI -+ [(match_dup 0) -+ (match_dup 3)] -+ VUNSPEC_SYNC_STORE_IF_LOCK) ) -+ (use (match_dup 2)) -+ (use (match_dup 4))] -+ "" -+ { -+ rtx *mem_expr = &operands[1]; -+ rtx ptr_reg; -+ if ( !avr32_ks16_memory_operand (*mem_expr, GET_MODE (*mem_expr)) ) -+ { -+ ptr_reg = force_reg (Pmode, XEXP (*mem_expr, 0)); -+ XEXP (*mem_expr, 0) = ptr_reg; -+ } -+ else -+ { -+ rtx address = XEXP (*mem_expr, 0); -+ if ( REG_P (address) ) -+ ptr_reg = address; -+ else if ( REG_P (XEXP (address, 0)) ) -+ ptr_reg = XEXP (address, 0); -+ else -+ ptr_reg = XEXP (address, 1); -+ } -+ -+ operands[3] = gen_rtx_LABEL_REF(Pmode, gen_label_rtx ()); -+ operands[4] = ptr_reg; -+ } -+ ) -+ -+ -+;(define_insn "sync_si" -+; [(set (match_operand:SI 0 "memory_operand" "+RKs16") -+; (unspec_volatile:SI -+; [(atomic_op:SI (match_dup 0) -+; (match_operand:SI 1 "register_operand" "r"))] -+; VUNSPEC_SYNC_CMPXCHG)) -+; (clobber (match_scratch:SI 2 "=&r"))] -+; "" -+; "0: -+; ssrf\t5 -+; ld.w\t%2,%0 -+; \t%2,%1 -+; stcond\t%0, %2 -+; brne\t0b -+; " -+; [(set_attr "length" "14") -+; (set_attr "cc" "clobber")] -+; ) -+; -+;(define_insn "sync_new_si" -+; [(set (match_operand:SI 1 "memory_operand" "+RKs16") -+; (unspec_volatile:SI -+; [(atomic_op:SI (match_dup 1) -+; (match_operand:SI 2 "register_operand" "r"))] -+; VUNSPEC_SYNC_CMPXCHG)) -+; (set (match_operand:SI 0 "register_operand" "=&r") -+; (atomic_op:SI (match_dup 1) -+; (match_dup 2)))] -+; "" -+; "0: -+; ssrf\t5 -+; ld.w\t%0,%1 -+; \t%0,%2 -+; stcond\t%1, %0 -+; brne\t0b -+; " -+; [(set_attr "length" "14") -+; (set_attr "cc" "clobber")] -+; ) -+ -+(define_insn "sync_lock_test_and_setsi" -+ [ (set (match_operand:SI 0 "register_operand" "=&r") -+ (match_operand:SI 1 "memory_operand" "+RKu00")) -+ (set (match_dup 1) -+ (match_operand:SI 2 "register_operand" "r")) ] -+ "" -+ "xchg\t%0, %p1, %2" -+ [(set_attr "length" "4")] -+ ) ---- /dev/null -+++ b/gcc/config/avr32/t-avr32 -@@ -0,0 +1,102 @@ -+ -+MD_INCLUDES= $(srcdir)/config/avr32/avr32.md \ -+ $(srcdir)/config/avr32/sync.md \ -+ $(srcdir)/config/avr32/simd.md \ -+ $(srcdir)/config/avr32/predicates.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) -+ -+# 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 -+ -+LIB1ASMSRC = avr32/lib1funcs.S -+LIB1ASMFUNCS = _avr32_f64_mul _avr32_f64_mul_fast _avr32_f64_addsub _avr32_f64_addsub_fast _avr32_f64_to_u32 \ -+ _avr32_f64_to_s32 _avr32_f64_to_u64 _avr32_f64_to_s64 _avr32_u32_to_f64 \ -+ _avr32_s32_to_f64 _avr32_f64_cmp_eq _avr32_f64_cmp_ge _avr32_f64_cmp_lt \ -+ _avr32_f32_cmp_eq _avr32_f32_cmp_ge _avr32_f32_cmp_lt _avr32_f64_div _avr32_f64_div_fast \ -+ _avr32_f32_div _avr32_f32_div_fast _avr32_f32_addsub _avr32_f32_addsub_fast \ -+ _avr32_f32_mul _avr32_s32_to_f32 _avr32_u32_to_f32 _avr32_f32_to_s32 \ -+ _avr32_f32_to_u32 _avr32_f32_to_f64 _avr32_f64_to_f32 _mulsi3 -+ -+#LIB2FUNCS_EXTRA += $(srcdir)/config/avr32/lib2funcs.S -+ -+MULTILIB_OPTIONS = march=ap/march=ucr1/march=ucr2/march=ucr2nomul/march=ucr3/march=ucr3fp -+MULTILIB_DIRNAMES = ap ucr1 ucr2 ucr2nomul ucr3 ucr3fp -+MULTILIB_EXCEPTIONS = -+MULTILIB_MATCHES += march?ap=mpart?ap7000 -+MULTILIB_MATCHES += march?ap=mpart?ap7001 -+MULTILIB_MATCHES += march?ap=mpart?ap7002 -+MULTILIB_MATCHES += march?ap=mpart?ap7200 -+MULTILIB_MATCHES += march?ucr1=march?uc -+MULTILIB_MATCHES += march?ucr1=mpart?uc3a0512es -+MULTILIB_MATCHES += march?ucr2=mpart?uc3a0128 -+MULTILIB_MATCHES += march?ucr2=mpart?uc3a0256 -+MULTILIB_MATCHES += march?ucr2=mpart?uc3a0512 -+MULTILIB_MATCHES += march?ucr2=mpart?uc3a1128 -+MULTILIB_MATCHES += march?ucr2=mpart?uc3a1256 -+MULTILIB_MATCHES += march?ucr1=mpart?uc3a1512es -+MULTILIB_MATCHES += march?ucr2=mpart?uc3a1512 -+MULTILIB_MATCHES += march?ucr2nomul=mpart?uc3a3revd -+MULTILIB_MATCHES += march?ucr2=mpart?uc3a364 -+MULTILIB_MATCHES += march?ucr2=mpart?uc3a364s -+MULTILIB_MATCHES += march?ucr2=mpart?uc3a3128 -+MULTILIB_MATCHES += march?ucr2=mpart?uc3a3128s -+MULTILIB_MATCHES += march?ucr2=mpart?uc3a3256 -+MULTILIB_MATCHES += march?ucr2=mpart?uc3a3256s -+MULTILIB_MATCHES += march?ucr1=mpart?uc3b064 -+MULTILIB_MATCHES += march?ucr1=mpart?uc3b0128 -+MULTILIB_MATCHES += march?ucr1=mpart?uc3b0256es -+MULTILIB_MATCHES += march?ucr1=mpart?uc3b0256 -+MULTILIB_MATCHES += march?ucr2=mpart?uc3b0512 -+MULTILIB_MATCHES += march?ucr2=mpart?uc3b0512revc -+MULTILIB_MATCHES += march?ucr1=mpart?uc3b164 -+MULTILIB_MATCHES += march?ucr1=mpart?uc3b1128 -+MULTILIB_MATCHES += march?ucr1=mpart?uc3b1256es -+MULTILIB_MATCHES += march?ucr1=mpart?uc3b1256 -+MULTILIB_MATCHES += march?ucr2=mpart?uc3b1512 -+MULTILIB_MATCHES += march?ucr2=mpart?uc3b1512revc -+MULTILIB_MATCHES += march?ucr3=mpart?uc3c0512crevc -+MULTILIB_MATCHES += march?ucr3=mpart?uc3c1512crevc -+MULTILIB_MATCHES += march?ucr3=mpart?uc3c2512crevc -+MULTILIB_MATCHES += march?ucr3=mpart?uc3l0256 -+MULTILIB_MATCHES += march?ucr3=mpart?uc3l0128 -+MULTILIB_MATCHES += march?ucr3=mpart?uc3l064 -+MULTILIB_MATCHES += march?ucr3=mpart?uc3l032 -+MULTILIB_MATCHES += march?ucr3=mpart?uc3l016 -+MULTILIB_MATCHES += march?ucr3=mpart?uc3l064revb -+MULTILIB_MATCHES += march?ucr3fp=mpart?uc3c064c -+MULTILIB_MATCHES += march?ucr3fp=mpart?uc3c0128c -+MULTILIB_MATCHES += march?ucr3fp=mpart?uc3c0256c -+MULTILIB_MATCHES += march?ucr3fp=mpart?uc3c0512c -+MULTILIB_MATCHES += march?ucr3fp=mpart?uc3c164c -+MULTILIB_MATCHES += march?ucr3fp=mpart?uc3c1128c -+MULTILIB_MATCHES += march?ucr3fp=mpart?uc3c1256c -+MULTILIB_MATCHES += march?ucr3fp=mpart?uc3c1512c -+MULTILIB_MATCHES += march?ucr3fp=mpart?uc3c264c -+MULTILIB_MATCHES += march?ucr3fp=mpart?uc3c2128c -+MULTILIB_MATCHES += march?ucr3fp=mpart?uc3c2256c -+MULTILIB_MATCHES += march?ucr3fp=mpart?uc3c2512c -+MULTILIB_MATCHES += march?ucr3=mpart?mxt768e -+ -+ -+EXTRA_MULTILIB_PARTS = crtbegin.o crtbeginS.o crtend.o crtendS.o crti.o crtn.o -+ -+CRTSTUFF_T_CFLAGS = -mrelax -+CRTSTUFF_T_CFLAGS_S = -mrelax -fPIC -+TARGET_LIBGCC2_CFLAGS += -mrelax -+ -+LIBGCC = stmp-multilib -+INSTALL_LIBGCC = install-multilib -+ -+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 -+ -+ -+ ---- /dev/null -+++ b/gcc/config/avr32/t-avr32-linux -@@ -0,0 +1,102 @@ -+ -+MD_INCLUDES= $(srcdir)/config/avr32/avr32.md \ -+ $(srcdir)/config/avr32/sync.md \ -+ $(srcdir)/config/avr32/simd.md \ -+ $(srcdir)/config/avr32/predicates.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) -+ -+# 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 -+ -+LIB1ASMSRC = avr32/lib1funcs.S -+LIB1ASMFUNCS = _avr32_f64_mul _avr32_f64_mul_fast _avr32_f64_addsub _avr32_f64_addsub_fast _avr32_f64_to_u32 \ -+ _avr32_f64_to_s32 _avr32_f64_to_u64 _avr32_f64_to_s64 _avr32_u32_to_f64 \ -+ _avr32_s32_to_f64 _avr32_f64_cmp_eq _avr32_f64_cmp_ge _avr32_f64_cmp_lt \ -+ _avr32_f32_cmp_eq _avr32_f32_cmp_ge _avr32_f32_cmp_lt _avr32_f64_div _avr32_f64_div_fast \ -+ _avr32_f32_div _avr32_f32_div_fast _avr32_f32_addsub _avr32_f32_addsub_fast \ -+ _avr32_f32_mul _avr32_s32_to_f32 _avr32_u32_to_f32 _avr32_f32_to_s32 \ -+ _avr32_f32_to_u32 _avr32_f32_to_f64 _avr32_f64_to_f32 _mulsi3 -+ -+#LIB2FUNCS_EXTRA += $(srcdir)/config/avr32/lib2funcs.S -+ -+MULTILIB_OPTIONS = march=ap/march=ucr1/march=ucr2/march=ucr2nomul/march=ucr3/march=ucr3fp -+MULTILIB_DIRNAMES = ap ucr1 ucr2 ucr2nomul ucr3 ucr3fp -+MULTILIB_EXCEPTIONS = -+MULTILIB_MATCHES += march?ap=mpart?ap7000 -+MULTILIB_MATCHES += march?ap=mpart?ap7001 -+MULTILIB_MATCHES += march?ap=mpart?ap7002 -+MULTILIB_MATCHES += march?ap=mpart?ap7200 -+MULTILIB_MATCHES += march?ucr1=march?uc -+MULTILIB_MATCHES += march?ucr1=mpart?uc3a0512es -+MULTILIB_MATCHES += march?ucr2=mpart?uc3a0128 -+MULTILIB_MATCHES += march?ucr2=mpart?uc3a0256 -+MULTILIB_MATCHES += march?ucr2=mpart?uc3a0512 -+MULTILIB_MATCHES += march?ucr2=mpart?uc3a1128 -+MULTILIB_MATCHES += march?ucr2=mpart?uc3a1256 -+MULTILIB_MATCHES += march?ucr1=mpart?uc3a1512es -+MULTILIB_MATCHES += march?ucr2=mpart?uc3a1512 -+MULTILIB_MATCHES += march?ucr2nomul=mpart?uc3a3revd -+MULTILIB_MATCHES += march?ucr2=mpart?uc3a364 -+MULTILIB_MATCHES += march?ucr2=mpart?uc3a364s -+MULTILIB_MATCHES += march?ucr2=mpart?uc3a3128 -+MULTILIB_MATCHES += march?ucr2=mpart?uc3a3128s -+MULTILIB_MATCHES += march?ucr2=mpart?uc3a3256 -+MULTILIB_MATCHES += march?ucr2=mpart?uc3a3256s -+MULTILIB_MATCHES += march?ucr1=mpart?uc3b064 -+MULTILIB_MATCHES += march?ucr1=mpart?uc3b0128 -+MULTILIB_MATCHES += march?ucr1=mpart?uc3b0256es -+MULTILIB_MATCHES += march?ucr1=mpart?uc3b0256 -+MULTILIB_MATCHES += march?ucr2=mpart?uc3b0512 -+MULTILIB_MATCHES += march?ucr2=mpart?uc3b0512revc -+MULTILIB_MATCHES += march?ucr1=mpart?uc3b164 -+MULTILIB_MATCHES += march?ucr1=mpart?uc3b1128 -+MULTILIB_MATCHES += march?ucr1=mpart?uc3b1256es -+MULTILIB_MATCHES += march?ucr1=mpart?uc3b1256 -+MULTILIB_MATCHES += march?ucr2=mpart?uc3b1512 -+MULTILIB_MATCHES += march?ucr2=mpart?uc3b1512revc -+MULTILIB_MATCHES += march?ucr3=mpart?uc3c0512crevc -+MULTILIB_MATCHES += march?ucr3=mpart?uc3c1512crevc -+MULTILIB_MATCHES += march?ucr3=mpart?uc3c2512crevc -+MULTILIB_MATCHES += march?ucr3=mpart?uc3l0256 -+MULTILIB_MATCHES += march?ucr3=mpart?uc3l0128 -+MULTILIB_MATCHES += march?ucr3=mpart?uc3l064 -+MULTILIB_MATCHES += march?ucr3=mpart?uc3l032 -+MULTILIB_MATCHES += march?ucr3=mpart?uc3l016 -+MULTILIB_MATCHES += march?ucr3=mpart?uc3l064revb -+MULTILIB_MATCHES += march?ucr3fp=mpart?uc3c064c -+MULTILIB_MATCHES += march?ucr3fp=mpart?uc3c0128c -+MULTILIB_MATCHES += march?ucr3fp=mpart?uc3c0256c -+MULTILIB_MATCHES += march?ucr3fp=mpart?uc3c0512c -+MULTILIB_MATCHES += march?ucr3fp=mpart?uc3c164c -+MULTILIB_MATCHES += march?ucr3fp=mpart?uc3c1128c -+MULTILIB_MATCHES += march?ucr3fp=mpart?uc3c1256c -+MULTILIB_MATCHES += march?ucr3fp=mpart?uc3c1512c -+MULTILIB_MATCHES += march?ucr3fp=mpart?uc3c264c -+MULTILIB_MATCHES += march?ucr3fp=mpart?uc3c2128c -+MULTILIB_MATCHES += march?ucr3fp=mpart?uc3c2256c -+MULTILIB_MATCHES += march?ucr3fp=mpart?uc3c2512c -+MULTILIB_MATCHES += march?ucr3=mpart?mxt768e -+ -+ -+EXTRA_MULTILIB_PARTS = crtbegin.o crtbeginS.o crtend.o crtendS.o -+ -+CRTSTUFF_T_CFLAGS = -mrelax -+CRTSTUFF_T_CFLAGS_S = -mrelax -fPIC -+TARGET_LIBGCC2_CFLAGS += -mrelax -+ -+LIBGCC = stmp-multilib -+INSTALL_LIBGCC = install-multilib -+ -+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 -+ -+ -+ ---- /dev/null -+++ b/gcc/config/avr32/t-elf -@@ -0,0 +1,16 @@ -+ -+# Assemble startup files. -+$(T)crti.o: $(srcdir)/config/avr32/crti.asm $(GCC_PASSES) -+ $(GCC_FOR_TARGET) $(CRTSTUFF_CFLAGS) $(CRTSTUFF_T_CFLAGS) $(INCLUDES) \ -+ -c -o $(T)crti.o -x assembler-with-cpp $(srcdir)/config/avr32/crti.asm -+ -+$(T)crtn.o: $(srcdir)/config/avr32/crtn.asm $(GCC_PASSES) -+ $(GCC_FOR_TARGET) $(CRTSTUFF_CFLAGS) $(CRTSTUFF_T_CFLAGS) $(INCLUDES) \ -+ -c -o $(T)crtn.o -x assembler-with-cpp $(srcdir)/config/avr32/crtn.asm -+ -+ -+# Build the libraries for both hard and soft floating point -+EXTRA_MULTILIB_PARTS = crtbegin.o crtbeginS.o crtend.o crtendS.o crti.o crtn.o -+ -+LIBGCC = stmp-multilib -+INSTALL_LIBGCC = install-multilib ---- /dev/null -+++ b/gcc/config/avr32/uc3fpu.md -@@ -0,0 +1,198 @@ -+;; AVR32 machine description file for Floating-Point instructions. -+;; Copyright 2003-2006 Atmel Corporation. -+;; -+;; -+;; This file is part of GCC. -+;; -+;; 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 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 this program; if not, write to the Free Software -+;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ -+(define_insn "*movsf_uc3fp" -+ [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,m") -+ (match_operand:SF 1 "general_operand" "r,G,m,r"))] -+ "TARGET_ARCH_FPU && TARGET_HARD_FLOAT" -+ "@ -+ mov\t%0, %1 -+ mov\t%0, %1 -+ ld.w\t%0, %1 -+ st.w\t%0, %1" -+ [(set_attr "length" "2,4,4,4") -+ (set_attr "type" "alu,alu,load,store")]) -+ -+(define_insn "mulsf3" -+ [(set (match_operand:SF 0 "register_operand" "=r") -+ (mult:SF (match_operand:SF 1 "register_operand" "r") -+ (match_operand:SF 2 "register_operand" "r")))] -+ "TARGET_ARCH_FPU && TARGET_HARD_FLOAT" -+ "fmul.s\t%0, %1, %2" -+ [(set_attr "length" "4") -+ (set_attr "type" "fmul")]) -+ -+(define_insn "nmulsf3" -+ [(set (match_operand:SF 0 "register_operand" "=r") -+ (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "%r") -+ (match_operand:SF 2 "register_operand" "r"))))] -+ "TARGET_ARCH_FPU && TARGET_HARD_FLOAT" -+ "fnmul.s\t%0, %1, %2" -+ [(set_attr "length" "4") -+ (set_attr "type" "fmul")]) -+ -+(define_insn "macsf3" -+ [(set (match_operand:SF 0 "register_operand" "=r") -+ (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "r") -+ (match_operand:SF 2 "register_operand" "r")) -+ (match_operand:SF 3 "register_operand" "r")))] -+ "TARGET_ARCH_FPU && TARGET_HARD_FLOAT" -+ "fmac.s\t%0, %3, %1, %2" -+ [(set_attr "length" "4") -+ (set_attr "type" "fmul")]) -+ -+;(define_insn "nmacsf3" -+; [(set (match_operand:SF 0 "register_operand" "=r") -+; (plus:SF (neg:SF (match_operand:SF 1 "register_operand" "r")) -+; (mult:SF(match_operand:SF 2 "register_operand" "r") -+; (match_operand:SF 3 "register_operand" "r"))))] -+; "TARGET_ARCH_FPU && TARGET_HARD_FLOAT" -+; "fnmac.s\t%0, %1, %2, %3" -+; [(set_attr "length" "4") -+; (set_attr "type" "fmul")]) -+ -+(define_insn "nmacsf3" -+ [(set (match_operand:SF 0 "register_operand" "=r") -+ (minus:SF (mult:SF (match_operand:SF 2 "register_operand" "r") -+ (match_operand:SF 3 "register_operand" "r")) -+ (match_operand:SF 1 "register_operand" "r")))] -+ "TARGET_ARCH_FPU && TARGET_HARD_FLOAT" -+ "fnmac.s\t%0, %1, %2, %3" -+ [(set_attr "length" "4") -+ (set_attr "type" "fmul")]) -+ -+(define_insn "msubacsf3" -+ [(set (match_operand:SF 0 "register_operand" "=r") -+ (minus:SF (match_operand:SF 3 "register_operand" "r") -+ (mult:SF (match_operand:SF 1 "register_operand" "r") -+ (match_operand:SF 2 "register_operand" "r"))))] -+ "TARGET_ARCH_FPU && TARGET_HARD_FLOAT" -+ "fmsc.s\t%0, %3, %1, %2" -+ [(set_attr "length" "4") -+ (set_attr "type" "fmul")]) -+ -+(define_insn "nmsubacsf3" -+ [(set (match_operand:SF 0 "register_operand" "=r") -+ (minus:SF (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "r") -+ (match_operand:SF 2 "register_operand" "r"))) -+ (match_operand:SF 3 "register_operand" "r")))] -+ "TARGET_ARCH_FPU && TARGET_HARD_FLOAT" -+ "fnmsc.s\t%0, %3, %1, %2" -+ [(set_attr "length" "4") -+ (set_attr "type" "fmul")]) -+ -+(define_insn "addsf3" -+ [(set (match_operand:SF 0 "register_operand" "=r") -+ (plus:SF (match_operand:SF 1 "register_operand" "%r") -+ (match_operand:SF 2 "register_operand" "r")))] -+ "TARGET_ARCH_FPU && TARGET_HARD_FLOAT" -+ "fadd.s\t%0, %1, %2" -+ [(set_attr "length" "4") -+ (set_attr "type" "fmul")]) -+ -+(define_insn "subsf3" -+ [(set (match_operand:SF 0 "register_operand" "=r") -+ (minus:SF (match_operand:SF 1 "register_operand" "r") -+ (match_operand:SF 2 "register_operand" "r")))] -+ "TARGET_ARCH_FPU && TARGET_HARD_FLOAT" -+ "fsub.s\t%0, %1, %2" -+ [(set_attr "length" "4") -+ (set_attr "type" "fmul")]) -+ -+(define_insn "fixuns_truncsfsi2" -+ [(set (match_operand:SI 0 "register_operand" "=r") -+ (unsigned_fix:SI (match_operand:SF 1 "register_operand" "r")))] -+ "TARGET_ARCH_FPU && TARGET_HARD_FLOAT" -+ "fcastrs.uw\t%0, %1" -+ [(set_attr "length" "4")]) -+ -+(define_insn "fix_truncsfsi2" -+ [(set (match_operand:SI 0 "register_operand" "=r") -+ (fix:SI (match_operand:SF 1 "register_operand" "r")))] -+ "TARGET_ARCH_FPU && TARGET_HARD_FLOAT" -+ "fcastrs.sw\t%0, %1" -+ [(set_attr "length" "4")]) -+ -+(define_insn "floatunssisf2" -+ [(set (match_operand:SF 0 "register_operand" "=r") -+ (unsigned_float:SF (match_operand:SI 1 "register_operand" "r")))] -+ "TARGET_ARCH_FPU && TARGET_HARD_FLOAT" -+ "fcastuw.s\t%0, %1" -+ [(set_attr "length" "4")]) -+ -+(define_insn "floatsisf2" -+ [(set (match_operand:SF 0 "register_operand" "=r") -+ (float:SF (match_operand:SI 1 "register_operand" "r")))] -+ "TARGET_ARCH_FPU && TARGET_HARD_FLOAT" -+ "fcastsw.s\t%0, %1" -+ [(set_attr "length" "4")]) -+ -+(define_insn "cmpsf_internal_uc3fp" -+ [(set (cc0) -+ (compare:CC -+ (match_operand:SF 0 "register_operand" "r") -+ (match_operand:SF 1 "register_operand" "r")))] -+ "TARGET_ARCH_FPU && TARGET_HARD_FLOAT" -+ { -+ if (!rtx_equal_p(cc_prev_status.mdep.value, SET_SRC(PATTERN (insn))) ) -+ return "fcmp.s\t%0, %1"; -+ return ""; -+ } -+ [(set_attr "length" "4") -+ (set_attr "cc" "compare")]) -+ -+(define_expand "divsf3" -+ [(set (match_operand:SF 0 "register_operand" "=r") -+ (div:SF (match_operand:SF 1 "register_operand" "r") -+ (match_operand:SF 2 "register_operand" "r")))] -+ "TARGET_ARCH_FPU && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations" -+ "{ -+ emit_insn(gen_frcpa_internal(operands[0],operands[2])); -+ emit_insn(gen_mulsf3(operands[0],operands[0],operands[1])); -+ DONE; -+ }" -+) -+ -+(define_insn "frcpa_internal" -+ [(set (match_operand:SF 0 "register_operand" "=r") -+ (unspec:SF [(match_operand:SF 1 "register_operand" "r")] UNSPEC_FRCPA))] -+ "TARGET_ARCH_FPU && TARGET_HARD_FLOAT" -+ "frcpa.s %0,%1" -+ [(set_attr "length" "4")]) -+ -+(define_expand "sqrtsf2" -+ [(set (match_operand:SF 0 "register_operand" "") -+ (sqrt:SF (match_operand:SF 1 "register_operand" "")))] -+ "TARGET_ARCH_FPU && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations" -+ " -+{ -+ rtx scratch = gen_reg_rtx (SFmode); -+ emit_insn (gen_rsqrtsf2 (scratch, operands[1], CONST1_RTX (SFmode))); -+ emit_insn (gen_divsf3(operands[0], force_reg (SFmode, CONST1_RTX (SFmode)), -+ scratch)); -+ DONE; -+}") -+ -+(define_insn "rsqrtsf2" -+ [(set (match_operand:SF 0 "register_operand" "=r") -+ (div:SF (match_operand:SF 2 "const_1f_operand" "F") -+ (sqrt:SF (match_operand:SF 1 "register_operand" "?r"))))] -+ "TARGET_ARCH_FPU && TARGET_HARD_FLOAT" -+ "frsqrta.s %1, %0") ---- /dev/null -+++ b/gcc/config/avr32/uclinux-elf.h -@@ -0,0 +1,20 @@ -+ -+/* Run-time Target Specification. */ -+#undef TARGET_VERSION -+#define TARGET_VERSION fputs (" (AVR32 uClinux with ELF)", stderr) -+ -+/* We don't want a .jcr section on uClinux. As if this makes a difference... */ -+#define TARGET_USE_JCR_SECTION 0 -+ -+/* Here we go. Drop the crtbegin/crtend stuff completely. */ -+#undef STARTFILE_SPEC -+#define STARTFILE_SPEC \ -+ "%{!shared: %{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s}" \ -+ " %{!p:%{profile:gcrt1.o%s}" \ -+ " %{!profile:crt1.o%s}}}} crti.o%s" -+ -+#undef ENDFILE_SPEC -+#define ENDFILE_SPEC "crtn.o%s" -+ -+#undef TARGET_DEFAULT -+#define TARGET_DEFAULT (AVR32_FLAG_NO_INIT_GOT) ---- a/gcc/config/host-linux.c -+++ b/gcc/config/host-linux.c -@@ -25,6 +25,9 @@ - #include "hosthooks.h" - #include "hosthooks-def.h" - -+#ifndef SSIZE_MAX -+#define SSIZE_MAX LONG_MAX -+#endif - - /* Linux has a feature called exec-shield-randomize that perturbs the - address of non-fixed mapped segments by a (relatively) small amount. ---- a/gcc/config.gcc -+++ b/gcc/config.gcc -@@ -834,6 +834,24 @@ avr-*-*) - tm_file="avr/avr.h dbxelf.h" - use_fixproto=yes - ;; -+avr32*-*-linux*) -+ tm_file="dbxelf.h elfos.h linux.h avr32/linux-elf.h avr32/avr32.h " -+ tmake_file="t-linux avr32/t-avr32-linux" -+ extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o" -+ extra_modes=avr32/avr32-modes.def -+ gnu_ld=yes -+ ;; -+avr32*-*-uclinux*) -+ tm_file="dbxelf.h elfos.h linux.h avr32/linux-elf.h avr32/uclinux-elf.h avr32/avr32.h" -+ tmake_file="t-linux avr32/t-avr32-linux" -+ extra_modes=avr32/avr32-modes.def -+ gnu_ld=yes -+ ;; -+avr32-*-*) -+ tm_file="dbxelf.h elfos.h avr32/avr32.h avr32/avr32-elf.h" -+ tmake_file="avr32/t-avr32 avr32/t-elf" -+ extra_modes=avr32/avr32-modes.def -+ ;; - bfin*-elf*) - tm_file="${tm_file} dbxelf.h elfos.h bfin/elf.h" - tmake_file=bfin/t-bfin-elf -@@ -2950,6 +2968,32 @@ case "${target}" in - fi - ;; - -+ avr32*-*-*) -+ supported_defaults="part arch" -+ -+ case "$with_part" in -+ "" \ -+ | "ap7000" | "ap7010" | "ap7020" | "uc3a0256" | "uc3a0512" | "uc3a1128" | "uc3a1256" | "uc3a1512" ) -+ # OK -+ ;; -+ *) -+ echo "Unknown part used in --with-part=$with_part" 1>&2 -+ exit 1 -+ ;; -+ esac -+ -+ case "$with_arch" in -+ "" \ -+ | "ap" | "uc") -+ # OK -+ ;; -+ *) -+ echo "Unknown arch used in --with-arch=$with_arch" 1>&2 -+ exit 1 -+ ;; -+ esac -+ ;; -+ - fr*-*-*linux*) - supported_defaults=cpu - case "$with_cpu" in ---- a/gcc/configure.ac -+++ b/gcc/configure.ac -@@ -2174,10 +2174,9 @@ L2:], - as_ver=`$gcc_cv_as --version 2>/dev/null | sed 1q` - if echo "$as_ver" | grep GNU > /dev/null; then - changequote(,)dnl -- as_vers=`echo $as_ver | sed -n \ -- -e 's,^.*[ ]\([0-9][0-9]*\.[0-9][0-9]*.*\)$,\1,p'` -- as_major=`expr "$as_vers" : '\([0-9]*\)'` -- as_minor=`expr "$as_vers" : '[0-9]*\.\([0-9]*\)'` -+ as_ver=`echo $as_ver | sed -e 's/GNU assembler\( (GNU Binutils)\)\? \([0-9.][0-9.]*\).*/\2/'` -+ as_major=`echo $as_ver | sed 's/\..*//'` -+ as_minor=`echo $as_ver | sed 's/[^.]*\.\([0-9]*\).*/\1/'` - changequote([,])dnl - if test $as_major -eq 2 && test $as_minor -lt 11 - then : -@@ -3077,7 +3076,7 @@ esac - case "$target" in - i?86*-*-* | mips*-*-* | alpha*-*-* | powerpc*-*-* | sparc*-*-* | m68*-*-* \ - | x86_64*-*-* | hppa*-*-* | arm*-*-* | strongarm*-*-* | xscale*-*-* \ -- | xstormy16*-*-* | cris-*-* | xtensa-*-* | bfin-*-* | score*-*-* | spu-*-*) -+ | xstormy16*-*-* | cris-*-* | xtensa-*-* | bfin-*-* | score*-*-* | spu-*-* | avr32-*-*) - insn="nop" - ;; - ia64*-*-* | s390*-*-*) ---- a/gcc/doc/extend.texi -+++ b/gcc/doc/extend.texi -@@ -2336,7 +2336,7 @@ This attribute is ignored for R8C target - - @item interrupt - @cindex interrupt handler functions --Use this attribute on the ARM, AVR, CRX, M32C, M32R/D, m68k, MS1, -+Use this attribute on the ARM, AVR, AVR32, CRX, M32C, M32R/D, m68k, MS1, - and Xstormy16 ports to indicate that the specified function is an - interrupt handler. The compiler will generate function entry and exit - sequences suitable for use in an interrupt handler when this attribute -@@ -2356,6 +2356,15 @@ void f () __attribute__ ((interrupt ("IR - - Permissible values for this parameter are: IRQ, FIQ, SWI, ABORT and UNDEF@. - -+Note, for the AVR32, you can specify which banking scheme is used for -+the interrupt mode this interrupt handler is used in like this: -+ -+@smallexample -+void f () __attribute__ ((interrupt ("FULL"))); -+@end smallexample -+ -+Permissible values for this parameter are: FULL, HALF, NONE and UNDEF. -+ - On ARMv7-M the interrupt type is ignored, and the attribute means the function - may be called with a word aligned stack pointer. - -@@ -3925,6 +3934,23 @@ placed in either the @code{.bss_below100 - - @end table - -+@subsection AVR32 Variable Attributes -+ -+One attribute is currently defined for AVR32 configurations: -+@code{rmw_addressable} -+ -+@table @code -+@item rmw_addressable -+@cindex @code{rmw_addressable} attribute -+ -+This attribute can be used to signal that a variable can be accessed -+with the addressing mode of the AVR32 Atomic Read-Modify-Write memory -+instructions and hence make it possible for gcc to generate these -+instructions without using built-in functions or inline assembly statements. -+Variables used within the AVR32 Atomic Read-Modify-Write built-in -+functions will automatically get the @code{rmw_addressable} attribute. -+@end table -+ - @subsection AVR Variable Attributes - - @table @code -@@ -6708,6 +6734,7 @@ instructions, but allow the compiler to - * Alpha Built-in Functions:: - * ARM iWMMXt Built-in Functions:: - * ARM NEON Intrinsics:: -+* AVR32 Built-in Functions:: - * Blackfin Built-in Functions:: - * FR-V Built-in Functions:: - * X86 Built-in Functions:: -@@ -6947,6 +6974,7 @@ long long __builtin_arm_wxor (long long, - long long __builtin_arm_wzero () - @end smallexample - -+ - @node ARM NEON Intrinsics - @subsection ARM NEON Intrinsics - -@@ -6955,6 +6983,74 @@ when the @option{-mfpu=neon} switch is u - - @include arm-neon-intrinsics.texi - -+@node AVR32 Built-in Functions -+@subsection AVR32 Built-in Functions -+ -+Built-in functions for atomic memory (RMW) instructions. Note that these -+built-ins will fail for targets where the RMW instructions are not -+implemented. Also note that these instructions only that a Ks15 << 2 -+memory address and will therefor not work with any runtime computed -+memory addresses. The user is responsible for making sure that any -+pointers used within these functions points to a valid memory address. -+ -+@smallexample -+void __builtin_mems(int */*ptr*/, int /*bit*/) -+void __builtin_memc(int */*ptr*/, int /*bit*/) -+void __builtin_memt(int */*ptr*/, int /*bit*/) -+@end smallexample -+ -+Built-in functions for DSP instructions. Note that these built-ins will -+fail for targets where the DSP instructions are not implemented. -+ -+@smallexample -+int __builtin_sats (int /*Rd*/,int /*sa*/, int /*bn*/) -+int __builtin_satu (int /*Rd*/,int /*sa*/, int /*bn*/) -+int __builtin_satrnds (int /*Rd*/,int /*sa*/, int /*bn*/) -+int __builtin_satrndu (int /*Rd*/,int /*sa*/, int /*bn*/) -+short __builtin_mulsathh_h (short, short) -+int __builtin_mulsathh_w (short, short) -+short __builtin_mulsatrndhh_h (short, short) -+int __builtin_mulsatrndwh_w (int, short) -+int __builtin_mulsatwh_w (int, short) -+int __builtin_macsathh_w (int, short, short) -+short __builtin_satadd_h (short, short) -+short __builtin_satsub_h (short, short) -+int __builtin_satadd_w (int, int) -+int __builtin_satsub_w (int, int) -+long long __builtin_mulwh_d(int, short) -+long long __builtin_mulnwh_d(int, short) -+long long __builtin_macwh_d(long long, int, short) -+long long __builtin_machh_d(long long, short, short) -+@end smallexample -+ -+Other built-in functions for instructions that cannot easily be -+generated by the compiler. -+ -+@smallexample -+void __builtin_ssrf(int); -+void __builtin_csrf(int); -+void __builtin_musfr(int); -+int __builtin_mustr(void); -+int __builtin_mfsr(int /*Status Register Address*/) -+void __builtin_mtsr(int /*Status Register Address*/, int /*Value*/) -+int __builtin_mfdr(int /*Debug Register Address*/) -+void __builtin_mtdr(int /*Debug Register Address*/, int /*Value*/) -+void __builtin_cache(void * /*Address*/, int /*Cache Operation*/) -+void __builtin_sync(int /*Sync Operation*/) -+void __builtin_tlbr(void) -+void __builtin_tlbs(void) -+void __builtin_tlbw(void) -+void __builtin_breakpoint(void) -+int __builtin_xchg(void * /*Address*/, int /*Value*/ ) -+short __builtin_bswap_16(short) -+int __builtin_bswap_32(int) -+void __builtin_cop(int/*cpnr*/, int/*crd*/, int/*crx*/, int/*cry*/, int/*op*/) -+int __builtin_mvcr_w(int/*cpnr*/, int/*crs*/) -+void __builtin_mvrc_w(int/*cpnr*/, int/*crd*/, int/*value*/) -+long long __builtin_mvcr_d(int/*cpnr*/, int/*crs*/) -+void __builtin_mvrc_d(int/*cpnr*/, int/*crd*/, long long/*value*/) -+@end smallexample -+ - @node Blackfin Built-in Functions - @subsection Blackfin Built-in Functions - ---- a/gcc/doc/invoke.texi -+++ b/gcc/doc/invoke.texi -@@ -195,7 +195,7 @@ in the following sections. - -fvisibility-ms-compat @gol - -Wabi -Wctor-dtor-privacy @gol - -Wnon-virtual-dtor -Wreorder @gol ---Weffc++ -Wno-deprecated -Wstrict-null-sentinel @gol -+-Weffc++ -Wno-deprecated @gol - -Wno-non-template-friend -Wold-style-cast @gol - -Woverloaded-virtual -Wno-pmf-conversions @gol - -Wsign-promo} -@@ -609,6 +609,12 @@ Objective-C and Objective-C++ Dialects}. - -mauto-incdec -minmax -mlong-calls -mshort @gol - -msoft-reg-count=@var{count}} - -+@emph{AVR32 Options} -+@gccoptlist{-muse-rodata-section -mhard-float -msoft-float -mrelax @gol -+-mforce-double-align -mno-init-got -mrelax -mmd-reorg-opt -masm-addr-pseudos @gol -+-mpart=@var{part} -mcpu=@var{cpu} -march=@var{arch} @gol -+-mfast-float -mimm-in-const-pool} -+ - @emph{MCore Options} - @gccoptlist{-mhardlit -mno-hardlit -mdiv -mno-div -mrelax-immediates @gol - -mno-relax-immediates -mwide-bitfields -mno-wide-bitfields @gol -@@ -3163,13 +3169,11 @@ requiring @option{-O}. - If you want to warn about code which uses the uninitialized value of the - variable in its own initializer, use the @option{-Winit-self} option. - --These warnings occur for individual uninitialized or clobbered --elements of structure, union or array variables as well as for --variables which are uninitialized or clobbered as a whole. They do --not occur for variables or elements declared @code{volatile}. Because --these warnings depend on optimization, the exact variables or elements --for which there are warnings will depend on the precise optimization --options and version of GCC used. -+These warnings occur only for variables that are candidates for -+register allocation. Therefore, they do not occur for a variable that -+is declared @code{volatile}, or whose address is taken, or whose size -+is other than 1, 2, 4 or 8 bytes. Also, they do not occur for -+structures, unions or arrays, even when they are in registers. - - Note that there may be no warning about a variable that is used only - to compute a value that itself is never used, because such -@@ -7034,10 +7038,6 @@ If number of candidates in the set is sm - we always try to remove unnecessary ivs from the set during its - optimization when a new iv is added to the set. - --@item scev-max-expr-size --Bound on size of expressions used in the scalar evolutions analyzer. --Large expressions slow the analyzer. -- - @item omega-max-vars - The maximum number of variables in an Omega constraint system. - The default value is 128. -@@ -8363,6 +8363,7 @@ platform. - * ARC Options:: - * ARM Options:: - * AVR Options:: -+* AVR32 Options:: - * Blackfin Options:: - * CRIS Options:: - * CRX Options:: -@@ -8834,6 +8835,129 @@ comply to the C standards, but it will p - size. - @end table - -+@node AVR32 Options -+@subsection AVR32 Options -+@cindex AVR32 Options -+ -+These options are defined for AVR32 implementations: -+ -+@table @gcctabopt -+@item -muse-rodata-section -+@opindex muse-rodata-section -+Use section @samp{.rodata} for read-only data instead of @samp{.text}. -+ -+@item -mhard-float -+@opindex mhard-float -+Use floating point coprocessor instructions. -+ -+@item -msoft-float -+@opindex msoft-float -+Use software floating-point library for floating-point operations. -+ -+@item -mforce-double-align -+@opindex mforce-double-align -+Force double-word alignment for double-word memory accesses. -+ -+@item -masm-addr-pseudos -+@opindex masm-addr-pseudos -+Use assembler pseudo-instructions lda.w and call for handling direct -+addresses. (Enabled by default) -+ -+@item -mno-init-got -+@opindex mno-init-got -+Do not initialize the GOT register before using it when compiling PIC -+code. -+ -+@item -mrelax -+@opindex mrelax -+Let invoked assembler and linker do relaxing -+(Enabled by default when optimization level is >1). -+This means that when the address of symbols are known at link time, -+the linker can optimize @samp{icall} and @samp{mcall} -+instructions into a @samp{rcall} instruction if possible. -+Loading the address of a symbol can also be optimized. -+ -+@item -mmd-reorg-opt -+@opindex mmd-reorg-opt -+Perform machine dependent optimizations in reorg stage. -+ -+@item -mpart=@var{part} -+@opindex mpart -+Generate code for the specified part. Permissible parts are: -+@samp{ap7000}, -+@samp{ap7001}, -+@samp{ap7002}, -+@samp{ap7200}, -+@samp{uc3a0128}, -+@samp{uc3a0256}, -+@samp{uc3a0512}, -+@samp{uc3a0512es}, -+@samp{uc3a1128}, -+@samp{uc3a1256}, -+@samp{uc3a1512}, -+@samp{uc3a1512es}, -+@samp{uc3a3revd}, -+@samp{uc3a364}, -+@samp{uc3a364s}, -+@samp{uc3a3128}, -+@samp{uc3a3128s}, -+@samp{uc3a3256}, -+@samp{uc3a3256s}, -+@samp{uc3b064}, -+@samp{uc3b0128}, -+@samp{uc3b0256}, -+@samp{uc3b0256es}, -+@samp{uc3b0512}, -+@samp{uc3b0512revc}, -+@samp{uc3b164}, -+@samp{uc3b1128}, -+@samp{uc3b1256}, -+@samp{uc3b1256es}, -+@samp{uc3b1512} -+@samp{uc3b1512revc} -+@samp{uc3c0512crevc}, -+@samp{uc3c1512crevc}, -+@samp{uc3c2512crevc}, -+@samp{uc3l0256}, -+@samp{uc3l0128}, -+@samp{uc3l064}, -+@samp{uc3l032}, -+@samp{uc3l016}, -+@samp{uc3l064revb}, -+@samp{uc3c064c}, -+@samp{uc3c0128c}, -+@samp{uc3c0256c}, -+@samp{uc3c0512c}, -+@samp{uc3c164c}, -+@samp{uc3c1128c}, -+@samp{uc3c1256c}, -+@samp{uc3c1512c}, -+@samp{uc3c264c}, -+@samp{uc3c2128c}, -+@samp{uc3c2256c}, -+@samp{uc3c2512c}, -+@samp{mxt768e}. -+ -+@item -mcpu=@var{cpu-type} -+@opindex mcpu -+Same as -mpart. Obsolete. -+ -+@item -march=@var{arch} -+@opindex march -+Generate code for the specified architecture. Permissible architectures are: -+@samp{ap}, @samp{uc} and @samp{ucr2}. -+ -+@item -mfast-float -+@opindex mfast-float -+Enable fast floating-point library that does not conform to IEEE-754 but is still good enough -+for most applications. The fast floating-point library does not round to the nearest even -+but away from zero. Enabled by default if the -funsafe-math-optimizations switch is specified. -+ -+@item -mimm-in-const-pool -+@opindex mimm-in-const-pool -+Put large immediates in constant pool. This is enabled by default for archs with insn-cache. -+@end table -+ - @node Blackfin Options - @subsection Blackfin Options - @cindex Blackfin Options -@@ -8889,29 +9013,12 @@ When enabled, the compiler will ensure t - contain speculative loads after jump instructions. If this option is used, - @code{__WORKAROUND_SPECULATIVE_LOADS} is defined. - --@item -mno-specld-anomaly --@opindex mno-specld-anomaly --Don't generate extra code to prevent speculative loads from occurring. -- - @item -mcsync-anomaly - @opindex mcsync-anomaly - When enabled, the compiler will ensure that the generated code does not - contain CSYNC or SSYNC instructions too soon after conditional branches. - If this option is used, @code{__WORKAROUND_SPECULATIVE_SYNCS} is defined. - --@item -mno-csync-anomaly --@opindex mno-csync-anomaly --Don't generate extra code to prevent CSYNC or SSYNC instructions from --occurring too soon after a conditional branch. -- --@item -mlow-64k --@opindex mlow-64k --When enabled, the compiler is free to take advantage of the knowledge that --the entire program fits into the low 64k of memory. -- --@item -mno-low-64k --@opindex mno-low-64k --Assume that the program is arbitrarily large. This is the default. - - @item -mstack-check-l1 - @opindex mstack-check-l1 -@@ -8925,11 +9032,6 @@ This allows for execute in place and sha - without virtual memory management. This option implies @option{-fPIC}. - With a @samp{bfin-elf} target, this option implies @option{-msim}. - --@item -mno-id-shared-library --@opindex mno-id-shared-library --Generate code that doesn't assume ID based shared libraries are being used. --This is the default. -- - @item -mleaf-id-shared-library - @opindex mleaf-id-shared-library - Generate code that supports shared libraries via the library ID method, -@@ -8971,11 +9073,6 @@ call on this register. This switch is n - will lie outside of the 24 bit addressing range of the offset based - version of subroutine call instruction. - --This feature is not enabled by default. Specifying --@option{-mno-long-calls} will restore the default behavior. Note these --switches have no effect on how the compiler generates code to handle --function calls via function pointers. -- - @item -mfast-fp - @opindex mfast-fp - Link with the fast floating-point library. This library relaxes some of ---- a/gcc/doc/md.texi -+++ b/gcc/doc/md.texi -@@ -3,6 +3,7 @@ - @c This is part of the GCC manual. - @c For copying conditions, see the file gcc.texi. - -+ - @ifset INTERNALS - @node Machine Desc - @chapter Machine Descriptions -@@ -1681,6 +1682,58 @@ A memory reference suitable for iWMMXt l - A memory reference suitable for the ARMv4 ldrsb instruction. - @end table - -+@item AVR32 family---@file{avr32.h} -+@table @code -+@item f -+Floating-point registers (f0 to f15) -+ -+@item Ku@var{bits} -+Unsigned constant representable with @var{bits} number of bits (Must be -+two digits). I.e: An unsigned 8-bit constant is written as @samp{Ku08} -+ -+@item Ks@var{bits} -+Signed constant representable with @var{bits} number of bits (Must be -+two digits). I.e: A signed 12-bit constant is written as @samp{Ks12} -+ -+@item Is@var{bits} -+The negated range of a signed constant representable with @var{bits} -+number of bits. The same as @samp{Ks@var{bits}} with a negated range. -+This means that the constant must be in the range @math{-2^{bits-1}-1} to @math{2^{bits-1}} -+ -+@item G -+A single/double precision floating-point immediate or 64-bit integer -+immediate where the least and most significant words both can be -+loaded with a move instruction. That is the the integer form of the -+values in the least and most significant words both are in the range -+@math{-2^{20}} to @math{2^{20}-1}. -+ -+@item RKs@var{bits} -+A memory reference where the address consists of a base register -+plus a signed immediate displacement with range given by @samp{Ks@var{bits}} -+which has the same format as for the signed immediate integer constraint -+given above. -+ -+@item RKu@var{bits} -+A memory reference where the address consists of a base register -+plus an unsigned immediate displacement with range given by @samp{Ku@var{bits}} -+which has the same format as for the unsigned immediate integer constraint -+given above. -+ -+@item S -+A memory reference with an immediate or register offset -+ -+@item T -+A memory reference to a constant pool entry -+ -+@item W -+A valid operand for use in the @samp{lda.w} instruction macro when -+relaxing is enabled -+ -+@item Z -+A memory reference valid for coprocessor memory instructions -+ -+@end table -+ - @item AVR family---@file{config/avr/constraints.md} - @table @code - @item l ---- a/gcc/expmed.c -+++ b/gcc/expmed.c -@@ -463,9 +463,9 @@ store_bit_field_1 (rtx str_rtx, unsigned - ? ((GET_MODE_SIZE (fieldmode) >= UNITS_PER_WORD - || GET_MODE_SIZE (GET_MODE (op0)) == GET_MODE_SIZE (fieldmode)) - && byte_offset % GET_MODE_SIZE (fieldmode) == 0) -- : (! SLOW_UNALIGNED_ACCESS (fieldmode, MEM_ALIGN (op0)) -+ : ( (! SLOW_UNALIGNED_ACCESS (fieldmode, MEM_ALIGN (op0)) - || (offset * BITS_PER_UNIT % bitsize == 0 -- && MEM_ALIGN (op0) % GET_MODE_BITSIZE (fieldmode) == 0)))) -+ && MEM_ALIGN (op0) % GET_MODE_BITSIZE (fieldmode) == 0))))) - { - if (MEM_P (op0)) - op0 = adjust_address (op0, fieldmode, offset); ---- a/gcc/expr.c -+++ b/gcc/expr.c -@@ -52,6 +52,7 @@ along with GCC; see the file COPYING3. - #include "tree-flow.h" - #include "target.h" - #include "timevar.h" -+#include "c-common.h" - #include "df.h" - #include "diagnostic.h" - -@@ -3620,16 +3621,17 @@ emit_single_push_insn (enum machine_mode - } - else - { -+ emit_move_insn (stack_pointer_rtx, -+ expand_binop (Pmode, - #ifdef STACK_GROWS_DOWNWARD -- /* ??? This seems wrong if STACK_PUSH_CODE == POST_DEC. */ -- dest_addr = gen_rtx_PLUS (Pmode, stack_pointer_rtx, -- GEN_INT (-(HOST_WIDE_INT) rounded_size)); -+ sub_optab, - #else -- /* ??? This seems wrong if STACK_PUSH_CODE == POST_INC. */ -- dest_addr = gen_rtx_PLUS (Pmode, stack_pointer_rtx, -- GEN_INT (rounded_size)); -+ add_optab, - #endif -- dest_addr = gen_rtx_PRE_MODIFY (Pmode, stack_pointer_rtx, dest_addr); -+ stack_pointer_rtx, -+ GEN_INT (rounded_size), -+ NULL_RTX, 0, OPTAB_LIB_WIDEN)); -+ dest_addr = stack_pointer_rtx; - } - - dest = gen_rtx_MEM (mode, dest_addr); -@@ -5739,7 +5741,8 @@ store_field (rtx target, HOST_WIDE_INT b - is a bit field, we cannot use addressing to access it. - Use bit-field techniques or SUBREG to store in it. */ - -- if (mode == VOIDmode -+ if ( -+ mode == VOIDmode - || (mode != BLKmode && ! direct_store[(int) mode] - && GET_MODE_CLASS (mode) != MODE_COMPLEX_INT - && GET_MODE_CLASS (mode) != MODE_COMPLEX_FLOAT) -@@ -5896,7 +5899,18 @@ get_inner_reference (tree exp, HOST_WIDE - { - tree field = TREE_OPERAND (exp, 1); - size_tree = DECL_SIZE (field); -- if (!DECL_BIT_FIELD (field)) -+ if (!DECL_BIT_FIELD (field) -+ /* Added for AVR32: -+ Bitfields with a size equal to a target storage -+ type might not cause DECL_BIT_FIELD to return -+ true since it can be optimized into a normal array -+ access operation. But for volatile bitfields we do -+ not allow this when targetm.narrow_volatile_bitfield () -+ is false. We can use DECL_C_BIT_FIELD to check if this -+ really is a c-bitfield. */ -+ && !(TREE_THIS_VOLATILE (exp) -+ && !targetm.narrow_volatile_bitfield () -+ && DECL_C_BIT_FIELD (field)) ) - mode = DECL_MODE (field); - else if (DECL_MODE (field) == BLKmode) - blkmode_bitfield = true; -@@ -7889,7 +7903,8 @@ expand_expr_real_1 (tree exp, rtx target - by doing the extract into an object as wide as the field - (which we know to be the width of a basic mode), then - storing into memory, and changing the mode to BLKmode. */ -- if (mode1 == VOIDmode -+ if ( -+ mode1 == VOIDmode - || REG_P (op0) || GET_CODE (op0) == SUBREG - || (mode1 != BLKmode && ! direct_load[(int) mode1] - && GET_MODE_CLASS (mode) != MODE_COMPLEX_INT ---- a/gcc/function.c -+++ b/gcc/function.c -@@ -2715,7 +2715,11 @@ assign_parm_setup_reg (struct assign_par - SET_DECL_RTL (parm, parmreg); - - /* Copy the value into the register. */ -- if (data->nominal_mode != data->passed_mode -+ if ( (data->nominal_mode != data->passed_mode -+ /* Added for AVR32: If passed_mode is equal -+ to promoted nominal mode why should be convert? -+ The conversion should make no difference. */ -+ && data->passed_mode != promoted_nominal_mode) - || promoted_nominal_mode != data->promoted_mode) - { - int save_tree_used; ---- a/gcc/genemit.c -+++ b/gcc/genemit.c -@@ -121,6 +121,24 @@ max_operand_vec (rtx insn, int arg) - } - - static void -+gen_vararg_prologue(int operands) -+{ -+ int i; -+ -+ if (operands > 1) -+ { -+ for (i = 1; i < operands; i++) -+ printf(" rtx operand%d ATTRIBUTE_UNUSED;\n", i); -+ -+ printf(" va_list args;\n\n"); -+ printf(" va_start(args, operand0);\n"); -+ for (i = 1; i < operands; i++) -+ printf(" operand%d = va_arg(args, rtx);\n", i); -+ printf(" va_end(args);\n\n"); -+ } -+} -+ -+static void - print_code (RTX_CODE code) - { - const char *p1; -@@ -406,18 +424,16 @@ gen_insn (rtx insn, int lineno) - fatal ("match_dup operand number has no match_operand"); - - /* Output the function name and argument declarations. */ -- printf ("rtx\ngen_%s (", XSTR (insn, 0)); -+ printf ("rtx\ngen_%s ", XSTR (insn, 0)); -+ - if (operands) -- for (i = 0; i < operands; i++) -- if (i) -- printf (",\n\trtx operand%d ATTRIBUTE_UNUSED", i); -+ printf("(rtx operand0 ATTRIBUTE_UNUSED, ...)\n"); - else -- printf ("rtx operand%d ATTRIBUTE_UNUSED", i); -- else -- printf ("void"); -- printf (")\n"); -+ printf("(void)\n"); - printf ("{\n"); - -+ gen_vararg_prologue(operands); -+ - /* Output code to construct and return the rtl for the instruction body. */ - - if (XVECLEN (insn, 1) == 1) -@@ -461,16 +477,12 @@ gen_expand (rtx expand) - operands = max_operand_vec (expand, 1); - - /* Output the function name and argument declarations. */ -- printf ("rtx\ngen_%s (", XSTR (expand, 0)); -+ printf ("rtx\ngen_%s ", XSTR (expand, 0)); - if (operands) -- for (i = 0; i < operands; i++) -- if (i) -- printf (",\n\trtx operand%d", i); -- else -- printf ("rtx operand%d", i); -+ printf("(rtx operand0 ATTRIBUTE_UNUSED, ...)\n"); - else -- printf ("void"); -- printf (")\n"); -+ printf("(void)\n"); -+ - printf ("{\n"); - - /* If we don't have any C code to write, only one insn is being written, -@@ -480,6 +492,8 @@ gen_expand (rtx expand) - && operands > max_dup_opno - && XVECLEN (expand, 1) == 1) - { -+ gen_vararg_prologue(operands); -+ - printf (" return "); - gen_exp (XVECEXP (expand, 1, 0), DEFINE_EXPAND, NULL); - printf (";\n}\n\n"); -@@ -493,6 +507,7 @@ gen_expand (rtx expand) - for (; i <= max_scratch_opno; i++) - printf (" rtx operand%d ATTRIBUTE_UNUSED;\n", i); - printf (" rtx _val = 0;\n"); -+ gen_vararg_prologue(operands); - printf (" start_sequence ();\n"); - - /* The fourth operand of DEFINE_EXPAND is some code to be executed ---- a/gcc/genflags.c -+++ b/gcc/genflags.c -@@ -127,7 +127,6 @@ static void - gen_proto (rtx insn) - { - int num = num_operands (insn); -- int i; - const char *name = XSTR (insn, 0); - int truth = maybe_eval_c_test (XSTR (insn, 2)); - -@@ -158,12 +157,7 @@ gen_proto (rtx insn) - if (num == 0) - fputs ("void", stdout); - else -- { -- for (i = 1; i < num; i++) -- fputs ("rtx, ", stdout); -- -- fputs ("rtx", stdout); -- } -+ fputs("rtx, ...", stdout); - - puts (");"); - -@@ -173,12 +167,7 @@ gen_proto (rtx insn) - { - printf ("static inline rtx\ngen_%s", name); - if (num > 0) -- { -- putchar ('('); -- for (i = 0; i < num-1; i++) -- printf ("rtx ARG_UNUSED (%c), ", 'a' + i); -- printf ("rtx ARG_UNUSED (%c))\n", 'a' + i); -- } -+ puts("(rtx ARG_UNUSED(a), ...)"); - else - puts ("(void)"); - puts ("{\n return 0;\n}"); ---- a/gcc/genoutput.c -+++ b/gcc/genoutput.c -@@ -386,7 +386,7 @@ output_insn_data (void) - } - - if (d->name && d->name[0] != '*') -- printf (" (insn_gen_fn) gen_%s,\n", d->name); -+ printf (" gen_%s,\n", d->name); - else - printf (" 0,\n"); - ---- a/gcc/ifcvt.c -+++ b/gcc/ifcvt.c -@@ -81,7 +81,7 @@ static int num_possible_if_blocks; - static int num_updated_if_blocks; - - /* # of changes made. */ --static int num_true_changes; -+int num_true_changes; - - /* Whether conditional execution changes were made. */ - static int cond_exec_changed_p; -@@ -286,6 +286,9 @@ cond_exec_process_insns (ce_if_block_t * - if (must_be_last) - return FALSE; - -+#ifdef IFCVT_ALLOW_MODIFY_TEST_IN_INSN -+ if ( !IFCVT_ALLOW_MODIFY_TEST_IN_INSN ) -+#endif - if (modified_in_p (test, insn)) - { - if (!mod_ok) -@@ -566,15 +569,18 @@ cond_exec_process_if_block (ce_if_block_ - IFCVT_MODIFY_FINAL (ce_info); - #endif - -+ /* Merge the blocks! */ -+ if ( reload_completed ){ - /* Conversion succeeded. */ - if (dump_file) - fprintf (dump_file, "%d insn%s converted to conditional execution.\n", - n_insns, (n_insns == 1) ? " was" : "s were"); - -- /* Merge the blocks! */ - merge_if_block (ce_info); - cond_exec_changed_p = TRUE; - return TRUE; -+ } -+ return FALSE; - - fail: - #ifdef IFCVT_MODIFY_CANCEL -@@ -1080,7 +1086,11 @@ noce_try_addcc (struct noce_if_info *if_ - != UNKNOWN)) - { - rtx cond = if_info->cond; -- enum rtx_code code = reversed_comparison_code (cond, if_info->jump); -+ /* This generates wrong code for AVR32. The cond code need not be reversed -+ since the addmodecc patterns add if the condition is NOT met. */ -+ /* enum rtx_code code = reversed_comparison_code (cond, if_info->jump);*/ -+ enum rtx_code code = GET_CODE(cond); -+ - - /* First try to use addcc pattern. */ - if (general_operand (XEXP (cond, 0), VOIDmode) -@@ -3017,7 +3027,12 @@ find_if_header (basic_block test_bb, int - && noce_find_if_block (test_bb, then_edge, else_edge, pass)) - goto success; - -- if (HAVE_conditional_execution && reload_completed -+ if (HAVE_conditional_execution && -+#ifdef IFCVT_COND_EXEC_BEFORE_RELOAD -+ (reload_completed || IFCVT_COND_EXEC_BEFORE_RELOAD) -+#else -+ reload_completed -+#endif - && cond_exec_find_if_block (&ce_info)) - goto success; - -@@ -3132,7 +3147,11 @@ cond_exec_find_if_block (struct ce_if_bl - - /* We only ever should get here after reload, - and only if we have conditional execution. */ -+#ifdef IFCVT_COND_EXEC_BEFORE_RELOAD -+ gcc_assert (HAVE_conditional_execution && (reload_completed||IFCVT_COND_EXEC_BEFORE_RELOAD)); -+#else - gcc_assert (HAVE_conditional_execution && reload_completed); -+#endif - - /* Discover if any fall through predecessors of the current test basic block - were && tests (which jump to the else block) or || tests (which jump to -@@ -4226,6 +4245,14 @@ gate_handle_if_after_reload (void) - static unsigned int - rest_of_handle_if_after_reload (void) - { -+ /* Hack for the AVR32 experimental ifcvt processing before reload. -+ The AVR32 specific ifcvt code needs to know when ifcvt after reload -+ has begun. */ -+#ifdef IFCVT_COND_EXEC_BEFORE_RELOAD -+ if ( IFCVT_COND_EXEC_BEFORE_RELOAD ) -+ cfun->machine->ifcvt_after_reload = 1; -+#endif -+ - if_convert (); - return 0; - } ---- a/gcc/longlong.h -+++ b/gcc/longlong.h -@@ -239,6 +239,41 @@ UDItype __umulsidi3 (USItype, USItype); - #define UDIV_TIME 100 - #endif /* __arm__ */ - -+#if defined (__avr32__) && W_TYPE_SIZE == 32 -+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ -+ __asm__ ("add\t%1, %4, %5\n\tadc\t%0, %2, %3" \ -+ : "=r" ((USItype) (sh)), \ -+ "=&r" ((USItype) (sl)) \ -+ : "r" ((USItype) (ah)), \ -+ "r" ((USItype) (bh)), \ -+ "r" ((USItype) (al)), \ -+ "r" ((USItype) (bl)) __CLOBBER_CC) -+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ -+ __asm__ ("sub\t%1, %4, %5\n\tsbc\t%0, %2, %3" \ -+ : "=r" ((USItype) (sh)), \ -+ "=&r" ((USItype) (sl)) \ -+ : "r" ((USItype) (ah)), \ -+ "r" ((USItype) (bh)), \ -+ "r" ((USItype) (al)), \ -+ "r" ((USItype) (bl)) __CLOBBER_CC) -+ -+#if !defined (__AVR32_NO_MUL__) -+#define __umulsidi3(a,b) ((UDItype)(a) * (UDItype)(b)) -+ -+#define umul_ppmm(w1, w0, u, v) \ -+{ \ -+ DWunion __w; \ -+ __w.ll = __umulsidi3 (u, v); \ -+ w1 = __w.s.high; \ -+ w0 = __w.s.low; \ -+} -+#endif -+ -+#define count_leading_zeros(COUNT,X) ((COUNT) = __builtin_clz (X)) -+#define count_trailing_zeros(COUNT,X) ((COUNT) = __builtin_ctz (X)) -+#define COUNT_LEADING_ZEROS_0 32 -+#endif -+ - #if defined (__CRIS__) && __CRIS_arch_version >= 3 - #define count_leading_zeros(COUNT, X) ((COUNT) = __builtin_clz (X)) - #if __CRIS_arch_version >= 8 ---- a/gcc/optabs.h -+++ b/gcc/optabs.h -@@ -586,7 +586,7 @@ extern enum insn_code reload_out_optab[N - extern optab code_to_optab[NUM_RTX_CODE + 1]; - - --typedef rtx (*rtxfun) (rtx); -+typedef rtx (*rtxfun) (rtx, ...); - - /* Indexed by the rtx-code for a conditional (e.g. EQ, LT,...) - gives the gen_function to make a branch to test that condition. */ ---- a/gcc/regrename.c -+++ b/gcc/regrename.c -@@ -1580,6 +1580,9 @@ copyprop_hardreg_forward_1 (basic_block - bool changed = false; - rtx insn; - -+ rtx prev_pred_test; -+ int prev_pred_insn_skipped = 0; -+ - for (insn = BB_HEAD (bb); ; insn = NEXT_INSN (insn)) - { - int n_ops, i, alt, predicated; -@@ -1619,6 +1622,58 @@ copyprop_hardreg_forward_1 (basic_block - recog_data.operand_type[i] = OP_INOUT; - } - -+ -+ /* Added for targets (AVR32) which supports test operands to be modified -+ in cond_exec instruction. For these targets we cannot make a change to -+ the test operands if one of the test operands is an output operand This beacuse -+ changing the test operands might cause the need for inserting a new test -+ insns in the middle of a sequence of cond_exec insns and if the test operands -+ are modified these tests will fail. -+ */ -+ if ( IFCVT_ALLOW_MODIFY_TEST_IN_INSN -+ && predicated ) -+ { -+ int insn_skipped = 0; -+ rtx test = COND_EXEC_TEST (PATTERN (insn)); -+ -+ /* Check if the previous insn was a skipped predicated insn with the same -+ test as this predicated insns. If so we cannot do any modification to -+ this insn either since we cannot emit the test insn because the operands -+ are clobbered. */ -+ if ( prev_pred_insn_skipped -+ && (rtx_equal_p (test, prev_pred_test) -+ || rtx_equal_p (test, reversed_condition (prev_pred_test))) ) -+ { -+ insn_skipped = 1; -+ } -+ else -+ { -+ /* Check if the output operand is used in the test expression. */ -+ for (i = 0; i < n_ops; ++i) -+ if ( recog_data.operand_type[i] == OP_INOUT -+ && reg_mentioned_p (recog_data.operand[i], test) ) -+ { -+ insn_skipped = 1; -+ break; -+ } -+ -+ } -+ -+ prev_pred_test = test; -+ prev_pred_insn_skipped = insn_skipped; -+ if ( insn_skipped ) -+ { -+ if (insn == BB_END (bb)) -+ break; -+ else -+ continue; -+ } -+ } -+ else -+ { -+ prev_pred_insn_skipped = 0; -+ } -+ - /* For each earlyclobber operand, zap the value data. */ - for (i = 0; i < n_ops; i++) - if (recog_op_alt[i][alt].earlyclobber) ---- a/gcc/sched-deps.c -+++ b/gcc/sched-deps.c -@@ -1406,7 +1406,14 @@ fixup_sched_groups (rtx insn) - - prev_nonnote = prev_nonnote_insn (insn); - if (BLOCK_FOR_INSN (insn) == BLOCK_FOR_INSN (prev_nonnote) -- && ! sched_insns_conditions_mutex_p (insn, prev_nonnote)) -+ /* Modification for AVR32 by RP: Why is this here, this will -+ cause instruction to be without any dependencies which might -+ cause it to be moved anywhere. For the AVR32 we try to keep -+ a group of conditionals together even if they are mutual exclusive. -+ */ -+ && (! sched_insns_conditions_mutex_p (insn, prev_nonnote) -+ || GET_CODE (PATTERN (insn)) == COND_EXEC ) -+ ) - add_dependence (insn, prev_nonnote, REG_DEP_ANTI); - } - -@@ -1905,8 +1912,29 @@ sched_analyze_insn (struct deps *deps, r - - if (code == COND_EXEC) - { -+#ifdef IFCVT_ALLOW_MODIFY_TEST_IN_INSN -+ if (IFCVT_ALLOW_MODIFY_TEST_IN_INSN) -+ { -+ /* Check if we have a group og conditional instructions with the same test. -+ If so we must make sure that they are not scheduled apart in order to -+ avoid unnecesarry tests and if one of the registers in the test is modified -+ in the instruction this is needed to ensure correct code. */ -+ if ( prev_nonnote_insn (insn) -+ && INSN_P (prev_nonnote_insn (insn)) -+ && GET_CODE (PATTERN (prev_nonnote_insn (insn))) == COND_EXEC -+ && rtx_equal_p (XEXP(COND_EXEC_TEST (PATTERN (prev_nonnote_insn (insn))), 0), XEXP (COND_EXEC_TEST (x), 0)) -+ && rtx_equal_p (XEXP(COND_EXEC_TEST (PATTERN (prev_nonnote_insn (insn))), 1), XEXP (COND_EXEC_TEST (x), 1)) -+ && ( GET_CODE (COND_EXEC_TEST (PATTERN (prev_nonnote_insn (insn)))) == GET_CODE (COND_EXEC_TEST (x)) -+ || GET_CODE (COND_EXEC_TEST (PATTERN (prev_nonnote_insn (insn)))) == reversed_comparison_code (COND_EXEC_TEST (x), insn))) -+ { -+ SCHED_GROUP_P (insn) = 1; -+ //CANT_MOVE (prev_nonnote_insn (insn)) = 1; -+ } -+ } -+#endif - sched_analyze_2 (deps, COND_EXEC_TEST (x), insn); - -+ - /* ??? Should be recording conditions so we reduce the number of - false dependencies. */ - x = COND_EXEC_CODE (x); ---- a/gcc/testsuite/gcc.dg/sibcall-3.c -+++ b/gcc/testsuite/gcc.dg/sibcall-3.c -@@ -5,7 +5,7 @@ - Copyright (C) 2002 Free Software Foundation Inc. - Contributed by Hans-Peter Nilsson */ - --/* { dg-do run { xfail arc-*-* avr-*-* cris-*-* crisv32-*-* h8300-*-* hppa*64*-*-* m32r-*-* m68hc1?-*-* mcore-*-* mn10300-*-* xstormy16-*-* v850*-*-* vax-*-* xtensa-*-* } } */ -+/* { dg-do run { xfail arc-*-* avr-*-* avr32-*-* cris-*-* crisv32-*-* h8300-*-* hppa*64*-*-* m32r-*-* m68hc1?-*-* mcore-*-* mn10300-*-* xstormy16-*-* v850*-*-* vax-*-* xtensa-*-* } } */ - /* -mlongcall disables sibcall patterns. */ - /* { dg-skip-if "" { powerpc*-*-* } { "-mlongcall" } { "" } } */ - /* { dg-options "-O2 -foptimize-sibling-calls" } */ ---- a/gcc/testsuite/gcc.dg/sibcall-4.c -+++ b/gcc/testsuite/gcc.dg/sibcall-4.c -@@ -5,7 +5,7 @@ - Copyright (C) 2002 Free Software Foundation Inc. - Contributed by Hans-Peter Nilsson */ - --/* { dg-do run { xfail arc-*-* avr-*-* cris-*-* crisv32-*-* h8300-*-* hppa*64*-*-* m32r-*-* m68hc1?-*-* mcore-*-* mn10300-*-* xstormy16-*-* v850*-*-* vax-*-* xtensa-*-* } } */ -+/* { dg-do run { xfail arc-*-* avr-*-* avr32-*-* cris-*-* crisv32-*-* h8300-*-* hppa*64*-*-* m32r-*-* m68hc1?-*-* mcore-*-* mn10300-*-* xstormy16-*-* v850*-*-* vax-*-* xtensa-*-* } } */ - /* -mlongcall disables sibcall patterns. */ - /* { dg-skip-if "" { powerpc*-*-* } { "-mlongcall" } { "" } } */ - /* { dg-options "-O2 -foptimize-sibling-calls" } */ ---- a/gcc/testsuite/gcc.dg/trampoline-1.c -+++ b/gcc/testsuite/gcc.dg/trampoline-1.c -@@ -46,6 +46,8 @@ void foo (void) - - int main (void) - { -+#ifndef NO_TRAMPOLINES - foo (); -+#endif - return 0; - } ---- a/gcc/testsuite/g++.old-deja/g++.pt/static11.C -+++ b/gcc/testsuite/g++.old-deja/g++.pt/static11.C -@@ -2,7 +2,7 @@ - // in their dejagnu baseboard description) require that the status is - // final when exit is entered (or main returns), and not "overruled" by a - // destructor calling _exit. It's not really worth it to handle that. --// { dg-do run { xfail mmix-knuth-mmixware arm*-*-elf arm*-*-eabi m68k-*-elf } } -+// { dg-do run { xfail mmix-knuth-mmixware avr32-*-elf arm*-*-elf arm*-*-eabi m68k-*-elf } } - - // Bug: g++ was failing to destroy C::a because it was using two - // different sentry variables for construction and destruction. ---- a/libgcc/config.host -+++ b/libgcc/config.host -@@ -240,6 +240,13 @@ arm-*-pe*) - ;; - arm*-*-kaos*) - ;; -+avr32-*-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" -+ ;; -+avr32-*-*) -+ ;; - avr-*-rtems*) - ;; - avr-*-*) ---- a/libstdc++-v3/config/os/gnu-linux/ctype_base.h -+++ b/libstdc++-v3/config/os/gnu-linux/ctype_base.h -@@ -31,6 +31,8 @@ - // - // ISO C++ 14882: 22.1 Locales - // -+#include -+#include - - /** @file ctype_base.h - * This is an internal header file, included by other library headers. -@@ -45,7 +47,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std) - struct ctype_base - { - // Non-standard typedefs. -+#ifdef __UCLIBC__ -+ typedef const __ctype_touplow_t* __to_type; -+#else - typedef const int* __to_type; -+#endif - - // NB: Offsets into ctype::_M_table force a particular size - // on the mask type. Because of this, we don't use an enum. ---- a/libstdc++-v3/include/Makefile.in -+++ b/libstdc++-v3/include/Makefile.in -@@ -36,6 +36,7 @@ POST_UNINSTALL = : - build_triplet = @build@ - host_triplet = @host@ - target_triplet = @target@ -+LIBOBJDIR = - DIST_COMMON = $(top_srcdir)/fragment.am $(srcdir)/Makefile.in \ - $(srcdir)/Makefile.am - subdir = include ---- a/libstdc++-v3/libmath/Makefile.in -+++ b/libstdc++-v3/libmath/Makefile.in -@@ -37,6 +37,7 @@ POST_UNINSTALL = : - build_triplet = @build@ - host_triplet = @host@ - target_triplet = @target@ -+LIBOBJDIR = - subdir = libmath - DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am - ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 ---- a/libstdc++-v3/libsupc++/Makefile.in -+++ b/libstdc++-v3/libsupc++/Makefile.in -@@ -38,6 +38,7 @@ POST_UNINSTALL = : - build_triplet = @build@ - host_triplet = @host@ - target_triplet = @target@ -+LIBOBJDIR = - DIST_COMMON = $(top_srcdir)/fragment.am $(srcdir)/Makefile.in \ - $(srcdir)/Makefile.am $(glibcxxinstall_HEADERS) - subdir = libsupc++ ---- a/libstdc++-v3/Makefile.in -+++ b/libstdc++-v3/Makefile.in -@@ -36,6 +36,7 @@ POST_UNINSTALL = : - build_triplet = @build@ - host_triplet = @host@ - target_triplet = @target@ -+LIBOBJDIR = - DIST_COMMON = $(top_srcdir)/fragment.am $(srcdir)/../config.guess \ - $(srcdir)/../config.sub README ChangeLog $(srcdir)/Makefile.in \ - $(srcdir)/Makefile.am $(top_srcdir)/configure \ ---- a/libstdc++-v3/po/Makefile.in -+++ b/libstdc++-v3/po/Makefile.in -@@ -36,6 +36,7 @@ POST_UNINSTALL = : - build_triplet = @build@ - host_triplet = @host@ - target_triplet = @target@ -+LIBOBJDIR = - DIST_COMMON = $(top_srcdir)/fragment.am $(srcdir)/Makefile.in \ - $(srcdir)/Makefile.am - subdir = po ---- a/libstdc++-v3/src/Makefile.in -+++ b/libstdc++-v3/src/Makefile.in -@@ -37,6 +37,7 @@ POST_UNINSTALL = : - build_triplet = @build@ - host_triplet = @host@ - target_triplet = @target@ -+LIBOBJDIR = - DIST_COMMON = $(top_srcdir)/fragment.am $(srcdir)/Makefile.in \ - $(srcdir)/Makefile.am - subdir = src diff --git a/toolchain/gcc/patches/4.3.5/993-arm_insn-opinit-RTX_CODE-fixup.patch b/toolchain/gcc/patches/4.3.5/993-arm_insn-opinit-RTX_CODE-fixup.patch deleted file mode 100644 index befe58c845..0000000000 --- a/toolchain/gcc/patches/4.3.5/993-arm_insn-opinit-RTX_CODE-fixup.patch +++ /dev/null @@ -1,37 +0,0 @@ -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. - ---- a/gcc/config/arm/arm-protos.h -+++ b/gcc/config/arm/arm-protos.h -@@ -40,15 +40,14 @@ extern HOST_WIDE_INT thumb_compute_initi - 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, ---- a/gcc/genopinit.c -+++ b/gcc/genopinit.c -@@ -487,6 +487,7 @@ from the machine description file `md'. - 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"); - diff --git a/toolchain/gcc/patches/4.3.5/995-short-enums.diff b/toolchain/gcc/patches/4.3.5/995-short-enums.diff deleted file mode 100644 index 62d66925af..0000000000 --- a/toolchain/gcc/patches/4.3.5/995-short-enums.diff +++ /dev/null @@ -1,36 +0,0 @@ -see gcc PR34205 ---- a/gcc/tree.h -+++ b/gcc/tree.h -@@ -39,6 +39,7 @@ enum tree_code { - - 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 ---- a/gcc/rtl.h -+++ b/gcc/rtl.h -@@ -48,9 +48,11 @@ enum rtx_code { - #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. */ ---- a/gcc/c-common.h -+++ b/gcc/c-common.h -@@ -125,6 +125,7 @@ enum rid - 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) \ diff --git a/toolchain/gcc/patches/4.3.5/998-gcc-4.3.0-fix-header.00.patch b/toolchain/gcc/patches/4.3.5/998-gcc-4.3.0-fix-header.00.patch deleted file mode 100644 index 3f889321f0..0000000000 --- a/toolchain/gcc/patches/4.3.5/998-gcc-4.3.0-fix-header.00.patch +++ /dev/null @@ -1,13 +0,0 @@ -\\\\ -\\ gcc PR33200 ---- a/gcc/config.gcc -+++ b/gcc/config.gcc -@@ -2332,7 +2332,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-*-rtems*) - tmake_file="sh/t-sh sh/t-elf t-rtems sh/t-rtems" diff --git a/toolchain/gcc/patches/4.3.5/999-coldfire.patch b/toolchain/gcc/patches/4.3.5/999-coldfire.patch deleted file mode 100644 index c8b883b899..0000000000 --- a/toolchain/gcc/patches/4.3.5/999-coldfire.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- a/gcc/config.gcc -+++ b/gcc/config.gcc -@@ -1645,6 +1645,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 diff --git a/toolchain/gcc/patches/4.4.1+cs/000-codesourcery_2010_71.patch b/toolchain/gcc/patches/4.4.1+cs/000-codesourcery_2010_71.patch deleted file mode 100644 index cf2e68f13e..0000000000 --- a/toolchain/gcc/patches/4.4.1+cs/000-codesourcery_2010_71.patch +++ /dev/null @@ -1,29759 +0,0 @@ ---- a/gcc/addresses.h -+++ b/gcc/addresses.h -@@ -78,3 +78,42 @@ - - 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/calls.c -+++ b/gcc/calls.c -@@ -3803,7 +3803,7 @@ - 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 -@@ -4048,8 +4048,17 @@ - /* 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/c-common.c -+++ b/gcc/c-common.c -@@ -33,7 +33,6 @@ - #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 @@ - #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 @@ - 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 @@ - #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 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 @@ - 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 @@ - - 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 -@@ -3994,6 +3994,7 @@ - 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; -@@ -4531,6 +4532,12 @@ - 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. */ -@@ -5044,6 +5051,7 @@ - { - 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 -@@ -5087,6 +5095,14 @@ - } - } - -+ 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); - } -@@ -8071,7 +8087,7 @@ - - /* 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/cfgexpand.c -+++ b/gcc/cfgexpand.c -@@ -488,7 +488,8 @@ - { - 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 @@ - 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 @@ - 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 @@ - 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 @@ - 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 @@ - 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 @@ - 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 @@ - 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/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" -@@ -53,6 +54,8 @@ - #include "debug.h" - #include "langhooks.h" - #include "df.h" -+#include "intl.h" -+#include "params.h" - - /* Forward definitions of types. */ - typedef struct minipool_node Mnode; -@@ -110,6 +113,7 @@ - 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 *); -@@ -123,6 +127,10 @@ - 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); -@@ -148,6 +156,9 @@ - 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; -@@ -175,6 +186,7 @@ - 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); -@@ -197,6 +209,15 @@ - 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); - - - /* Initialize the GCC target structure. */ -@@ -256,6 +277,12 @@ - #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 -@@ -299,6 +326,9 @@ - #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 - -@@ -353,6 +383,9 @@ - #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 */ -@@ -360,6 +393,9 @@ - #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 - -@@ -398,6 +434,30 @@ - #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; - - /* Obstack for minipool constant handling. */ -@@ -423,18 +483,18 @@ - /* 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; - -@@ -473,9 +533,19 @@ - #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) -@@ -497,6 +567,7 @@ - #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. */ -@@ -533,6 +604,9 @@ - /* 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; - -@@ -551,6 +625,9 @@ - /* 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; -@@ -561,6 +638,9 @@ - /* 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 -@@ -593,6 +673,8 @@ - /* 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. */ -@@ -673,9 +755,11 @@ - {"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} - }; - -@@ -705,49 +789,34 @@ - - /* 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; -@@ -765,6 +834,23 @@ - }; - - -+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; -@@ -922,6 +1008,44 @@ - set_optab_libfunc (umod_optab, DImode, NULL); - 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; -+ } - } - - /* On AAPCS systems, this is the "struct __va_list". */ -@@ -1135,6 +1259,7 @@ - arm_override_options (void) - { - unsigned i; -+ int len; - enum processor_type target_arch_cpu = arm_none; - enum processor_type selected_cpu = arm_none; - -@@ -1152,7 +1277,11 @@ - { - /* 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. */ -@@ -1178,8 +1307,8 @@ - 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; -@@ -1279,7 +1408,11 @@ - - 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; -@@ -1289,8 +1422,35 @@ - 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++) -@@ -1383,6 +1543,7 @@ - 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; -@@ -1390,12 +1551,25 @@ - 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) -@@ -1434,7 +1608,6 @@ - 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")) -@@ -1445,46 +1618,52 @@ - 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) -@@ -1505,9 +1684,6 @@ - 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. */ -@@ -1518,15 +1694,40 @@ - 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; - -@@ -1616,8 +1817,7 @@ - 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; -@@ -1653,6 +1853,36 @@ - - /* 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 -@@ -1782,6 +2012,14 @@ - 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 ()); -+} -+ - - /* 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 -@@ -2873,14 +3111,19 @@ - - /* 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); -@@ -2897,7 +3140,36 @@ - } - } - -- 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 -@@ -2907,10 +3179,12 @@ - { - 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) -@@ -2923,27 +3197,56 @@ - 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) - { -@@ -2960,7 +3263,7 @@ - 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) - { -@@ -2980,18 +3283,18 @@ - 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. */ -@@ -3003,10 +3306,10 @@ - continue; - - if (!DECL_BIT_FIELD_TYPE (field)) -- return 1; -+ return true; - } - -- return 0; -+ return false; - } - - if (TREE_CODE (type) == UNION_TYPE) -@@ -3023,18 +3326,18 @@ - 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. */ -@@ -3059,14 +3362,780 @@ - 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; -@@ -3120,6 +4189,17 @@ - { - 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 -@@ -3161,10 +4241,16 @@ - - 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; - -@@ -3176,6 +4262,39 @@ - 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 - extension to the ARM ABI. */ - -@@ -3226,6 +4345,8 @@ - /* 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 }, -@@ -3328,6 +4449,21 @@ - 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 -@@ -3489,7 +4625,7 @@ - - /* 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; - -@@ -3522,6 +4658,21 @@ - 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; -@@ -4120,6 +5271,7 @@ - if (GET_MODE_SIZE (mode) <= 4 - && ! (arm_arch4 - && (mode == HImode -+ || mode == HFmode - || (mode == QImode && outer == SIGN_EXTEND)))) - { - if (code == MULT) -@@ -4148,13 +5300,15 @@ - 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 -@@ -4325,7 +5479,8 @@ - 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 -@@ -5024,7 +6179,7 @@ - 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); -@@ -5063,23 +6218,6 @@ - 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)); -@@ -5102,7 +6240,9 @@ - - 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 -@@ -5143,6 +6283,17 @@ - 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)) & -@@ -5164,6 +6315,19 @@ - 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: -@@ -5192,7 +6356,9 @@ - - 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 -@@ -5307,7 +6473,9 @@ - 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; -@@ -5460,7 +6628,9 @@ - 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; -@@ -5563,7 +6733,8 @@ - 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); -@@ -5638,7 +6809,8 @@ - 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; -@@ -5668,7 +6840,8 @@ - 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; -@@ -5698,7 +6871,8 @@ - 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; -@@ -5722,7 +6896,8 @@ - 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)); -@@ -5939,7 +7114,9 @@ - - 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; -@@ -6096,7 +7273,9 @@ - - 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; -@@ -6919,10 +8098,13 @@ - } - - /* 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; - -@@ -6955,23 +8137,16 @@ - 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) -@@ -7038,10 +8213,19 @@ - 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)) -@@ -7438,6 +8622,9 @@ - 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); -@@ -7667,6 +8854,9 @@ - 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); -@@ -7874,7 +9064,7 @@ - - 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; - -@@ -7937,7 +9127,7 @@ - - /* 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; - -@@ -9555,7 +10745,10 @@ - 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); -@@ -9867,6 +11060,8 @@ - insn = table; - } - } -+ else if (LABEL_P (insn) && (align_jumps > 0 || align_loops > 0)) -+ address += MAX (align_jumps, align_loops); - } - - fix = minipool_fix_head; -@@ -10072,6 +11267,21 @@ - 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) -@@ -10142,6 +11352,56 @@ - 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. */ -@@ -10758,7 +12018,7 @@ - } - - /* 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) -@@ -10954,6 +12214,12 @@ - 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 (); -@@ -10968,7 +12234,7 @@ - { - /* We're only using DImode here because it's a convenient size. */ - ops[0] = gen_rtx_REG (DImode, REGNO (reg) + 2 * i); -- ops[1] = adjust_address (mem, SImode, 8 * i); -+ ops[1] = adjust_address (mem, DImode, 8 * i); - if (reg_overlap_mentioned_p (ops[0], mem)) - { - gcc_assert (overlap == -1); -@@ -11557,7 +12823,7 @@ - if (count > 0) - { - /* Workaround ARM10 VFPr1 bug. */ -- if (count == 2 && !arm_arch6) -+ if (count == 2 && !arm_arch6 && !low_irq_latency) - count++; - saved += count * 8; - } -@@ -11886,6 +13152,41 @@ - 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) - { -@@ -11946,7 +13247,7 @@ - /* 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]) -@@ -12169,7 +13470,7 @@ - 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]) -@@ -12253,22 +13554,19 @@ - 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); - } -@@ -12389,6 +13687,32 @@ - - 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)) -@@ -12737,22 +14061,23 @@ - { - 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) - { -@@ -12876,7 +14201,7 @@ - - /* 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]) -@@ -13483,7 +14808,11 @@ - { - 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); - } -@@ -13704,6 +15033,30 @@ - } - 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': -@@ -13821,6 +15174,57 @@ - } - 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) - { -@@ -13854,6 +15258,12 @@ - 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; - } -@@ -14245,6 +15655,10 @@ - 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) -@@ -14618,6 +16032,11 @@ - 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) -@@ -14637,16 +16056,16 @@ - 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) -@@ -16103,6 +17522,15 @@ - } - - 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 (); -@@ -16112,6 +17540,71 @@ - - 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 -@@ -17191,6 +18684,7 @@ - unsigned HOST_WIDE_INT mask = 0xff; - int i; - -+ val = val & (unsigned HOST_WIDE_INT)0xffffffffu; - if (val == 0) /* XXX */ - return 0; - -@@ -18279,40 +19773,8 @@ - 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"); -@@ -18362,6 +19824,11 @@ - 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(); - } -@@ -18591,6 +20058,23 @@ - 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) - { -@@ -18628,19 +20112,24 @@ - 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; - } -@@ -19024,9 +20513,10 @@ - || 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; -@@ -19057,9 +20547,14 @@ - 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; -@@ -19070,6 +20565,39 @@ - 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 -@@ -19556,6 +21084,7 @@ - case cortexr4f: - case cortexa8: - case cortexa9: -+ case marvell_f: - return 2; - - default: -@@ -19620,6 +21149,10 @@ - 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; - -@@ -19676,6 +21209,87 @@ - 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-cores.def -+++ b/gcc/config/arm/arm-cores.def -@@ -104,6 +104,7 @@ - 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("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.h -+++ b/gcc/config/arm/arm.h -@@ -85,6 +85,10 @@ - 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 @@ - #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 @@ - /* 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 @@ - 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 @@ - #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 @@ - /* 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 @@ - /* 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 @@ - /* 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 @@ - 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 @@ - /* 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 @@ - (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 @@ - || 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 @@ - 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 @@ - 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 @@ - /* 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 @@ - - /* 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 @@ - ? 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 @@ - 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 @@ - 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 @@ - 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 @@ - - /* 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))) - - -@@ -2324,7 +2406,8 @@ - /* 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)) - - /* Position Independent Code. */ - /* We decide which register to use based on the compilation options and -@@ -2392,6 +2475,7 @@ - - /* 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) - - #undef ASM_APP_OFF - #define ASM_APP_OFF (TARGET_THUMB1 ? "\t.code\t16\n" : \ -@@ -2404,6 +2488,19 @@ - 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 @@ - 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") - - -@@ -472,9 +479,9 @@ - if (TARGET_THUMB1) - { - if (GET_CODE (operands[1]) != REG) -- operands[1] = force_reg (SImode, operands[1]); -+ operands[1] = force_reg (DImode, operands[1]); - if (GET_CODE (operands[2]) != REG) -- operands[2] = force_reg (SImode, operands[2]); -+ operands[2] = force_reg (DImode, operands[2]); - } - " - ) -@@ -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 -+; r3, r3, -+; 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)" - "") - - ;; 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")] - ) - - ;; 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; -+ }" -+) - - ;; 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; -+ }" -+) - - ;; 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")] - ) - - -@@ -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)))] - ) - - -@@ -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-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 @@ - 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_neon.h -+++ b/gcc/config/arm/arm_neon.h -@@ -61,7 +61,7 @@ - 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 +5085,7 @@ - __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 +5151,7 @@ - __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 +5283,7 @@ - __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 +5349,7 @@ - __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 +5415,7 @@ - __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 +5481,7 @@ - __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 +6591,7 @@ - __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 +6621,7 @@ - __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 +6735,7 @@ - __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 +6765,7 @@ - __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 +6831,7 @@ - __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 +6861,7 @@ - __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 +7851,7 @@ - __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 +7917,7 @@ - __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 +7977,7 @@ - __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 +8043,7 @@ - __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 +8109,7 @@ - __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 +8175,7 @@ - __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 +8247,7 @@ - __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 +8313,7 @@ - __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 +8373,7 @@ - __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 +8439,7 @@ - __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 +8512,7 @@ - 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 +8600,7 @@ - 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 +8676,7 @@ - { - 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 +8748,7 @@ - { - 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 +8807,7 @@ - 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 +8892,7 @@ - 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 +8969,7 @@ - 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 +9032,7 @@ - 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 +9088,7 @@ - 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 +9140,7 @@ - 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 +9228,7 @@ - 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 +9304,7 @@ - { - 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 +9376,7 @@ - { - 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 +9435,7 @@ - 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 +9520,7 @@ - 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 +9597,7 @@ - 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 +9660,7 @@ - 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 +9716,7 @@ - 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 +9768,7 @@ - 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 +9856,7 @@ - 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 +9932,7 @@ - { - 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 +10004,7 @@ - { - 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 +10063,7 @@ - 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 +10148,7 @@ - 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 +10225,7 @@ - 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 +10288,7 @@ - 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 +10344,7 @@ - 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/arm.opt -+++ b/gcc/config/arm/arm.opt -@@ -78,6 +78,10 @@ - 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 @@ - 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 @@ - 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 @@ - 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-protos.h -+++ b/gcc/config/arm/arm-protos.h -@@ -88,7 +88,7 @@ - - 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 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 @@ - - #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/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/bpabi.S -+++ b/gcc/config/arm/bpabi.S -@@ -64,20 +64,69 @@ - - #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 @@ - #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-v6m.S -+++ b/gcc/config/arm/bpabi-v6m.S -@@ -69,9 +69,52 @@ - - #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 @@ - #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/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 -+ . */ -+ -+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_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 @@ - 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 @@ - 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 @@ - 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 @@ - @ 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 @@ - @ 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 @@ - @ 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 @@ - - 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 @@ - 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 -@@ -1117,7 +1117,7 @@ - ARM_FUNC_ALIAS eqdf2 cmpdf2 - mov ip, #1 @ how should we specify unordered here? - --1: str ip, [sp, #-4] -+1: str ip, [sp, #-4]! - - @ Trap any INF/NAN first. - mov ip, xh, lsl #1 -@@ -1129,7 +1129,8 @@ - - @ Test for equality. - @ Note that 0.0 is equal to -0.0. --2: orrs ip, xl, xh, lsl #1 @ if x == 0.0 or -0.0 -+2: add sp, sp, #4 -+ orrs ip, xl, xh, lsl #1 @ if x == 0.0 or -0.0 - do_it eq, e - COND(orr,s,eq) ip, yl, yh, lsl #1 @ and y == 0.0 or -0.0 - teqne xh, yh @ or xh == yh -@@ -1168,7 +1169,7 @@ - bne 2b - orrs ip, yl, yh, lsl #12 - beq 2b @ y is not NAN --5: ldr r0, [sp, #-4] @ unordered return code -+5: ldr r0, [sp], #4 @ unordered return code - RET - - FUNC_END gedf2 -@@ -1194,7 +1195,7 @@ - - @ 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 @@ - 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 @@ - 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 - -@@ -822,7 +822,7 @@ - ARM_FUNC_ALIAS eqsf2 cmpsf2 - mov ip, #1 @ how should we specify unordered here? - --1: str ip, [sp, #-4] -+1: str ip, [sp, #-4]! - - @ Trap any INF/NAN first. - mov r2, r0, lsl #1 -@@ -834,7 +834,8 @@ - - @ Compare values. - @ Note that 0.0 is equal to -0.0. --2: orrs ip, r2, r3, lsr #1 @ test if both are 0, clear C flag -+2: add sp, sp, #4 -+ orrs ip, r2, r3, lsr #1 @ test if both are 0, clear C flag - do_it ne - teqne r0, r1 @ if not 0 compare sign - do_it pl -@@ -858,7 +859,7 @@ - bne 2b - movs ip, r1, lsl #9 - beq 2b @ r1 is not NAN --5: ldr r0, [sp, #-4] @ return unordered code. -+5: ldr r0, [sp], #4 @ return unordered code. - RET - - FUNC_END gesf2 -@@ -881,7 +882,7 @@ - - @ 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 @@ - #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 @@ - .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 @@ - .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 @@ - 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 @@ - #define yyl r2 - #endif - -+#ifdef __ARM_EABI__ -+.macro WEAK name -+ .weak SYM (__\name) -+.endm -+#endif -+ - #ifdef __thumb__ - /* Register aliases. */ - -@@ -437,6 +562,43 @@ - - #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 @@ - 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 @@ - - @ 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 @@ - /* ------------------------------------------------------------------------ */ - #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 @@ - 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 @@ - mov r0, r2 - RET - --11: moveq r0, #1 -+11: do_it eq, e -+ moveq r0, #1 - movne r0, #0 - RET - -@@ -845,19 +1022,24 @@ - - #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 @@ - - #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 @@ - 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 @@ - 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 @@ - - 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 @@ - - #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 @@ - /* Constant taken from . */ - #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 @@ - 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.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") -+ ---- /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/montavista-linux.h -@@ -0,0 +1,33 @@ -+/* MontaVista GNU/Linux Configuration. -+ 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 -+. */ -+ -+/* Add -tarmv6 and -tthumb2 options for convenience in generating multilibs. -+*/ -+#undef CC1_SPEC -+#define CC1_SPEC " \ -+ %{tarmv6: -march=armv6 -mfloat-abi=softfp ; \ -+ tthumb2: -mthumb -march=armv7-a -mfloat-abi=softfp ; \ -+ : -march=armv5t}" -+ -+/* The various C libraries each have their own subdirectory. */ -+#undef SYSROOT_SUFFIX_SPEC -+#define SYSROOT_SUFFIX_SPEC \ -+ "%{tarmv6:/armv6 ; \ -+ tthumb2:/thumb2}" ---- a/gcc/config/arm/neon-gen.ml -+++ b/gcc/config/arm/neon-gen.ml -@@ -122,6 +122,7 @@ - | 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 @@ - typeinfo; - Format.print_newline (); - (* Extra types not in . *) -- 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" - ---- 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) -+ || register_operand (operands[1], 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) -+ || register_operand (operands[1], 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" -@@ -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, operands[1]); -+ } - }) - - (define_insn "*neon_mov" - [(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) -+ || register_operand (operands[1], mode))" - { - switch (which_alternative) - { -@@ -658,6 +675,49 @@ - neon_disambiguate_copy (operands, dest, src, 4); - }) - -+(define_expand "movmisalign" -+ [(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) -+ && !s_register_operand (operands[1], mode)) -+ FAIL; -+}) -+ -+(define_insn "*movmisalign_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.\t{%P1}, %A0" -+ [(set_attr "neon_type" "neon_vst1_1_2_regs_vst2_2_regs")]) -+ -+(define_insn "*movmisalign_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.\t{%P0}, %A1" -+ [(set_attr "neon_type" "neon_vld1_1_2_regs")]) -+ -+(define_insn "*movmisalign_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.\t{%q1}, %A0" -+ [(set_attr "neon_type" "neon_vst1_1_2_regs_vst2_2_regs")]) -+ -+(define_insn "*movmisalign_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.\t{%q0}, %A1" -+ [(set_attr "neon_type" "neon_vld1_1_2_regs")]) -+ - (define_insn "vec_set_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 "*mul3add_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.\t%0, %2, %3" -+ [(set (attr "neon_type") -+ (if_then_else (ne (symbol_ref "") (const_int 0)) -+ (if_then_else (ne (symbol_ref "") (const_int 0)) -+ (const_string "neon_fp_vmla_ddd") -+ (const_string "neon_fp_vmla_qqq")) -+ (if_then_else (ne (symbol_ref "") (const_int 0)) -+ (if_then_else -+ (ne (symbol_ref "") (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 "") (const_int 0)) -+ (const_string "neon_mla_qqq_8_16") -+ (const_string "neon_mla_qqq_32_qqd_32_scalar")))))] -+) -+ -+(define_insn "*mul3negadd_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.\t%0, %2, %3" -+ [(set (attr "neon_type") -+ (if_then_else (ne (symbol_ref "") (const_int 0)) -+ (if_then_else (ne (symbol_ref "") (const_int 0)) -+ (const_string "neon_fp_vmla_ddd") -+ (const_string "neon_fp_vmla_qqq")) -+ (if_then_else (ne (symbol_ref "") (const_int 0)) -+ (if_then_else -+ (ne (symbol_ref "") (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 "") (const_int 0)) -+ (const_string "neon_mla_qqq_8_16") -+ (const_string "neon_mla_qqq_32_qqd_32_scalar")))))] -+) -+ - (define_insn "ior3" - [(set (match_operand:VDQ 0 "s_register_operand" "=w,w") - (ior:VDQ (match_operand:VDQ 1 "s_register_operand" "w,0") -@@ -3611,7 +3715,8 @@ - UNSPEC_VSHLL_N))] - "TARGET_NEON" - { -- neon_const_bounds (operands[2], 0, neon_element_bits (mode)); -+ /* The boundaries are: 0 < imm <= size. */ -+ neon_const_bounds (operands[2], 0, neon_element_bits (mode) + 1); - return "vshll.%T3%#\t%q0, %P1, %2"; - } - [(set_attr "neon_type" "neon_shift_1")] ---- a/gcc/config/arm/neon.ml -+++ b/gcc/config/arm/neon.ml -@@ -50,7 +50,7 @@ - | 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 @@ - | 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/neon-testgen.ml -+++ b/gcc/config/arm/neon-testgen.ml -@@ -51,8 +51,8 @@ - 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/netbsd-elf.h -+++ b/gcc/config/arm/netbsd-elf.h -@@ -153,5 +153,5 @@ - 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 -+ . */ -+ -+#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 @@ - $(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 += 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* ---- 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/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". We only use these when -+;; optimizing for size since "muls" is slow on all known -+;; implementations and since "mul" will be generated by -+;; "*arm_mulsi3_v6" anyhow. The assembler will use a 16-bit encoding -+;; for "mul" 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/t-linux-eabi -+++ b/gcc/config/arm/t-linux-eabi -@@ -6,8 +6,8 @@ - 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 @@ - 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/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 @@ - while (code != _URC_END_OF_STACK - && code != _URC_FAILURE); - -- finish: - restore_non_core_regs (&saved_vrs); - return code; - } -@@ -1168,6 +1167,9 @@ - { - 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 @@ - 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 @@ - _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 @@ - 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))" - { -+ if (can_create_pseudo_p ()) -+ { -+ if (GET_CODE (operands[0]) != REG) -+ operands[1] = force_reg (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" ---- /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 -+;; . -+;; -+;; 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 @@ - #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) -@@ -203,7 +203,7 @@ - #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 @@ - 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 @@ - /* 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 @@ - - __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 @@ - 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 @@ - 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 @@ - 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 -+++ b/gcc/config/i386/i386.c -@@ -1036,6 +1036,79 @@ - 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 @@ - #define m_PENT4 (1<